changeset 12883:0dec197d1bb7

imapc: Fixes to handling expunges.
author Timo Sirainen <tss@iki.fi>
date Mon, 04 Apr 2011 15:27:33 +0300
parents dc0d02efe64b
children f051c326463e
files src/lib-storage/index/imapc/imapc-mail-fetch.c src/lib-storage/index/imapc/imapc-mail.c src/lib-storage/index/imapc/imapc-mailbox.c
diffstat 3 files changed, 37 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/imapc/imapc-mail-fetch.c	Mon Apr 04 15:08:50 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c	Mon Apr 04 15:27:33 2011 +0300
@@ -51,7 +51,9 @@
 {
 	struct imapc_mail *mail = (struct imapc_mail *)_mail;
 	struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box;
+	struct mail_index_view *view;
 	string_t *str;
+	uint32_t seq;
 
 	if (_mail->lookup_abort != MAIL_LOOKUP_ABORT_NEVER)
 		return -1;
@@ -61,6 +63,16 @@
 	if (fields == 0)
 		return 0;
 
+	/* if we already know that the mail is expunged,
+	   don't try to FETCH it */
+	view = mbox->delayed_sync_view != NULL ?
+		mbox->delayed_sync_view : mbox->box.view;
+	if (!mail_index_lookup_seq(view, _mail->uid, &seq) ||
+	    mail_index_is_expunged(view, seq)) {
+		mail_set_expunged(_mail);
+		return -1;
+	}
+
 	if ((fields & MAIL_FETCH_STREAM_BODY) != 0)
 		fields |= MAIL_FETCH_STREAM_HEADER;
 
--- a/src/lib-storage/index/imapc/imapc-mail.c	Mon Apr 04 15:08:50 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-mail.c	Mon Apr 04 15:27:33 2011 +0300
@@ -98,6 +98,25 @@
 	return 0;
 }
 
+static bool imapc_mail_is_expunged(struct mail *_mail)
+{
+	struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box;
+	struct imapc_seqmap *seqmap;
+	uint32_t lseq;
+
+	/* first we'll need to convert the mail's sequence to sync_view's
+	   sequence. if there's no sync_view, then no mails have been
+	   expunged. */
+	if (mbox->sync_view == NULL)
+		return FALSE;
+
+	if (!mail_index_lookup_seq(mbox->sync_view, _mail->uid, &lseq))
+		return TRUE;
+
+	seqmap = imapc_client_mailbox_get_seqmap(mbox->client_box);
+	return imapc_seqmap_lseq_to_rseq(seqmap, lseq) == 0;
+}
+
 static int
 imapc_mail_get_stream(struct mail *_mail, struct message_size *hdr_size,
 		      struct message_size *body_size, struct istream **stream_r)
@@ -118,14 +137,9 @@
 			return -1;
 
 		if (data->stream == NULL) {
-			struct imapc_mailbox *mbox =
-				(struct imapc_mailbox *)_mail->box;
-			struct imapc_seqmap *seqmap;
-
-			seqmap = imapc_client_mailbox_get_seqmap(mbox->client_box);
-			if (imapc_seqmap_lseq_to_rseq(seqmap, _mail->seq) == 0)
+			if (_mail->expunged || imapc_mail_is_expunged(_mail))
 				mail_set_expunged(_mail);
-			else if (!_mail->expunged) {
+			else {
 				mail_storage_set_critical(_mail->box->storage,
 					"imapc: Remote server didn't send BODY[]");
 			}
--- a/src/lib-storage/index/imapc/imapc-mailbox.c	Mon Apr 04 15:08:50 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-mailbox.c	Mon Apr 04 15:27:33 2011 +0300
@@ -202,13 +202,14 @@
 	seqmap = imapc_client_mailbox_get_seqmap(mbox->client_box);
 	lseq = imapc_seqmap_rseq_to_lseq(seqmap, rseq);
 
+	/* fetch_mails' view is different from sync_view, so we can't compare
+	   their sequences directly. that is why this code supports only
+	   UID FETCH commands which are guaranteed to have UID in the reply. */
 	array_foreach(&mbox->fetch_mails, mailp) {
 		struct imapc_mail *mail = *mailp;
 
-		if (mail->imail.mail.mail.seq == lseq) {
-			i_assert(uid == 0 || mail->imail.mail.mail.uid == uid);
+		if (mail->imail.mail.mail.uid == uid)
 			imapc_mail_fetch_update(mail, reply, list);
-		}
 	}
 
 	imapc_mailbox_init_delayed_trans(mbox);