From: Timo Sirainen Date: Sat, 21 Sep 2013 23:07:16 +0000 (+0300) Subject: mbox: Fixed mailbox_list_index=yes to work with non-Dovecot mbox changes. X-Git-Tag: 2.2.6~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fad2e085dbb4cf09cfd99b96f9cd89994f0908be;p=thirdparty%2Fdovecot%2Fcore.git mbox: Fixed mailbox_list_index=yes to work with non-Dovecot mbox changes. --- diff --git a/src/lib-storage/index/mbox/Makefile.am b/src/lib-storage/index/mbox/Makefile.am index c3e3fd509b..4165a20b32 100644 --- a/src/lib-storage/index/mbox/Makefile.am +++ b/src/lib-storage/index/mbox/Makefile.am @@ -19,6 +19,7 @@ libstorage_mbox_la_SOURCES = \ mbox-md5-all.c \ mbox-save.c \ mbox-settings.c \ + mbox-sync-list-index.c \ mbox-sync-parse.c \ mbox-sync-rewrite.c \ mbox-sync-update.c \ diff --git a/src/lib-storage/index/mbox/mbox-storage.c b/src/lib-storage/index/mbox/mbox-storage.c index 8fd1e8f04b..0d4195182f 100644 --- a/src/lib-storage/index/mbox/mbox-storage.c +++ b/src/lib-storage/index/mbox/mbox-storage.c @@ -379,6 +379,7 @@ mbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list, mbox->storage = (struct mbox_storage *)storage; mbox->mbox_fd = -1; mbox->mbox_lock_type = F_UNLCK; + mbox->mbox_list_index_ext_id = (uint32_t)-1; if (strcmp(mbox->storage->set->mbox_md5, "apop3d") == 0) mbox->md5_v = mbox_md5_apop3d; @@ -836,8 +837,8 @@ struct mailbox mbox_mailbox = { index_storage_attribute_iter_init, index_storage_attribute_iter_next, index_storage_attribute_iter_deinit, - index_storage_list_index_has_changed, - index_storage_list_index_update_sync, + mbox_list_index_has_changed, + mbox_list_index_update_sync, mbox_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit, diff --git a/src/lib-storage/index/mbox/mbox-storage.h b/src/lib-storage/index/mbox/mbox-storage.h index 35dd3553ef..2e69814cc4 100644 --- a/src/lib-storage/index/mbox/mbox-storage.h +++ b/src/lib-storage/index/mbox/mbox-storage.h @@ -22,6 +22,12 @@ struct mbox_index_header { uint8_t unused[3]; guid_128_t mailbox_guid; }; + +struct mbox_list_index_record { + uint32_t mtime; + uint32_t size; +}; + struct mbox_storage { struct mail_storage storage; @@ -47,7 +53,7 @@ struct mbox_mailbox { bool mbox_writeonly; unsigned int external_transactions; - uint32_t mbox_ext_idx, md5hdr_ext_idx; + uint32_t mbox_ext_idx, md5hdr_ext_idx, mbox_list_index_ext_id; struct mbox_index_header mbox_hdr; const struct mailbox_update *sync_hdr_update; diff --git a/src/lib-storage/index/mbox/mbox-sync-list-index.c b/src/lib-storage/index/mbox/mbox-sync-list-index.c new file mode 100644 index 0000000000..80e9b9d9a2 --- /dev/null +++ b/src/lib-storage/index/mbox/mbox-sync-list-index.c @@ -0,0 +1,93 @@ +/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "mbox-storage.h" +#include "mbox-sync-private.h" + +static unsigned int +mbox_list_get_ext_id(struct mbox_mailbox *mbox, + struct mail_index_view *view) +{ + if (mbox->mbox_list_index_ext_id == (uint32_t)-1) { + mbox->mbox_list_index_ext_id = + mail_index_ext_register(mail_index_view_get_index(view), + "mbox", 0, + sizeof(struct mbox_list_index_record), + sizeof(uint32_t)); + } + return mbox->mbox_list_index_ext_id; +} + +int mbox_list_index_has_changed(struct mailbox *box, + struct mail_index_view *list_view, + uint32_t seq) +{ + struct mbox_mailbox *mbox = (struct mbox_mailbox *)box; + const struct mbox_list_index_record *rec; + const void *data; + const char *path; + struct stat st; + uint32_t ext_id; + bool expunged; + int ret; + + ret = index_storage_list_index_has_changed(box, list_view, seq); + if (ret != 0) + return ret; + + ext_id = mbox_list_get_ext_id(mbox, list_view); + mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged); + rec = data; + + if (rec == NULL || expunged || rec->mtime == 0) { + /* doesn't exist or not synced */ + return 1; + } + + ret = mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_MAILBOX, &path); + if (ret < 0) + return ret; + i_assert(ret > 0); + + if (stat(path, &st) < 0) { + mail_storage_set_critical(box->storage, + "stat(%s) failed: %m", path); + return -1; + } + if ((time_t)rec->mtime != st.st_mtime || + rec->size != (uint32_t)(st.st_size & 0xffffffffU)) + return 1; + return 0; +} + +void mbox_list_index_update_sync(struct mailbox *box, + struct mail_index_transaction *trans, + uint32_t seq) +{ + struct mbox_mailbox *mbox = (struct mbox_mailbox *)box; + struct mail_index_view *list_view; + const struct mbox_index_header *mhdr = &mbox->mbox_hdr; + const struct mbox_list_index_record *old_rec; + struct mbox_list_index_record new_rec; + const void *data; + uint32_t ext_id; + bool expunged; + + index_storage_list_index_update_sync(box, trans, seq); + + /* get the current record */ + list_view = mail_index_transaction_get_view(trans); + ext_id = mbox_list_get_ext_id(mbox, list_view); + mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged); + if (expunged) + return; + old_rec = data; + + memset(&new_rec, 0, sizeof(new_rec)); + new_rec.mtime = mhdr->sync_mtime; + new_rec.size = mhdr->sync_size & 0xffffffffU; + + if (old_rec == NULL || + memcmp(old_rec, &new_rec, sizeof(*old_rec)) != 0) + mail_index_update_ext(trans, seq, ext_id, &new_rec, NULL); +} diff --git a/src/lib-storage/index/mbox/mbox-sync-private.h b/src/lib-storage/index/mbox/mbox-sync-private.h index 4c56c9038e..43fcd30b06 100644 --- a/src/lib-storage/index/mbox/mbox-sync-private.h +++ b/src/lib-storage/index/mbox/mbox-sync-private.h @@ -183,4 +183,11 @@ void mbox_sync_headers_add_space(struct mbox_sync_mail_context *ctx, size_t size); int mbox_sync_get_guid(struct mbox_mailbox *mbox); +int mbox_list_index_has_changed(struct mailbox *box, + struct mail_index_view *list_view, + uint32_t seq); +void mbox_list_index_update_sync(struct mailbox *box, + struct mail_index_transaction *trans, + uint32_t seq); + #endif