git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1365 77e5149b-7576-45b1-b177-96237e5ba77b
Nigel Horne authored on 2005/03/02 03:58:01... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Tue Mar 1 18:57:18 GMT 2005 (njh) |
|
2 |
+---------------------------------- |
|
3 |
+ * clamav-milter: Improved database update detection when not --external |
|
4 |
+ |
|
1 | 5 |
Tue Mar 1 02:29:54 CET 2005 (tk) |
2 | 6 |
--------------------------------- |
3 | 7 |
* clamscan: use --include-dir/exclude-dir for directories instead of |
... | ... |
@@ -698,6 +698,10 @@ Changes |
698 | 698 |
0.83 13/2/05: Up issue |
699 | 699 |
0.83a 23/2/05: Issue a warning if sendmail can't be executed |
700 | 700 |
Remove pidfile, suggested by Stephen Gran <steve@lobefin.net> |
701 |
+0.83b 1/3/05: When not using --external, if a database update is |
|
702 |
+ found, stop accepting inputs to quiten the |
|
703 |
+ system for the database reload, rather than |
|
704 |
+ wait for it to happen by itself |
|
701 | 705 |
|
702 | 706 |
INTERNATIONALISATION |
703 | 707 |
|
... | ... |
@@ -26,6 +26,9 @@ |
26 | 26 |
* |
27 | 27 |
* Change History: |
28 | 28 |
* $Log: clamav-milter.c,v $ |
29 |
+ * Revision 1.185 2005/03/01 18:55:14 nigelhorne |
|
30 |
+ * Improved database update detection when not --external |
|
31 |
+ * |
|
29 | 32 |
* Revision 1.184 2005/02/23 09:41:39 nigelhorne |
30 | 33 |
* Remove the pidfile |
31 | 34 |
* |
... | ... |
@@ -563,9 +566,9 @@ |
563 | 563 |
* Revision 1.6 2003/09/28 16:37:23 nigelhorne |
564 | 564 |
* Added -f flag use MaxThreads if --max-children not set |
565 | 565 |
*/ |
566 |
-static char const rcsid[] = "$Id: clamav-milter.c,v 1.184 2005/02/23 09:41:39 nigelhorne Exp $"; |
|
566 |
+static char const rcsid[] = "$Id: clamav-milter.c,v 1.185 2005/03/01 18:55:14 nigelhorne Exp $"; |
|
567 | 567 |
|
568 |
-#define CM_VERSION "0.83a" |
|
568 |
+#define CM_VERSION "0.83b" |
|
569 | 569 |
|
570 | 570 |
#if HAVE_CONFIG_H |
571 | 571 |
#include "clamav-config.h" |
... | ... |
@@ -894,6 +897,9 @@ static pthread_mutex_t n_children_mutex = PTHREAD_MUTEX_INITIALIZER; |
894 | 894 |
static pthread_cond_t n_children_cond = PTHREAD_COND_INITIALIZER; |
895 | 895 |
static unsigned int n_children = 0; |
896 | 896 |
static unsigned int max_children = 0; |
897 |
+static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
898 |
+static pthread_cond_t accept_cond = PTHREAD_COND_INITIALIZER; |
|
899 |
+static int accept_inputs; |
|
897 | 900 |
static int child_timeout = 0; /* number of seconds to wait for |
898 | 901 |
* a child to die. Set to 0 to |
899 | 902 |
* wait forever |
... | ... |
@@ -1328,7 +1334,7 @@ main(int argc, char **argv) |
1328 | 1328 |
/* FIXME: error if --servers and --external is not given */ |
1329 | 1329 |
/* TODO: support freshclam's daemon notify if --external is not given */ |
1330 | 1330 |
|
1331 |
- if (optind == argc) { |
|
1331 |
+ if(optind == argc) { |
|
1332 | 1332 |
fprintf(stderr, _("%s: No socket-addr given\n"), argv[0]); |
1333 | 1333 |
return EX_USAGE; |
1334 | 1334 |
} |
... | ... |
@@ -1924,6 +1930,7 @@ main(int argc, char **argv) |
1924 | 1924 |
limits.archivememlim = 0; |
1925 | 1925 |
} |
1926 | 1926 |
} |
1927 |
+ accept_inputs = 1; |
|
1927 | 1928 |
|
1928 | 1929 |
#ifdef SESSION |
1929 | 1930 |
/* FIXME: add localSocket support to watchdog */ |
... | ... |
@@ -2053,6 +2060,8 @@ createSession(int s) |
2053 | 2053 |
char hostname[MAXHOSTNAMELEN + 1]; |
2054 | 2054 |
|
2055 | 2055 |
cli_strtokbuf(serverHostNames, serverNumber, ":", hostname); |
2056 |
+ if(strcmp(hostname, "127.0.0.1") == 0) |
|
2057 |
+ gethostname(hostname, sizeof(hostname)); |
|
2056 | 2058 |
#else |
2057 | 2059 |
char *hostname = cli_strtok(serverHostNames, serverNumber, ":"); |
2058 | 2060 |
#endif |
... | ... |
@@ -2316,6 +2325,8 @@ findServer(void) |
2316 | 2316 |
char hostname[MAXHOSTNAMELEN + 1]; |
2317 | 2317 |
|
2318 | 2318 |
cli_strtokbuf(serverHostNames, i, ":", hostname); |
2319 |
+ if(strcmp(hostname, "127.0.0.1") == 0) |
|
2320 |
+ gethostname(hostname, sizeof(hostname)); |
|
2319 | 2321 |
#else |
2320 | 2322 |
char *hostname = cli_strtok(serverHostNames, i, ":"); |
2321 | 2323 |
#endif |
... | ... |
@@ -2395,10 +2406,27 @@ clamfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr) |
2395 | 2395 |
char ip[INET_ADDRSTRLEN]; /* IPv4 only */ |
2396 | 2396 |
#endif |
2397 | 2397 |
const char *remoteIP; |
2398 |
+ int accepting; |
|
2398 | 2399 |
|
2399 | 2400 |
if(quitting) |
2400 | 2401 |
return cl_error; |
2401 | 2402 |
|
2403 |
+ pthread_mutex_lock(&accept_mutex); |
|
2404 |
+ accepting = accept_inputs; |
|
2405 |
+ pthread_mutex_unlock(&accept_mutex); |
|
2406 |
+ if(!accepting) { |
|
2407 |
+ cli_warnmsg("Not accepting inputs at the moment\n"); |
|
2408 |
+ if(dont_wait) |
|
2409 |
+ return SMFIS_TEMPFAIL; |
|
2410 |
+ do { |
|
2411 |
+ pthread_cond_wait(&accept_cond, &accept_mutex); |
|
2412 |
+ pthread_mutex_lock(&accept_mutex); |
|
2413 |
+ accepting = accept_inputs; |
|
2414 |
+ pthread_mutex_unlock(&accept_mutex); |
|
2415 |
+ } while(!accepting); |
|
2416 |
+ cli_warnmsg("Accepting inputs again\n"); |
|
2417 |
+ } |
|
2418 |
+ |
|
2402 | 2419 |
if(ctx == NULL) { |
2403 | 2420 |
if(use_syslog) |
2404 | 2421 |
syslog(LOG_ERR, _("clamfi_connect: ctx is null")); |
... | ... |
@@ -3038,15 +3066,24 @@ clamfi_eom(SMFICTX *ctx) |
3038 | 3038 |
syslog(LOG_DEBUG, _("clamfi_eom: read %s"), mess); |
3039 | 3039 |
cli_dbgmsg(_("clamfi_eom: read %s\n"), mess); |
3040 | 3040 |
} else { |
3041 |
+#ifdef MAXHOSTNAMELEN |
|
3042 |
+ char hostname[MAXHOSTNAMELEN + 1]; |
|
3043 |
+ |
|
3044 |
+ cli_strtokbuf(serverHostNames, privdata->serverNumber, ":", hostname); |
|
3045 |
+ if(strcmp(hostname, "127.0.0.1") == 0) |
|
3046 |
+ gethostname(hostname, sizeof(hostname)); |
|
3047 |
+#else |
|
3048 |
+ char *hostname = cli_strtok(serverHostNames, privdata->serverNumber, ":"); |
|
3049 |
+#endif |
|
3041 | 3050 |
/* |
3042 | 3051 |
* TODO: if more than one host has been specified, try |
3043 | 3052 |
* another one - setting cl_error to SMFIS_TEMPFAIL helps |
3044 | 3053 |
* by forcing a retry |
3045 | 3054 |
*/ |
3046 | 3055 |
clamfi_cleanup(ctx); |
3047 |
- syslog(LOG_NOTICE, _("clamfi_eom: read nothing from clamd")); |
|
3056 |
+ syslog(LOG_NOTICE, _("clamfi_eom: read nothing from clamd on %s"), hostname); |
|
3048 | 3057 |
#ifdef CL_DEBUG |
3049 |
- cli_dbgmsg(_("clamfi_eom: read nothing from clamd\n")); |
|
3058 |
+ cli_dbgmsg(_("clamfi_eom: read nothing from clamd on %s\n"), hostname); |
|
3050 | 3059 |
#endif |
3051 | 3060 |
#ifdef SESSION |
3052 | 3061 |
pthread_mutex_lock(&sstatus_mutex); |
... | ... |
@@ -3116,6 +3153,8 @@ clamfi_eom(SMFICTX *ctx) |
3116 | 3116 |
char hostname[MAXHOSTNAMELEN + 1]; |
3117 | 3117 |
|
3118 | 3118 |
if(cli_strtokbuf(serverHostNames, privdata->serverNumber, ":", hostname)) { |
3119 |
+ if(strcmp(hostname, "127.0.0.1") == 0) |
|
3120 |
+ gethostname(hostname, sizeof(hostname)); |
|
3119 | 3121 |
#else |
3120 | 3122 |
char *hostname = cli_strtok(serverHostNames, privdata->serverNumber, ":"); |
3121 | 3123 |
if(hostname) { |
... | ... |
@@ -4750,6 +4789,8 @@ watchdog(void *a) |
4750 | 4750 |
pthread_mutex_unlock(&watchdog_mutex); |
4751 | 4751 |
|
4752 | 4752 |
if(!external) { |
4753 |
+ int dbstatus = cl_statchkdir(&dbstat); |
|
4754 |
+ |
|
4753 | 4755 |
/* |
4754 | 4756 |
* Re-load the database if the server's not busy. |
4755 | 4757 |
* TODO: If a reload is needed go into a mode when |
... | ... |
@@ -4759,12 +4800,54 @@ watchdog(void *a) |
4759 | 4759 |
* servers |
4760 | 4760 |
*/ |
4761 | 4761 |
pthread_mutex_lock(&n_children_mutex); |
4762 |
- if((n_children == 0) && (cl_statchkdir(&dbstat) == 1)) { |
|
4762 |
+ if((n_children == 0) && (dbstatus == 1)) { |
|
4763 |
+ pthread_mutex_lock(&accept_mutex); |
|
4764 |
+ accept_inputs = 0; |
|
4765 |
+ pthread_mutex_unlock(&accept_mutex); |
|
4766 |
+ cli_dbgmsg("Database has changed\n"); |
|
4767 |
+ cl_statfree(&dbstat); |
|
4768 |
+ /* check for race condition */ |
|
4769 |
+ while(n_children > 0) |
|
4770 |
+ pthread_cond_wait(&n_children_cond, &n_children_mutex); |
|
4771 |
+ if(use_syslog) |
|
4772 |
+ syslog(LOG_WARNING, _("Loading new database")); |
|
4773 |
+ if(loadDatabase() != 0) { |
|
4774 |
+ pthread_mutex_unlock(&n_children_mutex); |
|
4775 |
+ smfi_stop(); |
|
4776 |
+ return NULL; |
|
4777 |
+ } |
|
4778 |
+ pthread_mutex_lock(&accept_mutex); |
|
4779 |
+ accept_inputs = 1; |
|
4780 |
+ pthread_cond_broadcast(&accept_cond); |
|
4781 |
+ pthread_mutex_unlock(&accept_mutex); |
|
4782 |
+ } else if(dbstatus == 0) |
|
4783 |
+ cli_dbgmsg("Database has not changed\n"); |
|
4784 |
+ else if(dbstatus == 1) { |
|
4785 |
+ cli_warnmsg("Not reloading database until idle\n"); |
|
4786 |
+ pthread_mutex_lock(&accept_mutex); |
|
4787 |
+ accept_inputs = 0; |
|
4788 |
+ pthread_mutex_unlock(&accept_mutex); |
|
4789 |
+ |
|
4790 |
+ while(n_children > 0) |
|
4791 |
+ pthread_cond_wait(&n_children_cond, &n_children_mutex); |
|
4792 |
+ |
|
4763 | 4793 |
cl_statfree(&dbstat); |
4764 | 4794 |
if(use_syslog) |
4765 | 4795 |
syslog(LOG_WARNING, _("Loading new database")); |
4766 |
- if(loadDatabase() != 0) |
|
4767 |
- exit(EX_CONFIG); |
|
4796 |
+ if(loadDatabase() != 0) { |
|
4797 |
+ pthread_mutex_unlock(&n_children_mutex); |
|
4798 |
+ smfi_stop(); |
|
4799 |
+ return NULL; |
|
4800 |
+ } |
|
4801 |
+ pthread_mutex_lock(&accept_mutex); |
|
4802 |
+ accept_inputs = 1; |
|
4803 |
+ pthread_cond_broadcast(&accept_cond); |
|
4804 |
+ pthread_mutex_unlock(&accept_mutex); |
|
4805 |
+ } else { |
|
4806 |
+ smfi_stop(); |
|
4807 |
+ cli_errmsg("Database error - clamav-milter is stopping\n"); |
|
4808 |
+ pthread_mutex_unlock(&n_children_mutex); |
|
4809 |
+ return NULL; |
|
4768 | 4810 |
} |
4769 | 4811 |
pthread_mutex_unlock(&n_children_mutex); |
4770 | 4812 |
continue; |
... | ... |
@@ -4872,6 +4955,7 @@ watchdog(void *a) |
4872 | 4872 |
while(!quitting) { |
4873 | 4873 |
struct timespec ts; |
4874 | 4874 |
struct timeval tp; |
4875 |
+ int dbstatus; |
|
4875 | 4876 |
|
4876 | 4877 |
gettimeofday(&tp, NULL); |
4877 | 4878 |
|
... | ... |
@@ -4902,13 +4986,54 @@ watchdog(void *a) |
4902 | 4902 |
* otherwise a reload may not occur on overloaded |
4903 | 4903 |
* servers |
4904 | 4904 |
*/ |
4905 |
+ dbstatus = cl_statchkdir(&dbstat); |
|
4905 | 4906 |
pthread_mutex_lock(&n_children_mutex); |
4906 |
- if((n_children == 0) && (cl_statchkdir(&dbstat) == 1)) { |
|
4907 |
+ if((n_children == 0) && (dbstatus == 1)) { |
|
4908 |
+ pthread_mutex_lock(&accept_mutex); |
|
4909 |
+ accept_inputs = 0; |
|
4910 |
+ pthread_mutex_unlock(&accept_mutex); |
|
4911 |
+ cli_dbgmsg("Database has changed\n"); |
|
4907 | 4912 |
cl_statfree(&dbstat); |
4913 |
+ /* check for race condition */ |
|
4914 |
+ while(n_children > 0) |
|
4915 |
+ pthread_cond_wait(&n_children_cond, &n_children_mutex); |
|
4908 | 4916 |
if(use_syslog) |
4909 | 4917 |
syslog(LOG_WARNING, _("Loading new database")); |
4910 |
- if(loadDatabase() != 0) |
|
4911 |
- exit(EX_CONFIG); |
|
4918 |
+ if(loadDatabase() != 0) { |
|
4919 |
+ pthread_mutex_unlock(&n_children_mutex); |
|
4920 |
+ smfi_stop(); |
|
4921 |
+ return NULL; |
|
4922 |
+ } |
|
4923 |
+ pthread_mutex_lock(&accept_mutex); |
|
4924 |
+ accept_inputs = 1; |
|
4925 |
+ pthread_cond_broadcast(&accept_cond); |
|
4926 |
+ pthread_mutex_unlock(&accept_mutex); |
|
4927 |
+ } else if(dbstatus == 0) |
|
4928 |
+ cli_dbgmsg("Database has not changed\n"); |
|
4929 |
+ else if(dbstatus == 1) { |
|
4930 |
+ cli_warnmsg("Not reloading database until idle\n"); |
|
4931 |
+ pthread_mutex_lock(&accept_mutex); |
|
4932 |
+ accept_inputs = 0; |
|
4933 |
+ pthread_mutex_unlock(&accept_mutex); |
|
4934 |
+ while(n_children > 0) |
|
4935 |
+ pthread_cond_wait(&n_children_cond, &n_children_mutex); |
|
4936 |
+ cl_statfree(&dbstat); |
|
4937 |
+ if(use_syslog) |
|
4938 |
+ syslog(LOG_WARNING, _("Loading new database")); |
|
4939 |
+ if(loadDatabase() != 0) { |
|
4940 |
+ pthread_mutex_unlock(&n_children_mutex); |
|
4941 |
+ smfi_stop(); |
|
4942 |
+ return NULL; |
|
4943 |
+ } |
|
4944 |
+ pthread_mutex_lock(&accept_mutex); |
|
4945 |
+ accept_inputs = 1; |
|
4946 |
+ pthread_cond_broadcast(&accept_cond); |
|
4947 |
+ pthread_mutex_unlock(&accept_mutex); |
|
4948 |
+ } else { |
|
4949 |
+ smfi_stop(); |
|
4950 |
+ cli_errmsg("Database error - clamav-milter is stopping\n"); |
|
4951 |
+ pthread_mutex_unlock(&n_children_mutex); |
|
4952 |
+ return NULL; |
|
4912 | 4953 |
} |
4913 | 4954 |
pthread_mutex_unlock(&n_children_mutex); |
4914 | 4955 |
} |
... | ... |
@@ -5006,6 +5131,10 @@ quit(void) |
5006 | 5006 |
|
5007 | 5007 |
quitting++; |
5008 | 5008 |
|
5009 |
+ pthread_mutex_lock(&accept_mutex); |
|
5010 |
+ accept_inputs = 0; |
|
5011 |
+ pthread_mutex_unlock(&accept_mutex); |
|
5012 |
+ |
|
5009 | 5013 |
#ifdef SESSION |
5010 | 5014 |
pthread_mutex_lock(&version_mutex); |
5011 | 5015 |
#endif |
... | ... |
@@ -5195,7 +5324,7 @@ sigsegv(int sig) |
5195 | 5195 |
syslog(LOG_ERR, "Segmentation fault :-( Bye.."); |
5196 | 5196 |
cli_dbgmsg("Segmentation fault :-( Bye..\n"); |
5197 | 5197 |
|
5198 |
- exit(SIGSEGV); |
|
5198 |
+ smfi_stop(); |
|
5199 | 5199 |
} |
5200 | 5200 |
|
5201 | 5201 |
static void |