Index: squid-2.7.STABLE5/src/protos.h
===================================================================
--- squid-2.7.STABLE5.orig/src/protos.h
+++ squid-2.7.STABLE5/src/protos.h
@@ -34,6 +34,8 @@
 #ifndef SQUID_PROTOS_H
 #define SQUID_PROTOS_H
 
+#include "MemBuf.h"
+
 extern void accessLogLog(AccessLogEntry *, aclCheck_t * checklist);
 extern void accessLogRotate(void);
 extern void accessLogClose(void);
@@ -620,33 +622,6 @@ extern ipcache_addrs *ipcacheCheckNumeri
 extern void ipcache_restart(void);
 extern int ipcacheAddEntryFromHosts(const char *name, const char *ipaddr);
 
-/* MemBuf */
-/* init with specific sizes */
-extern void memBufInit(MemBuf * mb, mb_size_t szInit, mb_size_t szMax);
-/* init with defaults */
-extern void memBufDefInit(MemBuf * mb);
-/* cleans mb; last function to call if you do not give .buf away */
-extern void memBufClean(MemBuf * mb);
-/* resets mb preserving (or initializing if needed) memory buffer */
-extern void memBufReset(MemBuf * mb);
-/* unfirtunate hack to test if the buffer has been Init()ialized */
-extern int memBufIsNull(MemBuf * mb);
-/* calls memcpy, appends exactly size bytes, extends buffer if needed */
-extern void memBufAppend(MemBuf * mb, const void *buf, int size);
-/* calls snprintf, extends buffer if needed */
-#if STDC_HEADERS
-extern void
-memBufPrintf(MemBuf * mb, const char *fmt,...) PRINTF_FORMAT_ARG2;
-#else
-extern void memBufPrintf();
-#endif
-/* vprintf for other printf()'s to use */
-extern void memBufVPrintf(MemBuf * mb, const char *fmt, va_list ap);
-/* returns free() function to be used, _freezes_ the object! */
-extern FREE *memBufFreeFunc(MemBuf * mb);
-/* puts report on MemBuf _module_ usage into mb */
-extern void memBufReport(MemBuf * mb);
-
 extern char *mime_get_header(const char *mime, const char *header);
 extern char *mime_get_header_field(const char *mime, const char *name, const char *prefix);
 extern size_t headersEnd(const char *, size_t);
Index: squid-2.7.STABLE5/src/structs.h
===================================================================
--- squid-2.7.STABLE5.orig/src/structs.h
+++ squid-2.7.STABLE5/src/structs.h
@@ -37,6 +37,8 @@
 #include "config.h"
 #include "splay.h"
 
+#include "MemBuf.h"
+
 #define PEER_MULTICAST_SIBLINGS 1
 
 struct _dlink_node {
@@ -969,19 +971,6 @@ struct _fileMap {
     unsigned long *file_map;
 };
 
-/* auto-growing memory-resident buffer with printf interface */
-/* note: when updating this struct, update MemBufNULL #define */
-struct _MemBuf {
-    /* public, read-only */
-    char *buf;
-    mb_size_t size;		/* used space, does not count 0-terminator */
-
-    /* private, stay away; use interface function instead */
-    mb_size_t max_capacity;	/* when grows: assert(new_capacity <= max_capacity) */
-    mb_size_t capacity;		/* allocated space */
-    unsigned stolen:1;		/* the buffer has been stolen for use by someone else */
-};
-
 /* see Packer.c for description */
 struct _Packer {
     /* protected, use interface functions instead */
Index: squid-2.7.STABLE5/src/typedefs.h
===================================================================
--- squid-2.7.STABLE5.orig/src/typedefs.h
+++ squid-2.7.STABLE5/src/typedefs.h
@@ -160,7 +160,6 @@ typedef struct _pingerReplyData pingerRe
 typedef struct _icp_common_t icp_common_t;
 typedef struct _Meta_data Meta_data;
 typedef struct _iostats iostats;
-typedef struct _MemBuf MemBuf;
 typedef struct _mem_node mem_node;
 typedef struct _mem_hdr mem_hdr;
 typedef struct _store_client store_client;
Index: squid-2.7.STABLE5/tools/cachemgr.c
===================================================================
--- squid-2.7.STABLE5.orig/tools/cachemgr.c
+++ squid-2.7.STABLE5/tools/cachemgr.c
@@ -133,6 +133,7 @@
 
 #include "util.h"
 #include "snprintf.h"
+#include "MemBuf.h"
 
 #ifndef DEFAULT_CACHEMGR_CONFIG
 #define DEFAULT_CACHEMGR_CONFIG "/etc/squid/cachemgr.conf"
@@ -398,81 +399,79 @@ menu_url(cachemgr_request * req, const c
     return url;
 }
 
-static const char *
-munge_menu_line(const char *buf, cachemgr_request * req)
+static void
+munge_menu_line(MemBuf *out, const char *buf, cachemgr_request * req)
 {
-    char *x;
+    char *buf_copy, *x;
     const char *a;
     const char *d;
     const char *p;
     char *a_url;
-    char *buf_copy;
-    static char html[2 * 1024];
-    if (strlen(buf) < 1)
-	return buf;
-    if (*buf != ' ')
-	return buf;
-    buf_copy = x = xstrdup(buf);
+
+    const char bufLen = strlen(buf);
+    if (bufLen < 1 || *buf != ' ') {
+        memBufAppend(out, buf, bufLen);
+        return;
+    }
+    buf_copy = x = xstrndup(buf, bufLen);
+
     a = xstrtok(&x, '\t');
     d = xstrtok(&x, '\t');
     p = xstrtok(&x, '\t');
     a_url = xstrdup(menu_url(req, a));
     /* no reason to give a url for a disabled action */
     if (!strcmp(p, "disabled"))
-	snprintf(html, sizeof(html), "<LI type=\"circle\">%s (disabled)<A HREF=\"%s\">.</A>\n", d, a_url);
+	memBufPrintf(out, "<LI type=\"circle\">%s (disabled)<A HREF=\"%s\">.</A>\n", d, a_url);
     else
 	/* disable a hidden action (requires a password, but password is not in squid.conf) */
     if (!strcmp(p, "hidden"))
-	snprintf(html, sizeof(html), "<LI type=\"circle\">%s (hidden)<A HREF=\"%s\">.</A>\n", d, a_url);
+	memBufPrintf(out, "<LI type=\"circle\">%s (hidden)<A HREF=\"%s\">.</A>\n", d, a_url);
     else
 	/* disable link if authentication is required and we have no password */
     if (!strcmp(p, "protected") && !req->passwd)
-	snprintf(html, sizeof(html), "<LI type=\"circle\">%s (requires <a href=\"%s\">authentication</a>)<A HREF=\"%s\">.</A>\n",
+	memBufPrintf(out, "<LI type=\"circle\">%s (requires <a href=\"%s\">authentication</a>)<A HREF=\"%s\">.</A>\n",
 	    d, menu_url(req, "authenticate"), a_url);
     else
 	/* highlight protected but probably available entries */
     if (!strcmp(p, "protected"))
-	snprintf(html, sizeof(html), "<LI type=\"square\"><A HREF=\"%s\"><font color=\"#FF0000\">%s</font></A>\n",
-	    a_url, d);
+	memBufPrintf(out, "<LI type=\"square\"><A HREF=\"%s\"><font color=\"#FF0000\">%s</font></A>\n", a_url, d);
     /* public entry or unknown type of protection */
     else
-	snprintf(html, sizeof(html), "<LI type=\"disk\"><A HREF=\"%s\">%s</A>\n", a_url, d);
+	memBufPrintf(out, "<LI type=\"disk\"><A HREF=\"%s\">%s</A>\n", a_url, d);
     xfree(a_url);
     xfree(buf_copy);
-    return html;
 }
 
-static const char *
-munge_other_line(const char *buf, cachemgr_request * req)
+static void
+munge_other_line(MemBuf *out, const char *buf, cachemgr_request * req)
 {
     static const char *ttags[] =
     {"td", "th"};
-    static char html[4096];
     static int table_line_num = 0;
     static int next_is_header = 0;
     int is_header = 0;
     const char *ttag;
     char *buf_copy;
     char *x, *p;
-    int l = 0;
     /* does it look like a table? */
     if (!strchr(buf, '\t') || *buf == '\t') {
 	/* nope, just text */
-	snprintf(html, sizeof(html), "%s%s",
-	    table_line_num ? "</table>\n<pre>" : "", html_quote(buf));
+        if (table_line_num)
+            memBufAppend(out, "</table>\n<pre>", 14);
+        memBufPrintf(out, "%s", html_quote(buf));
 	table_line_num = 0;
-	return html;
+	return;
     }
     /* start html table */
     if (!table_line_num) {
-	l += snprintf(html + l, sizeof(html) - l, "</pre><table cellpadding=\"2\" cellspacing=\"1\">\n");
+        memBufAppend(out, "</pre><table cellpadding=\"2\" cellspacing=\"1\">\n", 46);
 	next_is_header = 0;
     }
     /* remove '\n' */
     is_header = (!table_line_num || next_is_header) && !strchr(buf, ':') && !is_number(buf);
     ttag = ttags[is_header];
     /* record starts */
-    l += snprintf(html + l, sizeof(html) - l, "<tr>");
+    memBufAppend(out, "<tr>", 4);
     /* substitute '\t' */
     buf_copy = x = xstrdup(buf);
     if ((p = strchr(x, '\n')))
@@ -484,17 +483,16 @@ munge_other_line(const char *buf, cachem
 	    column_span++;
 	    x++;
 	}
-	l += snprintf(html + l, sizeof(html) - l, "<%s colspan=\"%d\" align=\"%s\">%s</%s>",
+	memBufPrintf(out, "<%s colspan=\"%d\" align=\"%s\">%s</%s>",
 	    ttag, column_span,
 	    is_header ? "center" : is_number(cell) ? "right" : "left",
 	    html_quote(cell), ttag);
     }
     xfree(buf_copy);
     /* record ends */
-    l += snprintf(html + l, sizeof(html) - l, "</tr>\n");
+    memBufAppend(out, "</tr>\n", 6);
     next_is_header = is_header && strstr(buf, "\t\t");
     table_line_num++;
-    return html;
 }
 
 static const char *
@@ -619,14 +617,21 @@ read_reply(int s, cachemgr_request * req
 		printf("<PRE>\n");
 	    }
 	    istate = isBody;
-	    /* yes, fall through, we do not want to loose the first line */
+	    /* yes, fall through, we do not want to lose the first line */
 	case isBody:
+        {
+            MemBuf out;
+            memBufDefInit(&out);
 	    /* interpret [and reformat] cache response */
 	    if (parse_menu)
-		fputs(munge_menu_line(buf, req), stdout);
+		munge_menu_line(&out, buf, req);
 	    else
-		fputs(munge_other_line(buf, req), stdout);
-	    break;
+		munge_other_line(&out, buf, req);
+
+            fputs(out.buf, stdout);
+            memBufClean(&out);
+            break;
+        }
 	case isForward:
 	    /* forward: no modifications allowed */
 	    /*
Index: squid-2.7.STABLE5/include/MemBuf.h
===================================================================
--- /dev/null
+++ squid-2.7.STABLE5/include/MemBuf.h
@@ -0,0 +1,54 @@
+#ifndef SQUID_MEMBUF_H
+#define SQUID_MEMBUF_H
+
+#ifndef SQUID_TYPEDEFS_H
+// not very portable, but we need this to make patch work without messing
+// around too much
+typedef int mb_size_t;
+typedef void FREE(void*);
+#endif
+
+/* auto-growing memory-resident buffer with printf interface */
+/* note: when updating this struct, update MemBufNULL #define */
+typedef struct _MemBuf {
+    /* public, read-only */
+    char *buf;
+    mb_size_t size;             /* used space, does not count 0-terminator */
+
+    /* private, stay away; use interface function instead */
+    mb_size_t max_capacity;     /* when grows: assert(new_capacity <= max_capacity) */
+    mb_size_t capacity;         /* allocated space */
+    unsigned stolen:1;          /* the buffer has been stolen for use by someone else */
+} MemBuf;
+
+
+/* MemBuf */
+/* init with specific sizes */
+extern void memBufInit(MemBuf * mb, mb_size_t szInit, mb_size_t szMax);
+/* init with defaults */
+extern void memBufDefInit(MemBuf * mb);
+/* cleans mb; last function to call if you do not give .buf away */
+extern void memBufClean(MemBuf * mb);
+/* resets mb preserving (or initializing if needed) memory buffer */
+extern void memBufReset(MemBuf * mb);
+/* unfirtunate hack to test if the buffer has been Init()ialized */
+extern int memBufIsNull(MemBuf * mb);
+/* calls memcpy, appends exactly size bytes, extends buffer if needed */
+extern void memBufAppend(MemBuf * mb, const void *buf, int size);
+/* calls snprintf, extends buffer if needed */
+#if STDC_HEADERS
+extern void
+memBufPrintf(MemBuf * mb, const char *fmt,...) PRINTF_FORMAT_ARG2;
+#else
+extern void memBufPrintf();
+#endif
+/* vprintf for other printf()'s to use */
+extern void memBufVPrintf(MemBuf * mb, const char *fmt, va_list ap);
+/* returns free() function to be used, _freezes_ the object! */
+extern FREE *memBufFreeFunc(MemBuf * mb);
+/* puts report on MemBuf _module_ usage into mb */
+extern void memBufReport(MemBuf * mb);
+
+
+#endif
+
Index: squid-2.7.STABLE5/tools/Makefile.am
===================================================================
--- squid-2.7.STABLE5.orig/tools/Makefile.am
+++ squid-2.7.STABLE5/tools/Makefile.am
@@ -31,7 +31,7 @@ libexec_PROGRAMS = \
 
 squidclient_SOURCES = squidclient.c
 cossdump_SOURCES = cossdump.c
-cachemgr__CGIEXT__SOURCES = cachemgr.c
+cachemgr__CGIEXT__SOURCES = cachemgr.c ../src/MemBuf.c tools_debug.c tools_mem.c
 cachemgr__CGIEXT__CFLAGS = -DDEFAULT_CACHEMGR_CONFIG=\"$(DEFAULT_CACHEMGR_CONFIG)\" $(AM_CFLAGS)
 
 LDADD = -L../lib -lmiscutil $(XTRA_LIBS)
Index: squid-2.7.STABLE5/tools/tools_mem.c
===================================================================
--- /dev/null
+++ squid-2.7.STABLE5/tools/tools_mem.c
@@ -0,0 +1,26 @@
+#include "../src/squid.h"
+
+/* net_size is the new size, *gross size is the old gross size, to be changed to
+ * the new gross size as a side-effect.
+ */
+void *
+memReallocBuf(void *oldbuf, size_t net_size, size_t * gross_size)
+{
+    void *rv=xrealloc(oldbuf,net_size);
+//    if (net_size > *gross_size)
+//        memset(rv+net_size,0,net_size-*gross_size);
+    *gross_size=net_size;
+    return rv;
+}
+
+void
+memFreeBuf(size_t size, void *buf)
+{
+    xfree(buf);
+}
+
+FREE* memFreeBufFunc(size_t size)
+{
+    return xfree;
+}
+
Index: squid-2.7.STABLE5/tools/tools_debug.c
===================================================================
--- /dev/null
+++ squid-2.7.STABLE5/tools/tools_debug.c
@@ -0,0 +1,10 @@
+#include "../src/squid.h"
+
+void
+xassert(const char *msg, const char *file, int line)
+{
+    fprintf(stderr, "assertion failed: %s:%d: \"%s\"\n", file, line, msg);
+   abort();
+}
+
+
