From 644d6988edd67c7cbd54acfa644c62168e29c8a1 Mon Sep 17 00:00:00 2001 From: Lefteris Chatzimparmpas Date: Sun, 19 Feb 2012 14:58:36 +0100 Subject: [PATCH] Correct the TRYCREATE functionality It's better not to continuesly try to create a mailbox, when the server continues to report TRYCREATE. When appending messages it failed to create a mailbox when the mailbox didn't exist and the server responded with TRYCREATE. --- src/imapfilter.h | 2 +- src/request.c | 70 +++++++++++++++++++++--------------------------- src/response.c | 17 +++++++++--- 3 files changed, 44 insertions(+), 45 deletions(-) diff --git a/src/imapfilter.h b/src/imapfilter.h index 526c11c..9b964e7 100644 --- a/src/imapfilter.h +++ b/src/imapfilter.h @@ -181,7 +181,7 @@ int request_idle(session *ssn); /* response.c */ int response_generic(session *ssn, int tag); -int response_continuation(session *ssn); +int response_continuation(session *ssn, int tag); int response_greeting(session *ssn); int response_capability(session *ssn, int tag); int response_authenticate(session *ssn, int tag, unsigned char **cont); diff --git a/src/request.c b/src/request.c index c3a164d..231a1fd 100644 --- a/src/request.c +++ b/src/request.c @@ -603,25 +603,18 @@ request_copy(session *ssn, const char *mesg, const char *mbox) m = apply_namespace(mbox, ssn->ns.prefix, ssn->ns.delim); - do { + TRY(t = send_request(ssn, "UID COPY %s \"%s\"", mesg, m)); + TRY(r = response_generic(ssn, t)); + if (r == STATUS_TRYCREATE) { + TRY(t = send_request(ssn, "CREATE \"%s\"", m)); + TRY(response_generic(ssn, t)); + if (get_option_boolean("subscribe")) { + TRY(t = send_request(ssn, "SUBSCRIBE \"%s\"", m)); + TRY(response_generic(ssn, t)); + } TRY(t = send_request(ssn, "UID COPY %s \"%s\"", mesg, m)); TRY(r = response_generic(ssn, t)); - switch (r) { - case STATUS_TRYCREATE: - TRY(t = send_request(ssn, "CREATE \"%s\"", m)); - TRY(response_generic(ssn, t)); - - if (get_option_boolean("subscribe")) { - TRY(t = send_request(ssn, "SUBSCRIBE \"%s\"", - m)); - TRY(response_generic(ssn, t)); - } - break; - case -1: - return -1; - break; - } - } while (r == STATUS_TRYCREATE); + } return r; } @@ -639,33 +632,30 @@ request_append(session *ssn, const char *mbox, const char *mesg, size_t m = apply_namespace(mbox, ssn->ns.prefix, ssn->ns.delim); - do { + TRY(t = send_request(ssn, "APPEND \"%s\"%s%s%s%s%s%s {%d}", m, + (flags ? " (" : ""), (flags ? flags : ""), + (flags ? ")" : ""), (date ? " \"" : ""), + (date ? date : ""), (date ? "\"" : ""), mesglen)); + TRY(r = response_continuation(ssn, t)); + + if (r == STATUS_TRYCREATE) { + TRY(t = send_request(ssn, "CREATE \"%s\"", m)); + TRY(response_generic(ssn, t)); + if (get_option_boolean("subscribe")) { + TRY(t = send_request(ssn, "SUBSCRIBE \"%s\"", m)); + TRY(response_generic(ssn, t)); + } TRY(t = send_request(ssn, "APPEND \"%s\"%s%s%s%s%s%s {%d}", m, (flags ? " (" : ""), (flags ? flags : ""), (flags ? ")" : ""), (date ? " \"" : ""), (date ? date : ""), (date ? "\"" : ""), mesglen)); - TRY(r = response_continuation(ssn)); + TRY(r = response_continuation(ssn, t)); + } - switch (r) { - case STATUS_CONTINUE: - TRY(send_continuation(ssn, mesg, mesglen)); - TRY(r = response_generic(ssn, t)); - break; - case STATUS_TRYCREATE: - TRY(t = send_request(ssn, "CREATE \"%s\"", m)); - TRY(response_generic(ssn, t)); - - if (get_option_boolean("subscribe")) { - TRY(t = send_request(ssn, "SUBSCRIBE \"%s\"", - m)); - TRY(response_generic(ssn, t)); - } - break; - case -1: - return -1; - break; - } - } while (r == STATUS_TRYCREATE); + if (r == STATUS_CONTINUE) { + TRY(send_continuation(ssn, mesg, mesglen)); + TRY(r = response_generic(ssn, t)); + } return r; } @@ -774,7 +764,7 @@ request_idle(session *ssn) ri = 0; TRY(t = send_request(ssn, "IDLE")); - TRY(r = response_continuation(ssn)); + TRY(r = response_continuation(ssn, t)); if (r == STATUS_CONTINUE) { TRY(ri = response_idle(ssn, t)); TRY(send_continuation(ssn, "DONE", strlen("DONE"))); diff --git a/src/response.c b/src/response.c index 360be03..1aec3f9 100644 --- a/src/response.c +++ b/src/response.c @@ -240,8 +240,9 @@ response_generic(session *ssn, int tag) * Get server data and make sure there is a continuation response inside them. */ int -response_continuation(session *ssn) +response_continuation(session *ssn, int tag) { + int r; ssize_t n; buffer_reset(&ibuf); @@ -255,9 +256,17 @@ response_continuation(session *ssn) if (check_bye(ibuf.data)) return STATUS_BYE; - } while (!check_continuation(ibuf.data)); + } while ((r = check_tag(ibuf.data, ssn, tag)) == STATUS_NONE && + !check_continuation(ibuf.data)); - return STATUS_CONTINUE; + if (r == STATUS_NO && + (check_trycreate(ibuf.data) || get_option_boolean("create"))) + return STATUS_TRYCREATE; + + if (r == STATUS_NONE) + return STATUS_CONTINUE; + + return r; } @@ -348,7 +357,7 @@ response_authenticate(session *ssn, int tag, unsigned char **cont) re = &responses[RESPONSE_AUTHENTICATE]; - if ((r = response_continuation(ssn)) == STATUS_CONTINUE && + if ((r = response_continuation(ssn, tag)) == STATUS_CONTINUE && !regexec(re->preg, ibuf.data, re->nmatch, re->pmatch, 0)) *cont = (unsigned char *)xstrndup(ibuf.data + re->pmatch[1].rm_so, re->pmatch[1].rm_eo -