]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: If APPEND to selected mailbox doesn't send EXISTS, try if NOOP sends it.
authorTimo Sirainen <tss@iki.fi>
Wed, 10 Apr 2013 19:11:33 +0000 (22:11 +0300)
committerTimo Sirainen <tss@iki.fi>
Wed, 10 Apr 2013 19:11:33 +0000 (22:11 +0300)
This makes Dovecot behave better with Courier.

src/lib-storage/index/imapc/imapc-mailbox.c
src/lib-storage/index/imapc/imapc-save.c
src/lib-storage/index/imapc/imapc-storage.c
src/lib-storage/index/imapc/imapc-storage.h

index e7cee7aa800bf0377dce4843569e8caa826aced4..17ad6b27b5a10afd641037f760b0913a9503b41e 100644 (file)
@@ -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);
 }
 
index 7f1bdc9efa0872989c79522f923def90609de0c6..7e80c7c1a704b2cd0c741a2640da8985b4ec1478 100644 (file)
@@ -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;
 }
 
index e563d123a7d28b9ea3abb792c760b8970d9770c3..4a3e03410a6a13249c2cd1812529e8b020e1388d 100644 (file)
@@ -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) {
index 418b3fc30ef89a8ab0220de404ca36fb69f62290..941d7dc177f44c5f106b5bca67e0e6f1558e17ff 100644 (file)
@@ -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 {