Mercurial > dovecot > original-hg > dovecot-1.2
changeset 5562:24b751bc0995 HEAD
Added sync_notify() callback to struct mail_storage. It's now called for
expunges and flag/keyword changes (except with cydir).
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 17 Apr 2007 15:41:26 +0300 |
parents | ead3e882c9c9 |
children | 063b184597fa |
files | src/lib-storage/index/cydir/cydir-storage.c src/lib-storage/index/cydir/cydir-sync.c src/lib-storage/index/cydir/cydir-sync.h src/lib-storage/index/dbox/dbox-storage.c src/lib-storage/index/dbox/dbox-sync-expunge.c src/lib-storage/index/dbox/dbox-sync.c src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/maildir/maildir-sync.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/index/mbox/mbox-sync-private.h src/lib-storage/index/mbox/mbox-sync-update.c src/lib-storage/index/mbox/mbox-sync.c src/lib-storage/mail-storage-private.h |
diffstat | 13 files changed, 134 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/cydir/cydir-storage.c Tue Apr 17 15:40:39 2007 +0300 +++ b/src/lib-storage/index/cydir/cydir-storage.c Tue Apr 17 15:41:26 2007 +0300 @@ -453,6 +453,7 @@ cydir_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit, + NULL, cydir_notify_changes, index_transaction_begin, index_transaction_commit,
--- a/src/lib-storage/index/cydir/cydir-sync.c Tue Apr 17 15:40:39 2007 +0300 +++ b/src/lib-storage/index/cydir/cydir-sync.c Tue Apr 17 15:41:26 2007 +0300 @@ -27,7 +27,7 @@ static string_t *cydir_get_path_prefix(struct cydir_mailbox *mbox) { - string_t *path = t_str_new(256); + string_t *path = str_new(default_pool, 256); const char *dir; dir = mailbox_list_get_path(mbox->storage->storage.list, @@ -38,13 +38,44 @@ return path; } +static int +cydir_sync_expunge(struct cydir_sync_context *ctx, uint32_t seq1, uint32_t seq2) +{ + struct mailbox *box = &ctx->mbox->ibox.box; + uint32_t uid; + + if (ctx->path == NULL) { + ctx->path = cydir_get_path_prefix(ctx->mbox); + ctx->path_dir_prefix_len = str_len(ctx->path); + } + + for (; seq1 <= seq2; seq1++) { + if (mail_index_lookup_uid(ctx->sync_view, seq1, &uid) < 0) { + mail_storage_set_index_error(&ctx->mbox->ibox); + return -1; + } + + str_truncate(ctx->path, ctx->path_dir_prefix_len); + str_printfa(ctx->path, "%u.", uid); + if (unlink(str_c(ctx->path)) == 0) { + if (box->v.sync_notify != NULL) { + box->v.sync_notify(box, uid, + MAILBOX_SYNC_TYPE_EXPUNGE); + } + } else if (errno != ENOENT) { + mail_storage_set_critical(&ctx->mbox->storage->storage, + "unlink(%s) failed: %m", str_c(ctx->path)); + /* continue anyway */ + } + } + return 0; +} + static int cydir_sync_index(struct cydir_sync_context *ctx) { const struct mail_index_header *hdr; struct mail_index_sync_rec sync_rec; - string_t *path = NULL; - unsigned int prefix_len = 0; - uint32_t seq1, seq2, uid; + uint32_t seq1, seq2; int ret; hdr = mail_index_get_header(ctx->sync_view); @@ -53,12 +84,8 @@ return -1; } - /* unlink expunged messages */ while ((ret = mail_index_sync_next(ctx->index_sync_ctx, &sync_rec)) > 0) { - if (sync_rec.type != MAIL_INDEX_SYNC_TYPE_EXPUNGE) - continue; - if (mail_index_lookup_uid_range(ctx->sync_view, sync_rec.uid1, sync_rec.uid2, &seq1, &seq2) < 0) { @@ -66,30 +93,24 @@ return -1; } if (seq1 == 0) { - /* already expunged everything. nothing to do. */ + /* already expunged, nothing to do. */ continue; } - if (path == NULL) { - path = cydir_get_path_prefix(ctx->mbox); - prefix_len = str_len(path); - } - - for (; seq1 <= seq2; seq1++) { - if (mail_index_lookup_uid(ctx->sync_view, seq1, - &uid) < 0) { - mail_storage_set_index_error(&ctx->mbox->ibox); + switch (sync_rec.type) { + case MAIL_INDEX_SYNC_TYPE_APPEND: + /* don't care */ + break; + case MAIL_INDEX_SYNC_TYPE_EXPUNGE: + if (cydir_sync_expunge(ctx, seq1, seq2) < 0) return -1; - } - - str_truncate(path, prefix_len); - str_printfa(path, "%u.", uid); - if (unlink(str_c(path)) < 0 && errno != ENOENT) { - mail_storage_set_critical( - &ctx->mbox->storage->storage, - "unlink(%s) failed: %m", str_c(path)); - /* continue anyway */ - } + break; + case MAIL_INDEX_SYNC_TYPE_FLAGS: + case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD: + case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE: + case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET: + /* FIXME: should be bother calling sync_notify()? */ + break; } } return 0; @@ -137,6 +158,8 @@ } else { mail_index_sync_rollback(&ctx->index_sync_ctx); } + if (ctx->path != NULL) + str_free(&ctx->path); i_free(ctx); return 0; }
--- a/src/lib-storage/index/cydir/cydir-sync.h Tue Apr 17 15:40:39 2007 +0300 +++ b/src/lib-storage/index/cydir/cydir-sync.h Tue Apr 17 15:41:26 2007 +0300 @@ -8,6 +8,9 @@ struct cydir_mailbox *mbox; struct mail_index_sync_ctx *index_sync_ctx; struct mail_index_view *sync_view; + + string_t *path; + unsigned int path_dir_prefix_len; }; int cydir_sync_begin(struct cydir_mailbox *mbox,
--- a/src/lib-storage/index/dbox/dbox-storage.c Tue Apr 17 15:40:39 2007 +0300 +++ b/src/lib-storage/index/dbox/dbox-storage.c Tue Apr 17 15:41:26 2007 +0300 @@ -595,6 +595,7 @@ dbox_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit, + NULL, dbox_notify_changes, index_transaction_begin, index_transaction_commit,
--- a/src/lib-storage/index/dbox/dbox-sync-expunge.c Tue Apr 17 15:40:39 2007 +0300 +++ b/src/lib-storage/index/dbox/dbox-sync-expunge.c Tue Apr 17 15:41:26 2007 +0300 @@ -35,8 +35,10 @@ const struct dbox_sync_file_entry *sync_entry, unsigned int *sync_idx, uint32_t *uid1_r, uint32_t *uid2_r) { + struct mailbox *box = &ctx->mbox->ibox.box; const struct dbox_sync_rec *sync_recs; unsigned int count; + uint32_t uid; sync_recs = array_get(&sync_entry->sync_recs, &count); @@ -49,6 +51,15 @@ if (dbox_sync_rec_get_uids(ctx, &sync_recs[*sync_idx], uid1_r, uid2_r) < 0) return -1; + + if (box->v.sync_notify != NULL) { + /* all of the UIDs uid1..uid2 should exist */ + for (uid = *uid1_r; uid <= *uid2_r; uid++) { + box->v.sync_notify(box, uid, + MAILBOX_SYNC_TYPE_EXPUNGE); + } + } + return 1; }
--- a/src/lib-storage/index/dbox/dbox-sync.c Tue Apr 17 15:40:39 2007 +0300 +++ b/src/lib-storage/index/dbox/dbox-sync.c Tue Apr 17 15:41:26 2007 +0300 @@ -155,6 +155,8 @@ const unsigned char *array, const unsigned char *mask) { struct dbox_mailbox *mbox = ctx->mbox; + struct mailbox *box = &mbox->ibox.box; + enum mailbox_sync_type sync_type; uint32_t file_seq, uid2; uoff_t offset; unsigned int i, start; @@ -172,7 +174,27 @@ if ((ret = dbox_file_seek(mbox, file_seq, offset, FALSE)) <= 0) return ret; + switch (sync_rec->type) { + case MAIL_INDEX_SYNC_TYPE_EXPUNGE: + sync_type = MAILBOX_SYNC_TYPE_EXPUNGE; + break; + case MAIL_INDEX_SYNC_TYPE_FLAGS: + sync_type = MAILBOX_SYNC_TYPE_FLAGS; + break; + case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD: + case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE: + case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET: + sync_type = MAILBOX_SYNC_TYPE_KEYWORDS; + break; + default: + sync_type = 0; + i_unreached(); + } while (mbox->file->seeked_uid <= uid2) { + if (box->v.sync_notify != NULL) { + box->v.sync_notify(box, mbox->file->seeked_uid, + sync_type); + } for (i = 0; i < flag_count; ) { if (!mask[i]) { i++;
--- a/src/lib-storage/index/maildir/maildir-storage.c Tue Apr 17 15:40:39 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.c Tue Apr 17 15:41:26 2007 +0300 @@ -1055,6 +1055,7 @@ maildir_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit, + NULL, maildir_notify_changes, index_transaction_begin, index_transaction_commit,
--- a/src/lib-storage/index/maildir/maildir-sync.c Tue Apr 17 15:40:39 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync.c Tue Apr 17 15:41:26 2007 +0300 @@ -232,7 +232,7 @@ struct mail_index_transaction *trans; ARRAY_DEFINE(sync_recs, struct mail_index_sync_rec); - uint32_t seq; + uint32_t seq, uid; int dirty_state; }; @@ -397,9 +397,15 @@ } static int maildir_expunge(struct maildir_mailbox *mbox, const char *path, - void *context __attr_unused__) + struct maildir_index_sync_context *ctx) { + struct mailbox *box = &mbox->ibox.box; + if (unlink(path) == 0) { + if (box->v.sync_notify != NULL) { + box->v.sync_notify(box, ctx->uid, + MAILBOX_SYNC_TYPE_EXPUNGE); + } mbox->dirty_cur_time = ioloop_time; return 1; } @@ -414,9 +420,11 @@ static int maildir_sync_flags(struct maildir_mailbox *mbox, const char *path, struct maildir_index_sync_context *ctx) { + struct mailbox *box = &mbox->ibox.box; const struct mail_index_sync_rec *recs; const char *dir, *fname, *newfname, *newpath; enum mail_flags flags; + enum mailbox_sync_type sync_type = 0; ARRAY_TYPE(keyword_indexes) keywords; unsigned int i, count; uint8_t flags8; @@ -441,11 +449,13 @@ switch (recs[i].type) { case MAIL_INDEX_SYNC_TYPE_FLAGS: mail_index_sync_flags_apply(&recs[i], &flags8); + sync_type |= MAILBOX_SYNC_TYPE_FLAGS; break; case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD: case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE: case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET: mail_index_sync_keywords_apply(&recs[i], &keywords); + sync_type |= MAILBOX_SYNC_TYPE_KEYWORDS; break; case MAIL_INDEX_SYNC_TYPE_APPEND: case MAIL_INDEX_SYNC_TYPE_EXPUNGE: @@ -453,12 +463,15 @@ break; } } - + i_assert(sync_type != 0); newfname = maildir_filename_set_flags(ctx->keywords_sync_ctx, fname, flags8, &keywords); newpath = t_strconcat(dir, newfname, NULL); if (rename(path, newpath) == 0) { + if (box->v.sync_notify != NULL) + box->v.sync_notify(box, ctx->uid, sync_type); + if ((flags8 & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) ctx->dirty_state = -1; mbox->dirty_cur_time = ioloop_time; @@ -556,6 +569,7 @@ } ctx->seq = seq; + ctx->uid = uid; if (expunged) { maildir_sync_check_timeouts(ctx->maildir_sync_ctx, TRUE);
--- a/src/lib-storage/index/mbox/mbox-storage.c Tue Apr 17 15:40:39 2007 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.c Tue Apr 17 15:41:26 2007 +0300 @@ -998,6 +998,7 @@ mbox_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit, + NULL, mbox_notify_changes, index_transaction_begin, index_transaction_commit,
--- a/src/lib-storage/index/mbox/mbox-sync-private.h Tue Apr 17 15:40:39 2007 +0300 +++ b/src/lib-storage/index/mbox/mbox-sync-private.h Tue Apr 17 15:41:26 2007 +0300 @@ -165,7 +165,7 @@ void mbox_sync_apply_index_syncs(struct mbox_sync_context *sync_ctx, struct mbox_sync_mail *mail, - bool *keywords_changed_r); + enum mailbox_sync_type *sync_type_r); int mbox_sync_seek(struct mbox_sync_context *sync_ctx, uoff_t from_offset); void mbox_sync_file_update_ext_modified(struct mbox_sync_context *sync_ctx); void mbox_sync_file_updated(struct mbox_sync_context *sync_ctx, bool dirty);
--- a/src/lib-storage/index/mbox/mbox-sync-update.c Tue Apr 17 15:40:39 2007 +0300 +++ b/src/lib-storage/index/mbox/mbox-sync-update.c Tue Apr 17 15:41:26 2007 +0300 @@ -382,7 +382,7 @@ void mbox_sync_update_header(struct mbox_sync_mail_context *ctx) { uint8_t old_flags; - bool keywords_changed; + enum mailbox_sync_type sync_type; i_assert(ctx->mail.uid != 0 || ctx->mail.pseudo); @@ -390,12 +390,12 @@ if (array_count(&ctx->sync_ctx->syncs) > 0) { mbox_sync_apply_index_syncs(ctx->sync_ctx, &ctx->mail, - &keywords_changed); + &sync_type); if ((old_flags & XSTATUS_FLAGS_MASK) != (ctx->mail.flags & XSTATUS_FLAGS_MASK)) mbox_sync_update_xstatus(ctx); - if (keywords_changed) + if ((sync_type & MAILBOX_SYNC_TYPE_KEYWORDS) != 0) mbox_sync_update_xkeywords(ctx); }
--- a/src/lib-storage/index/mbox/mbox-sync.c Tue Apr 17 15:40:39 2007 +0300 +++ b/src/lib-storage/index/mbox/mbox-sync.c Tue Apr 17 15:41:26 2007 +0300 @@ -284,18 +284,18 @@ void mbox_sync_apply_index_syncs(struct mbox_sync_context *sync_ctx, struct mbox_sync_mail *mail, - bool *keywords_changed_r) + enum mailbox_sync_type *sync_type_r) { const struct mail_index_sync_rec *syncs; unsigned int i, count; - - *keywords_changed_r = FALSE; + enum mailbox_sync_type sync_type = 0; syncs = array_get(&sync_ctx->syncs, &count); for (i = 0; i < count; i++) { switch (syncs[i].type) { case MAIL_INDEX_SYNC_TYPE_FLAGS: mail_index_sync_flags_apply(&syncs[i], &mail->flags); + sync_type |= MAILBOX_SYNC_TYPE_FLAGS; break; case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD: case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE: @@ -313,12 +313,14 @@ } if (mail_index_sync_keywords_apply(&syncs[i], &mail->keywords)) - *keywords_changed_r = TRUE; + sync_type |= MAILBOX_SYNC_TYPE_KEYWORDS; break; default: break; } } + + *sync_type_r = sync_type; } static int @@ -481,8 +483,9 @@ static int 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_context *sync_ctx = mail_ctx->sync_ctx; struct mbox_sync_mail *mail = &mail_ctx->mail; + struct mailbox *box = &sync_ctx->mbox->ibox.box; uint8_t mbox_flags; mbox_flags = mail->flags & MAIL_FLAGS_MASK; @@ -509,7 +512,7 @@ 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; - bool keywords_changed; + enum mailbox_sync_type sync_type; memset(&idx_mail, 0, sizeof(idx_mail)); idx_mail.flags = rec->flags; @@ -525,7 +528,9 @@ return -1; } mbox_sync_apply_index_syncs(sync_ctx, &idx_mail, - &keywords_changed); + &sync_type); + if (sync_type != 0 && box->v.sync_notify != NULL) + box->v.sync_notify(box, rec->uid, sync_type); #define SYNC_FLAGS (MAIL_RECENT | MAIL_INDEX_MAIL_FLAG_DIRTY) if ((idx_mail.flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) { @@ -720,6 +725,12 @@ static void mbox_sync_handle_expunge(struct mbox_sync_mail_context *mail_ctx) { struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx; + struct mailbox *box = &sync_ctx->mbox->ibox.box; + + if (box->v.sync_notify != NULL) { + box->v.sync_notify(box, mail_ctx->mail.uid, + MAILBOX_SYNC_TYPE_EXPUNGE); + } mail_ctx->mail.expunged = TRUE; mail_ctx->mail.offset = mail_ctx->mail.from_offset; @@ -727,6 +738,7 @@ mail_ctx->body_offset - mail_ctx->mail.from_offset + mail_ctx->mail.body_size; mail_ctx->mail.body_size = 0; + mail_ctx->mail.uid = 0; if (sync_ctx->seq == 1) { /* expunging first message, fix space to contain next @@ -1210,7 +1222,6 @@ return -1; sync_ctx->dest_first_mail = FALSE; } else { - mail_ctx->mail.uid = 0; mbox_sync_handle_expunge(mail_ctx); }
--- a/src/lib-storage/mail-storage-private.h Tue Apr 17 15:40:39 2007 +0300 +++ b/src/lib-storage/mail-storage-private.h Tue Apr 17 15:41:26 2007 +0300 @@ -91,6 +91,9 @@ enum mailbox_status_items status_items, struct mailbox_status *status_r); + void (*sync_notify)(struct mailbox *box, uint32_t uid, + enum mailbox_sync_type sync_type); + void (*notify_changes)(struct mailbox *box); struct mailbox_transaction_context *