dovecot: Fixed handling \Recent flags.

dovecot at dovecot.org dovecot at dovecot.org
Sat Dec 29 21:13:00 EET 2007


details:   http://hg.dovecot.org/dovecot/rev/7999ce2bb43a
changeset: 7067:7999ce2bb43a
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Dec 29 21:12:56 2007 +0200
description:
Fixed handling \Recent flags.

diffstat:

2 files changed, 52 insertions(+), 29 deletions(-)
src/lib-storage/index/maildir/maildir-save.c       |   19 +++++-
src/lib-storage/index/maildir/maildir-sync-index.c |   62 +++++++++++---------

diffs (175 lines):

diff -r 048325df1ec4 -r 7999ce2bb43a src/lib-storage/index/maildir/maildir-save.c
--- a/src/lib-storage/index/maildir/maildir-save.c	Sat Dec 29 19:10:35 2007 +0200
+++ b/src/lib-storage/index/maildir/maildir-save.c	Sat Dec 29 21:12:56 2007 +0200
@@ -576,7 +576,7 @@ int maildir_transaction_save_commit_pre(
 	struct maildir_transaction_context *t =
 		(struct maildir_transaction_context *)ctx->ctx.transaction;
 	struct maildir_filename *mf;
-	uint32_t seq, first_uid, next_uid;
+	uint32_t seq, uid, first_uid, next_uid;
 	enum maildir_uidlist_rec_flag flags;
 	bool newdir, sync_commit = FALSE;
 	int ret;
@@ -627,10 +627,25 @@ int maildir_transaction_save_commit_pre(
 		first_uid = maildir_uidlist_get_next_uid(ctx->mbox->uidlist);
 		i_assert(first_uid != 0);
 		mail_index_append_assign_uids(ctx->trans, first_uid, &next_uid);
+		i_assert(next_uid = first_uid + ctx->files_count);
+
+		/* these mails are all recent in our session */
+		for (uid = first_uid; uid < next_uid; uid++)
+			index_mailbox_set_recent_uid(&ctx->mbox->ibox, uid);
+
+		if (!ctx->mbox->ibox.keep_recent) {
+			/* maildir_sync_index() dropped recent flags from
+			   existing messages. we'll still need to drop recent
+			   flags from these newly added messages. */
+			mail_index_update_header(ctx->trans,
+				offsetof(struct mail_index_header,
+					 first_recent_uid),
+				&next_uid, sizeof(next_uid), FALSE);
+		}
 
 		/* this will work even if index isn't updated */
 		*t->ictx.first_saved_uid = first_uid;
-		*t->ictx.last_saved_uid = first_uid + ctx->files_count - 1;
+		*t->ictx.last_saved_uid = next_uid - 1;
 	} else {
 		/* since we couldn't lock uidlist, we'll have to drop the
 		   appends to index. */
diff -r 048325df1ec4 -r 7999ce2bb43a src/lib-storage/index/maildir/maildir-sync-index.c
--- a/src/lib-storage/index/maildir/maildir-sync-index.c	Sat Dec 29 19:10:35 2007 +0200
+++ b/src/lib-storage/index/maildir/maildir-sync-index.c	Sat Dec 29 21:12:56 2007 +0200
@@ -259,19 +259,20 @@ int maildir_sync_index(struct maildir_in
 {
 	struct maildir_mailbox *mbox = ctx->mbox;
 	struct mail_index_view *view = ctx->view;
+	struct mail_index_view *view2;
 	struct maildir_uidlist_iter_ctx *iter;
 	struct mail_index_transaction *trans = ctx->trans;
 	const struct mail_index_header *hdr;
 	struct mail_index_header empty_hdr;
 	const struct mail_index_record *rec;
-	uint32_t seq, uid, prev_uid;
+	uint32_t seq, seq2, uid, prev_uid;
         enum maildir_uidlist_rec_flag uflags;
 	const char *filename;
 	ARRAY_TYPE(keyword_indexes) idx_keywords;
-	uint32_t uid_validity, next_uid, hdr_next_uid, last_nonrecent_uid;
+	uint32_t uid_validity, next_uid, hdr_next_uid, first_recent_uid;
 	unsigned int changes = 0;
 	int ret = 0;
-	bool recent, expunged, full_rescan = FALSE;
+	bool expunged, full_rescan = FALSE;
 
 	i_assert(!mbox->syncing_commit);
 	i_assert(maildir_uidlist_is_locked(mbox->uidlist));
@@ -295,7 +296,7 @@ int maildir_sync_index(struct maildir_in
 	hdr_next_uid = hdr->next_uid;
 
 	mbox->syncing_commit = TRUE;
-	seq = prev_uid = last_nonrecent_uid = 0;
+	seq = prev_uid = 0; first_recent_uid = hdr->first_recent_uid;
 	t_array_init(&ctx->keywords, MAILDIR_MAX_KEYWORDS);
 	t_array_init(&idx_keywords, MAILDIR_MAX_KEYWORDS);
 	iter = maildir_uidlist_iter_init(mbox->uidlist);
@@ -313,12 +314,6 @@ int maildir_sync_index(struct maildir_in
 	again:
 		ctx->seq = ++seq;
 		ctx->uid = uid;
-
-		if ((uflags & MAILDIR_UIDLIST_REC_FLAG_RECENT) == 0 &&
-		    (uflags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) == 0)
-			last_nonrecent_uid = uid;
-		recent = (uflags & MAILDIR_UIDLIST_REC_FLAG_RECENT) != 0 &&
-			uid >= hdr->first_recent_uid;
 
 		if (seq > hdr->messages_count) {
 			if (uid < hdr_next_uid) {
@@ -328,6 +323,18 @@ int maildir_sync_index(struct maildir_in
 				continue;
 			}
 
+			/* Trust uidlist recent flags only for newly added
+			   messages. When saving/copying messages with flags
+			   they're stored to cur/ and uidlist treats them
+			   as non-recent. */
+			if ((uflags & MAILDIR_UIDLIST_REC_FLAG_RECENT) != 0) {
+				if (uid > first_recent_uid)
+					first_recent_uid = uid;
+			} else {
+				if (uid >= first_recent_uid)
+					first_recent_uid = uid + 1;
+			}
+
 			hdr_next_uid = uid + 1;
 			mail_index_append(trans, uid, &seq);
 			mail_index_update_flags(trans, seq, MODIFY_REPLACE,
@@ -341,8 +348,6 @@ int maildir_sync_index(struct maildir_in
 							   MODIFY_REPLACE, kw);
 				mail_index_keywords_free(&kw);
 			}
-			if (recent)
-				index_mailbox_set_recent_uid(&mbox->ibox, uid);
 			continue;
 		}
 
@@ -372,9 +377,6 @@ int maildir_sync_index(struct maildir_in
 			continue;
 		}
 
-		if (recent)
-			index_mailbox_set_recent_uid(&mbox->ibox, uid);
-
 		/* the private flags are stored only in indexes, keep them */
 		ctx->flags |= rec->flags & mbox->ibox.box.private_flags_mask;
 
@@ -424,19 +426,27 @@ int maildir_sync_index(struct maildir_in
 	maildir_uidlist_iter_deinit(&iter);
 	mbox->syncing_commit = FALSE;
 
-	if (ctx->uidlist_sync_ctx != NULL) {
-		if (maildir_uidlist_sync_deinit(&ctx->uidlist_sync_ctx) < 0)
-			ret = -1;
-	}
-
-	if (mbox->ibox.box.v.sync_notify != NULL)
-		mbox->ibox.box.v.sync_notify(&mbox->ibox.box, 0, 0);
-
 	if (!partial) {
 		/* expunge the rest */
 		for (seq++; seq <= hdr->messages_count; seq++)
 			mail_index_expunge(trans, seq);
 	}
+
+	/* add \Recent flags. use updated view so it contains newly
+	   appended messages. */
+	view2 = mail_index_transaction_open_updated_view(trans);
+	if (mail_index_lookup_seq_range(view2, first_recent_uid, (uint32_t)-1,
+					&seq, &seq2))
+		index_mailbox_set_recent_seq(&mbox->ibox, view2, seq, seq2);
+	mail_index_view_close(&view2);
+
+	if (ctx->uidlist_sync_ctx != NULL) {
+		if (maildir_uidlist_sync_deinit(&ctx->uidlist_sync_ctx) < 0)
+			ret = -1;
+	}
+
+	if (mbox->ibox.box.v.sync_notify != NULL)
+		mbox->ibox.box.v.sync_notify(&mbox->ibox.box, 0, 0);
 
 	if (ctx->changed)
 		mbox->maildir_hdr.cur_mtime = time(NULL);
@@ -462,10 +472,8 @@ int maildir_sync_index(struct maildir_in
 			&next_uid, sizeof(next_uid), FALSE);
 	}
 
-	if (ctx->mbox->ibox.keep_recent &&
-	    hdr->first_recent_uid < last_nonrecent_uid + 1) {
-		uint32_t first_recent_uid = last_nonrecent_uid + 1;
-
+	i_assert(hdr->first_recent_uid <= first_recent_uid);
+	if (hdr->first_recent_uid < first_recent_uid) {
 		mail_index_update_header(ctx->trans,
 			offsetof(struct mail_index_header, first_recent_uid),
 			&first_recent_uid, sizeof(first_recent_uid), FALSE);


More information about the dovecot-cvs mailing list