Index: /trunk/server/memcached.c
===================================================================
--- /trunk/server/memcached.c (revision 619)
+++ /trunk/server/memcached.c (revision 620)
@@ -1160,8 +1160,7 @@
     int flags;
     time_t exptime;
-    int vlen;
+    int vlen, old_vlen;
     uint32_t req_memory_ptr, in_memory_ptr;
-
-    item *it;
+    item *it, *old_it;
 
     assert(c != NULL);
@@ -1207,8 +1206,20 @@
     }
 
+    /* Check if append -- if yes, search for previous entry, and allocate memory for both */
+    if( comm == NREAD_APPEND ){
+       old_it = assoc_find(key,nkey);
+
+       if( old_it && (old_it->nbytes)>2 ){ // previous must be more than \r\n
+          old_vlen = old_it->nbytes - 2;
+          vlen += old_vlen;                // append the length of old data
+       } else {
+          comm = NREAD_REPLACE;            // no old entry: treat as replace
+       }
+    }
+
     it = item_alloc(key, nkey, flags, realtime(exptime), vlen+2);
 
     /* HANDLE_CAS VALIDATION */
-    if(handle_cas == true)
+    if (handle_cas == true)
     {
       item *itmp=item_get(key, it->nkey);
@@ -1252,8 +1263,20 @@
     }
 
-    c->item_comm = comm;
     c->item = it;
     c->ritem = ITEM_data(it);
     c->rlbytes = it->nbytes;
+
+
+    /* If append, prepend old data before new - adjust item, rlbytes variables too
+     * Now that data has been merged, treat simply as a replace command
+     */
+    if (comm == NREAD_APPEND ){
+       memcpy( c->ritem, ITEM_data(old_it), old_vlen );
+       c->ritem += old_vlen;
+       c->rlbytes -= old_vlen;
+       comm = NREAD_REPLACE;
+    }
+
+    c->item_comm = comm;
     conn_set_state(c, conn_nread);
 }
@@ -1488,5 +1511,6 @@
                ((strcmp(tokens[COMMAND_TOKEN].value, "add") == 0 && (comm = NREAD_ADD)) ||
                 (strcmp(tokens[COMMAND_TOKEN].value, "set") == 0 && (comm = NREAD_SET)) ||
-                (strcmp(tokens[COMMAND_TOKEN].value, "replace") == 0 && (comm = NREAD_REPLACE)))) {
+                (strcmp(tokens[COMMAND_TOKEN].value, "replace") == 0 && (comm = NREAD_REPLACE)) ||
+                (strcmp(tokens[COMMAND_TOKEN].value, "append") == 0 && (comm = NREAD_APPEND)) )) {
 
         process_update_command(c, tokens, ntokens, comm, false);
Index: /trunk/server/ChangeLog
===================================================================
--- /trunk/server/ChangeLog (revision 619)
+++ /trunk/server/ChangeLog (revision 620)
@@ -15,4 +15,7 @@
 	* Switch to unsigned 64-bit increment/decrement counters
 	  from Evan Miller and Dusgtin Sallings.
+
+	* Add append command support written by Filipe Laborde.
+	  Tests/protocol doc updates by myself.
 
 2007-08-21 Paul Lindner <lindner@inuus.com>
Index: /trunk/server/memcached.h
===================================================================
--- /trunk/server/memcached.h (revision 619)
+++ /trunk/server/memcached.h (revision 620)
@@ -138,4 +138,5 @@
 #define NREAD_SET 2
 #define NREAD_REPLACE 3
+#define NREAD_APPEND 4
 
 typedef struct {
Index: /trunk/server/doc/protocol.txt
===================================================================
--- /trunk/server/doc/protocol.txt (revision 619)
+++ /trunk/server/doc/protocol.txt (revision 620)
@@ -54,8 +54,9 @@
 There are three types of commands. 
 
-Storage commands (there are four: "set", "add", "replace", and "cas")
-ask the server to store some data identified by a key. The client
-sends a command line, and then a data block; after that the client
-expects one line of response, which will indicate success or faulure.
+Storage commands (there are five: "set", "add", "replace", "append"
+and "cas") ask the server to store some data identified by a key. The
+client sends a command line, and then a data block; after that the
+client expects one line of response, which will indicate success or
+faulure.
 
 Retrieval commands (there are two: "get" and "gets") ask the server to
@@ -128,5 +129,5 @@
 <command name> <key> <flags> <exptime> <bytes> [<unqiue>]\r\n
 
-- <command name> is "set", "add", "replace", or "cas"
+- <command name> is "set", "add", "replace", "append", or "cas"
 
   "set" means "store this data".  
@@ -137,4 +138,6 @@
   "replace" means "store this data, but only if the server *does*
   already hold data for this key".
+
+  "append" means "add this data to an existing key".
 
   "cas" is a check and set operation which means "store this data but
@@ -183,4 +186,5 @@
 - "EXISTS\r\n" to indicate that the item you are trying to store with
 a "cas" command has been modified since you last fetched it.
+
 
 Retrieval command:
