From b50e80d237435686c4ea525643f266731a600981 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Sun, 9 Oct 2011 17:15:31 +0300 Subject: [PATCH] imapc: Fixed detecting when messages are missing from index. --- src/lib-storage/index/imapc/imapc-mail.c | 8 +--- src/lib-storage/index/imapc/imapc-mailbox.c | 13 +----- src/lib-storage/index/imapc/imapc-storage.c | 49 +++++++++++---------- src/lib-storage/index/imapc/imapc-storage.h | 5 ++- src/lib-storage/index/imapc/imapc-sync.c | 36 +++++++++++---- 5 files changed, 60 insertions(+), 51 deletions(-) diff --git a/src/lib-storage/index/imapc/imapc-mail.c b/src/lib-storage/index/imapc/imapc-mail.c index bb6ba7cf39..6e9f9e306e 100644 --- a/src/lib-storage/index/imapc/imapc-mail.c +++ b/src/lib-storage/index/imapc/imapc-mail.c @@ -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); } diff --git a/src/lib-storage/index/imapc/imapc-mailbox.c b/src/lib-storage/index/imapc/imapc-mailbox.c index 2a87a4b529..f93dfd93ba 100644 --- a/src/lib-storage/index/imapc/imapc-mailbox.c +++ b/src/lib-storage/index/imapc/imapc-mailbox.c @@ -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); diff --git a/src/lib-storage/index/imapc/imapc-storage.c b/src/lib-storage/index/imapc/imapc-storage.c index 923a4bf3e6..8df0645751 100644 --- a/src/lib-storage/index/imapc/imapc-storage.c +++ b/src/lib-storage/index/imapc/imapc-storage.c @@ -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; diff --git a/src/lib-storage/index/imapc/imapc-storage.h b/src/lib-storage/index/imapc/imapc-storage.h index ac45ae0fad..1c10bc3045 100644 --- a/src/lib-storage/index/imapc/imapc-storage.h +++ b/src/lib-storage/index/imapc/imapc-storage.h @@ -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, diff --git a/src/lib-storage/index/imapc/imapc-sync.c b/src/lib-storage/index/imapc/imapc-sync.c index 9a3bd2d9a4..39941dceea 100644 --- a/src/lib-storage/index/imapc/imapc-sync.c +++ b/src/lib-storage/index/imapc/imapc-sync.c @@ -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) -- 2.47.3