git-svn: trunk@1590
Nigel Horne authored on 2005/05/27 23:56:19... | ... |
@@ -1,3 +1,12 @@ |
1 |
+Fri May 27 15:55:00 BST 2005 (njh) |
|
2 |
+---------------------------------- |
|
3 |
+ * clamav-milter: EXPERIMENTAL |
|
4 |
+ When loading a new database when not in external mode, |
|
5 |
+ keep scanning with the old one rather than |
|
6 |
+ hold up incoming mails while waiting for |
|
7 |
+ clamav-milter to become idle then reloading the |
|
8 |
+ database |
|
9 |
+ |
|
1 | 10 |
Thu May 26 04:03:31 CEST 2005 (tk) |
2 | 11 |
---------------------------------- |
3 | 12 |
* clamd/scanner.c: quick recovery of thread resources when clamd clients |
... | ... |
@@ -812,6 +812,11 @@ Changes |
812 | 812 |
When dying use LOG_CRIT rather than LOG_ERR |
813 | 813 |
0.85d 25/5/05: When not in external mode, TEMPFAIL when loading a new |
814 | 814 |
database, even when --dont-wait isn't given |
815 |
+0.85e 27/5/05: When loading a new database when not in external mode, |
|
816 |
+ keep scanning with the old one rather than |
|
817 |
+ hold up incoming mails while waiting for |
|
818 |
+ clamav-milter to become idle then reloading the |
|
819 |
+ database |
|
815 | 820 |
|
816 | 821 |
4. INTERNATIONALISATION |
817 | 822 |
|
... | ... |
@@ -22,9 +22,9 @@ |
22 | 22 |
* |
23 | 23 |
* For installation instructions see the file INSTALL that came with this file |
24 | 24 |
*/ |
25 |
-static char const rcsid[] = "$Id: clamav-milter.c,v 1.205 2005/05/25 19:39:03 nigelhorne Exp $"; |
|
25 |
+static char const rcsid[] = "$Id: clamav-milter.c,v 1.206 2005/05/27 14:52:58 nigelhorne Exp $"; |
|
26 | 26 |
|
27 |
-#define CM_VERSION "0.85d" |
|
27 |
+#define CM_VERSION "0.85e" |
|
28 | 28 |
|
29 | 29 |
#if HAVE_CONFIG_H |
30 | 30 |
#include "clamav-config.h" |
... | ... |
@@ -285,6 +285,7 @@ static const char *progname; /* our name - usually clamav-milter */ |
285 | 285 |
|
286 | 286 |
/* Variables for --external */ |
287 | 287 |
static int external = 0; /* scan messages ourself or use clamd? */ |
288 |
+static pthread_mutex_t root_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
288 | 289 |
static struct cl_node *root = NULL; |
289 | 290 |
static struct cl_limits limits; |
290 | 291 |
static struct cl_stat dbstat; |
... | ... |
@@ -371,9 +372,6 @@ static pthread_mutex_t n_children_mutex = PTHREAD_MUTEX_INITIALIZER; |
371 | 371 |
static pthread_cond_t n_children_cond = PTHREAD_COND_INITIALIZER; |
372 | 372 |
static volatile unsigned int n_children = 0; |
373 | 373 |
static unsigned int max_children = 0; |
374 |
-static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
375 |
-static pthread_cond_t accept_cond = PTHREAD_COND_INITIALIZER; |
|
376 |
-static volatile int accept_inputs; |
|
377 | 374 |
static int child_timeout = 0; /* number of seconds to wait for |
378 | 375 |
* a child to die. Set to 0 to |
379 | 376 |
* wait forever |
... | ... |
@@ -1051,11 +1049,9 @@ main(int argc, char **argv) |
1051 | 1051 |
|
1052 | 1052 |
if(cfgopt(copt, "LogVerbose")) { |
1053 | 1053 |
logVerbose = 1; |
1054 |
-#if 0 |
|
1055 |
-#if SENDMAIL_VERSION > 8.13 |
|
1054 |
+#if ((SENDMAIL_VERSION_A > 8) || ((SENDMAIL_VERSION_A == 8) && (SENDMAIL_VERSION_B >= 13))) |
|
1056 | 1055 |
smfi_setdbg(6); |
1057 | 1056 |
#endif |
1058 |
-#endif |
|
1059 | 1057 |
} |
1060 | 1058 |
use_syslog = 1; |
1061 | 1059 |
|
... | ... |
@@ -1485,7 +1481,6 @@ main(int argc, char **argv) |
1485 | 1485 |
limits.archivememlim = 0; |
1486 | 1486 |
} |
1487 | 1487 |
} |
1488 |
- accept_inputs = 1; |
|
1489 | 1488 |
|
1490 | 1489 |
#ifdef SESSION |
1491 | 1490 |
/* FIXME: add localSocket support to watchdog */ |
... | ... |
@@ -1573,14 +1568,12 @@ main(int argc, char **argv) |
1573 | 1573 |
return EX_UNAVAILABLE; |
1574 | 1574 |
} |
1575 | 1575 |
|
1576 |
-#if 0 |
|
1577 |
-#if SENDMAIL_VERSION > 8.13 |
|
1576 |
+#if ((SENDMAIL_VERSION_A > 8) || ((SENDMAIL_VERSION_A == 8) && (SENDMAIL_VERSION_B >= 13))) |
|
1578 | 1577 |
if(smfi_opensocket(1) == MI_FAILURE) { |
1579 | 1578 |
cli_errmsg("Can't open/create %s\n", port); |
1580 | 1579 |
return EX_CONFIG; |
1581 | 1580 |
} |
1582 | 1581 |
#endif |
1583 |
-#endif |
|
1584 | 1582 |
|
1585 | 1583 |
signal(SIGPIPE, SIG_IGN); /* libmilter probably does this as well */ |
1586 | 1584 |
|
... | ... |
@@ -1991,34 +1984,10 @@ clamfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr) |
1991 | 1991 |
char ip[INET_ADDRSTRLEN]; /* IPv4 only */ |
1992 | 1992 |
#endif |
1993 | 1993 |
const char *remoteIP; |
1994 |
- int accepting; |
|
1995 | 1994 |
|
1996 | 1995 |
if(quitting) |
1997 | 1996 |
return cl_error; |
1998 | 1997 |
|
1999 |
- pthread_mutex_lock(&accept_mutex); |
|
2000 |
- accepting = accept_inputs; |
|
2001 |
- pthread_mutex_unlock(&accept_mutex); |
|
2002 |
- if(!accepting) { |
|
2003 |
- cli_warnmsg("Not accepting inputs at the moment\n"); |
|
2004 |
-#if 0 |
|
2005 |
- /* |
|
2006 |
- * We must refuse here even if dont_wait isn't set, since |
|
2007 |
- * it could take some time, and sendmail could time us out |
|
2008 |
- * and refuse to have anything more to do with us until |
|
2009 |
- * the program is restarted |
|
2010 |
- */ |
|
2011 |
- if(dont_wait) |
|
2012 |
- return SMFIS_TEMPFAIL; |
|
2013 |
- pthread_mutex_lock(&accept_mutex); |
|
2014 |
- while(!accept_inputs) |
|
2015 |
- pthread_cond_wait(&accept_cond, &accept_mutex); |
|
2016 |
- pthread_mutex_unlock(&accept_mutex); |
|
2017 |
- cli_warnmsg("Accepting inputs again\n"); |
|
2018 |
-#endif |
|
2019 |
- return SMFIS_TEMPFAIL; |
|
2020 |
- } |
|
2021 |
- |
|
2022 | 1998 |
if(ctx == NULL) { |
2023 | 1999 |
if(use_syslog) |
2024 | 2000 |
syslog(LOG_ERR, _("clamfi_connect: ctx is null")); |
... | ... |
@@ -2604,12 +2573,21 @@ clamfi_eom(SMFICTX *ctx) |
2604 | 2604 |
if(!external) { |
2605 | 2605 |
const char *virname; |
2606 | 2606 |
unsigned long int scanned = 0L; |
2607 |
+ struct cl_node *scanning_root; |
|
2607 | 2608 |
|
2608 | 2609 |
/* |
2609 | 2610 |
* TODO: consider using cl_scandesc and not using a temporary |
2610 | 2611 |
* file from the mail being read in |
2611 | 2612 |
*/ |
2612 |
- switch(cl_scanfile(privdata->filename, &virname, &scanned, root, &limits, options)) { |
|
2613 |
+ pthread_mutex_lock(&root_mutex); |
|
2614 |
+ scanning_root = cl_dup(root); |
|
2615 |
+ pthread_mutex_unlock(&root_mutex); |
|
2616 |
+ if(scanning_root == NULL) { |
|
2617 |
+ cli_errmsg("scanning_root == NULL\n"); |
|
2618 |
+ clamfi_cleanup(ctx); |
|
2619 |
+ return cl_error; |
|
2620 |
+ } |
|
2621 |
+ switch(cl_scanfile(privdata->filename, &virname, &scanned, scanning_root, &limits, options)) { |
|
2613 | 2622 |
case CL_CLEAN: |
2614 | 2623 |
strcpy(mess, "OK"); |
2615 | 2624 |
break; |
... | ... |
@@ -2622,6 +2600,7 @@ clamfi_eom(SMFICTX *ctx) |
2622 | 2622 |
logger(mess); |
2623 | 2623 |
break; |
2624 | 2624 |
} |
2625 |
+ cl_free(scanning_root); |
|
2625 | 2626 |
|
2626 | 2627 |
#ifdef SESSION |
2627 | 2628 |
session = NULL; |
... | ... |
@@ -4426,71 +4405,29 @@ watchdog(void *a) |
4426 | 4426 |
pthread_mutex_unlock(&watchdog_mutex); |
4427 | 4427 |
|
4428 | 4428 |
if(!external) { |
4429 |
- int dbstatus = cl_statchkdir(&dbstat); |
|
4430 |
- |
|
4431 | 4429 |
/* |
4432 |
- * Re-load the database if the server's not busy. |
|
4433 |
- * TODO: If a reload is needed go into a mode when |
|
4434 |
- * new scans aren't accepted, to force the number |
|
4435 |
- * of children to 0 so that we can reload, |
|
4436 |
- * otherwise a reload may not occur on overloaded |
|
4437 |
- * servers |
|
4430 |
+ * Re-load the database if needed |
|
4438 | 4431 |
*/ |
4439 |
- pthread_mutex_lock(&n_children_mutex); |
|
4440 |
- if((n_children == 0) && (dbstatus == 1)) { |
|
4441 |
- pthread_mutex_lock(&accept_mutex); |
|
4442 |
- accept_inputs = 0; |
|
4443 |
- pthread_mutex_unlock(&accept_mutex); |
|
4444 |
- cli_dbgmsg("Database has changed\n"); |
|
4445 |
- cl_statfree(&dbstat); |
|
4446 |
- /* check for race condition */ |
|
4447 |
- while(n_children > 0) |
|
4448 |
- pthread_cond_wait(&n_children_cond, &n_children_mutex); |
|
4449 |
- if(use_syslog) |
|
4450 |
- syslog(LOG_WARNING, _("Loading new database")); |
|
4451 |
- if(loadDatabase() != 0) { |
|
4452 |
- pthread_mutex_unlock(&n_children_mutex); |
|
4453 |
- smfi_stop(); |
|
4454 |
- cli_errmsg("Failed to load updated database\n"); |
|
4455 |
- return NULL; |
|
4456 |
- } |
|
4457 |
- pthread_mutex_lock(&accept_mutex); |
|
4458 |
- accept_inputs = 1; |
|
4459 |
- pthread_cond_broadcast(&accept_cond); |
|
4460 |
- pthread_mutex_unlock(&accept_mutex); |
|
4461 |
- } else if(dbstatus == 0) |
|
4462 |
- cli_dbgmsg("Database has not changed\n"); |
|
4463 |
- else if(dbstatus == 1) { |
|
4464 |
- cli_warnmsg("Not reloading database until idle - waiting for %d children\n", n_children); |
|
4465 |
- pthread_mutex_lock(&accept_mutex); |
|
4466 |
- accept_inputs = 0; |
|
4467 |
- pthread_mutex_unlock(&accept_mutex); |
|
4468 |
- |
|
4469 |
- while(n_children > 0) { |
|
4470 |
- pthread_cond_wait(&n_children_cond, &n_children_mutex); |
|
4471 |
- cli_warnmsg("Waiting for %d children until database reload\n", n_children); |
|
4472 |
- } |
|
4473 |
- |
|
4474 |
- cl_statfree(&dbstat); |
|
4475 |
- if(use_syslog) |
|
4476 |
- syslog(LOG_WARNING, _("Loading new database")); |
|
4477 |
- if(loadDatabase() != 0) { |
|
4478 |
- pthread_mutex_unlock(&n_children_mutex); |
|
4432 |
+ switch(cl_statchkdir(&dbstat)) { |
|
4433 |
+ case 1: |
|
4434 |
+ cli_dbgmsg("Database has changed\n"); |
|
4435 |
+ cl_statfree(&dbstat); |
|
4436 |
+ if(use_syslog) |
|
4437 |
+ syslog(LOG_WARNING, _("Loading new database")); |
|
4438 |
+ if(loadDatabase() != 0) { |
|
4439 |
+ smfi_stop(); |
|
4440 |
+ cli_errmsg("Failed to load updated database\n"); |
|
4441 |
+ return NULL; |
|
4442 |
+ } |
|
4443 |
+ break; |
|
4444 |
+ case 0: |
|
4445 |
+ cli_dbgmsg("Database has not changed\n"); |
|
4446 |
+ break; |
|
4447 |
+ default: |
|
4479 | 4448 |
smfi_stop(); |
4480 |
- cli_errmsg("Failed to load updated database\n"); |
|
4449 |
+ cli_errmsg("Database error - %s is stopping\n", progname); |
|
4481 | 4450 |
return NULL; |
4482 |
- } |
|
4483 |
- pthread_mutex_lock(&accept_mutex); |
|
4484 |
- accept_inputs = 1; |
|
4485 |
- pthread_cond_broadcast(&accept_cond); |
|
4486 |
- pthread_mutex_unlock(&accept_mutex); |
|
4487 |
- } else { |
|
4488 |
- smfi_stop(); |
|
4489 |
- cli_errmsg("Database error - %s is stopping\n", progname); |
|
4490 |
- pthread_mutex_unlock(&n_children_mutex); |
|
4491 |
- return NULL; |
|
4492 | 4451 |
} |
4493 |
- pthread_mutex_unlock(&n_children_mutex); |
|
4494 | 4452 |
continue; |
4495 | 4453 |
} |
4496 | 4454 |
i = 0; |
... | ... |
@@ -4597,7 +4534,6 @@ watchdog(void *a) |
4597 | 4597 |
while(!quitting) { |
4598 | 4598 |
struct timespec ts; |
4599 | 4599 |
struct timeval tp; |
4600 |
- int dbstatus; |
|
4601 | 4600 |
|
4602 | 4601 |
gettimeofday(&tp, NULL); |
4603 | 4602 |
|
... | ... |
@@ -4621,69 +4557,29 @@ watchdog(void *a) |
4621 | 4621 |
pthread_mutex_unlock(&watchdog_mutex); |
4622 | 4622 |
|
4623 | 4623 |
/* |
4624 |
- * Re-load the database if the server's not busy. |
|
4625 |
- * TODO: If a reload is needed go into a mode when |
|
4626 |
- * new scans aren't accepted, to force the number |
|
4627 |
- * of children to 0 so that we can reload, |
|
4628 |
- * otherwise a reload may not occur on overloaded |
|
4629 |
- * servers |
|
4624 |
+ * Re-load the database. |
|
4630 | 4625 |
*/ |
4631 |
- dbstatus = cl_statchkdir(&dbstat); |
|
4632 |
- pthread_mutex_lock(&n_children_mutex); |
|
4633 |
- if((n_children == 0) && (dbstatus == 1)) { |
|
4634 |
- pthread_mutex_lock(&accept_mutex); |
|
4635 |
- accept_inputs = 0; |
|
4636 |
- pthread_mutex_unlock(&accept_mutex); |
|
4637 |
- cli_dbgmsg("Database has changed\n"); |
|
4638 |
- cl_statfree(&dbstat); |
|
4639 |
- /* check for race condition */ |
|
4640 |
- while(n_children > 0) |
|
4641 |
- pthread_cond_wait(&n_children_cond, &n_children_mutex); |
|
4642 |
- if(use_syslog) |
|
4643 |
- syslog(LOG_WARNING, _("Loading new database")); |
|
4644 |
- if(loadDatabase() != 0) { |
|
4645 |
- pthread_mutex_unlock(&n_children_mutex); |
|
4646 |
- smfi_stop(); |
|
4647 |
- cli_errmsg("Failed to load updated database\n"); |
|
4648 |
- return NULL; |
|
4649 |
- } |
|
4650 |
- pthread_mutex_lock(&accept_mutex); |
|
4651 |
- accept_inputs = 1; |
|
4652 |
- pthread_cond_broadcast(&accept_cond); |
|
4653 |
- pthread_mutex_unlock(&accept_mutex); |
|
4654 |
- } else if(dbstatus == 0) |
|
4655 |
- cli_dbgmsg("Database has not changed\n"); |
|
4656 |
- else if(dbstatus == 1) { |
|
4657 |
- cli_warnmsg("Not reloading database until idle - waiting for %d children\n", n_children); |
|
4658 |
- pthread_mutex_lock(&accept_mutex); |
|
4659 |
- accept_inputs = 0; |
|
4660 |
- pthread_mutex_unlock(&accept_mutex); |
|
4661 |
- |
|
4662 |
- while(n_children > 0) { |
|
4663 |
- pthread_cond_wait(&n_children_cond, &n_children_mutex); |
|
4664 |
- cli_warnmsg("Waiting for %d children until database reload\n", n_children); |
|
4665 |
- } |
|
4666 |
- cl_statfree(&dbstat); |
|
4667 |
- if(use_syslog) |
|
4668 |
- syslog(LOG_WARNING, _("Loading new database")); |
|
4669 |
- if(loadDatabase() != 0) { |
|
4670 |
- pthread_mutex_unlock(&n_children_mutex); |
|
4626 |
+ switch(cl_statchkdir(&dbstat)) { |
|
4627 |
+ case 1: |
|
4628 |
+ cli_dbgmsg("Database has changed\n"); |
|
4629 |
+ cl_statfree(&dbstat); |
|
4630 |
+ if(use_syslog) |
|
4631 |
+ syslog(LOG_WARNING, _("Loading new database")); |
|
4632 |
+ if(loadDatabase() != 0) { |
|
4633 |
+ smfi_stop(); |
|
4634 |
+ cli_errmsg("Failed to load updated database\n"); |
|
4635 |
+ return NULL; |
|
4636 |
+ } |
|
4637 |
+ break; |
|
4638 |
+ case 0: |
|
4639 |
+ cli_dbgmsg("Database has not changed\n"); |
|
4640 |
+ break; |
|
4641 |
+ default: |
|
4671 | 4642 |
smfi_stop(); |
4672 |
- cli_errmsg("Failed to load updated database\n"); |
|
4643 |
+ cli_errmsg("Database error - %s is stopping\n", progname); |
|
4673 | 4644 |
return NULL; |
4674 |
- } |
|
4675 |
- pthread_mutex_lock(&accept_mutex); |
|
4676 |
- accept_inputs = 1; |
|
4677 |
- if(pthread_cond_broadcast(&accept_cond) < 0) |
|
4678 |
- perror("pthread_cond_broadcast"); |
|
4679 |
- pthread_mutex_unlock(&accept_mutex); |
|
4680 |
- } else { |
|
4681 |
- smfi_stop(); |
|
4682 |
- cli_errmsg("Database error - %s is stopping\n", progname); |
|
4683 |
- pthread_mutex_unlock(&n_children_mutex); |
|
4684 |
- return NULL; |
|
4685 | 4645 |
} |
4686 |
- pthread_mutex_unlock(&n_children_mutex); |
|
4646 |
+ continue; |
|
4687 | 4647 |
} |
4688 | 4648 |
cli_dbgmsg("watchdog quits\n"); |
4689 | 4649 |
return NULL; |
... | ... |
@@ -4779,10 +4675,6 @@ quit(void) |
4779 | 4779 |
|
4780 | 4780 |
quitting++; |
4781 | 4781 |
|
4782 |
- pthread_mutex_lock(&accept_mutex); |
|
4783 |
- accept_inputs = 0; |
|
4784 |
- pthread_mutex_unlock(&accept_mutex); |
|
4785 |
- |
|
4786 | 4782 |
#ifdef SESSION |
4787 | 4783 |
pthread_mutex_lock(&version_mutex); |
4788 | 4784 |
#endif |
... | ... |
@@ -4793,10 +4685,12 @@ quit(void) |
4793 | 4793 |
#endif |
4794 | 4794 |
|
4795 | 4795 |
if(!external) { |
4796 |
+ pthread_mutex_lock(&root_mutex); |
|
4796 | 4797 |
if(root) { |
4797 | 4798 |
cl_free(root); |
4798 | 4799 |
root = NULL; |
4799 | 4800 |
} |
4801 |
+ pthread_mutex_unlock(&root_mutex); |
|
4800 | 4802 |
} else { |
4801 | 4803 |
#ifdef SESSION |
4802 | 4804 |
int i = 0; |
... | ... |
@@ -4862,8 +4756,7 @@ broadcast(const char *mess) |
4862 | 4862 |
} |
4863 | 4863 |
|
4864 | 4864 |
/* |
4865 |
- * Load a new database into the internal scanner - it is up to the caller to |
|
4866 |
- * ensure that no threads are currently scanning |
|
4865 |
+ * Load a new database into the internal scanner |
|
4867 | 4866 |
*/ |
4868 | 4867 |
static int |
4869 | 4868 |
loadDatabase(void) |
... | ... |
@@ -4875,6 +4768,7 @@ loadDatabase(void) |
4875 | 4875 |
char *daily, *ptr; |
4876 | 4876 |
struct cl_cvd *d; |
4877 | 4877 |
const struct cfgstruct *cpt; |
4878 |
+ struct cl_node *newroot, *oldroot; |
|
4878 | 4879 |
static const char *dbdir; |
4879 | 4880 |
|
4880 | 4881 |
assert(!external); |
... | ... |
@@ -4933,30 +4827,30 @@ loadDatabase(void) |
4933 | 4933 |
if((ptr = strchr(clamav_version, '\n')) != NULL) |
4934 | 4934 |
*ptr = '\0'; |
4935 | 4935 |
|
4936 |
- if(root) { |
|
4937 |
- cl_free(root); |
|
4938 |
- root = NULL; |
|
4939 |
- } |
|
4940 | 4936 |
signatures = 0; |
4941 |
- ret = cl_loaddbdir(dbdir, &root, &signatures); |
|
4937 |
+ newroot = NULL; |
|
4938 |
+ ret = cl_loaddbdir(dbdir, &newroot, &signatures); |
|
4942 | 4939 |
if(ret != 0) { |
4943 | 4940 |
cli_errmsg("%s\n", cl_strerror(ret)); |
4944 | 4941 |
return -1; |
4945 | 4942 |
} |
4946 |
- if(root == NULL) { |
|
4943 |
+ if(newroot == NULL) { |
|
4947 | 4944 |
cli_errmsg("Can't initialize the virus database.\n"); |
4948 | 4945 |
return -1; |
4949 | 4946 |
} |
4950 | 4947 |
|
4951 |
- ret = cl_build(root); |
|
4948 |
+ ret = cl_build(newroot); |
|
4952 | 4949 |
if(ret != 0) { |
4953 | 4950 |
cli_errmsg("Database initialization error: %s\n", cl_strerror(ret)); |
4951 |
+ cl_free(newroot); |
|
4954 | 4952 |
return -1; |
4955 | 4953 |
} |
4956 |
- cli_dbgmsg("Database updated\n"); |
|
4957 |
- if(use_syslog) { |
|
4958 |
- syslog(LOG_INFO, _("ClamAV: Protecting against %u viruses"), signatures); |
|
4954 |
+ pthread_mutex_lock(&root_mutex); |
|
4955 |
+ oldroot = root; |
|
4956 |
+ root = newroot; |
|
4957 |
+ pthread_mutex_unlock(&root_mutex); |
|
4959 | 4958 |
|
4959 |
+ if(use_syslog) { |
|
4960 | 4960 |
#ifdef SESSION |
4961 | 4961 |
pthread_mutex_lock(&version_mutex); |
4962 | 4962 |
#endif |
... | ... |
@@ -4964,7 +4858,13 @@ loadDatabase(void) |
4964 | 4964 |
#ifdef SESSION |
4965 | 4965 |
pthread_mutex_unlock(&version_mutex); |
4966 | 4966 |
#endif |
4967 |
+ syslog(LOG_INFO, _("ClamAV: Protecting against %u viruses"), signatures); |
|
4967 | 4968 |
} |
4969 |
+ if(oldroot) { |
|
4970 |
+ cli_dbgmsg("Database updated\n"); |
|
4971 |
+ cl_free(oldroot); |
|
4972 |
+ } else |
|
4973 |
+ cli_dbgmsg("Database loaded\n"); |
|
4968 | 4974 |
|
4969 | 4975 |
return cl_statinidir(dbdir, &dbstat); |
4970 | 4976 |
} |