diff -b -u memcachedb-0.1.0.orig/memcachedb.c memcachedb-0.1.0/memcachedb.c
--- memcachedb-0.1.0.orig/memcachedb.c	2007-12-18 00:20:11.000000000 +0000
+++ memcachedb-0.1.0/memcachedb.c	2007-12-17 23:56:55.000000000 +0000
@@ -138,20 +138,22 @@
             perror("malloc()");
             return 0;
         }
-        c->rbuf = c->wbuf = 0;
+        c->rbuf = c->wbuf = c->pbuf = 0;
 
         c->rbuf = (char *) malloc(DATA_BUFFER_SIZE);
         c->wbuf = (char *) malloc(DATA_BUFFER_SIZE);
+        c->pbuf = (char *) malloc(DATA_BUFFER_SIZE);
 
-        if (c->rbuf == 0 || c->wbuf == 0) {
+        if (c->rbuf == 0 || c->wbuf == 0 || c->pbuf == 0) {
 
             if (c->rbuf != 0) free(c->rbuf);
             if (c->wbuf != 0) free(c->wbuf);
+            if (c->pbuf != 0) free(c->pbuf);
             free(c);
             perror("malloc()");
             return 0;
         }
-        c->rsize = c->wsize = DATA_BUFFER_SIZE;
+        c->rsize = c->wsize = c->psize = DATA_BUFFER_SIZE;
 
         stats.conn_structs++;
     }
@@ -273,7 +275,7 @@
     stats.set_cmds++;
 
     while (1) {
-        if (strncmp(ITEM_data(it) + it->nbytes - 2, "\r\n", 2) != 0) {
+        if (strncmp(c->pbuf + it->nbytes - 2, "\r\n", 2) != 0) {
             out_string(c, "CLIENT_ERROR bad data chunk");
             break;
         }
@@ -299,8 +301,8 @@
         cleanup_dbt();
         dbkey.data = ITEM_key(it);
         dbkey.size = strlen(ITEM_key(it));
-        dbdata.data = ITEM_data(it);
-        dbdata.size = it->nbytes;
+        dbdata.data = c->pbuf;		/* ITEM_data(it) is too small */ 
+        dbdata.size = it->nbytes;	/* SMELL, do we really want to store the \r\n as well? */
 
         if ((ret = dbp->put(dbp, NULL, &dbkey, &dbdata, 0)) == 0) {
             /* some future code? */
@@ -410,21 +412,24 @@
                &len);
  
         if (res != 4 || strlen(key) == 0) {
-            out_string(c, "CLIENT_ERROR bad command line format");
+            out_string(c, "CLIENT_ERROR bad command line format (or key too long)");
             return;
         }
  
         it->nkey = strlen(key) + 1;
         it->nbytes = len + 2;
-        if (END_LEN < it->nbytes + it->nkey) {
+        
+        if (c->psize < it->nbytes) {
+        	/* TODO perhaps malloc a bigger buffer for c->pbuf ? */
             out_string(c, "CLIENT_ERROR data too long");
             return;
         }
         c->item_comm = comm;
  
-        c->rcurr = ITEM_data(it);
-        c->rlbytes = it->nbytes;
-        c->state = conn_nread;
+ 		/* don't need to memset(c->pbuf, 0 ,c->psize);	 clear buffer. Is this necessary? */ 
+        c->rcurr = c->pbuf;				/* tell the state machine to read the payload into pbuf */
+        c->rlbytes = it->nbytes;		/* how many bytes to read */
+        c->state = conn_nread;			/* change state machine state to read bytes from connection */
         return;
     }
 
@@ -484,6 +489,7 @@
         }
  
         if (END_LEN <= putit->nkey + 12) {
+            /* SMELL could use c->pbuf instead (for *really* long numbers :-) */
             out_string(c, "CLIENT_ERROR data too long");
             return;
         }
@@ -517,8 +523,8 @@
             dbkey.data = key;
             dbkey.size = strlen(key);
             it->nkey = dbkey.size + 1;
-            dbdata.data = ITEM_data(it);
-            dbdata.ulen = END_LEN - it->nkey;
+            dbdata.data = c->pbuf;	/* ITEM_data(it) is too small */ 
+            dbdata.ulen = c->psize;
                          
             if ((ret = dbp->get(dbp, NULL, &dbkey, &dbdata, 0)) == 0) {
                 it->nbytes = dbdata.size;
@@ -936,10 +942,10 @@
         case conn_mwrite:
             /* 
              * we're writing ibytes bytes from iptr. iptr alternates between
-             * ibuf, where we build a string "VALUE...", and ITEM_data(it) for the 
+             * ibuf, where we build a string "VALUE...", and c->pbuf for the 
              * current item. When we finish a chunk, we choose the next one using 
              * ipart, which has the following semantics: 0 - start the loop, 1 - 
-             * we finished ibuf, go to current ITEM_data(it); 2 - we finished ITEM_data(it),
+             * we finished ibuf, go to current c->pbuf; 2 - we finished c->pbuf,
              * move to the next item and build its ibuf; 3 - we finished all items, 
              * write "END".
              */
@@ -974,7 +980,7 @@
             switch (c->ipart) {
             case 1:
                 it = &(c->item);
-                c->iptr = ITEM_data(it);
+                	c->iptr = c->pbuf; 
                 c->ibytes = it->nbytes;
                 c->ipart = 2;
                 break;
diff -b -u memcachedb-0.1.0.orig/memcachedb.h memcachedb-0.1.0/memcachedb.h
--- memcachedb-0.1.0.orig/memcachedb.h	2007-12-18 00:20:11.000000000 +0000
+++ memcachedb-0.1.0/memcachedb.h	2007-12-17 23:56:57.000000000 +0000
@@ -60,18 +60,19 @@
 extern struct stats stats;
 extern struct settings settings;
 
-#define END_LEN 32
-#define END_LEN_STR "31"
+#define END_LEN 64
+#define END_LEN_STR "63"
 
 typedef struct _stritem {
-    int nbytes;            /* size of data */
-    int nkey;
-    char end[END_LEN];
+    int nbytes;				/* size of payload data */
+    int nkey;				/* size of key */
+    char end[END_LEN];		/* buffer for key */
 } item;
 
 #define ITEM_key(item) ((char*)&((item)->end[0]))
 
 /* warning: don't use these macros with a function, as it evals its arg twice */
+/* only used for short payloads, like incr & decr, that can fit into the key buffer */
 #define ITEM_data(item) ((char*) &((item)->end[0]) + (item)->nkey)
 #define ITEM_ntotal(item) sizeof(struct _stritem)
 
@@ -96,11 +97,11 @@
     short ev_flags;
     short which;        /* which events were just triggered */
 
-    char *rbuf;
+    char *rbuf;			/* DATA_BUFFER_SIZE */
     int rsize;
     int rbytes;
 
-    char *wbuf;
+    char *wbuf;			/* DATA_BUFFER_SIZE */
     char *wcurr;
     int wsize;
     int wbytes;
@@ -119,8 +120,10 @@
      * data. The data is read into ITEM_data(item) to avoid extra copying.
      */
 
-    item item;
+    item item;				/* current command: holds key, key len, payload len */
     int item_comm;        /* which one is it: set/add/replace */
+    char *pbuf;				/* payload buffer, DATA_BUFFER_SIZE */
+	int psize;
 
     /* data for the swallow state */
     int sbytes;            /* how many bytes to swallow */

