]> granicus.if.org Git - curl/commitdiff
imap: Implemented APPEND final processing
authorJiri Hruska <jirka@fud.cz>
Fri, 1 Mar 2013 19:34:51 +0000 (20:34 +0100)
committerSteve Holme <steve_holme@hotmail.com>
Sat, 2 Mar 2013 19:34:25 +0000 (19:34 +0000)
The APPEND operation needs to be performed in several steps:
  1) We send "<tag> APPEND <mailbox> <flags> {<size>}\r\n"
  2) Server responds with continuation respose "+ ...\r\n"
  3) We start the transfer and send <size> bytes of data
  4) Only now we end the request command line by sending "\r\n"
  5) Server responds with "<tag> OK ...\r\n"

This commit performs steps 4 and 5, in the DONE phase, as more
processing is required after the transfer.

lib/imap.c

index 16cb8efb28106ff13d2dfbb27b2130b0e8713f01..c1eef85145daae6b5e5d26c9391aa63830fb019e 100644 (file)
@@ -1410,6 +1410,26 @@ static CURLcode imap_state_append_resp(struct connectdata *conn,
   }
 }
 
+/* For final APPEND responses performed after the upload */
+static CURLcode imap_state_append_final_resp(struct connectdata *conn,
+                                             int imapcode,
+                                             imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+
+  (void)instate; /* No use for this yet */
+
+  /* Final response, stop and return the final status */
+  if(imapcode == 'O')
+    result = CURLE_OK;
+  else
+    result = CURLE_UPLOAD_FAILED;
+
+  state(conn, IMAP_STOP);
+
+  return result;
+}
+
 static CURLcode imap_statemach_act(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
@@ -1516,6 +1536,10 @@ static CURLcode imap_statemach_act(struct connectdata *conn)
       result = imap_state_append_resp(conn, imapcode, imapc->state);
       break;
 
+    case IMAP_APPEND_FINAL:
+      result = imap_state_append_final_resp(conn, imapcode, imapc->state);
+      break;
+
     case IMAP_LOGOUT:
       /* fallthrough, just stop! */
     default:
@@ -1660,7 +1684,15 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
     result = status;         /* use the already set error code */
   }
   else if(!data->set.connect_only) {
-    state(conn, IMAP_FETCH_FINAL);
+    /* Handle responses after FETCH or APPEND transfer has finished */
+    if(!data->set.upload)
+      state(conn, IMAP_FETCH_FINAL);
+    else {
+      /* End the APPEND command first by sending an empty line */
+      result = Curl_pp_sendf(&conn->proto.imapc.pp, "");
+      if(!result)
+        state(conn, IMAP_APPEND_FINAL);
+    }
 
     /* Run the state-machine
 
@@ -1669,7 +1701,8 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
        non-blocking DONE operations, not in the multi state machine and with
        Curl_done() invokes on several places in the code!
     */
-    result = imap_block_statemach(conn);
+    if(!result)
+      result = imap_block_statemach(conn);
   }
 
   /* Cleanup our per-request based variables */