diff -urNw clamav-devel.jm/clamav-milter/clamav-milter.c clamav-devel.jm-pl2/clamav-milter/clamav-milter.c
--- clamav-devel.jm/clamav-milter/clamav-milter.c	Thu Apr 29 00:30:51 2004
+++ clamav-devel.jm-pl2/clamav-milter/clamav-milter.c	Thu Apr 29 00:32:17 2004
@@ -861,6 +861,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;
@@ -902,6 +908,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.");
@@ -963,9 +976,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[] = {
@@ -1033,6 +1046,9 @@
 				"max-children", 1, NULL, 'm'
 			},
 			{
+				"max-child-wait", 2, NULL, 'w'
+			},
+			{
 				"server", 1, NULL, 's'
 			},
 			{
@@ -1147,6 +1163,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);
@@ -1865,12 +1887,14 @@
 {
 	struct privdata *privdata;
 	int	ret_code = 0;
+	char	*envid = smfi_getsymval(ctx,"i"); 
 
 	if(logVerbose)
 		syslog(LOG_DEBUG, "clamfi_envfrom: %s", argv[0]);
 
 	cli_dbgmsg("clamfi_envfrom: %s\n", argv[0]);
 
+
 	if(max_children > 0) {
 		int rc = 0;
 
@@ -1887,6 +1911,22 @@
 			struct timezone tz;
 
 			/*
+			 * 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
@@ -1897,13 +1937,13 @@
 			 * It stops sendmail getting fidgety.
 			 */
 			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 for some to exit",
-					n_children, max_children);
+					"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);
 			while(rc != ETIMEDOUT);
@@ -1916,9 +1956,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 -urNw clamav-devel.jm/docs/man/clamav-milter.8 clamav-devel.jm-pl2/docs/man/clamav-milter.8
--- clamav-devel.jm/docs/man/clamav-milter.8	Thu Apr 29 00:30:51 2004
+++ clamav-devel.jm-pl2/docs/man/clamav-milter.8	Thu Apr 29 00:25:50 2004
@@ -150,7 +150,13 @@
 \fB\-\-max\-children=n, \-m n\fR
 Maximum number of children.
 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
 \fB\-\-template\-file=file \-t file\fR
 File points to a file whose contents is sent whenever a virus is intercepted.
