]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
mbox: Fixed mailbox_list_index=yes to work with non-Dovecot mbox changes.
authorTimo Sirainen <tss@iki.fi>
Sat, 21 Sep 2013 23:07:16 +0000 (02:07 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 21 Sep 2013 23:07:16 +0000 (02:07 +0300)
src/lib-storage/index/mbox/Makefile.am
src/lib-storage/index/mbox/mbox-storage.c
src/lib-storage/index/mbox/mbox-storage.h
src/lib-storage/index/mbox/mbox-sync-list-index.c [new file with mode: 0644]
src/lib-storage/index/mbox/mbox-sync-private.h

index c3e3fd509b160c4840daa517680f29ed286d21db..4165a20b3280db4a894e789c76427ecf2ea44161 100644 (file)
@@ -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 \
index 8fd1e8f04bdc03e892a98353ef581b1d32459a18..0d4195182f0043eeb7f7294187a7c33c102de49b 100644 (file)
@@ -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,
index 35dd3553efd93b2707dbaa9df08de95b194118a5..2e69814cc49392886e32bed3ea744ae5af9f9a43 100644 (file)
@@ -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 (file)
index 0000000..80e9b9d
--- /dev/null
@@ -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);
+}
index 4c56c9038ea1f3a8b0e2330c506a351e50f276b1..43fcd30b06037f4a812e2a680622b6d6b8ff1bc6 100644 (file)
@@ -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