diff -urN clamav-devel.clean.jm-pl6/clamav-config.h.in clamav-devel.jm-pl6/clamav-config.h.in
--- clamav-devel.clean.jm-pl6/clamav-config.h.in	Wed May 19 08:58:22 2004
+++ clamav-devel.jm-pl6/clamav-config.h.in	Wed May 19 09:28:45 2004
@@ -177,6 +177,12 @@
 /* Define to 1 if you have the `vsnprintf' function. */
 #undef HAVE_VSNPRINTF
 
+/* Define to 1 if you have the `asprintf' function. */
+#undef HAVE_ASPRINTF
+
+/* Define to 1 if you have the `vasprintf' function. */
+#undef HAVE_VASPRINTF
+
 /* zlib installed */
 #undef HAVE_ZLIB_H
 
diff -urN clamav-devel.clean.jm-pl6/clamav-milter/Makefile.am clamav-devel.jm-pl6/clamav-milter/Makefile.am
--- clamav-devel.clean.jm-pl6/clamav-milter/Makefile.am	Wed May 19 08:58:22 2004
+++ clamav-devel.jm-pl6/clamav-milter/Makefile.am	Wed May 19 09:28:45 2004
@@ -28,6 +28,8 @@
     $(top_srcdir)/shared/getopt.h \
     $(top_srcdir)/shared/memory.c \
     $(top_srcdir)/shared/memory.h \
+    $(top_srcdir)/shared/vsnprintf_alloc.h\
+    $(top_srcdir)/shared/vsnprintf_alloc.c\
     clamav-milter.c
 
 man_MANS = $(top_srcdir)/docs/man/clamav-milter.8
diff -urN clamav-devel.clean.jm-pl6/clamav-milter/clamav-milter.c clamav-devel.jm-pl6/clamav-milter/clamav-milter.c
--- clamav-devel.clean.jm-pl6/clamav-milter/clamav-milter.c	Wed May 19 08:58:22 2004
+++ clamav-devel.jm-pl6/clamav-milter/clamav-milter.c	Wed May 19 09:30:02 2004
@@ -649,7 +649,7 @@
  */
 static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.88 2004/05/16 08:25:09 nigelhorne Exp $";
 
-#define	CM_VERSION	"0.71"
+#define	CM_VERSION	"0.71-jm-pl6"
 
 /*#define	CONFDIR	"/usr/local/etc"*/
 
@@ -717,6 +717,27 @@
 typedef	unsigned short	in_port_t;
 #endif
 
+#define ALLOC_CHECK(_function_,_pointer_,_cleanup_)	{\
+	int save_errno = errno;				\
+	if(!_pointer_){					\
+		fprintf(stderr,"%s: %s() line %d, %s: ",\
+			__FILE__,			\
+			__func__,			\
+			__LINE__,			\
+			_function_ );			\
+		errno = save_errno;			\
+		perror("");				\
+		if(!_cleanup_)				\
+			exit(save_errno);		\
+		else {					\
+			ret_code = save_errno;		\
+			if(!ret_code)			\
+				ret_code = 1;		\
+			goto cleanup;			\
+		}					\
+	}						\
+}
+
 /*
  * TODO: optional: xmessage on console when virus stopped (SNMP would be real nice!)
  *	Having said that, with LogSysLog you can (on Linux) configure the system
@@ -761,7 +782,8 @@
 	u_char	*body;		/* body of the message if Sflag is set */
 	size_t	bodyLen;	/* number of bytes in body */
 	header_list_t headers;	/* Message headers */
-	long	numBytes;	/* Number of bytes sent so far */
+ 	size_t	numBytes;	/* Number of bytes sent so far */
+ 	char	*envid;		/* Sendmail envid ($i) */
 	char	*received;	/* keep track of received from */
 	const	char	*rejectCode;	/* 550 or 554? */
 	char	*messageID;	/* sendmailID */
@@ -784,7 +806,7 @@
 static	sfsistat	clamfi_close(SMFICTX *ctx);
 static	void		clamfi_cleanup(SMFICTX *ctx);
 static	void		clamfi_free(struct privdata *privdata);
-static	int		clamfi_send(struct privdata *privdata, size_t len, const char *format, ...);
+static	ssize_t		clamfi_send(struct privdata *privdata, size_t len, const char *format, ...);
 static	char		*strrcpy(char *dest, const char *source);
 static	int		clamd_recv(int sock, char *buf, size_t len);
 static	off_t		updateSigFile(void);
@@ -856,10 +878,11 @@
 				 * number of seconds to wait for clamd to
 				 * respond, see ReadTimeout in clamav.conf
 				 */
-static	long	streamMaxLength = -1;	/* StreamMaxLength from clamav.conf */
+static	size_t	streamMaxLength = -1;	/* StreamMaxLength from clamav.conf */
 static	int	logClean = 1;	/*
 				 * Add clean items to the log file
 				 */
+static	int	logInfected = 1; /* Redundantly log verbose infected messages */
 static	char	*signature = "-- \nScanned by ClamAv - http://www.clamav.net\n";
 static	time_t	signatureStamp;
 static	char	*templatefile;	/* e-mail to be sent when virus detected */
@@ -872,6 +895,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;
@@ -907,6 +936,7 @@
 	puts("\t--config-file=FILE\t-c FILE\tRead configuration from FILE.");
 	puts("\t--debug\t\t\t-D\tPrint debug messages.");
 	puts("\t--dont-log-clean\t-C\tDon't add an entry to syslog that a mail is clean.");
+	puts("\t--dont-log-infected\t-I\tDon't add our own entry to syslog that a mail is infected.");
 	puts("\t--dont-scan-on-error\t-d\tPass e-mails through unscanned if a system error occurs.");
 	puts("\t--from=EMAIL\t\t-a EMAIL\tError messages come from here.");
 	puts("\t--force-scan\t\t-f\tForce scan all messages (overrides (-o and -l).");
@@ -914,6 +944,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.");
@@ -935,6 +972,7 @@
 int
 main(int argc, char **argv)
 {
+	int	ret_code = 0;
 	extern char *optarg;
 	const char *cfgfile = CL_DEFAULT_CFG;
 	struct cfgstruct *cpt;
@@ -974,9 +1012,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:Ilm: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:Ilm:nNop:PqQ:dhHs:St:U:Vw::";
 #endif
 
 		static struct option long_options[] = {
@@ -993,6 +1031,9 @@
 				"dont-log-clean", 0, NULL, 'C'
 			},
 			{
+				"dont-log-infected", 0, NULL, 'I'
+			},
+			{
 				"dont-scan-on-error", 0, NULL, 'd'
 			},
 			{
@@ -1041,6 +1082,9 @@
 				"max-children", 1, NULL, 'm'
 			},
 			{
+				"max-child-wait", 2, NULL, 'w'
+			},
+			{
 				"server", 1, NULL, 's'
 			},
 			{
@@ -1103,6 +1147,9 @@
 			case 'i':	/* pidfile */
 				pidfile = optarg;
 				break;
+			case 'I':	/* pidfile */
+				logInfected = 0;
+				break;
 			case 'l':	/* scan mail from the lan */
 				lflag++;
 				break;
@@ -1152,6 +1199,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);
@@ -1303,6 +1356,8 @@
 		umask(077);
 
 		serverIPs = (long *)cli_malloc(sizeof(long));
+		ALLOC_CHECK("cli_malloc",serverIPs,0);
+			
 		serverIPs[0] = inet_addr("127.0.0.1");
 	} else if((cpt = cfgopt(copt, "TCPSocket")) != NULL) {
 		int i, activeServers;
@@ -1333,6 +1388,7 @@
 		cli_dbgmsg("numServers: %d\n", numServers);
 
 		serverIPs = (long *)cli_malloc(numServers * sizeof(long));
+		ALLOC_CHECK("cli_malloc",serverIPs,0);
 		activeServers = 0;
 
 		for(i = 0; i < numServers; i++) {
@@ -1491,6 +1547,8 @@
 		syslog(LOG_INFO, "Started: %s", clamav_version);
 
 	return smfi_main();
+cleanup:
+	return(ret_code);
 }
 
 /*
@@ -1613,6 +1671,7 @@
 	fd_set rfds;
 	struct timeval tv;
 	int retval;
+	int ret_code = 0;
 
 	assert(tcpSocket != 0);
 	assert(numServers > 0);
@@ -1621,7 +1680,9 @@
 		return 0;
 
 	servers = (struct sockaddr_in *)cli_calloc(numServers, sizeof(struct sockaddr_in));
+	ALLOC_CHECK("cli_calloc",servers,1);
 	socks = (int *)cli_malloc(numServers * sizeof(int));
+	ALLOC_CHECK("cli_malloc",socks,1);
 
 	FD_ZERO(&rfds);
 
@@ -1701,7 +1762,15 @@
 	cli_dbgmsg("findServer: No response from any server\n");
 	if(use_syslog)
 		syslog(LOG_WARNING, "findServer: No response from any server");
+cleanup:
+	if(ret_code){
+		if(servers)
+			free(servers);
+		if(socks)
+			free(socks);
+	}
 	return 0;
+	
 }
 
 /*
@@ -1863,12 +1932,15 @@
 clamfi_envfrom(SMFICTX *ctx, char **argv)
 {
 	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;
 
@@ -1890,6 +1962,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
@@ -1904,8 +1992,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);
@@ -1919,16 +2011,20 @@
 		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;
+			}
 		}
 	}
 
 	privdata = (struct privdata *)cli_calloc(1, sizeof(struct privdata));
-	if(privdata == NULL)
-		return cl_error;
-
+ 	ALLOC_CHECK("cli_calloc",privdata,1);
 	privdata->dataSocket = -1;	/* 0.4 */
 	privdata->cmdSocket = -1;	/* 0.4 */
 
@@ -1940,15 +2036,18 @@
 	privdata->rejectCode = "550";
 
 	privdata->from = strdup(argv[0]);
+	privdata->envid = envid; 
+	if(!privdata->envid)
+		privdata->envid = "Uknown";
 
 	if(hflag)
-		privdata->headers = header_list_new();
+		if(!(privdata->headers = header_list_new()))
+			goto cleanup;
 
 	if(smfi_setpriv(ctx, privdata) == MI_SUCCESS)
 		return SMFIS_CONTINUE;
-
+cleanup:
 	clamfi_free(privdata);
-
 	return cl_error;
 }
 
@@ -1956,19 +2055,26 @@
 clamfi_envrcpt(SMFICTX *ctx, char **argv)
 {
 	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
+	int ret_code = 0;
+	void * p = NULL;
 
 	if(logVerbose)
 		syslog(LOG_DEBUG, "clamfi_envrcpt: %s", argv[0]);
-
 	cli_dbgmsg("clamfi_envrcpt: %s\n", argv[0]);
 
+ 	if(!privdata)
+ 		return cl_error;
+
 	if(privdata->to == NULL) {
 		privdata->to = cli_malloc(sizeof(char *) * 2);
+		ALLOC_CHECK("cli_malloc",privdata->to,1);
 
 		assert(privdata->numTo == 0);
-	} else
-		privdata->to = cli_realloc(privdata->to, sizeof(char *) * (privdata->numTo + 2));
-
+	} else {
+		p = cli_realloc(privdata->to, (sizeof(char *) * (privdata->numTo + 2)));
+		ALLOC_CHECK("cli_realloc",p,1);
+		privdata->to = p;
+	}
 	if(privdata->to == NULL)
 		return cl_error;
 
@@ -1976,6 +2082,8 @@
 	privdata->to[++privdata->numTo] = NULL;
 
 	return SMFIS_CONTINUE;
+cleanup:
+	return cl_error;
 }
 
 static sfsistat
@@ -2111,48 +2219,41 @@
 clamfi_body(SMFICTX *ctx, u_char *bodyp, size_t len)
 {
 	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
-	int nbytes;
+	void * p = NULL;
+	int ret_code = 0;
 
 	if(logVerbose)
 		syslog(LOG_DEBUG, "clamfi_envbody: %u bytes", len);
 #ifdef	CL_DEBUG
 	cli_dbgmsg("clamfi_envbody: %u bytes\n", len);
 #endif
+	if(!privdata)
+		return cl_error;
 
-	nbytes = clamfi_send(privdata, len, (char *)bodyp);
-	if(streamMaxLength > 0L) {
-		if(privdata->numBytes > streamMaxLength) {
-			if(use_syslog) {
-				const char *sendmailId = smfi_getsymval(ctx, "i");
-				if(sendmailId == NULL)
-					sendmailId = "Unknown";
-				syslog(LOG_NOTICE, "%s: Message more than StreamMaxLength (%ld) bytes - not scanned",
-					sendmailId, streamMaxLength);
-			}
-			if(!nflag)
-				smfi_addheader(ctx, "X-Virus-Status", "Not Scanned - StreamMaxLength exceeded");
-
-			return SMFIS_ACCEPT;	/* clamfi_close will be called */
-		}
-	}
-	if(nbytes < len) {
-		clamfi_cleanup(ctx);	/* not needed, but just to be safe */
+	if(clamfi_send(privdata, len, (char *)bodyp) < 0) {
+		clamfi_cleanup(ctx);
 		return cl_error;
 	}
+
 	if(Sflag) {
 		if(privdata->body) {
 			assert(privdata->bodyLen > 0);
-			privdata->body = cli_realloc(privdata->body, privdata->bodyLen + len);
+			p = cli_realloc(privdata->body, privdata->bodyLen + len);
+			ALLOC_CHECK("cli_realloc",p,1);
+			privdata->body = p;
 			memcpy(&privdata->body[privdata->bodyLen], bodyp, len);
 			privdata->bodyLen += len;
 		} else {
 			assert(privdata->bodyLen == 0);
 			privdata->body = cli_malloc(len);
+ 			ALLOC_CHECK("cli_malloc",privdata->body,1);
 			memcpy(privdata->body, bodyp, len);
 			privdata->bodyLen = len;
 		}
 	}
 	return SMFIS_CONTINUE;
+cleanup:
+	return cl_error;
 }
 
 static sfsistat
@@ -2160,12 +2261,15 @@
 {
 	int rc = SMFIS_CONTINUE;
 	char *ptr;
-	const char *sendmailId;
 	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
 	char mess[128];
+	int ret_code = 0;
+	void * p = NULL;
+	char **to, *err = NULL;
 
 	if(logVerbose)
 		syslog(LOG_DEBUG, "clamfi_eom");
+
 #ifdef	CL_DEBUG
 	cli_dbgmsg("clamfi_eom\n");
 	assert(privdata != NULL);
@@ -2173,6 +2277,8 @@
 	assert(!((privdata->cmdSocket >= 0) && (privdata->filename != NULL)));
 	assert(privdata->dataSocket >= 0);
 #endif
+	if(!privdata)
+		goto cleanup;
 
 	close(privdata->dataSocket);
 	privdata->dataSocket = -1;
@@ -2202,7 +2308,7 @@
 			return cl_error;
 		}
 
-		snprintf(cmdbuf, sizeof(cmdbuf) - 1, "SCAN %s", privdata->filename);
+		snprintf(cmdbuf, sizeof(cmdbuf) - 1, "MAILSCAN %s", privdata->filename);
 
 		nbytes = (int)strlen(cmdbuf);
 
@@ -2236,37 +2342,22 @@
 	close(privdata->cmdSocket);
 	privdata->cmdSocket = -1;
 
-	sendmailId = smfi_getsymval(ctx, "i");
-	if(sendmailId == NULL)
-		sendmailId = "Unknown";
-
 	if(!nflag)
 		smfi_addheader(ctx, "X-Virus-Scanned", clamav_version);
 
 	if(strstr(mess, "ERROR") != NULL) {
-		if(strstr(mess, "Size exceeded") != NULL) {
-			/*
-			 * Clamd has stopped on StreamMaxLength before us
-			 */
-			if(use_syslog)
-				syslog(LOG_NOTICE, "%s: Message more than StreamMaxLength (%ld) bytes - not scanned",
-					sendmailId, streamMaxLength);
-			clamfi_cleanup(ctx);	/* not needed, but just to be safe */
-			if(!nflag)
-				smfi_addheader(ctx, "X-Virus-Status", "Not Scanned - StreamMaxLength exceeded");
-			return SMFIS_ACCEPT;
-		}
 		if(!nflag)
 			smfi_addheader(ctx, "X-Virus-Status", "Not Scanned");
 
-		cli_warnmsg("%s: %s\n", sendmailId, mess);
+		cli_warnmsg("%s: %s\n", privdata->envid, mess);
 		if(use_syslog)
-			syslog(LOG_ERR, "%s: %s\n", sendmailId, mess);
+			syslog(LOG_ERR, "%s: %s\n", privdata->envid, mess);
 		clamfi_cleanup(ctx);
 		return cl_error;
 	}
 
 	if((ptr = strstr(mess, "FOUND")) == NULL) {
+		rc = SMFIS_ACCEPT;
 		if(!nflag)
 			smfi_addheader(ctx, "X-Virus-Status", "Clean");
 
@@ -2274,10 +2365,11 @@
 		 * TODO: if privdata->from is NULL it's probably SPAM, and
 		 * me might consider bouncing it...
 		 */
+		
 		if(use_syslog && logClean)
 			/* Include the sendmail queue ID in the log */
 			syslog(LOG_NOTICE, "%s: clean message from %s",
-				sendmailId,
+				privdata->envid,
 				(privdata->from) ? privdata->from : "an unknown sender");
 
 		if(privdata->body) {
@@ -2287,18 +2379,21 @@
 			off_t len = updateSigFile();
 
 			if(len) {
+				p = NULL;
+
 				assert(Sflag != 0);
 
-				privdata->body = cli_realloc(privdata->body, privdata->bodyLen + len);
-				if(privdata->body) {
+				p = cli_realloc(privdata->body, privdata->bodyLen + len);
+				ALLOC_CHECK("cli_realloc",p,1);
+				privdata->body = p;
 					memcpy(&privdata->body[privdata->bodyLen], signature, len);
 					smfi_replacebody(ctx, privdata->body, privdata->bodyLen + len);
-				}
+				
 			}
 		}
 	} else {
 		char reject[1024];
-		char **to, *virusname;
+		char *virusname;
 
 		*ptr = '\0';	/* Remove the "FOUND" word */
 
@@ -2311,53 +2406,38 @@
 		if(!nflag)
 			smfi_addheader(ctx, "X-Virus-Status", "Infected");
 
-		if(use_syslog) {
+#ifndef	CL_DEBUG
+		if(use_syslog && logInfected) {
+#else
+		{
+#endif /* CL_DEBUG */
+			int i;
 			/*
 			 * Setup err as a list of recipients
 			 */
-			char *err = (char *)cli_malloc(1024);
-			int i;
-
-			if(err == NULL) {
-				clamfi_cleanup(ctx);
-				return cl_error;
-			}
 
-			/*
-			 * Use snprintf rather than printf since we don't know the
-			 * length of privdata->from and may get a buffer overrun
-			 */
-			snprintf(err, 1023, "Intercepted virus from %s to",
+			asprintf(&err,"Intercepted virus from %s to",
 				privdata->from);
 
-			ptr = strchr(err, '\0');
-
-			i = 1024;
-
 			for(to = privdata->to; *to; to++) {
-				/*
-				 * Re-alloc if we are about run out of buffer space
-				 */
-				if(&ptr[strlen(*to) + 2] >= &err[i]) {
-					i += 1024;
-					err = cli_realloc(err, i);
-					if(err == NULL) {
-						clamfi_cleanup(ctx);
-						return cl_error;
-					}
-					ptr = strchr(err, '\0');
-				}
-				ptr = strrcpy(ptr, " ");
-				ptr = strrcpy(ptr, *to);
-			}
-			(void)strcpy(ptr, "\n");
+				ptr = NULL;
+				asprintf(&ptr,"%s %s",err,*to);
+				free(err);
+				err = ptr;
+			}
+			err = NULL;
+			asprintf(&err,"%s\n",ptr);
+			free(ptr);
+			ptr = NULL;
+			if(use_syslog)
+				/* Include the sendmail queue ID in the log */
+				syslog(LOG_NOTICE, "%s: %s %s", privdata->envid, mess, err);
 
-			/* Include the sendmail queue ID in the log */
-			syslog(LOG_NOTICE, "%s: %s%s", sendmailId, mess, err);
 #ifdef	CL_DEBUG
 			cli_dbgmsg("%s\n", err);
-#endif
-			free(err);
+#endif /* CL_DEBUG */
+  			free(err);
+
 		}
 
 		if(!qflag) {
@@ -2430,7 +2510,7 @@
 						 * information
 						 */
 						fprintf(sendmail, "The message %s sent from %s to\n",
-							sendmailId, from);
+							privdata->envid, from);
 					else
 						fprintf(sendmail, "A message sent from %s to\n",
 							from);
@@ -2520,8 +2600,12 @@
 		snprintf(reject, sizeof(reject) - 1, "%sdetected by ClamAV - http://www.clamav.net", virusname);
 		smfi_setreply(ctx, (char *)privdata->rejectCode, "5.7.1", reject);
 	}
+cleanup:
 	clamfi_cleanup(ctx);
-
+	if(ret_code){
+		if(err)
+			free(err);
+	}
 	return rc;
 }
 
@@ -2668,12 +2752,13 @@
 /*
  * Returns < 0 for failure, otherwise the number of bytes sent
  */
-static int
+static ssize_t
 clamfi_send(struct privdata *privdata, size_t len, const char *format, ...)
 {
-	char output[BUFSIZ];
+	char * output = NULL;
 	const char *ptr;
-	int ret = 0;
+	ssize_t ret = 0;
+	int ret_code = 0;
 
 	assert(format != NULL);
 
@@ -2687,7 +2772,8 @@
 		va_list argp;
 
 		va_start(argp, format);
-		vsnprintf(output, sizeof(output) - 1, format, argp);
+		vasprintf(&output, format, argp);
+		ALLOC_CHECK("vasprintf",output,1);
 		va_end(argp);
 
 		len = strlen(output);
@@ -2707,6 +2793,24 @@
 	}
 #endif
 
+	if(!quarantine_dir && (
+ 		streamMaxLength &&
+		len + privdata->numBytes > streamMaxLength) 
+	   ){
+		if(use_syslog && privdata->numBytes != streamMaxLength){
+                        char buf[1024];
+                        syslog(LOG_INFO,"%s: size exceeded max of %u , "
+					"already wrote %u, will write %u more instead "
+					"of len %u",
+                                        privdata->envid,
+                                        streamMaxLength,
+                                        privdata->numBytes,
+                                        streamMaxLength - privdata->numBytes,
+					len);
+                }
+		len = (streamMaxLength - privdata->numBytes);
+	}
+
 	while(len > 0) {
 		const int nbytes = (quarantine_dir) ?
 			write(privdata->dataSocket, ptr, len) :
@@ -2731,17 +2835,23 @@
 			}
 			checkClamd();
 
-			return -1;
+			ret_code = -1;
+			goto cleanup;
 		}
 		ret += nbytes;
 		len -= nbytes;
 		ptr = &ptr[nbytes];
 
-		if(streamMaxLength > 0L) {
-			privdata->numBytes += nbytes;
-			if(privdata->numBytes >= streamMaxLength)
-				break;
-		}
+		privdata->numBytes += nbytes;
+	}
+cleanup:
+	if(output)
+		free(output);
+	if(ret_code){
+#ifdef CL_DEBUG
+		cli_dbgmsg("vasprintf: %s\n",output);
+#endif
+		return(-1);
 	}
 	return ret;
 }
@@ -2801,6 +2911,8 @@
 {
 	struct stat statb;
 	int fd;
+	int ret_code = 0;
+	void * p = NULL;
 
 	if(sigFilename == NULL)
 		/* nothing to read */
@@ -2825,25 +2937,32 @@
 	}
 
 	signatureStamp = statb.st_mtime;
+	p = cli_realloc(signature, statb.st_size + 1);
+	ALLOC_CHECK("cli_realloc",p,1);
+	signature = p;
 
-	signature = cli_realloc(signature, statb.st_size);
 	read(fd, signature, statb.st_size);
 	close(fd);
 
 	return statb.st_size;
+cleanup:
+	return strlen(signature);
 }
 
 static header_list_t
 header_list_new(void)
 {
+	int ret_code = 0;
+	void * p = NULL;
 	header_list_t ret;
 
 	ret = (header_list_t)cli_malloc(sizeof(struct header_list_struct));
-	if(ret) {
+	ALLOC_CHECK("cli_malloc",ret,1);
 		ret->first = NULL;
 		ret->last = NULL;
-	}
 	return ret;
+cleanup:
+	return NULL;
 }
 
 static void
@@ -2867,19 +2986,16 @@
 	char *header;
 	size_t len;
 	struct header_node_t *new_node;
+	int ret_code = 0;
 
 	len = strlen(headerf) + strlen(headerv) + 3;
 
 	header = (char *)cli_malloc(len);
-	if(header == NULL)
-		return;
+	ALLOC_CHECK("cli_malloc",header,1);
 
 	sprintf(header, "%s: %s", headerf, headerv);
 	new_node = (struct header_node_t *)cli_malloc(sizeof(struct header_node_t));
-	if(new_node == NULL) {
-		free(header);
-		return;
-	}
+	ALLOC_CHECK("cli_malloc",new_node,1);
 	new_node->header = header;
 	new_node->next = NULL;
 	if(!list->first)
@@ -2888,6 +3004,13 @@
 		list->last->next = new_node;
 
 	list->last = new_node;
+cleanup:
+	if(ret_code){
+		if(header)
+			free(header);
+		if(new_node)
+			free(new_node);
+	}	
 }
 
 static void
@@ -2909,6 +3032,9 @@
 static int
 connect2clamd(struct privdata *privdata)
 {
+	int  ret = 0;
+	int	ret_code = 0;
+
 	char **to;
 
 	assert(privdata != NULL);
@@ -2945,7 +3071,7 @@
 		DD = tm->tm_mday;
 
 		privdata->filename = (char *)cli_malloc(strlen(quarantine_dir) + 19);
-
+		ALLOC_CHECK("cli_malloc",privdata->filename,1);
 		sprintf(privdata->filename, "%s/%02d%02d%02d", quarantine_dir,
 			YY, MM, DD);
 
@@ -3038,7 +3164,7 @@
 
 		shutdown(privdata->dataSocket, SHUT_RD);
 
-		if(send(privdata->cmdSocket, "STREAM\n", 7, 0) < 7) {
+		if(send(privdata->cmdSocket, "MAILSTREAM\n", 11, 0) < 7) {
 			perror("send");
 			if(use_syslog)
 				syslog(LOG_ERR, "send failed to clamd");
@@ -3116,6 +3242,8 @@
 	cli_dbgmsg("connect2clamd OK\n");
 
 	return 1;
+cleanup:
+	return 0;
 }
 
 /*
@@ -3170,8 +3298,9 @@
 {
 	FILE *fin = fopen(filename, "r");
 	struct stat statb;
-	char *buf, *ptr;
+	char *buf = NULL, *ptr = NULL;
 	int rc;
+	int ret_code = 0; /*ALLOC_CHECK*/
 
 	if(fin == NULL) {
 		perror(filename);
@@ -3191,14 +3320,9 @@
 		return -1;
 	}
 	buf = cli_malloc(statb.st_size + 1);
-	if(buf == NULL) {
-		if(use_syslog)
-			syslog(LOG_ERR, "Out of memory");
-		fclose(fin);
-		return -1;
-	}
+	ALLOC_CHECK("cli_malloc",buf,1);
+
 	fread(buf, sizeof(char), statb.st_size, fin);
-	fclose(fin);
 	buf[statb.st_size] = '\0';
 
 	if((ptr = strstr(buf, "%v")) != NULL) {
@@ -3210,8 +3334,11 @@
 		rc = (fputs(ptr, sendmail) == EOF) ? -1 : 0;
 	} else
 		rc = (fputs(buf, sendmail) == EOF) ? -1 : 0;
-
-	free(buf);
+cleanup:
+	if(buf)
+		free(buf);
+	if(fin)
+		fclose(fin);
 
 	return 0;
 }
diff -urN clamav-devel.clean.jm-pl6/clamd/options.c clamav-devel.jm-pl6/clamd/options.c
--- clamav-devel.clean.jm-pl6/clamd/options.c	Wed May 19 08:58:22 2004
+++ clamav-devel.jm-pl6/clamd/options.c	Wed May 19 09:28:53 2004
@@ -37,6 +37,7 @@
 #include "others.h"
 #include "../libclamav/others.h"
 #include "memory.h"
+#include "../shared/cl_debug.h"
 
 void clamd(struct optstruct *opt);
 
@@ -58,6 +59,10 @@
 #if defined(C_LINUX) && defined(CL_DEBUG)
 	/* njh@bandsman.co.uk: create a dump if needed */
 	struct rlimit rlim;
+
+#ifdef CL_DEBUG
+    mtrace();
+#endif
 
     rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
     if(setrlimit(RLIMIT_CORE, &rlim) < 0)
diff -urN clamav-devel.clean.jm-pl6/clamd/server-th.c clamav-devel.jm-pl6/clamd/server-th.c
--- clamav-devel.clean.jm-pl6/clamd/server-th.c	Wed May 19 08:58:22 2004
+++ clamav-devel.jm-pl6/clamd/server-th.c	Wed May 19 09:28:53 2004
@@ -366,6 +366,11 @@
     sigdelset(&sigset, SIGHUP);
     sigdelset(&sigset, SIGPIPE);
     sigdelset(&sigset, SIGUSR2);
+    sigdelset(&sigset, SIGTSTP);
+    sigdelset(&sigset, SIGBUS);
+    sigdelset(&sigset, SIGILL);
+    sigdelset(&sigset, SIGABRT);
+    sigdelset(&sigset, SIGQUIT);
     sigprocmask(SIG_SETMASK, &sigset, NULL);
  
     /* SIGINT, SIGTERM, SIGSEGV */
diff -urN clamav-devel.clean.jm-pl6/clamd/session.c clamav-devel.jm-pl6/clamd/session.c
--- clamav-devel.clean.jm-pl6/clamd/session.c	Wed May 19 08:58:22 2004
+++ clamav-devel.jm-pl6/clamd/session.c	Wed May 19 09:28:45 2004
@@ -54,6 +54,9 @@
 #define CMD9 "SESSION"
 #define CMD10 "END"
 #define CMD11 "SHUTDOWN"
+#define CMD12 "MAILSTREAM"
+#define CMD13 "MAILSCAN"
+#define CMD14 "CONTMAILSCAN"
 
 
 int command(int desc, const struct cl_node *root, const struct cl_limits *limits, int options, const struct cfgstruct *copt)
@@ -150,6 +153,27 @@
     } else if(!strncmp(buff, CMD11, strlen(CMD11))) { /* SHUTDOWN */
 	return COMMAND_QUIT;
 
+    } else if(!strncmp(buff, CMD12, strlen(CMD12))) { /* MAILSTREAM */
+	if((cpt = cfgopt(copt,"ScanMail"))) {
+	    options |= CL_UNKNOWN_MAIL;
+	    scanstream(desc, NULL, root, limits, options, copt);
+	} else {
+	    mdprintf(desc, "UNKNOWN COMMAND\n");
+	}
+    } else if(!strncmp(buff, CMD13, strlen(CMD13))) { /* MAILSCAN */
+	if((cpt = cfgopt(copt,"ScanMail"))) {
+	    options |= CL_UNKNOWN_MAIL;
+	    scan(buff + strlen(CMD13) + 1, NULL, root, limits, options, copt, desc, 0);
+	} else {
+	    mdprintf(desc, "UNKNOWN COMMAND\n");
+	}
+    } else if(!strncmp(buff, CMD14, strlen(CMD14))) { /* CONTMAILSCAN */
+	if((cpt = cfgopt(copt,"ScanMail"))) {
+	    options |= CL_UNKNOWN_MAIL;
+	    scan(buff + strlen(CMD14) + 1, NULL, root, limits, options, copt, desc, 1);
+	} else {
+	    mdprintf(desc, "UNKNOWN COMMAND\n");
+	}
     } else {
 	mdprintf(desc, "UNKNOWN COMMAND\n");
     }
diff -urN clamav-devel.clean.jm-pl6/clamdscan/clamdscan.c clamav-devel.jm-pl6/clamdscan/clamdscan.c
--- clamav-devel.clean.jm-pl6/clamdscan/clamdscan.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/clamdscan/clamdscan.c	Wed May 19 09:28:45 2004
@@ -126,6 +126,8 @@
     mprintf("    --verbose           -v             Be verbose\n");
     mprintf("    --quiet                            Be quiet, only output error messages\n");
     mprintf("    --stdout                           Write to stdout instead of stderr\n");
+    mprintf("    --mail, --mbox-force, -M           All unknown file type will be a RFC822 mail file\n");
+    mprintf("    --stdout                           Write to stdout instead of stderr\n");
     mprintf("                                       (this help is always written to stdout)\n");
     mprintf("    --log=FILE          -l FILE        Save scan report in FILE\n");
     mprintf("    --log-verbose                      Log additional messages\n");
diff -urN clamav-devel.clean.jm-pl6/clamdscan/client.c clamav-devel.jm-pl6/clamdscan/client.c
--- clamav-devel.clean.jm-pl6/clamdscan/client.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/clamdscan/client.c	Wed May 19 09:28:45 2004
@@ -55,6 +55,7 @@
 	int sockd, wsockd, loopw = 60, bread, port;
 	const char *clamav_conf = getargl(opt, "config-file");
 	FILE *fd;
+	short unknown_mail = 0;
 
     if(!clamav_conf)
 	clamav_conf = DEFAULT_CFG;
@@ -64,6 +65,15 @@
 	return 2;
     }
 
+     if((cfgopt(copt, "ScanMail")) &&
+	(
+	    (optl(opt, "mbox-force")) ||
+	    (optl(opt, "mail")) ||
+	    (optc(opt, 'M'))
+         )
+        ) 
+	unknown_mail = 1;	    
+
     /* Set default address to connect to; needed for scanning a stream and no TCP address specified */
     server2.sin_addr.s_addr = inet_addr("127.0.0.1");    
     if(cfgopt(copt, "ScannerDaemonOutputFormat")) {
@@ -137,7 +147,7 @@
 	file = (char *) strdup(cwd);
 
     } else if(!strcmp(opt->filename, "-")) { /* scan data from stdin */
-	if(write(sockd, "STREAM", 6) <= 0) {
+	if(write(sockd, (unknown_mail) ? "MAILSTREAM" : "STREAM", (unknown_mail) ? 10 : 6) <= 0) {
 	    mprintf("@Can't write to the socket.\n");
 	    close(sockd);
 	    return 2;
@@ -229,7 +239,7 @@
 
 
     scancmd = mcalloc(strlen(file) + 20, sizeof(char));
-    sprintf(scancmd, "CONTSCAN %s", file);
+    sprintf(scancmd, "%s %s", (unknown_mail)? "CONTMAILSCAN" : "CONTSCAN", file);
     free(file);
 
     if(write(sockd, scancmd, strlen(scancmd)) <= 0) {
diff -urN clamav-devel.clean.jm-pl6/clamscan/clamscan.c clamav-devel.jm-pl6/clamscan/clamscan.c
--- clamav-devel.clean.jm-pl6/clamscan/clamscan.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/clamscan/clamscan.c	Wed May 19 09:28:45 2004
@@ -218,6 +218,10 @@
     mprintf("    --bell                               Sound bell on virus detection\n");
     mprintf("    --no-summary                         Disable summary at end of scanning\n");
     mprintf("    --mbox                -m             Treat stdin as a mailbox\n");
+    mprintf("    --mbox-force          -M\n");
+    mprintf("    --mail                -M             Unrecognized filetypes  will be be treated\n");
+    mprintf("                                         as RFC822 mail file.\n");
+    mprintf("                                         This implies --mbox (-m)\n");
     mprintf("\n");
     mprintf("    --no-ole2                            Disable OLE2 support\n");
     mprintf("    --no-archive                         Disable libclamav archive support\n");
diff -urN clamav-devel.clean.jm-pl6/clamscan/manager.c clamav-devel.jm-pl6/clamscan/manager.c
--- clamav-devel.clean.jm-pl6/clamscan/manager.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/clamscan/manager.c	Wed May 19 09:28:49 2004
@@ -164,12 +164,16 @@
     /* set (default) limits */
 
     limits = (struct cl_limits *) calloc(1, sizeof(struct cl_limits));
+    if(!limits)
+	exit(60);
 
     if(optl(opt, "max-space")) {
 	char *cpy, *ptr;
 	ptr = getargl(opt, "max-space");
 	if(tolower(ptr[strlen(ptr) - 1]) == 'm') {
 	    cpy = mcalloc(strlen(ptr), sizeof(char));
+	    if(!cpy)
+		exit(60);
 	    strncpy(cpy, ptr, strlen(ptr) - 1);
 	    limits->maxfilesize = atoi(cpy) * 1024 * 1024;
 	    free(cpy);
@@ -430,6 +434,12 @@
 
     if(optc(opt, 'm'))
 	options |= CL_MAIL;
+
+    if(optc(opt, 'M') || optl(opt,"mail")) {
+	options |= CL_MAIL;
+	options |= CL_UNKNOWN_MAIL;
+    }
+	
 
     /* 
      * check the extension  - this is a special case, normally we don't need to
diff -urN clamav-devel.clean.jm-pl6/clamscan/options.c clamav-devel.jm-pl6/clamscan/options.c
--- clamav-devel.clean.jm-pl6/clamscan/options.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/clamscan/options.c	Wed May 19 09:28:45 2004
@@ -43,7 +43,7 @@
 	int ret, opt_index, i, len;
 	struct optstruct *opt;
 
-	const char *getopt_parameters = "hvd:wriVl:m";
+	const char *getopt_parameters = "hvd:wriVl:mM";
 
 	static struct option long_options[] = {
 	    /* 
@@ -83,6 +83,8 @@
 	    {"block-encrypted", 0, 0, 0},
 	    {"no-ole2", 0, 0, 0},
 	    {"mbox", 0, 0, 'm'},
+	    {"mbox-force", 0, 0, 'M'},
+	    {"mail", 0, 0, 0},
 	    {"stdout", 0, 0, 0},
 	    {"unzip", 2, 0, 0},
 	    {"unrar", 2, 0, 0},
diff -urN clamav-devel.clean.jm-pl6/configure.in clamav-devel.jm-pl6/configure.in
--- clamav-devel.clean.jm-pl6/configure.in	Wed May 19 08:58:22 2004
+++ clamav-devel.jm-pl6/configure.in	Wed May 19 09:29:38 2004
@@ -17,7 +17,7 @@
 
 AC_INIT(clamscan/clamscan.c)
 AC_CREATE_TARGET_H(target.h)
-AM_INIT_AUTOMAKE(clamav, "devel-`date +%Y%m%d`")
+AM_INIT_AUTOMAKE(clamav, "devel-`date +%Y%m%d`-jm-pl6")
 AM_CONFIG_HEADER(clamav-config.h)
 
 LC_CURRENT=1
@@ -42,7 +42,7 @@
 AC_COMPILE_CHECK_SIZEOF(short)
 AC_COMPILE_CHECK_SIZEOF(int)
 AC_COMPILE_CHECK_SIZEOF(long)
-AC_CHECK_FUNCS(poll setsid memcpy snprintf vsnprintf strerror_r strlcpy strlcat inet_ntop)
+AC_CHECK_FUNCS(poll setsid memcpy snprintf vsnprintf asprintf vasprintf strerror_r strlcpy strlcat inet_ntop)
 AC_FUNC_MMAP
 
 # Check for broken snprintf
@@ -143,7 +143,12 @@
 
 AC_ARG_ENABLE(debug,
 [  --enable-debug	  Enable debug messages.],
-AC_DEFINE(CL_DEBUG,1,[enable debugging]),)
+AC_DEFINE(CL_DEBUG,1,[enable debugging])
+LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lmcheck"
+CLAMD_LIBS="$CLAMD_LIBS -lmcheck"
+CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -lmcheck"
+CLAMDSCAN_LIBS="$CLAMDSCAN_LIBS -lmcheck"
+,)
 
 AC_ARG_ENABLE(bigstack,
 [  --enable-bigstack	  Increase thread stack size.],
diff -urN clamav-devel.clean.jm-pl6/docs/man/clamav-milter.8 clamav-devel.jm-pl6/docs/man/clamav-milter.8
--- clamav-devel.clean.jm-pl6/docs/man/clamav-milter.8	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/docs/man/clamav-milter.8	Wed May 19 09:28:45 2004
@@ -64,6 +64,13 @@
 \fBclamav.conf\fR since it gives a feel-good factor.
 This option turns that off.
 .TP
+\fB-I, \-\-dont-log-infected\fR
+Messages with viruses are usually logged if SysLog is set in
+\fBclamav.conf\fR since it gives a feel-good factor.
+
+However, since sendmail will log it for us (if MilterLogLevel > 1 or if LOG_LEVEL is high enough), you may find that to be redundant.
+This option turns that off.
+.TP
 \fB-d, \-\-dont-scan-on-error\fR
 If a system error occurs pass messages through unscanned,
 usually when a system error occurs the milter raises a temporary failure which
@@ -145,7 +152,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
diff -urN clamav-devel.clean.jm-pl6/libclamav/blob.c clamav-devel.jm-pl6/libclamav/blob.c
--- clamav-devel.clean.jm-pl6/libclamav/blob.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/blob.c	Wed May 19 09:28:49 2004
@@ -166,8 +166,12 @@
 		b->size = len * 4;
 		b->data = cli_malloc(b->size);
 	} else if(b->size < b->len + len) {
+		void * p = NULL;
 		b->size += len * 4;
-		b->data = cli_realloc(b->data, b->size);
+		p = cli_realloc(b->data, b->size);
+		if(!p)
+		    return;
+		b->data = p;
 	}
 
 	if(b->data) {
@@ -200,8 +204,13 @@
 	b->isClosed = 1;
 
 	if(b->size != b->len) {
+		void * p = NULL;
+		
 		b->size = b->len;
-		b->data = cli_realloc(b->data, b->size);
+		p = cli_realloc(b->data, b->size);
+		if(!p)
+		    return;
+		b->data = p;
 	}
 }
 
@@ -252,7 +261,11 @@
 		b->size = len;
 		b->data = cli_malloc(len);
 	} else {
+		void * p = NULL;
 		b->size += len;
-		b->data = cli_realloc(b->data, b->size);
+		p = cli_realloc(b->data, b->size);
+		if(!p)
+		    return;
+		b->data = p;
 	}
 }
diff -urN clamav-devel.clean.jm-pl6/libclamav/clamav.h clamav-devel.jm-pl6/libclamav/clamav.h
--- clamav-devel.clean.jm-pl6/libclamav/clamav.h	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/clamav.h	Wed May 19 09:28:45 2004
@@ -70,6 +70,7 @@
 #define CL_DISABLERAR	4
 #define CL_OLE2		8
 #define CL_ENCRYPTED    16
+#define CL_UNKNOWN_MAIL	32
 
 struct cli_patt {
     short int *pattern;
diff -urN clamav-devel.clean.jm-pl6/libclamav/cvd.c clamav-devel.jm-pl6/libclamav/cvd.c
--- clamav-devel.clean.jm-pl6/libclamav/cvd.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/cvd.c	Wed May 19 09:28:49 2004
@@ -55,6 +55,8 @@
 
 
     fullname = (char *) calloc(sizeof(char), strlen(destdir) + 100 + 5);
+    if(!fullname)
+	return -1;
 
     while(1) {
 
@@ -163,6 +165,8 @@
     }
 
     cvd = (struct cl_cvd *) cli_calloc(1, sizeof(struct cl_cvd));
+    if(!cvd)
+	return NULL;
 
     if(!(cvd->time = cli_strtok(head, 1, ":"))) {
 	cli_errmsg("CVD -> Can't extract time from header.\n");
diff -urN clamav-devel.clean.jm-pl6/libclamav/dsig.c clamav-devel.jm-pl6/libclamav/dsig.c
--- clamav-devel.clean.jm-pl6/libclamav/dsig.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/dsig.c	Wed May 19 09:28:49 2004
@@ -83,6 +83,8 @@
 
     mpz_init(p);
     decoded = (char *) calloc(plainlen + 1, sizeof(char));
+    if(!decoded)
+	return NULL;
 
     mpz_powm(p, c, e, n); /* plain = cipher^e mod n */
     mpz_clear(c);
diff -urN clamav-devel.clean.jm-pl6/libclamav/matcher.c clamav-devel.jm-pl6/libclamav/matcher.c
--- clamav-devel.clean.jm-pl6/libclamav/matcher.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/matcher.c	Wed May 19 09:28:49 2004
@@ -51,6 +51,7 @@
 	next = pos->trans[((unsigned char) pattern->pattern[i]) & 0xff]; 
 
 	if(!next) {
+	    void * p = NULL;
 	    next = (struct cl_node *) cli_calloc(1, sizeof(struct cl_node));
 	    if(!next) {
 		cli_dbgmsg("Unable to allocate pattern node (%d)\n", sizeof(struct cl_node));
@@ -58,11 +59,13 @@
 	    }
 
 	    root->nodes++;
-	    root->nodetable = (struct cl_node **) realloc(root->nodetable, (root->nodes) * sizeof(struct cl_node *));
-	    if (root->nodetable == NULL) {
+	    p = (struct cl_node **) realloc(root->nodetable, (root->nodes) * sizeof(struct cl_node *));
+	    if (p == NULL) {
 		cli_dbgmsg("Unable to realloc nodetable (%d)\n", (root->nodes) * sizeof(struct cl_node *));
+		free(next);
 		return CL_EMEM;
 	    }
+	    root->nodetable = p;
 	    root->nodetable[root->nodes - 1] = next;
 
 	    pos->trans[((unsigned char) pattern->pattern[i]) & 0xff] = next;
diff -urN clamav-devel.clean.jm-pl6/libclamav/mbox.c clamav-devel.jm-pl6/libclamav/mbox.c
--- clamav-devel.clean.jm-pl6/libclamav/mbox.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/mbox.c	Wed May 19 09:28:53 2004
@@ -214,7 +214,9 @@
 #endif
 
 #ifndef	CL_DEBUG
-/*#define	NDEBUG	/* map CLAMAV debug onto standard */
+  #define NDEBUG	/* map CLAMAV debug onto standard */
+#else
+  #undef NDEBUG
 #endif
 
 #ifdef CL_THREAD_SAFE
@@ -387,7 +389,10 @@
 		return 0;
 	}
 	m = messageCreate();
-	assert(m != NULL);
+	if(!m) {
+		assert(m);
+		return -1;
+	}
 
 	if(initialiseTables(&rfc821Table, &subtypeTable) < 0) {
 		messageDestroy(m);
@@ -669,8 +674,11 @@
 			aText = textAddMessage(aText, mainMessage);
 			break;
 		case TEXT:
-			if(tableFind(subtypeTable, mimeSubtype) == PLAIN)
+			if(tableFind(subtypeTable, mimeSubtype) == PLAIN) {
 				aText = textCopy(messageGetBody(mainMessage));
+				if(!aText)
+					 return 0;
+			}
 			break;
 		case MULTIPART:
 
@@ -736,6 +744,11 @@
 				int lines = 0;
 
 				aMessage = messages[multiparts] = messageCreate();
+				if(!aMessage) {
+					assert(aMessage);
+					continue;
+				}
+
 
 				cli_dbgmsg("Now read in part %d\n", multiparts);
 
diff -urN clamav-devel.clean.jm-pl6/libclamav/message.c clamav-devel.jm-pl6/libclamav/message.c
--- clamav-devel.clean.jm-pl6/libclamav/message.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/message.c	Wed May 19 09:28:49 2004
@@ -169,7 +169,7 @@
 #endif
 
 #ifndef	CL_DEBUG
-/*#define	NDEBUG	/* map CLAMAV debug onto standard */
+/*#define	NDEBUG*/	/* map CLAMAV debug onto standard */
 #endif
 
 #ifdef CL_THREAD_SAFE
@@ -250,6 +250,8 @@
 messageCreate(void)
 {
 	message *m = (message *)cli_calloc(1, sizeof(message));
+	if(!m)
+	   return NULL;
 
 	m->mimeType = NOMIME;
 	m->encodingType = NOENCODING;
@@ -443,8 +445,13 @@
 			return;	/* already in there */
 
 	if(offset == m->numberOfArguments) {
+		char ** p = NULL;
+
 		m->numberOfArguments++;
-		m->mimeArguments = (char **)cli_realloc(m->mimeArguments, m->numberOfArguments * sizeof(char *));
+		p = cli_realloc(m->mimeArguments, m->numberOfArguments * sizeof(char *));
+		if(!p)
+		    return;
+		m->mimeArguments = p;
 	}
 
 	m->mimeArguments[offset] = strdup(arg);
@@ -572,6 +579,8 @@
 			*ptr = '\0';
 
 			field = cli_malloc(strlen(key) + strlen(data) + 2);
+			if(!field)
+			    return;
 			sprintf(field, "%s=%s", key, data);
 
 			free((char *)key);
@@ -593,6 +602,8 @@
 
 			len = (size_t)string - (size_t)key + 1;
 			field = cli_malloc(len);
+			if(!field)
+			    return;
 
 			memcpy(field, key, len - 1);
 			field[len - 1] = '\0';
@@ -704,6 +715,7 @@
  * If needed a copy of the given line is taken which the caller must free
  * Line must not be terminated by a \n
  */
+
 int
 messageAddLine(message *m, const char *line, int takeCopy)
 {
@@ -732,6 +744,12 @@
 		assert(m->body_last->t_text != NULL);
 	} else {
 		assert(line != NULL);
+#ifdef CL_DEBUG
+		{
+			char * p = strdup(line);
+			free(p);
+		}
+#endif
 		m->body_last->t_text = (char *)line;
 	}
 
@@ -900,6 +918,12 @@
 		 *
 		 * See RFC1741
 		 */
+		
+		if(!tmp) {
+		   blobDestroy(b);
+		   return NULL;
+		}
+
 		while((t_line = t_line->t_next) != NULL)
 			blobAddData(tmp, (unsigned char *)t_line->t_text, strlen(t_line->t_text));
 
@@ -934,6 +958,11 @@
 		cli_dbgmsg("decode HQX7 message (%lu bytes)\n", len);
 
 		ptr = cli_malloc(len);
+		if(!ptr) {
+		    blobDestroy(tmp);
+		    blobDestroy(b);
+		    return NULL;
+		}
 		memcpy(ptr, data, len);
 		bytenumber = 0;
 
@@ -998,6 +1027,11 @@
 		 */
 		if(memchr(data, 0x90, newlen)) {
 			blob *u = blobCreate();	/* uncompressed data */
+			if(!u) {
+			    blobDestroy(tmp);
+			    blobDestroy(b);
+			    return NULL;
+			}
 
 			/*
 			 * Includes compression
@@ -1053,10 +1087,20 @@
 		 */
 		byte = data[0];
 		filename = cli_malloc(byte + 1);
+		if(!filename) {
+		   blobDestroy(tmp);
+		   blobDestroy(b);
+		   return NULL;
+		}
 		memcpy(filename, &data[1], byte);
 		filename[byte] = '\0';
 		blobSetFilename(b, filename);
 		ptr = cli_malloc(strlen(filename) + 6);
+		if(!ptr) {
+		   blobDestroy(tmp);
+		   blobDestroy(b);
+		   return NULL;
+		}
 		sprintf(ptr, "name=%s", filename);
 		messageAddArgument(m, ptr);
 		free(ptr);
@@ -1166,7 +1210,7 @@
 messageToText(const message *m)
 {
 	text *first = NULL, *last = NULL;
-	const text *t_line;
+	const text *t_line = NULL;
 
 	assert(m != NULL);
 
@@ -1175,15 +1219,20 @@
 		 * Fast copy
 		 */
 		for(t_line = messageGetBody(m); t_line; t_line = t_line->t_next) {
-			if(first == NULL)
+			if(first == NULL) {
 				first = last = cli_malloc(sizeof(text));
-			else {
+				if(!first)
+					return NULL;
+			} else {
 				last->t_next = cli_malloc(sizeof(text));
+				if(!last->t_next) {
+					textDestroy(first);
+					return NULL;
+				}
 				last = last->t_next;
 			}
 
-			if((last == NULL) ||
-			   ((last->t_text = strdup(t_line->t_text)) == NULL)) {
+			if(!(last->t_text = strdup(t_line->t_text))) {
 				textDestroy(first);
 				return NULL;
 			}
@@ -1219,15 +1268,25 @@
 
 			assert(uptr <= &data[sizeof(data)]);
 
-			if(first == NULL)
+			if(first == NULL) {
 				first = last = cli_malloc(sizeof(text));
-			else {
+				if(!first )
+					return NULL;
+			} else {
 				last->t_next = cli_malloc(sizeof(text));
+				if(!last->t_next) {
+					textDestroy(first);
+					return NULL;
+				}
 				last = last->t_next;
 			}
 
 			last->t_text = strdup((char *)data);
-			assert(last->t_text != NULL);
+			if(!last->t_text) {
+				assert(last->t_text != NULL);
+				textDestroy(first);
+				return NULL;
+			}
 
 			if(messageGetEncoding(m) == BASE64)
 				if(strchr(line, '='))
diff -urN clamav-devel.clean.jm-pl6/libclamav/ole2_extract.c clamav-devel.jm-pl6/libclamav/ole2_extract.c
--- clamav-devel.clean.jm-pl6/libclamav/ole2_extract.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/ole2_extract.c	Wed May 19 09:28:49 2004
@@ -554,7 +554,7 @@
 {
 	unsigned char buff[(1 << hdr->log2_big_block_size)];
 	int32_t current_block, ofd, len, offset;
-	char *name, *newname;
+	char *name = NULL, *newname = NULL;
 
 	if (prop->type != 2) {
 		/* Not a file */
@@ -579,6 +579,11 @@
 	}
 
 	newname = (char *) cli_malloc(strlen(name) + strlen(dir) + 2);
+	if(!newname) {
+	    if(name)
+	       free(name);
+	    return FALSE;
+	}
 	sprintf(newname, "%s/%s", dir, name);
 	free(name);
 
diff -urN clamav-devel.clean.jm-pl6/libclamav/others.c clamav-devel.jm-pl6/libclamav/others.c
--- clamav-devel.clean.jm-pl6/libclamav/others.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/others.c	Wed May 19 09:28:49 2004
@@ -174,6 +174,8 @@
     fclose(fd);
 
     md5str = (char*) calloc(32 + 1, sizeof(char));
+    if(!md5str)
+	return NULL;
 
     for(i=0; i<16; i++)
 	cnt += sprintf(md5str + cnt, "%02x", buffer[i]);
@@ -190,6 +192,8 @@
     md5_stream(fd, &buffer);
 
     md5str = (char*) calloc(32 + 1, sizeof(char));
+    if(!md5str)
+	return NULL;
 
     for(i=0; i<16; i++)
 	cnt += sprintf(md5str + cnt, "%02x", buffer[i]);
@@ -211,6 +215,8 @@
     memcpy(oldmd5buff, md5buff, 16);
 
     md5str = (char*) cli_calloc(32 + 1, sizeof(char));
+    if(!md5str)
+	return NULL;
 
     for(i=0; i<16; i++)
 	cnt += sprintf(md5str + cnt, "%02x", md5buff[i]);
@@ -350,6 +356,8 @@
 		if(dent->d_ino) {
 		    if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
 			fname = cli_calloc(strlen(dirname) + strlen(dent->d_name) + 2, sizeof(char));
+			if(!fname)
+			    return 0;
 			sprintf(fname, "%s/%s", dirname, dent->d_name);
 
 			/* stat the file */
diff -urN clamav-devel.clean.jm-pl6/libclamav/readdb.c clamav-devel.jm-pl6/libclamav/readdb.c
--- clamav-devel.clean.jm-pl6/libclamav/readdb.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/readdb.c	Wed May 19 09:28:49 2004
@@ -295,9 +295,16 @@
 	if(dent->d_ino) {
 	    if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") && (cli_strbcasestr(dent->d_name, ".db") || cli_strbcasestr(dent->d_name, ".db2") || cli_strbcasestr(dent->d_name, ".cvd"))) {
 
+		void * p = NULL;
+		
 		dbstat->no++;
-		dbstat->stattab = (struct stat *) realloc(dbstat->stattab, dbstat->no * sizeof(struct stat));
+		p = (struct stat *) realloc(dbstat->stattab, dbstat->no * sizeof(struct stat));
+		if(!p)	
+		    return CL_EMEM;
+		dbstat->stattab = p;
                 fname = cli_calloc(strlen(dirname) + strlen(dent->d_name) + 2, sizeof(char));
+		if(!fname)
+		    return CL_EMEM;
 		sprintf(fname, "%s/%s", dirname, dent->d_name);
 		stat(fname, &dbstat->stattab[dbstat->no - 1]);
 		free(fname);
@@ -335,6 +342,8 @@
 	    if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") && (cli_strbcasestr(dent->d_name, ".db") || cli_strbcasestr(dent->d_name, ".db2") || cli_strbcasestr(dent->d_name, ".cvd"))) {
 
                 fname = cli_calloc(strlen(dbstat->dir) + strlen(dent->d_name) + 2, sizeof(char));
+		if(!fname)
+		    return CL_EMEM;
 		sprintf(fname, "%s/%s", dbstat->dir, dent->d_name);
 		stat(fname, &sb);
 		free(fname);
diff -urN clamav-devel.clean.jm-pl6/libclamav/scanners.c clamav-devel.jm-pl6/libclamav/scanners.c
--- clamav-devel.clean.jm-pl6/libclamav/scanners.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/scanners.c	Wed May 19 09:28:49 2004
@@ -59,6 +59,7 @@
 #define SCAN_OLE2	    (options & CL_OLE2)
 #define DISABLE_RAR	    (options & CL_DISABLERAR)
 #define DETECT_ENCRYPTED    (options & CL_ENCRYPTED)
+#define SCAN_UNKNOWN_MAIL    (options & CL_UNKNOWN_MAIL)
 
 struct cli_magic_s {
     int offset;
@@ -721,6 +722,10 @@
 		if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
 		    /* build the full name */
 		    fname = cli_calloc(strlen(dirname) + strlen(dent->d_name) + 2, sizeof(char));
+		    if(!fname) {
+			closedir(dd);    
+			return(CL_EMEM);
+		    }
 		    sprintf(fname, "%s/%s", dirname, dent->d_name);
 
 		    /* stat the file */
@@ -768,6 +773,10 @@
 
 	for(i = 0; i < vba_project->count; i++) {
 	    fullname = (char *) cli_malloc(strlen(vba_project->dir) + strlen(vba_project->name[i]) + 2);
+	    if(!fullname) {
+		ret = CL_EMEM;
+		break;
+	    }
 	    sprintf(fullname, "%s/%s", vba_project->dir, vba_project->name[i]);
 	    fd = open(fullname, O_RDONLY);
 	    if(fd == -1) {
@@ -803,6 +812,10 @@
     } else if ((vba_project = (vba_project_t *) wm_dir_read(dirname))) {
     	for (i = 0; i < vba_project->count; i++) {
 		fullname = (char *) cli_malloc(strlen(vba_project->dir) + strlen(vba_project->name[i]) + 2);
+		if(!fullname) {
+		    ret = CL_EMEM;
+		    break;
+		}
 		sprintf(fullname, "%s/%s", vba_project->dir, vba_project->name[i]);
 		fd = open(fullname, O_RDONLY);
 		if(fd == -1) {
@@ -846,6 +859,10 @@
 		if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
 		    /* build the full name */
 		    fname = cli_calloc(strlen(dirname) + strlen(dent->d_name) + 2, sizeof(char));
+		    if(!fname) {
+			closedir(dd);
+			return CL_EMEM;
+		    }
 		    sprintf(fname, "%s/%s", dirname, dent->d_name);
 
 		    /* stat the file */
@@ -986,6 +1003,9 @@
     }
 
     type = cli_filetype(magic, bread);
+
+	if(type == CL_UNKNOWN_TYPE && SCAN_UNKNOWN_MAIL)
+		type = CL_MAILFILE;
 
     switch(type) {
 	case CL_DOSEXE:
diff -urN clamav-devel.clean.jm-pl6/libclamav/str.c clamav-devel.jm-pl6/libclamav/str.c
--- clamav-devel.clean.jm-pl6/libclamav/str.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/str.c	Wed May 19 09:28:49 2004
@@ -179,6 +179,8 @@
 	return NULL;
     }
     buffer = malloc(j-i+1);
+    if(!buffer)
+	return NULL;
     strncpy(buffer, line+i, j-i);
     buffer[j-i] = '\0';
 
diff -urN clamav-devel.clean.jm-pl6/libclamav/text.c clamav-devel.jm-pl6/libclamav/text.c
--- clamav-devel.clean.jm-pl6/libclamav/text.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/text.c	Wed May 19 09:28:53 2004
@@ -50,6 +50,7 @@
 #include "blob.h"
 #include "text.h"
 #include "others.h"
+#include "../shared/cl_debug.h"
 
 void
 textDestroy(text *t_head)
@@ -62,6 +63,20 @@
 	}
 }
 
+#ifdef CL_DEBUG
+int
+textTestDebug(text *t_head)
+{
+	while(t_head) {
+		void *p = NULL;
+		p = strdup(t_head->t_text);
+		free(p);
+		t_head = t_head->t_next;	
+	}
+	return 1;
+}
+#endif
+
 /*
  * Remove trailing spaces from the lines and trailing blank lines
  */
@@ -138,19 +153,27 @@
 	text *first = NULL, *last = NULL;
 
 	while(t_head) {
-		if(first == NULL)
+		if(first == NULL) {
 			last = first = (text *)cli_malloc(sizeof(text));
-		else {
+			if(!last) {
+				assert(last);
+				return NULL;
+			}
+		} else {
 			last->t_next = (text *)cli_malloc(sizeof(text));
+			if(!last->t_next) {
+				assert(last->t_next);
+				textDestroy(first);
+				return NULL;
+			}
 			last = last->t_next;
 		}
-
-		assert(last != NULL);
-
 		last->t_text = strdup(t_head->t_text);
-
-		assert(last->t_text != NULL);
-
+		if(!last->t_text) {
+			assert(last->t_text);
+			textDestroy(first);
+			return NULL;
+		}
 		t_head = t_head->t_next;
 	}
 
@@ -182,10 +205,17 @@
 		t_head = t_head->t_next;
 
 		assert(t_head != NULL);
+		if(!t_head)
+			return ret;
 
 		t_head->t_text = strdup(t->t_text);
 
 		assert(t_head->t_text != NULL);
+		if(!t_head->t_text) {
+			free(t_head->t_next);
+			t_head->t_next = NULL;
+			return ret;
+		}
 
 		t = t->t_next;
 	}
diff -urN clamav-devel.clean.jm-pl6/libclamav/unrarlib.c clamav-devel.jm-pl6/libclamav/unrarlib.c
--- clamav-devel.clean.jm-pl6/libclamav/unrarlib.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/unrarlib.c	Wed May 19 09:28:49 2004
@@ -553,6 +553,12 @@
     if((void*)(*(DWORD*)list) == NULL)      /* first entry                  */
     {
       tmp_List = malloc(sizeof(ArchiveList_struct));
+      if(!tmp_List) {
+	  fclose(ArcPtr);
+	  free(UnpMemory);
+	  return FALSE;
+      }
+	  
       tmp_List->next = NULL;
 
       (*(DWORD*)list) = (DWORD)tmp_List;
@@ -560,11 +566,24 @@
     } else                                  /* add entry                    */
     {
       tmp_List->next = malloc(sizeof(ArchiveList_struct));
+      if(!tmp_List) {
+	  fclose(ArcPtr);
+	  free(UnpMemory);
+	  return FALSE;
+      }
+	  
       tmp_List = (ArchiveList_struct*) tmp_List->next;
       tmp_List->next = NULL;
     }
 
     tmp_List->item.Name = malloc(NewLhd.NameSize + 1);
+    if(!tmp_List->item.Name) {
+	fclose(ArcPtr);
+	free(UnpMemory);
+	free(tmp_List);
+	return FALSE;
+    }
+	  
     strcpy(tmp_List->item.Name, ArcFileName);
     tmp_List->item.NameSize = NewLhd.NameSize;
     tmp_List->item.PackSize = NewLhd.PackSize;
diff -urN clamav-devel.clean.jm-pl6/libclamav/vba_extract.c clamav-devel.jm-pl6/libclamav/vba_extract.c
--- clamav-devel.clean.jm-pl6/libclamav/vba_extract.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/libclamav/vba_extract.c	Wed May 19 09:28:49 2004
@@ -219,9 +219,10 @@
 				continue;
 			}
 			buff = (unsigned char *) cli_malloc(10);
-			if (cli_readn(fd, buff, 10) != 10) {
+			if (!buff || (cli_readn(fd, buff, 10) != 10) ) {
 				cli_errmsg("failed to read blob\n");
-				free(buff);
+				if(buff)
+				    free(buff);
 				free(name);
 				close(fd);
 				return FALSE;
@@ -269,6 +270,8 @@
 	cli_dbgmsg("in vba56_dir_read()\n");
 
 	fullname = (char *) cli_malloc(strlen(dir) + 15);
+	if(!fullname)
+	    return NULL;
 	sprintf(fullname, "%s/_VBA_PROJECT", dir);
         fd = open(fullname, O_RDONLY);
 
@@ -424,10 +427,23 @@
 	cli_dbgmsg("\nVBA Record count: %d\n", record_count);
 	
 	vba_project = (vba_project_t *) cli_malloc(sizeof(struct vba_project_tag));
+	if(!vba_project) {
+	    close(fd);
+	    return NULL;
+	}
 	vba_project->name = (char **) cli_malloc(sizeof(char *) * record_count);
+	if(vba_project->name) {
+	    free(vba_project);
+	    return NULL;
+	}
 	vba_project->dir = strdup(dir);
 	vba_project->offset = (uint32_t *) cli_malloc (sizeof(uint32_t) *
 					record_count);
+	if(vba_project->offset) {
+	    free(vba_project->name);
+	    free(vba_project);
+	    return NULL;
+	}
 	vba_project->count = record_count;
 	for (i=0 ; i < record_count ; i++) {
 		if (cli_readn(fd, &length, 2) != 2) {
@@ -524,10 +540,16 @@
 {
 	if (array->length == 0) {
 		array->data = (unsigned char *) cli_malloc(len);
+		if(!array->data)
+		    return;
 		array->length = len;
 		memcpy(array->data, src, len);
 	} else {
-		array->data = realloc(array->data, array->length+len);
+		void * p = NULL;
+		p = realloc(array->data, array->length+len);
+		if(!p)
+		    return;
+		array->data = p;
 		memcpy(array->data+array->length, src, len);
 		array->length += len;
 	}
@@ -1004,14 +1026,16 @@
 
 	offset_end += size;
 	while (lseek(fd, 0, SEEK_CUR) < offset_end) {
+		macro_extname_t * p = NULL;
+		
 		macro_extnames->count++;
-		macro_extnames->macro_extname = (macro_extname_t *)
-			cli_realloc(macro_extnames->macro_extname,
+		p = (macro_extname_t *) cli_realloc(macro_extnames->macro_extname,
 				sizeof(macro_extname_t) * macro_extnames->count);
-		if (macro_extnames->macro_extname == NULL) {
+		if (p == NULL) {
 			cli_dbgmsg("read macro_extnames failed\n");
 			goto abort;;
 		}
+		macro_extnames->macro_extname = p;
 
 		macro_extname = &macro_extnames->macro_extname[macro_extnames->count-1];
 		if (is_unicode) {
diff -urN clamav-devel.clean.jm-pl6/shared/cfgparser.c clamav-devel.jm-pl6/shared/cfgparser.c
--- clamav-devel.clean.jm-pl6/shared/cfgparser.c	Wed May 19 08:58:23 2004
+++ clamav-devel.jm-pl6/shared/cfgparser.c	Wed May 19 09:28:45 2004
@@ -63,6 +63,7 @@
 	    {"TemporaryDirectory", OPT_STR},
 	    {"MaxFileSize", OPT_COMPSIZE},
 	    {"ScanMail", OPT_NOARG},
+	    {"ScanUnknownAsMail", OPT_NOARG},
 	    {"ScanOLE2", OPT_NOARG},
 	    {"ScanArchive", OPT_NOARG},
 	    {"ScanRAR", OPT_NOARG},
diff -urN clamav-devel.clean.jm-pl6/shared/cl_debug.h clamav-devel.jm-pl6/shared/cl_debug.h
--- clamav-devel.clean.jm-pl6/shared/cl_debug.h	Wed Dec 31 19:00:00 1969
+++ clamav-devel.jm-pl6/shared/cl_debug.h	Wed May 19 09:28:53 2004
@@ -0,0 +1,13 @@
+#ifndef CL_DEBUG_H
+	#define CL_DEBUG_H
+#ifdef CL_DEBUG
+
+#undef NDEBUG /*assert() on */
+#include <mcheck.h>
+
+int textTestDebug(text * t_head);
+	
+
+
+#endif /* CL_DEBUG */
+#endif /* CL_DEBUG_H */
diff -urN clamav-devel.clean.jm-pl6/shared/vsnprintf_alloc.c clamav-devel.jm-pl6/shared/vsnprintf_alloc.c
--- clamav-devel.clean.jm-pl6/shared/vsnprintf_alloc.c	Wed Dec 31 19:00:00 1969
+++ clamav-devel.jm-pl6/shared/vsnprintf_alloc.c	Wed May 19 09:28:45 2004
@@ -0,0 +1,185 @@
+#include "vsnprintf_alloc.h"
+
+
+
+int
+vsnprintf_alloc(char **p, size_t len, const char * fmt, va_list argp)
+{
+	char	*buf = NULL;
+	char	*bufp = NULL;
+	short	we_malloced = 0;
+	int	retlen = 0;
+	size_t	print_len = (len) ? len : strlen(fmt) + BUFSIZ;
+
+	if(!fmt || !p || len < 0)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	if(*p)
+	{
+		buf = realloc(*p, print_len + 1);
+		if(!buf)
+			return -1;
+		*p = buf;
+	}
+	else
+	{
+		if((buf = malloc(print_len + 1)))
+			we_malloced = 1;
+		else
+			return -1;
+	}
+
+	while(1)	
+	{
+		retlen  = vsnprintf(buf, print_len + 1, fmt, argp);
+		
+		buf[print_len] = '\0';
+			
+		if(retlen == -1)
+		{
+			if(errno == EINVAL)
+			{
+				if(we_malloced)
+					free(buf);
+				else
+					*p = buf;
+				errno = EINVAL;
+				return -1;
+			}
+			/* For optimization, switch this to doubling? */
+			print_len += BUFSIZ;
+		} 
+		else if(retlen > print_len) 
+		{
+			/* C99 */
+			print_len = retlen;
+		}
+		else
+		{
+			/* Sucess */
+			break;
+		}
+
+		if(len && print_len > len)
+			print_len = len;
+		
+		bufp = realloc(buf, print_len + 1);
+		if(!bufp)
+		{
+			if(we_malloced)
+				free(buf);
+			else
+				*p = buf;
+			return -1;
+		}
+		else
+			buf = bufp;
+	}
+
+	
+	*p = buf;
+	return(retlen);
+}
+
+int
+vsprintf_alloc(char **p, const char * fmt, va_list argp)
+{
+	if(!fmt || !p)
+	{	
+		errno = EINVAL;
+		return -1;
+	}
+
+	return(vsnprintf_alloc(p, 0, fmt, argp));
+}	
+
+int
+snprintf_alloc(char **p, size_t len, const char * fmt, ...)
+{
+	int retlen = 0;
+	va_list argp;
+
+	if(!fmt || !p || len < 0)
+	{	
+		errno = EINVAL;
+		return -1;
+	}
+
+	va_start(argp, fmt);
+	retlen = vsnprintf_alloc(p, len, fmt, argp);
+	va_end(argp);
+
+	return(retlen);
+}	
+
+int
+sprintf_alloc(char **p, const char * fmt, ...)
+{
+	int retlen = 0;
+	va_list argp;
+
+	if(!fmt || !p)
+	{	
+		errno = EINVAL;
+		return -1;
+	}
+
+	va_start(argp, fmt);
+	retlen = vsprintf_alloc(p, fmt, argp);
+	va_end(argp);
+
+	return(retlen);
+}	
+
+struct vsnprintf_alloc_cfg *
+vsnprintf_alloc_configure(struct vsnprintf_alloc_cfg * cfg)
+{
+
+}
+
+#if !HAVE_ASPRINTF
+int
+asprintf(char **p, const char * fmt, ...)
+{
+	int retlen = 0;
+	char * buf = NULL;
+	va_list argp;
+
+	if(!fmt || !p)
+	{	
+		errno = EINVAL;
+		return -1;
+	}
+
+	va_start(argp, fmt);
+	retlen = vsprintf_alloc(&buf, fmt, argp);
+	if(retlen >= 0)
+		*p = buf;
+	va_end(argp);
+
+	return(retlen);
+}
+#endif /* !HAVE_ASPRINTG */
+
+#if !HAVE_VASPRINTF
+int
+vasprintf(char **p, const char * fmt, va_list argp)
+{
+	char * buf = NULL;
+	int retlen = 0;
+
+	if(!fmt || !p)
+	{	
+		errno = EINVAL;
+		return -1;
+	}
+
+	retlen = vsnprintf_alloc(&buf, 0, fmt, argp);
+	if(retlen >= 0)
+		*p = buf;
+	return(retlen);
+}	
+#endif /* !HAVE_VASPRINTF */ 
diff -urN clamav-devel.clean.jm-pl6/shared/vsnprintf_alloc.h clamav-devel.jm-pl6/shared/vsnprintf_alloc.h
--- clamav-devel.clean.jm-pl6/shared/vsnprintf_alloc.h	Wed Dec 31 19:00:00 1969
+++ clamav-devel.jm-pl6/shared/vsnprintf_alloc.h	Wed May 19 09:28:45 2004
@@ -0,0 +1,93 @@
+#ifndef VSNPRINTF_ALLOC_H
+	#define VSNPRINTF_ALLOC_H
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <string.h>
+
+#ifndef BUFSIZ
+	#define BUFSIZ	4096
+#endif
+
+/*
+ * Takes: address of pointer to char, optional maximum length, printf(3) format string, and a variable list of arguments
+ * Returns: -1 for error or number of bytes (that would have been) printed into string.
+ * 
+ * The address of pointer to char MUST not be null. 
+ *
+ * If the pointer to char is NOT null, it MUST be a valid malloc'd memory string.
+ * 
+ * if pointer to char is null, malloc will be called and the address stored back in the passed in addressed pointer
+ * otherwise realloc will be used as needed on the passed in pointer address with the result stored back in.
+ *
+ * 
+ * Passing in a NULL address or a negative length or a NULL format string 
+ * OR
+ * Running out of memory will return -1.  
+ *
+ * Doing the former will result in errno == EINVAL. 
+ * Presumably the latter will result in errno == ENOMEM.
+ *
+ * On error the pointer to char will be valid if it was originaly supplied by you and you must free it.
+ *
+ * Passing in a length of zero will allow the function to allocate memory until the entire string is printed.
+ * Otherwise it will only allocate and print into the string up to the size specified, including terminating '\0'.
+ *
+ * 
+ */
+int
+snprintf_alloc(char **p, size_t len, const char *fmt, ...);
+
+/*
+ * Same as above except 0 is assumed for length
+ */
+int
+sprintf_alloc(char **p, const char *fmt, ...);
+
+/*
+ * same as snprintf_alloc except you pass it argp instead of variable list of arguments
+ */
+int
+vsnprintf_alloc(char **p, size_t len, const char *fmt, va_list argp);
+
+/*
+ * same as above except 0 is assumed for length
+ */
+int
+vsprintf_alloc(char **p, const char *fmt, va_list argp);
+
+#if !HAVE_ASPRINTF
+/*
+ * like sprintf_alloc except does not support privately allocated memory. Also does not require *p to be NULL/
+ * On error *p should NOT be used and will probably be NULL.
+ *
+ * WARNING: Passing in address of valid pointer for p will lead to memory leaks! 
+ */
+int
+asprintf(char **p, const char *fmt, ...);
+#endif /* !HAVE_ASPRINF */
+
+#if !HAVE_VASPRINTF
+/*
+ * like vsprintf_alloc except does not support privately allocated memory. Also does not require *p to be NULL/
+ * On error *p should NOT be used and will probably be NULL.
+ *
+ * WARNING: Passing in address of valid pointer for p will lead to memory leaks! 
+ */
+int
+vasprintf(char **p, const char *fmt, va_list argp);
+#endif /* !HAVE_VASPRINF */
+
+
+struct vsnprintf_alloc_cfg 
+{
+	void (*malloc) (size_t);
+	void (*free) (void *, size_t);
+	short 	multiply;
+	short	assertive;
+	size_t	internal_limit;	
+	short	free_on_error;
+};
+
+#endif /* VSNPRINTF_ALLOC_H */
