aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Hruska <jirka@fud.cz>2013-03-01 20:34:51 +0100
committerSteve Holme <steve_holme@hotmail.com>2013-03-02 19:34:25 +0000
commitf8c8c76d39ac2fa825481ba42ab2247cd122f963 (patch)
treeff0b3ad78f16ff8ea8b287e6a3e3cd658f6595f4
parent90b7d0ea599a030b5e24e1edcdb3c1d8e079f399 (diff)
imap: Implemented APPEND final processing
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.
-rw-r--r--lib/imap.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/lib/imap.c b/lib/imap.c
index 16cb8efb2..c1eef8514 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -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 */