diff options
author | Jiri Hruska <jirka@fud.cz> | 2013-03-01 20:34:51 +0100 |
---|---|---|
committer | Steve Holme <steve_holme@hotmail.com> | 2013-03-02 19:34:25 +0000 |
commit | f8c8c76d39ac2fa825481ba42ab2247cd122f963 (patch) | |
tree | ff0b3ad78f16ff8ea8b287e6a3e3cd658f6595f4 | |
parent | 90b7d0ea599a030b5e24e1edcdb3c1d8e079f399 (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.c | 37 |
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 */ |