]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Recent flag fixes. Should work perfectly now with maildir.
authorTimo Sirainen <tss@iki.fi>
Sat, 22 May 2004 22:23:29 +0000 (01:23 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 22 May 2004 22:23:29 +0000 (01:23 +0300)
--HG--
branch : HEAD

src/lib-index/mail-index-fsck.c
src/lib-index/mail-index-sync-update.c
src/lib-index/mail-index.c
src/lib-index/mail-index.h
src/lib-storage/index/index-mail.c
src/lib-storage/index/maildir/maildir-sync.c
src/lib-storage/index/maildir/maildir-uidlist.c

index 04f6c3400fb9da1bc3b332edf56bfb00f66a89a1..ebcbda4496891dd5aacd933a2b525fb6d5b9e801 100644 (file)
@@ -41,6 +41,7 @@ static int mail_index_fsck_locked(struct mail_index *index,
        }
 
        hdr.messages_count = 0;
+       hdr.recent_messages_count = 0;
        hdr.seen_messages_count = 0;
        hdr.deleted_messages_count = 0;
 
@@ -56,6 +57,8 @@ static int mail_index_fsck_locked(struct mail_index *index,
                }
 
                hdr.messages_count++;
+               if ((rec->flags & MAIL_RECENT) != 0)
+                       hdr.recent_messages_count++;
                if ((rec->flags & MAIL_SEEN) != 0)
                        hdr.seen_messages_count++;
                if ((rec->flags & MAIL_DELETED) != 0)
@@ -88,6 +91,7 @@ static int mail_index_fsck_locked(struct mail_index *index,
                 hdr.first_deleted_uid_lowwater = hdr.next_uid;
 
         CHECK(messages_count, !=);
+        CHECK(recent_messages_count, !=);
         CHECK(seen_messages_count, !=);
         CHECK(deleted_messages_count, !=);
 
index c46f038e6be57e072d8272efad6d7b5635874916..706e33a75d34a22a6d4e86c4a55a05475a6a5cfb 100644 (file)
@@ -20,20 +20,28 @@ struct mail_index_update_ctx {
 void mail_index_header_update_counts(struct mail_index_header *hdr,
                                     uint8_t old_flags, uint8_t new_flags)
 {
+       if (((old_flags ^ new_flags) & MAIL_RECENT) != 0) {
+               /* different recent-flag */
+               if ((old_flags & MAIL_RECENT) == 0)
+                       hdr->recent_messages_count++;
+               else if (--hdr->recent_messages_count == 0)
+                       hdr->first_recent_uid_lowwater = hdr->next_uid;
+       }
+
        if (((old_flags ^ new_flags) & MAIL_SEEN) != 0) {
                /* different seen-flag */
-               if ((old_flags & MAIL_SEEN) == 0)
-                       hdr->seen_messages_count++;
-               else
+               if ((old_flags & MAIL_SEEN) != 0)
                        hdr->seen_messages_count--;
+               else if (++hdr->seen_messages_count == hdr->messages_count)
+                       hdr->first_unseen_uid_lowwater = hdr->next_uid;
        }
 
        if (((old_flags ^ new_flags) & MAIL_DELETED) != 0) {
                /* different deleted-flag */
                if ((old_flags & MAIL_DELETED) == 0)
                        hdr->deleted_messages_count++;
-               else
-                       hdr->deleted_messages_count--;
+               else if (--hdr->deleted_messages_count == 0)
+                       hdr->first_deleted_uid_lowwater = hdr->next_uid;
        }
 }
 
index 0ae31dcfa6081b351426d43dfcb26f8422541c56..f9b6fb504e6b88b3af4186772aa8d91d0654ca35 100644 (file)
@@ -77,7 +77,8 @@ static int mail_index_check_header(struct mail_index *index,
        if (hdr->next_uid == 0)
                return 0;
 
-       if (hdr->seen_messages_count > hdr->messages_count ||
+       if (hdr->recent_messages_count > hdr->messages_count ||
+           hdr->seen_messages_count > hdr->messages_count ||
            hdr->deleted_messages_count > hdr->messages_count)
                return 0;
        if (hdr->first_recent_uid_lowwater > hdr->next_uid ||
index 5faf316f68c52d2b689715cef50c390a14afcc42..3f91bb052a74636cce14c9c802595995123cfda9 100644 (file)
@@ -6,7 +6,7 @@
 #define MAIL_INDEX_MAJOR_VERSION 4
 #define MAIL_INDEX_MINOR_VERSION 0
 
-#define MAIL_INDEX_HEADER_MIN_SIZE 68
+#define MAIL_INDEX_HEADER_MIN_SIZE 72
 
 /* Number of keywords in mail_index_record. */
 #define INDEX_KEYWORDS_COUNT (3*8)
@@ -77,6 +77,7 @@ struct mail_index_header {
        uint32_t next_uid;
 
        uint32_t messages_count;
+       uint32_t recent_messages_count;
        uint32_t seen_messages_count;
        uint32_t deleted_messages_count;
 
index 6708cb788b7bd81ea757257fe72ff1dfb8586917..101de3604e519c2454005cc3a2b114eff213635c 100644 (file)
@@ -169,7 +169,7 @@ const struct mail_full_flags *index_mail_get_flags(struct mail *_mail)
        struct index_mail *mail = (struct index_mail *) _mail;
        struct index_mail_data *data = &mail->data;
 
-       data->flags.flags = data->rec->flags;
+       data->flags.flags = data->rec->flags & MAIL_FLAGS_MASK;
        /*FIXME:data->flags.keywords =
                mail_keywords_list_get(mail->ibox->index->keywords);
        data->flags.keywords_count = MAIL_KEYWORDS_COUNT;*/
@@ -641,8 +641,7 @@ int index_mail_update_flags(struct mail *mail,
        enum mail_flags modify_flags;
        keywords_mask_t keywords;
 
-       /* \Recent can't be changed */
-       modify_flags = flags->flags & ~MAIL_RECENT;
+       modify_flags = flags->flags & MAIL_FLAGS_MASK;
 
        /*if (!index_mailbox_fix_keywords(ibox, &modify_flags,
                                            flags->keywords,
index e9e24c956437d1758861810c07e4d6f608a86c27..54c53dba9a9a0a10aee4732b6964e19d39d1e202 100644 (file)
@@ -442,6 +442,8 @@ static int maildir_scan_dir(struct maildir_sync_context *ctx, int new_dir)
                ret = maildir_uidlist_sync_next_pre(ctx->uidlist_sync_ctx,
                                                    dp->d_name);
                if (ret == 0) {
+                       /* new file and we couldn't lock uidlist, check this
+                          later in next sync. */
                        if (new_dir)
                                ctx->ibox->last_new_mtime = 0;
                        else
@@ -596,6 +598,13 @@ static int maildir_sync_index(struct maildir_sync_context *ctx)
        while (maildir_uidlist_iter_next(iter, &uid, &uflags, &filename)) {
                maildir_filename_get_flags(filename, &flags, keywords);
 
+               if ((uflags & MAILDIR_UIDLIST_REC_FLAG_RECENT) != 0 &&
+                   (uflags & MAILDIR_UIDLIST_REC_FLAG_NEW_DIR) != 0 &&
+                   (uflags & MAILDIR_UIDLIST_REC_FLAG_MOVED) == 0) {
+                       /* mail is recent for next session as well */
+                       flags |= MAIL_RECENT;
+               }
+
        __again:
                seq++;
                if ((uflags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) != 0) {
@@ -673,14 +682,21 @@ static int maildir_sync_index(struct maildir_sync_context *ctx)
                        continue;
                }
 
-               maildir_filename_get_flags(filename, &flags, keywords);
-               if ((uint8_t)flags != (rec->flags & MAIL_FLAGS_MASK) ||
+               if (((uint8_t)flags & ~MAIL_RECENT) !=
+                   (rec->flags & (MAIL_FLAGS_MASK^MAIL_RECENT)) ||
                    memcmp(keywords, rec->keywords,
                           INDEX_KEYWORDS_BYTE_COUNT) != 0) {
-                       /* FIXME: this is wrong if there's syncs later.
-                          it gets fixed in next sync however.. */
+                       /* FIXME: this is wrong if there's pending changes in
+                          transaction log already. it gets fixed in next sync
+                          however.. */
                        mail_index_update_flags(trans, seq, MODIFY_REPLACE,
                                                flags, keywords);
+               } else if ((flags & MAIL_RECENT) == 0 &&
+                          (rec->flags & MAIL_RECENT) != 0) {
+                       /* just remove recent flag */
+                       memset(keywords, 0, sizeof(keywords));
+                       mail_index_update_flags(trans, seq, MODIFY_REMOVE,
+                                               MAIL_RECENT, keywords);
                }
        }
        maildir_uidlist_iter_deinit(iter);
index 0d57f05daaaed15d6aa2a585adfacf6a0520a70a..bfd21e6892d2693913ee3b77f58a735f911750b9 100644 (file)
@@ -44,6 +44,7 @@ struct maildir_uidlist {
        uint32_t first_recent_uid;
 
        unsigned int initial_read:1;
+       unsigned int initial_sync:1;
 };
 
 struct maildir_uidlist_sync_ctx {
@@ -389,6 +390,18 @@ uint32_t maildir_uidlist_get_recent_count(struct maildir_uidlist *uidlist)
        size_t size;
        uint32_t count;
 
+       if (!uidlist->initial_sync) {
+               /* we haven't synced yet, trust index */
+               const struct mail_index_header *hdr;
+
+               if (mail_index_get_header(uidlist->ibox->view, &hdr) < 0)
+                       return 0;
+               return hdr->recent_messages_count;
+       }
+
+       /* all recent messages were in new/ dir, so even if we did only
+          a partial sync we should know all the recent messages. */
+
        if (uidlist->first_recent_uid == 0)
                return 0;
 
@@ -606,6 +619,10 @@ maildir_uidlist_sync_next_partial(struct maildir_uidlist_sync_ctx *ctx,
                buffer_append(uidlist->record_buf, &rec, sizeof(rec));
        }
 
+       if ((flags & MAILDIR_UIDLIST_REC_FLAG_RECENT) != 0 &&
+           rec->uid != (uint32_t)-1)
+               maildir_uidlist_mark_recent(uidlist, rec->uid);
+
        rec->flags = (rec->flags | flags) & ~MAILDIR_UIDLIST_REC_FLAG_NONSYNCED;
        rec->filename = p_strdup(uidlist->record_pool, filename);
        hash_insert(uidlist->files, rec->filename, rec);
@@ -777,6 +794,7 @@ int maildir_uidlist_sync_finish(struct maildir_uidlist_sync_ctx *ctx)
                }
        }
        ctx->finished = TRUE;
+       ctx->uidlist->initial_sync = TRUE;
        return !ctx->locked;
 }