From: Timo Sirainen Date: Wed, 10 Apr 2013 19:11:33 +0000 (+0300) Subject: imapc: If APPEND to selected mailbox doesn't send EXISTS, try if NOOP sends it. X-Git-Tag: 2.2.rc7~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=03f2a189a0985d87cfe443a1a5cc8ab6da052c30;p=thirdparty%2Fdovecot%2Fcore.git imapc: If APPEND to selected mailbox doesn't send EXISTS, try if NOOP sends it. This makes Dovecot behave better with Courier. --- diff --git a/src/lib-storage/index/imapc/imapc-mailbox.c b/src/lib-storage/index/imapc/imapc-mailbox.c index e7cee7aa80..17ad6b27b5 100644 --- a/src/lib-storage/index/imapc/imapc-mailbox.c +++ b/src/lib-storage/index/imapc/imapc-mailbox.c @@ -145,6 +145,7 @@ imapc_untagged_exists(const struct imapc_untagged_reply *reply, mbox->sync_fetch_first_uid = hdr->next_uid; } mbox->exists_count = exists_count; + mbox->exists_received = TRUE; imapc_mailbox_idle_notify(mbox); } diff --git a/src/lib-storage/index/imapc/imapc-save.c b/src/lib-storage/index/imapc/imapc-save.c index 7f1bdc9efa..7e80c7c1a7 100644 --- a/src/lib-storage/index/imapc/imapc-save.c +++ b/src/lib-storage/index/imapc/imapc-save.c @@ -183,6 +183,17 @@ static void imapc_save_callback(const struct imapc_command_reply *reply, imapc_client_stop(ctx->ctx->mbox->storage->client); } +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) { @@ -223,6 +234,8 @@ static int imapc_save_append(struct imapc_save_context *ctx) imap_to_datetime(mdata->received_date)); } + ctx->mbox->exists_received = FALSE; + input = i_stream_create_fd(ctx->fd, IO_BLOCK_SIZE, FALSE); sctx.ctx = ctx; sctx.ret = -2; @@ -233,6 +246,20 @@ static int imapc_save_append(struct imapc_save_context *ctx) 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 --git a/src/lib-storage/index/imapc/imapc-storage.c b/src/lib-storage/index/imapc/imapc-storage.c index e563d123a7..4a3e03410a 100644 --- a/src/lib-storage/index/imapc/imapc-storage.c +++ b/src/lib-storage/index/imapc/imapc-storage.c @@ -424,6 +424,7 @@ imapc_mailbox_open_callback(const struct imapc_command_reply *reply, 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 --git a/src/lib-storage/index/imapc/imapc-storage.h b/src/lib-storage/index/imapc/imapc-storage.h index 418b3fc30e..941d7dc177 100644 --- a/src/lib-storage/index/imapc/imapc-storage.h +++ b/src/lib-storage/index/imapc/imapc-storage.h @@ -103,6 +103,8 @@ struct imapc_mailbox { 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 {