From f8c8c76d39ac2fa825481ba42ab2247cd122f963 Mon Sep 17 00:00:00 2001 From: Jiri Hruska Date: Fri, 1 Mar 2013 20:34:51 +0100 Subject: [PATCH] imap: Implemented APPEND final processing The APPEND operation needs to be performed in several steps: 1) We send " APPEND {}\r\n" 2) Server responds with continuation respose "+ ...\r\n" 3) We start the transfer and send bytes of data 4) Only now we end the request command line by sending "\r\n" 5) Server responds with " 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 | 37 +++++++++++++++++++++++++++++++++++-- 1 file 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 */