bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen#include "lib.h"
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen#include "mbox-storage.h"
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen#include "mbox-sync-private.h"
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainenstatic unsigned int
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainenmbox_list_get_ext_id(struct mbox_mailbox *mbox,
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen struct mail_index_view *view)
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen{
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen if (mbox->mbox_list_index_ext_id == (uint32_t)-1) {
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen mbox->mbox_list_index_ext_id =
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen mail_index_ext_register(mail_index_view_get_index(view),
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen "mbox", 0,
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen sizeof(struct mbox_list_index_record),
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen sizeof(uint32_t));
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen }
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen return mbox->mbox_list_index_ext_id;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen}
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainenint mbox_list_index_has_changed(struct mailbox *box,
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen struct mail_index_view *list_view,
aa47c9bd1d1fc70cd699c49fd1ca92dbc7615953Timo Sirainen uint32_t seq, bool quick)
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen{
c150beda11da6fbbb1a936829550945d5e884f68Josef 'Jeff' Sipek struct mbox_mailbox *mbox = MBOX_MAILBOX(box);
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen const struct mbox_list_index_record *rec;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen const void *data;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen const char *path;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen struct stat st;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen uint32_t ext_id;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen bool expunged;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen int ret;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen
aa47c9bd1d1fc70cd699c49fd1ca92dbc7615953Timo Sirainen ret = index_storage_list_index_has_changed(box, list_view, seq, quick);
53cc097d3f8cd789f3c8fa0dfdd02bcda776230eTimo Sirainen if (ret != 0 || box->storage->set->mailbox_list_index_very_dirty_syncs)
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen return ret;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen ext_id = mbox_list_get_ext_id(mbox, list_view);
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged);
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen rec = data;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen if (rec == NULL || expunged || rec->mtime == 0) {
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen /* doesn't exist or not synced */
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen return 1;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen }
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen ret = mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_MAILBOX, &path);
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen if (ret < 0)
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen return ret;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen i_assert(ret > 0);
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen if (stat(path, &st) < 0) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(box, "stat(%s) failed: %m", path);
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen return -1;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen }
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen if ((time_t)rec->mtime != st.st_mtime ||
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen rec->size != (uint32_t)(st.st_size & 0xffffffffU))
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen return 1;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen return 0;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen}
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainenvoid mbox_list_index_update_sync(struct mailbox *box,
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen struct mail_index_transaction *trans,
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen uint32_t seq)
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen{
c150beda11da6fbbb1a936829550945d5e884f68Josef 'Jeff' Sipek struct mbox_mailbox *mbox = MBOX_MAILBOX(box);
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen struct mail_index_view *list_view;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen const struct mbox_index_header *mhdr = &mbox->mbox_hdr;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen const struct mbox_list_index_record *old_rec;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen struct mbox_list_index_record new_rec;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen const void *data;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen uint32_t ext_id;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen bool expunged;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen index_storage_list_index_update_sync(box, trans, seq);
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen /* get the current record */
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen list_view = mail_index_transaction_get_view(trans);
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen ext_id = mbox_list_get_ext_id(mbox, list_view);
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged);
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen if (expunged)
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen return;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen old_rec = data;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&new_rec);
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen new_rec.mtime = mhdr->sync_mtime;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen new_rec.size = mhdr->sync_size & 0xffffffffU;
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen if (old_rec == NULL ||
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen memcmp(old_rec, &new_rec, sizeof(*old_rec)) != 0)
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen mail_index_update_ext(trans, seq, ext_id, &new_rec, NULL);
fad2e085dbb4cf09cfd99b96f9cd89994f0908beTimo Sirainen}