# HG changeset patch # User Timo Sirainen # Date 1453996421 -7200 # Node ID 2470745d19e7bdddb2751e9faa467cb6f9ea6eae # Parent cb104cf148af46abcdec69325722edc345a09712 imapc: Don't ignore FETCH, SEARCH and EXPUNGE returning NO failures in syncing. Especially if the FETCH 1:* (FLAGS) didn't succeed, we expunged all the mails from local index. diff -r cb104cf148af -r 2470745d19e7 src/lib-storage/index/imapc/imapc-sync.c --- a/src/lib-storage/index/imapc/imapc-sync.c Thu Jan 28 17:43:01 2016 +0200 +++ b/src/lib-storage/index/imapc/imapc-sync.c Thu Jan 28 17:53:41 2016 +0200 @@ -12,16 +12,23 @@ #include "imapc-storage.h" #include "imapc-sync.h" +struct imapc_sync_command { + struct imapc_sync_context *ctx; + char *cmd_str; + bool ignore_no; +}; + static void imapc_sync_callback(const struct imapc_command_reply *reply, void *context) { - struct imapc_sync_context *ctx = context; + struct imapc_sync_command *cmd = context; + struct imapc_sync_context *ctx = cmd->ctx; i_assert(ctx->sync_command_count > 0); if (reply->state == IMAPC_COMMAND_STATE_OK) ; - else if (reply->state == IMAPC_COMMAND_STATE_NO) { + else if (reply->state == IMAPC_COMMAND_STATE_NO && cmd->ignore_no) { /* maybe the message was expunged already. some servers fail STOREs with NO in such situation. */ } else if (reply->state == IMAPC_COMMAND_STATE_DISCONNECTED) { @@ -31,25 +38,47 @@ ctx->failed = TRUE; } else { mail_storage_set_critical(&ctx->mbox->storage->storage, - "imapc: Sync command failed: %s", reply->text_full); + "imapc: Sync command '%s' failed: %s", + cmd->cmd_str, reply->text_full); ctx->failed = TRUE; } if (--ctx->sync_command_count == 0) imapc_client_stop(ctx->mbox->storage->client->client); + i_free(cmd->cmd_str); + i_free(cmd); +} + +static struct imapc_command * +imapc_sync_cmd_full(struct imapc_sync_context *ctx, const char *cmd_str, + bool ignore_no) +{ + struct imapc_sync_command *sync_cmd; + struct imapc_command *cmd; + + sync_cmd = i_new(struct imapc_sync_command, 1); + sync_cmd->ctx = ctx; + sync_cmd->cmd_str = i_strdup(cmd_str); + sync_cmd->ignore_no = ignore_no; + + ctx->sync_command_count++; + cmd = imapc_client_mailbox_cmd(ctx->mbox->client_box, + imapc_sync_callback, sync_cmd); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE); + imapc_command_send(cmd, cmd_str); + return cmd; } static struct imapc_command * imapc_sync_cmd(struct imapc_sync_context *ctx, const char *cmd_str) { - struct imapc_command *cmd; + return imapc_sync_cmd_full(ctx, cmd_str, FALSE); +} - ctx->sync_command_count++; - cmd = imapc_client_mailbox_cmd(ctx->mbox->client_box, - imapc_sync_callback, ctx); - imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE); - imapc_command_send(cmd, cmd_str); - return cmd; +static struct imapc_command * +imapc_sync_store_cmd(struct imapc_sync_context *ctx, const char *cmd_str) +{ + return imapc_sync_cmd_full(ctx, cmd_str, TRUE); } static void @@ -73,7 +102,7 @@ mail_index_lookup_uid(ctx->sync_view, seq2, &uid2); cmd = t_strdup_printf("UID STORE %u:%u +FLAGS \\Deleted", uid1, uid2); - imapc_sync_cmd(ctx, cmd); + imapc_sync_store_cmd(ctx, cmd); } } @@ -90,7 +119,7 @@ sync_rec->uid1, sync_rec->uid2); imap_write_flags(str, sync_rec->add_flags, NULL); str_append_c(str, ')'); - imapc_sync_cmd(ctx, str_c(str)); + imapc_sync_store_cmd(ctx, str_c(str)); } if (sync_rec->remove_flags != 0) { @@ -100,7 +129,7 @@ sync_rec->uid1, sync_rec->uid2); imap_write_flags(str, sync_rec->remove_flags, NULL); str_append_c(str, ')'); - imapc_sync_cmd(ctx, str_c(str)); + imapc_sync_store_cmd(ctx, str_c(str)); } } @@ -129,7 +158,7 @@ kw_p = array_idx(ctx->keywords, sync_rec->keyword_idx); str_append(str, *kw_p); str_append_c(str, ')'); - imapc_sync_cmd(ctx, str_c(str)); + imapc_sync_store_cmd(ctx, str_c(str)); } static void imapc_sync_expunge_finish(struct imapc_sync_context *ctx)