diff -urN clamav-devel-jm2/clamav-milter/Makefile.am clamav-devel-jm1/clamav-milter/Makefile.am
--- clamav-devel-jm2/clamav-milter/Makefile.am	Mon Apr 19 18:29:27 2004
+++ clamav-devel-jm1/clamav-milter/Makefile.am	Mon Apr 19 17:31:37 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-jm2/shared/vsnprintf_alloc.c clamav-devel-jm1/shared/vsnprintf_alloc.c
--- clamav-devel-jm2/shared/vsnprintf_alloc.c	Wed Dec 31 19:00:00 1969
+++ clamav-devel-jm1/shared/vsnprintf_alloc.c	Mon Apr 19 17:28:58 2004
@@ -0,0 +1,133 @@
+#include <vsnprintf_alloc.h>
+
+
+
+
+size_t vsnprintf_alloc(char **p, size_t len, const char * fmt, va_list argp)
+{
+	char	*buf = NULL;
+	short	we_malloced = 0;
+	size_t	retlen = 0;
+
+	if(!fmt)
+		return -1;
+	if(!p)
+		return -1;
+	if(len < 0)
+		return len;
+
+	if(*p)
+		buf = *p;
+	
+	{
+		size_t	print_len = strlen(fmt) + BUFSIZ;
+		char	*bufp = NULL;
+
+	do 
+	{
+		if(!buf && !(buf = malloc(print_len + 1)))
+			return -1;
+		else
+			we_malloced = 1;
+		if(retlen)
+		{
+			if(retlen == -1)
+			{/* For optimization, switch this to doubling? */
+				print_len += BUFSIZ;
+			} 
+			else if(retlen > print_len) 
+			{
+				print_len = retlen;
+			}
+			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;
+		}
+		retlen  = vsnprintf(buf, print_len + 1, fmt, argp);
+		buf[print_len] = '\0';
+
+	} while( (!len || print_len < len ) && (retlen == -1 || retlen > print_len) );
+		/* This block intentionaly left blank */
+	}
+	
+	*p = buf;
+	return(retlen);
+}
+
+size_t vsprintf_alloc(char **p, const char * fmt, va_list argp)
+{
+	size_t retlen = 0;
+	char * buf = NULL;
+
+	if(!fmt)
+		return -1;
+	if(!p)
+		return -1;
+
+	buf = *p;
+	retlen = vsnprintf_alloc(&buf, 0, fmt, argp);
+	*p = buf;
+
+	return(retlen);
+
+}	
+
+size_t snprintf_alloc(char **p, size_t len, const char * fmt, ...)
+{
+	size_t retlen = 0;
+	char * buf = NULL;
+	va_list argp;
+
+	if(!fmt)
+		return -1;
+	if(!p)
+		return -1;
+	if(len < 0)
+		return -1;
+
+	va_start(argp, fmt);
+	buf = *p;
+	retlen = vsnprintf_alloc(&buf, len, fmt, argp);
+	*p = buf;
+	va_end(argp);
+
+	return(retlen);
+
+}	
+
+size_t sprintf_alloc(char **p, const char * fmt, ...)
+{
+	size_t retlen = 0;
+	char * buf = NULL;
+	va_list argp;
+
+	if(!fmt)
+		return -1;
+	if(!p)
+		return -1;
+
+	va_start(argp, fmt);
+	buf = *p;
+	retlen = vsprintf_alloc(&buf, fmt, argp);
+	*p = buf;
+	va_end(argp);
+
+	return(retlen);
+
+}	
+
+struct vsnprintf_alloc_cfg *
+vsnprintf_alloc_configure(struct vsnprintf_alloc_cfg * cfg)
+{
+
+}
diff -urN clamav-devel-jm2/shared/vsnprintf_alloc.h clamav-devel-jm1/shared/vsnprintf_alloc.h
--- clamav-devel-jm2/shared/vsnprintf_alloc.h	Wed Dec 31 19:00:00 1969
+++ clamav-devel-jm1/shared/vsnprintf_alloc.h	Mon Apr 19 17:28:59 2004
@@ -0,0 +1,58 @@
+#ifndef VSNPRINTF_ALLOC_H
+	#define VSNPRINTF_ALLOC_H
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+
+/*
+ * 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.  
+ *
+ * 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'.
+ * 
+ */
+size_t snprintf_alloc(char **p, size_t len, const char *fmt, ...);
+
+/*
+ * Same as above except 0 is assumed for length
+ */
+size_t sprintf_alloc(char **p, const char *fmt, ...);
+
+/*
+ * same as snprintf_alloc except you pass it argp instead of variable list of arguments
+ */
+size_t vsnprintf_alloc(char **p, size_t len, const char *fmt, va_list argp);
+
+/*
+ * same as above except 0 is assumed for length
+ */
+size_t vsprintf_alloc(char **p, const char *fmt, va_list argp);
+
+
+struct vsnprintf_alloc_cfg 
+{
+	void (*malloc) (size_t);
+	void (*free) (void *, size_t);
+	short 	multiply;
+	short	assertive;
+	short	internal_limit;	
+	short	free_on_error;
+};
+
+#endif /* VSNPRINTF_ALLOC_H */
