# HG changeset patch # User Timo Sirainen # Date 1204142044 -7200 # Node ID 4e1161bad6ec5da44686c5a2a14019372fa2a55f # Parent 86af79a203d78f9ebea2ac0a06b1a48207bb2ee1 Fixed dirty flag/keyword handling. diff -r 86af79a203d7 -r 4e1161bad6ec src/lib-storage/index/mbox/mbox-sync-update.c --- a/src/lib-storage/index/mbox/mbox-sync-update.c Tue Feb 26 20:01:57 2008 +0200 +++ b/src/lib-storage/index/mbox/mbox-sync-update.c Wed Feb 27 21:54:04 2008 +0200 @@ -323,7 +323,8 @@ return; str = t_str_new(256); - keywords_append(ctx->sync_ctx, str, &ctx->mail.keywords); + if (array_is_created(&ctx->mail.keywords)) + keywords_append(ctx->sync_ctx, str, &ctx->mail.keywords); str_append_c(str, '\n'); mbox_sync_update_line(ctx, ctx->hdr_pos[MBOX_HDR_X_KEYWORDS], str); } @@ -375,35 +376,18 @@ static void mbox_sync_update_header_real(struct mbox_sync_mail_context *ctx) { - uint8_t old_flags; - enum mail_index_sync_type sync_type; - i_assert(ctx->mail.uid != 0 || ctx->mail.pseudo); - old_flags = ctx->mail.flags; - - index_sync_changes_apply(ctx->sync_ctx->sync_changes, - ctx->sync_ctx->mail_keyword_pool, - &ctx->mail.flags, &ctx->mail.keywords, - &sync_type); - - if ((old_flags & XSTATUS_FLAGS_MASK) != - (ctx->mail.flags & XSTATUS_FLAGS_MASK)) - mbox_sync_update_xstatus(ctx); - if ((sync_type & (MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD | - MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE | - MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET)) != 0) - mbox_sync_update_xkeywords(ctx); - if (!ctx->sync_ctx->mbox->ibox.keep_recent) ctx->mail.flags &= ~MAIL_RECENT; - if ((old_flags & STATUS_FLAGS_MASK) != - (ctx->mail.flags & STATUS_FLAGS_MASK)) - mbox_sync_update_status(ctx); + mbox_sync_update_status(ctx); + mbox_sync_update_xstatus(ctx); + mbox_sync_update_xkeywords(ctx); mbox_sync_update_x_imap_base(ctx); mbox_sync_update_x_uid(ctx); + mbox_sync_add_missing_headers(ctx); ctx->updated = TRUE; } diff -r 86af79a203d7 -r 4e1161bad6ec src/lib-storage/index/mbox/mbox-sync.c --- a/src/lib-storage/index/mbox/mbox-sync.c Tue Feb 26 20:01:57 2008 +0200 +++ b/src/lib-storage/index/mbox/mbox-sync.c Wed Feb 27 21:54:04 2008 +0200 @@ -315,20 +315,97 @@ } } +static void mbox_sync_get_dirty_flags(struct mbox_sync_mail_context *mail_ctx, + const struct mail_index_record *rec) +{ + struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx; + ARRAY_TYPE(keyword_indexes) idx_keywords; + uint8_t idx_flags, mbox_flags; + + /* default to undirtying the message. it gets added back if + flags/keywords don't match what is in the index. */ + mail_ctx->mail.flags &= ~MAIL_INDEX_MAIL_FLAG_DIRTY; + + /* replace flags */ + idx_flags = rec->flags & MAIL_FLAGS_NONRECENT; + mbox_flags = mail_ctx->mail.flags & MAIL_FLAGS_NONRECENT; + if (idx_flags != mbox_flags) { + mail_ctx->need_rewrite = TRUE; + mail_ctx->mail.flags = (mail_ctx->mail.flags & MAIL_RECENT) | + idx_flags | MAIL_INDEX_MAIL_FLAG_DIRTY; + } + + /* replace keywords */ + t_array_init(&idx_keywords, 32); + mail_index_lookup_keywords(sync_ctx->sync_view, sync_ctx->idx_seq, + &idx_keywords); + if (!index_keyword_array_cmp(&idx_keywords, &mail_ctx->mail.keywords)) { + mail_ctx->need_rewrite = TRUE; + mail_ctx->mail.flags |= MAIL_INDEX_MAIL_FLAG_DIRTY; + + if (!array_is_created(&mail_ctx->mail.keywords)) { + p_array_init(&mail_ctx->mail.keywords, + sync_ctx->mail_keyword_pool, + array_count(&idx_keywords)); + } + array_clear(&mail_ctx->mail.keywords); + array_append_array(&mail_ctx->mail.keywords, &idx_keywords); + } +} + +static void mbox_sync_update_flags(struct mbox_sync_mail_context *mail_ctx, + const struct mail_index_record *rec) +{ + struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx; + struct mailbox *box = &sync_ctx->mbox->ibox.box; + struct mbox_sync_mail *mail = &mail_ctx->mail; + enum mail_index_sync_type sync_type; + ARRAY_TYPE(keyword_indexes) orig_keywords = ARRAY_INIT; + uint8_t flags, orig_flags; + + if (rec != NULL) { + if ((rec->flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) { + /* flags and keywords are dirty. replace the current + ones from the flags in index file. */ + mbox_sync_get_dirty_flags(mail_ctx, rec); + } + } + + flags = orig_flags = mail->flags & MAIL_FLAGS_NONRECENT; + if (array_is_created(&mail->keywords)) { + t_array_init(&orig_keywords, 32); + array_append_array(&orig_keywords, &mail->keywords); + } + + /* apply new changes */ + index_sync_changes_apply(sync_ctx->sync_changes, + sync_ctx->mail_keyword_pool, + &flags, &mail->keywords, &sync_type); + if (flags != orig_flags || + !index_keyword_array_cmp(&mail->keywords, &orig_keywords)) { + mail_ctx->need_rewrite = TRUE; + mail->flags = flags | (mail->flags & MAIL_RECENT) | + MAIL_INDEX_MAIL_FLAG_DIRTY; + } + if (sync_type != 0 && box->v.sync_notify != NULL) { + box->v.sync_notify(box, rec->uid, + index_sync_type_convert(sync_type)); + } +} + static void mbox_sync_update_index(struct mbox_sync_mail_context *mail_ctx, const struct mail_index_record *rec) { struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx; struct mbox_sync_mail *mail = &mail_ctx->mail; - struct mailbox *box = &sync_ctx->mbox->ibox.box; + ARRAY_TYPE(keyword_indexes) idx_keywords; uint8_t mbox_flags; - mbox_flags = mail->flags & MAIL_FLAGS_NONRECENT; - - if (mail_ctx->dirty) - mbox_flags |= MAIL_INDEX_MAIL_FLAG_DIRTY; - else if (!sync_ctx->delay_writes) + mbox_flags = mail->flags & ~MAIL_RECENT; + if (!sync_ctx->delay_writes) { + /* changes are written to the mbox file */ mbox_flags &= ~MAIL_INDEX_MAIL_FLAG_DIRTY; + } if (rec == NULL) { /* new message */ @@ -343,61 +420,27 @@ mail_ctx->hdr_md5_sum, NULL); } } else { - /* see if we need to update flags in index file. the flags in - sync records are automatically applied to rec->flags at the - end of index syncing, so calculate those new flags first */ - struct mbox_sync_mail idx_mail; - enum mail_index_sync_type sync_type; - - memset(&idx_mail, 0, sizeof(idx_mail)); - idx_mail.flags = rec->flags & ~MAIL_RECENT; - - /* get old keywords */ - t_array_init(&idx_mail.keywords, 32); - mail_index_lookup_keywords(sync_ctx->sync_view, - sync_ctx->idx_seq, - &idx_mail.keywords); - index_sync_changes_apply(sync_ctx->sync_changes, - sync_ctx->mail_keyword_pool, - &idx_mail.flags, &idx_mail.keywords, - &sync_type); - if (sync_type != 0 && box->v.sync_notify != NULL) { - box->v.sync_notify(box, rec->uid, - index_sync_type_convert(sync_type)); - } - - if ((idx_mail.flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) { - /* flags are dirty. ignore whatever was in the mbox, - but update dirty flag state if needed. */ - mbox_flags &= ~MAIL_INDEX_MAIL_FLAG_DIRTY; - mbox_flags |= - idx_mail.flags & ~MAIL_INDEX_MAIL_FLAG_DIRTY; - if (sync_ctx->delay_writes) - mbox_flags |= MAIL_INDEX_MAIL_FLAG_DIRTY; - } - - if ((idx_mail.flags & ~MAIL_INDEX_MAIL_FLAG_DIRTY) != - (mbox_flags & ~MAIL_INDEX_MAIL_FLAG_DIRTY)) { + if ((rec->flags & MAIL_FLAGS_NONRECENT) != + (mbox_flags & MAIL_FLAGS_NONRECENT)) { /* flags other than recent/dirty have changed */ mail_index_update_flags(sync_ctx->t, sync_ctx->idx_seq, MODIFY_REPLACE, mbox_flags); - } else { - if (((idx_mail.flags ^ mbox_flags) & - MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) { - /* dirty flag state changed */ - bool dirty = (mbox_flags & - MAIL_INDEX_MAIL_FLAG_DIRTY) != 0; - mail_index_update_flags(sync_ctx->t, - sync_ctx->idx_seq, - dirty ? MODIFY_ADD : MODIFY_REMOVE, - (enum mail_flags) - MAIL_INDEX_MAIL_FLAG_DIRTY); - } + } else if (((rec->flags ^ mbox_flags) & + MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) { + /* only dirty flag state changed */ + bool dirty; + + dirty = (mbox_flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0; + mail_index_update_flags(sync_ctx->t, sync_ctx->idx_seq, + dirty ? MODIFY_ADD : MODIFY_REMOVE, + (enum mail_flags)MAIL_INDEX_MAIL_FLAG_DIRTY); } - if ((idx_mail.flags & MAIL_INDEX_MAIL_FLAG_DIRTY) == 0 && - !index_keyword_array_cmp(&idx_mail.keywords, - &mail_ctx->mail.keywords)) + /* see if keywords changed */ + t_array_init(&idx_keywords, 32); + mail_index_lookup_keywords(sync_ctx->sync_view, + sync_ctx->idx_seq, &idx_keywords); + if (!index_keyword_array_cmp(&idx_keywords, &mail->keywords)) mbox_sync_update_index_keywords(mail_ctx); /* see if we need to update md5 sum. */ @@ -622,8 +665,7 @@ mail_ctx->mail.from_offset = orig_from_offset; } } - } else if (mail_ctx->need_rewrite || - index_sync_changes_have(sync_ctx->sync_changes)) { + } else if (mail_ctx->need_rewrite) { mbox_sync_update_header(mail_ctx); if (sync_ctx->delay_writes) { /* mark it dirty and do it later */ @@ -1056,6 +1098,9 @@ mail_ctx->mail.idx_seq = sync_ctx->idx_seq; if (!expunged) { + if (!mail_ctx->mail.pseudo) T_BEGIN { + mbox_sync_update_flags(mail_ctx, rec); + } T_END; if (mbox_sync_handle_header(mail_ctx) < 0) return -1; sync_ctx->dest_first_mail = FALSE; @@ -1064,11 +1109,9 @@ } if (!mail_ctx->mail.pseudo) { - if (!expunged) { - T_BEGIN { - mbox_sync_update_index(mail_ctx, rec); - } T_END; - } + if (!expunged) T_BEGIN { + mbox_sync_update_index(mail_ctx, rec); + } T_END; sync_ctx->idx_seq++; }