mbox-sync-list-index.c revision 53cc097d3f8cd789f3c8fa0dfdd02bcda776230e
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2013-2014 Dovecot authors, see the included COPYING file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "lib.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mbox-storage.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mbox-sync-private.h"
dfa2201c6ac8ddb2d2798dee15662cfe774e644eMartti Rannanjärvi
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainenstatic unsigned int
f7423cbbd9dea363a5df18ebb96da055a977ae79Timo Sirainenmbox_list_get_ext_id(struct mbox_mailbox *mbox,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_index_view *view)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen if (mbox->mbox_list_index_ext_id == (uint32_t)-1) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mbox->mbox_list_index_ext_id =
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_index_ext_register(mail_index_view_get_index(view),
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen "mbox", 0,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen sizeof(struct mbox_list_index_record),
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen sizeof(uint32_t));
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen }
5a6343181a5183b1ae1c39d40fc5a1deb3b840d9Timo Sirainen return mbox->mbox_list_index_ext_id;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenint mbox_list_index_has_changed(struct mailbox *box,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_index_view *list_view,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen uint32_t seq)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const struct mbox_list_index_record *rec;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const void *data;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *path;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct stat st;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen uint32_t ext_id;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen bool expunged;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen int ret;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = index_storage_list_index_has_changed(box, list_view, seq);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (ret != 0 || box->storage->set->mailbox_list_index_very_dirty_syncs)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen return ret;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ext_id = mbox_list_get_ext_id(mbox, list_view);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen rec = data;
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen if (rec == NULL || expunged || rec->mtime == 0) {
4d4d6d4745682790c20d759ba93dbea46b812c5dTimo Sirainen /* doesn't exist or not synced */
4d4d6d4745682790c20d759ba93dbea46b812c5dTimo Sirainen return 1;
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainen ret = mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_MAILBOX, &path);
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainen if (ret < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return ret;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_assert(ret > 0);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
104318260228780a5c6b3181b3401e8e504e2776Timo Sirainen if (stat(path, &st) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_storage_set_critical(box->storage,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "stat(%s) failed: %m", path);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if ((time_t)rec->mtime != st.st_mtime ||
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rec->size != (uint32_t)(st.st_size & 0xffffffffU))
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen return 1;
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid mbox_list_index_update_sync(struct mailbox *box,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_index_transaction *trans,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen uint32_t seq)
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainen{
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainen struct mail_index_view *list_view;
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainen const struct mbox_index_header *mhdr = &mbox->mbox_hdr;
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen const struct mbox_list_index_record *old_rec;
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen struct mbox_list_index_record new_rec;
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen const void *data;
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen uint32_t ext_id;
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen bool expunged;
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen index_storage_list_index_update_sync(box, trans, seq);
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainen
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainen /* get the current record */
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainen list_view = mail_index_transaction_get_view(trans);
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainen ext_id = mbox_list_get_ext_id(mbox, list_view);
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged);
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainen if (expunged)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return;
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen old_rec = data;
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen memset(&new_rec, 0, sizeof(new_rec));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen new_rec.mtime = mhdr->sync_mtime;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen new_rec.size = mhdr->sync_size & 0xffffffffU;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (old_rec == NULL ||
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen memcmp(old_rec, &new_rec, sizeof(*old_rec)) != 0)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen mail_index_update_ext(trans, seq, ext_id, &new_rec, NULL);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen}
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen