]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: Fixed detecting when messages are missing from index.
authorTimo Sirainen <tss@iki.fi>
Sun, 9 Oct 2011 14:15:31 +0000 (17:15 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 9 Oct 2011 14:15:31 +0000 (17:15 +0300)
src/lib-storage/index/imapc/imapc-mail.c
src/lib-storage/index/imapc/imapc-mailbox.c
src/lib-storage/index/imapc/imapc-storage.c
src/lib-storage/index/imapc/imapc-storage.h
src/lib-storage/index/imapc/imapc-sync.c

index bb6ba7cf39e0aacfac89b7b0f078dbdf90c4bed2..6e9f9e306e6194759be2247105bc66cef5c25310 100644 (file)
@@ -30,8 +30,6 @@ static bool imapc_mail_is_expunged(struct mail *_mail)
 {
        struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box;
        struct imapc_msgmap *msgmap;
-       struct imapc_command *cmd;
-       struct imapc_simple_context sctx;
        uint32_t lseq, rseq;
 
        if (mbox->sync_view != NULL) {
@@ -47,11 +45,7 @@ static bool imapc_mail_is_expunged(struct mail *_mail)
 
        /* we may be running against a server that hasn't bothered sending
           us an EXPUNGE. see if NOOP sends it. */
-       imapc_simple_context_init(&sctx, mbox->storage);
-       cmd = imapc_client_mailbox_cmd(mbox->client_box,
-                                      imapc_simple_callback, &sctx);
-       imapc_command_send(cmd, "NOOP");
-       imapc_simple_run(&sctx);
+       imapc_mailbox_noop(mbox);
 
        return !imapc_msgmap_uid_to_rseq(msgmap, _mail->uid, &rseq);
 }
index 2a87a4b52928f601bcf9bea2ee986b5179a1ff57..f93dfd93baf4ccf92b0e20a08a220431f4978623 100644 (file)
@@ -12,8 +12,8 @@
 
 #define NOTIFY_DELAY_MSECS 500
 
-static void imapc_mailbox_set_corrupted(struct imapc_mailbox *mbox,
-                                       const char *reason, ...)
+void imapc_mailbox_set_corrupted(struct imapc_mailbox *mbox,
+                                const char *reason, ...)
 {
        va_list va;
 
@@ -239,15 +239,6 @@ imapc_mailbox_msgmap_update(struct imapc_mailbox *mbox,
                imapc_msgmap_append(msgmap, rseq, uid);
                if (uid < mbox->min_append_uid) {
                        /* message is already added to index */
-                       if (!mbox->initial_sync_done &&
-                           !mail_index_lookup_seq(mbox->delayed_sync_view,
-                                                  uid, lseq_r)) {
-                               imapc_mailbox_set_corrupted(mbox,
-                                       "Expunged message reappeared "
-                                       "(uid=%u < next_uid=%u)",
-                                       uid, mbox->min_append_uid);
-                               return -1;
-                       }
                } else if (mbox->syncing) {
                        mail_index_append(mbox->delayed_sync_trans,
                                          uid, lseq_r);
index 923a4bf3e662be2fa5f1a6420d7e4c26351d7df7..8df064575168379f79d55327648a18b83b597d7a 100644 (file)
@@ -137,31 +137,16 @@ void imapc_simple_callback(const struct imapc_command_reply *reply,
        imapc_client_stop(ctx->storage->client);
 }
 
-static void imapc_noop_callback(const struct imapc_command_reply *reply,
-                               void *context)
-
-{
-       struct imapc_storage *storage = context;
-
-       if (reply->state == IMAPC_COMMAND_STATE_OK)
-               ;
-       else if (reply->state == IMAPC_COMMAND_STATE_NO)
-               imapc_copy_error_from_reply(storage, MAIL_ERROR_PARAMS, reply);
-       else if (reply->state == IMAPC_COMMAND_STATE_DISCONNECTED)
-               mail_storage_set_internal_error(&storage->storage);
-       else {
-               mail_storage_set_critical(&storage->storage,
-                       "imapc: NOOP failed: %s", reply->text_full);
-       }
-}
-
-void imapc_noop_stop_callback(const struct imapc_command_reply *reply,
-                              void *context)
+void imapc_mailbox_noop(struct imapc_mailbox *mbox)
 {
-       struct imapc_storage *storage = context;
+       struct imapc_command *cmd;
+       struct imapc_simple_context sctx;
 
-       imapc_noop_callback(reply, context);
-       imapc_client_stop(storage->client);
+       imapc_simple_context_init(&sctx, mbox->storage);
+       cmd = imapc_client_mailbox_cmd(mbox->client_box,
+                                      imapc_simple_callback, &sctx);
+       imapc_command_send(cmd, "NOOP");
+       imapc_simple_run(&sctx);
 }
 
 static void imapc_storage_untagged_cb(const struct imapc_untagged_reply *reply,
@@ -657,6 +642,24 @@ static int imapc_mailbox_get_metadata(struct mailbox *box,
        return 0;
 }
 
+static void imapc_noop_callback(const struct imapc_command_reply *reply,
+                               void *context)
+
+{
+       struct imapc_storage *storage = context;
+
+       if (reply->state == IMAPC_COMMAND_STATE_OK)
+               ;
+       else if (reply->state == IMAPC_COMMAND_STATE_NO)
+               imapc_copy_error_from_reply(storage, MAIL_ERROR_PARAMS, reply);
+       else if (reply->state == IMAPC_COMMAND_STATE_DISCONNECTED)
+               mail_storage_set_internal_error(&storage->storage);
+       else {
+               mail_storage_set_critical(&storage->storage,
+                       "imapc: NOOP failed: %s", reply->text_full);
+       }
+}
+
 static void imapc_idle_timeout(struct imapc_mailbox *mbox)
 {
        struct imapc_command *cmd;
index ac45ae0fadbe6a2ae0a4106269bbc857677cf72d..1c10bc30455444c9edeb51b8cbd4261815242bf5 100644 (file)
@@ -116,10 +116,11 @@ void imapc_simple_context_init(struct imapc_simple_context *sctx,
 void imapc_simple_run(struct imapc_simple_context *sctx);
 void imapc_simple_callback(const struct imapc_command_reply *reply,
                           void *context);
-void imapc_noop_stop_callback(const struct imapc_command_reply *reply,
-                             void *context);
 int imapc_mailbox_commit_delayed_trans(struct imapc_mailbox *mbox,
                                       bool *changes_r);
+void imapc_mailbox_noop(struct imapc_mailbox *mbox);
+void imapc_mailbox_set_corrupted(struct imapc_mailbox *mbox,
+                                const char *reason, ...);
 
 void imapc_storage_register_untagged(struct imapc_storage *storage,
                                     const char *name,
index 9a3bd2d9a441c60108e8cb4c99f3cbbc5dd645aa..39941dceea180dc4d63d15e51e548c1ee8bc566b 100644 (file)
@@ -230,6 +230,26 @@ static void imapc_sync_uid_next(struct imapc_sync_context *ctx)
        }
 }
 
+static void imapc_initial_sync_check(struct imapc_sync_context *ctx)
+{
+       unsigned int idx_count;
+
+       idx_count = mail_index_view_get_messages_count(ctx->mbox->delayed_sync_view);
+       if (idx_count >= ctx->mbox->exists_count)
+               return;
+
+       /* NOOP should send EXPUNGEs */
+       imapc_mailbox_noop(ctx->mbox);
+
+       idx_count = mail_index_view_get_messages_count(ctx->mbox->delayed_sync_view);
+       if (idx_count < ctx->mbox->exists_count) {
+               imapc_mailbox_set_corrupted(ctx->mbox,
+                       "Index is missing messages (%u < %u)",
+                       idx_count, ctx->mbox->exists_count);
+               ctx->failed = TRUE;
+       }
+}
+
 static void imapc_sync_index(struct imapc_sync_context *ctx)
 {
        struct imapc_mailbox *mbox = ctx->mbox;
@@ -292,10 +312,15 @@ static void imapc_sync_index(struct imapc_sync_context *ctx)
        /* add uidnext after all appends */
        imapc_sync_uid_next(ctx);
 
-       imapc_sync_expunge_eom(ctx);
+       if (!ctx->failed)
+               imapc_sync_expunge_eom(ctx);
        if (mbox->box.v.sync_notify != NULL)
                mbox->box.v.sync_notify(&mbox->box, 0, 0);
-       mbox->initial_sync_done = TRUE;
+
+       if (!mbox->initial_sync_done) {
+               imapc_initial_sync_check(ctx);
+               mbox->initial_sync_done = TRUE;
+       }
 }
 
 static int
@@ -390,7 +415,6 @@ struct mailbox_sync_context *
 imapc_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
 {
        struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
-       struct imapc_command *cmd;
        enum imapc_capability capabilities;
        bool changes;
        int ret = 0;
@@ -404,11 +428,7 @@ imapc_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
        if ((capabilities & IMAPC_CAPABILITY_IDLE) == 0) {
                /* IDLE not supported. do NOOP to get latest changes
                   before starting sync. */
-               cmd = imapc_client_mailbox_cmd(mbox->client_box,
-                                              imapc_noop_stop_callback,
-                                              mbox->storage);
-               imapc_command_send(cmd, "NOOP");
-               imapc_storage_run(mbox->storage);
+               imapc_mailbox_noop(mbox);
        }
 
        if (imapc_mailbox_commit_delayed_trans(mbox, &changes) < 0)