dovecot-2.1: imapc: Fixed syncing external changes to mailbox wh...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Sep 4 11:51:37 EEST 2011
details: http://hg.dovecot.org/dovecot-2.1/rev/f8d5f872498d
changeset: 13378:f8d5f872498d
user: Timo Sirainen <tss at iki.fi>
date: Sun Sep 04 11:51:23 2011 +0300
description:
imapc: Fixed syncing external changes to mailbox when opening it.
diffstat:
src/lib-storage/index/imapc/imapc-mailbox.c | 58 ++++++++++++++++++++++++----
src/lib-storage/index/imapc/imapc-storage.h | 2 +
2 files changed, 51 insertions(+), 9 deletions(-)
diffs (111 lines):
diff -r 44e3c053f9f8 -r f8d5f872498d src/lib-storage/index/imapc/imapc-mailbox.c
--- a/src/lib-storage/index/imapc/imapc-mailbox.c Sun Sep 04 10:55:33 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-mailbox.c Sun Sep 04 11:51:23 2011 +0300
@@ -60,6 +60,29 @@
return ret;
}
+static void imapc_mailbox_open_finish(struct imapc_mailbox *mbox)
+{
+ const struct mail_index_record *rec;
+ struct imapc_seqmap *seqmap;
+ uint32_t lseq, rseq, old_count;
+
+ /* if we haven't seen FETCH reply for some messages at the end of
+ mailbox they've been externally expunged. */
+ imapc_mailbox_init_delayed_trans(mbox);
+ seqmap = imapc_client_mailbox_get_seqmap(mbox->client_box);
+
+ old_count = mail_index_view_get_messages_count(mbox->delayed_sync_view);
+ for (lseq = old_count; lseq > 0; lseq--) {
+ rec = mail_index_lookup(mbox->delayed_sync_view, lseq);
+ if (rec->uid <= mbox->highest_seen_uid)
+ break;
+
+ rseq = imapc_seqmap_lseq_to_rseq(seqmap, lseq);
+ imapc_seqmap_expunge(seqmap, rseq);
+ mail_index_expunge(mbox->delayed_sync_trans, lseq);
+ }
+}
+
static void
imapc_newmsgs_callback(const struct imapc_command_reply *reply,
void *context)
@@ -75,8 +98,10 @@
mail_storage_set_critical(&mbox->storage->storage,
"imapc: Command failed: %s", reply->text_full);
}
- if (mbox->opening)
+ if (mbox->opening) {
+ imapc_mailbox_open_finish(mbox);
imapc_client_stop(mbox->storage->client);
+ }
}
static void imapc_untagged_exists(const struct imapc_untagged_reply *reply,
@@ -94,15 +119,26 @@
if (view == NULL)
view = mbox->box.view;
- seqmap = imapc_client_mailbox_get_seqmap(mbox->client_box);
- next_lseq = mail_index_view_get_messages_count(view) + 1;
- next_rseq = imapc_seqmap_lseq_to_rseq(seqmap, next_lseq);
- if (next_rseq > rcount) {
- if (rcount == 0 || !mbox->opening)
- return;
- /* initial SELECT. we don't know what the flags are. */
+ if (rcount == 0) {
+ /* nothing in this mailbox */
+ return;
+ }
+ if (mbox->opening) {
+ /* We don't know the latest flags, refresh them. */
first_uid = 1;
} else {
+ seqmap = imapc_client_mailbox_get_seqmap(mbox->client_box);
+ next_lseq = mail_index_view_get_messages_count(view) + 1;
+ next_rseq = imapc_seqmap_lseq_to_rseq(seqmap, next_lseq);
+ if (rcount < next_rseq) {
+ if (rcount == next_rseq-1) {
+ /* duplicate EXISTS - ignore */
+ return;
+ }
+ imapc_mailbox_set_corrupted(mbox,
+ "EXISTS reply shrank mailbox size");
+ return;
+ }
hdr = mail_index_get_header(view);
first_uid = hdr->next_uid;
}
@@ -225,7 +261,9 @@
return;
}
/* we're opening the mailbox. this message was expunged
- externally, so expunge it ourself too. */
+ externally, so expunge it ourself too. this code assumes
+ that FETCH responses come in ascending order when opening
+ mailbox. */
imapc_seqmap_expunge(seqmap, rseq);
mail_index_expunge(mbox->delayed_sync_trans, lseq);
lseq++;
@@ -258,6 +296,8 @@
}
mail_index_keywords_unref(&kw);
} T_END;
+ if (mbox->highest_seen_uid < uid)
+ mbox->highest_seen_uid = uid;
imapc_mailbox_idle_notify(mbox);
}
diff -r 44e3c053f9f8 -r f8d5f872498d src/lib-storage/index/imapc/imapc-storage.h
--- a/src/lib-storage/index/imapc/imapc-storage.h Sun Sep 04 10:55:33 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-storage.h Sun Sep 04 11:51:23 2011 +0300
@@ -54,6 +54,8 @@
ARRAY_DEFINE(untagged_callbacks, struct imapc_mailbox_event_callback);
ARRAY_DEFINE(resp_text_callbacks, struct imapc_mailbox_event_callback);
+ uint32_t highest_seen_uid;
+
unsigned int opening:1;
unsigned int new_msgs:1;
};
More information about the dovecot-cvs
mailing list