diff -urN clamav-devel/clamav-milter/clamav-milter.c clamav-devel-jm4/clamav-milter/clamav-milter.c
--- clamav-devel/clamav-milter/clamav-milter.c	Mon May 10 07:04:36 2004
+++ clamav-devel-jm4/clamav-milter/clamav-milter.c	Wed May 12 22:37:00 2004
@@ -868,6 +868,12 @@
 static	pthread_cond_t	n_children_cond = PTHREAD_COND_INITIALIZER;
 static	unsigned	int	n_children = 0;
 static	unsigned	int	max_children = 0;
+/* 
+ * -1 wait 60 seconds for max_children and continue.
+ * 0  no waiting, exit if max_children.
+ * >0 means wait that long, then exit if neccessary.
+ */ 
+static	int	max_child_wait = 0; 
 short	use_syslog = 0;
 static	const	char	*pidFile;
 static	int	logVerbose = 0;
@@ -910,6 +916,13 @@
 	puts("\t--headers\t\t-H\tInclude original message headers in the report.");
 	puts("\t--local\t\t\t-l\tScan messages sent from machines on our LAN.");
 	puts("\t--outgoing\t\t-o\tScan outgoing messages from this machine.");
+	puts("\t--max-children\t\t-m\tMaximum amount of children to run.");
+	puts("\t--max-child-wait=secs\t-w\tAfter maximum amount of children,");
+	puts("\t\t\t\t\thow long do we wait for less children and do we exit?");
+	puts("\t\t\t\t\t0 or unspecified means no wait and exit.");
+	puts("\t\t\t\t\tNegative value means wait 60 seconds and continue.");
+	puts("\t\t\t\t\tPositive value means wait value seconds ");
+	puts("\t\t\t\t\tand exit if still max-children.");
 	puts("\t--noreject\t\t-N\tDon't reject viruses, silently throw them away.");
 	puts("\t--noxheader\t\t-n\tSuppress X-Virus-Scanned/X-Virus-Status headers.");
 	puts("\t--pidfile=FILE\t\t-i FILE\tLocation of pidfile.");
@@ -970,9 +983,9 @@
 	for(;;) {
 		int opt_index = 0;
 #ifdef	CL_DEBUG
-		const char *args = "bc:CDfF:lm:nNop:PqQ:dhHs:St:U:Vx:";
+		const char *args = "bc:CDfF:lm:nNop:PqQ:dhHs:St:U:Vw::x:";
 #else
-		const char *args = "bc:CDfF:lm:nNop:PqQ:dhHs:St:U:V";
+		const char *args = "bc:CDfF:lm:nNop:PqQ:dhHs:St:U:Vw::";
 #endif
 
 		static struct option long_options[] = {
@@ -1037,6 +1050,9 @@
 				"max-children", 1, NULL, 'm'
 			},
 			{
+				"max-child-wait", 2, NULL, 'w'
+			},
+			{
 				"server", 1, NULL, 's'
 			},
 			{
@@ -1148,6 +1164,12 @@
 			case 'V':
 				puts(clamav_version);
 				return EX_OK;
+			case 'w':
+				if(optarg)
+					max_child_wait = atoi(optarg);
+				else
+					max_child_wait = 0;
+				break;
 #ifdef	CL_DEBUG
 			case 'x':
 				debug_level = atoi(optarg);
@@ -1864,6 +1886,7 @@
 clamfi_envfrom(SMFICTX *ctx, char **argv)
 {
 	struct privdata *privdata;
+	char	*envid = smfi_getsymval(ctx,"i"); 
 
 	if(logVerbose)
 		syslog(LOG_DEBUG, "clamfi_envfrom: %s", argv[0]);
@@ -1891,6 +1914,22 @@
 					n_children, max_children);
 
 			/*
+			 * If --max-child-wait=0, then we dont bs around with 
+			 * waiting for children to exit.
+			 */
+
+			if(max_child_wait == 0) {
+				pthread_mutex_unlock(&n_children_mutex);
+				if(use_syslog)
+					syslog(LOG_NOTICE,
+						"%s: hit max-children limit (%u >= %u): exiting.",
+						envid, n_children, max_children);
+				clamfi_cleanup(ctx);
+				return cl_error;
+			}
+				
+
+			/*
 			 * Use pthread_cond_timedwait rather than
 			 * pthread_cond_wait since the sendmail which calls
 			 * us will have a timeout that we don't want to exceed
@@ -1905,8 +1944,12 @@
 			 * ensure it wakes up when a child goes away
 			 */
 			gettimeofday(&now, &tz);
-			timeout.tv_sec = now.tv_sec + 60;
+			timeout.tv_sec = now.tv_sec + ((max_child_wait > 0) ? max_child_wait : 60);
 			timeout.tv_nsec = 0;
+			if(use_syslog)
+				syslog(LOG_NOTICE,
+					"hit max-children limit (%u >= %u): waiting %d seconds for some to exit",
+					n_children, max_children, timeout.tv_sec - now.tv_sec);
 
 			do
 				rc = pthread_cond_timedwait(&n_children_cond, &n_children_mutex, &timeout);
@@ -1920,9 +1963,15 @@
 		if(rc == ETIMEDOUT) {
 #ifdef	CL_DEBUG
 			if(use_syslog)
-				syslog(LOG_NOTICE, "Timeout waiting for a child to die");
+#else
+			if(use_syslog && (max_child_wait > 0))
 #endif
+				syslog(LOG_NOTICE, "Timeout waiting for a child to die");
 			cli_dbgmsg("Timeout waiting for a child to die\n");
+			if(max_child_wait > 0 ) {
+				clamfi_cleanup(ctx);
+				return cl_error;
+			}
 		}
 	}
 
diff -urN clamav-devel/docs/man/clamav-milter.8 clamav-devel-jm4/docs/man/clamav-milter.8
--- clamav-devel/docs/man/clamav-milter.8	Mon May 10 07:04:40 2004
+++ clamav-devel-jm4/docs/man/clamav-milter.8	Wed May 12 22:35:33 2004
@@ -145,7 +145,13 @@
 maximum time a pending thread will be held up is 1 minute, so the number
 of threads can exceed this number for short periods of time.
 There is no default, if this argument is not \fBclamav\-milter\fR will
-spawn as many children as is necessary.
+spawn as many children as is necessary, except see clamav.conf(5) for the MaxThreads option.
+.TP
+\fB\-\-max\-child\-wait=n, \-w n\fR
+Maximum amount of time to wait for number of children to climb down from max\-children.
+If this is negative than we wait 60 seconds and then continue.
+If this is zero or unspecified we do not wait and we exit. This is the default.
+If this is positive we wait that many seconds for less than max\-children and if not, we then exit.
 .TP
 Most users will not need this option, if in doubt do not set it.
 .TP
