# HG changeset patch # User Timo Sirainen # Date 1365621093 -10800 # Node ID b63f87ed9311bf27c7daa6655e64fe4141434194 # Parent 8e9f1c744516add50e40fed78fda0773c62d1a45 imapc: If APPEND to selected mailbox doesn't send EXISTS, try if NOOP sends it. This makes Dovecot behave better with Courier. diff -r 8e9f1c744516 -r b63f87ed9311 src/lib-storage/index/imapc/imapc-mailbox.c --- a/src/lib-storage/index/imapc/imapc-mailbox.c Wed Apr 10 14:18:38 2013 +0300 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Wed Apr 10 22:11:33 2013 +0300 @@ -145,6 +145,7 @@ mbox->sync_fetch_first_uid = hdr->next_uid; } mbox->exists_count = exists_count; + mbox->exists_received = TRUE; imapc_mailbox_idle_notify(mbox); } diff -r 8e9f1c744516 -r b63f87ed9311 src/lib-storage/index/imapc/imapc-save.c --- a/src/lib-storage/index/imapc/imapc-save.c Wed Apr 10 14:18:38 2013 +0300 +++ b/src/lib-storage/index/imapc/imapc-save.c Wed Apr 10 22:11:33 2013 +0300 @@ -183,6 +183,17 @@ } static void +imapc_save_noop_callback(const struct imapc_command_reply *reply ATTR_UNUSED, + void *context) +{ + struct imapc_save_cmd_context *ctx = context; + + /* we don't really care about the reply */ + ctx->ret = 0; + imapc_client_stop(ctx->ctx->mbox->storage->client); +} + +static void imapc_append_keywords(string_t *str, struct mail_keywords *kw) { const ARRAY_TYPE(keywords) *kw_arr; @@ -221,6 +232,8 @@ imap_to_datetime(_ctx->received_date)); } + ctx->mbox->exists_received = FALSE; + input = i_stream_create_fd(ctx->fd, IO_BLOCK_SIZE, FALSE); sctx.ctx = ctx; sctx.ret = -2; @@ -231,6 +244,20 @@ i_stream_unref(&input); while (sctx.ret == -2) imapc_storage_run(ctx->mbox->storage); + + if (sctx.ret == 0 && ctx->mbox->selected && + !ctx->mbox->exists_received) { + /* e.g. Courier doesn't send EXISTS reply before the tagged + APPEND reply. That isn't exactly required by the IMAP RFC, + but it makes the behavior better. See if NOOP finds + the mail. */ + sctx.ret = -2; + cmd = imapc_client_cmd(ctx->mbox->storage->client, + imapc_save_noop_callback, &sctx); + imapc_command_send(cmd, "NOOP"); + while (sctx.ret == -2) + imapc_storage_run(ctx->mbox->storage); + } return sctx.ret; } diff -r 8e9f1c744516 -r b63f87ed9311 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Wed Apr 10 14:18:38 2013 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Wed Apr 10 22:11:33 2013 +0300 @@ -411,6 +411,7 @@ struct imapc_open_context *ctx = context; ctx->mbox->selecting = FALSE; + ctx->mbox->selected = TRUE; if (reply->state == IMAPC_COMMAND_STATE_OK) ctx->ret = 0; else if (reply->state == IMAPC_COMMAND_STATE_NO) { diff -r 8e9f1c744516 -r b63f87ed9311 src/lib-storage/index/imapc/imapc-storage.h --- a/src/lib-storage/index/imapc/imapc-storage.h Wed Apr 10 14:18:38 2013 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.h Wed Apr 10 22:11:33 2013 +0300 @@ -94,6 +94,8 @@ unsigned int selecting:1; unsigned int syncing:1; unsigned int initial_sync_done:1; + unsigned int selected:1; + unsigned int exists_received:1; }; struct imapc_simple_context {