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