sdbox-storage.c revision 0a7b04ec6441fdcf083392888b2e30844fc3e86d
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen/* Copyright (c) 2007-2011 Dovecot authors, see the included COPYING file */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "lib.h"
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen#include "master-service.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "mail-index-modseq.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "mail-search-build.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "mailbox-list-private.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "dbox-mail.h"
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen#include "dbox-save.h"
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainen#include "sdbox-file.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "sdbox-sync.h"
18565c69efcd7db003dbf27cf625ed822e889fb1Timo Sirainen#include "sdbox-storage.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenextern struct mail_storage dbox_storage, sdbox_storage;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenextern struct mailbox sdbox_mailbox;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenextern struct dbox_storage_vfuncs sdbox_dbox_storage_vfuncs;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainenstatic struct mail_storage *sdbox_storage_alloc(void)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen{
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen struct sdbox_storage *storage;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen pool_t pool;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen pool = pool_alloconly_create("sdbox storage", 512+256);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen storage = p_new(pool, struct sdbox_storage, 1);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen storage->storage.v = sdbox_dbox_storage_vfuncs;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen storage->storage.storage = sdbox_storage;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen storage->storage.storage.pool = pool;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen return &storage->storage.storage;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen}
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainenstatic struct mailbox *
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainensdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const char *name, enum mailbox_flags flags)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
af1f4b17a92ca7b2661737e65c7849df289d3070Timo Sirainen struct sdbox_mailbox *mbox;
af1f4b17a92ca7b2661737e65c7849df289d3070Timo Sirainen struct index_mailbox_context *ibox;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen pool_t pool;
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen /* dbox can't work without index files */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen flags &= ~MAILBOX_FLAG_NO_INDEX_FILES;
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen pool = pool_alloconly_create("sdbox mailbox", 1024*3);
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen mbox = p_new(pool, struct sdbox_mailbox, 1);
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen mbox->box = sdbox_mailbox;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen mbox->box.pool = pool;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen mbox->box.storage = storage;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen mbox->box.list = list;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen mbox->box.mail_vfuncs = &sdbox_mail_vfuncs;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen index_storage_mailbox_alloc(&mbox->box, name, flags, DBOX_INDEX_PREFIX);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen mail_index_set_fsync_mode(mbox->box.index,
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen storage->set->parsed_fsync_mode,
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen MAIL_INDEX_SYNC_TYPE_APPEND |
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen MAIL_INDEX_SYNC_TYPE_EXPUNGE);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen ibox->save_commit_pre = sdbox_transaction_save_commit_pre;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen ibox->save_commit_post = sdbox_transaction_save_commit_post;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen ibox->save_rollback = sdbox_transaction_save_rollback;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen ibox->index_flags |= MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS |
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen mbox->storage = (struct sdbox_storage *)storage;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen mbox->hdr_ext_id =
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen mail_index_ext_register(mbox->box.index, "dbox-hdr",
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen sizeof(struct sdbox_index_header), 0, 0);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen return &mbox->box;
597dce34068d603fb759b4dff404b34049213e51Timo Sirainen}
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainenint sdbox_read_header(struct sdbox_mailbox *mbox,
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen struct sdbox_index_header *hdr, bool log_error)
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen{
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen struct mail_index_view *view;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen const void *data;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen size_t data_size;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen int ret;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen view = mail_index_view_open(mbox->box.index);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen mail_index_get_header_ext(view, mbox->hdr_ext_id,
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen &data, &data_size);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (data_size < SDBOX_INDEX_HEADER_MIN_SIZE &&
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen (!mbox->box.creating || data_size != 0)) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (log_error) {
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen mail_storage_set_critical(
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen &mbox->storage->storage.storage,
6060b7c8edf8fce73470d0df6a2479b69b01c537Timo Sirainen "sdbox %s: Invalid dbox header size",
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen mbox->box.path);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen }
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen ret = -1;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen } else {
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen memset(hdr, 0, sizeof(*hdr));
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr)));
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen ret = 0;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mail_index_view_close(&view);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen return ret;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenvoid sdbox_update_header(struct sdbox_mailbox *mbox,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct mail_index_transaction *trans,
8000c86be02008b74acc71fa422444dc432e2c01Timo Sirainen const struct mailbox_update *update)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct sdbox_index_header hdr, new_hdr;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (sdbox_read_header(mbox, &hdr, TRUE) < 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen memset(&hdr, 0, sizeof(hdr));
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen new_hdr = hdr;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (update != NULL && !mail_guid_128_is_empty(update->mailbox_guid)) {
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen memcpy(new_hdr.mailbox_guid, update->mailbox_guid,
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen sizeof(new_hdr.mailbox_guid));
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen } else if (mail_guid_128_is_empty(new_hdr.mailbox_guid)) {
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen mail_generate_guid_128(new_hdr.mailbox_guid);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen
8000c86be02008b74acc71fa422444dc432e2c01Timo Sirainen if (memcmp(&hdr, &new_hdr, sizeof(hdr)) != 0) {
8000c86be02008b74acc71fa422444dc432e2c01Timo Sirainen mail_index_update_header_ext(trans, mbox->hdr_ext_id, 0,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen &new_hdr, sizeof(new_hdr));
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainenstatic int sdbox_mailbox_create_indexes(struct mailbox *box,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen const struct mailbox_update *update,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct mail_index_transaction *trans)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen{
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct mail_index_transaction *new_trans = NULL;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen const struct mail_index_header *hdr;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen uint32_t uid_validity, uid_next;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (trans == NULL) {
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen new_trans = mail_index_transaction_begin(box->view, 0);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen trans = new_trans;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen }
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen hdr = mail_index_get_header(box->view);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (update != NULL && update->uid_validity != 0)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen uid_validity = update->uid_validity;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen else if (hdr->uid_validity != 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen uid_validity = hdr->uid_validity;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen else {
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen /* set uidvalidity */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen uid_validity = dbox_get_uidvalidity_next(box->list);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen }
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (hdr->uid_validity != uid_validity) {
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen if (hdr->uid_validity != 0) {
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen /* UIDVALIDITY change requires index to be reset */
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen mail_index_reset(trans);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mail_index_update_header(trans,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen offsetof(struct mail_index_header, uid_validity),
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen &uid_validity, sizeof(uid_validity), TRUE);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen }
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen if (update != NULL && hdr->next_uid < update->min_next_uid) {
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen uid_next = update->min_next_uid;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen mail_index_update_header(trans,
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen offsetof(struct mail_index_header, next_uid),
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen &uid_next, sizeof(uid_next), TRUE);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen }
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen if (update != NULL && update->min_first_recent_uid != 0 &&
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen hdr->first_recent_uid < update->min_first_recent_uid) {
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen uint32_t first_recent_uid = update->min_first_recent_uid;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen mail_index_update_header(trans,
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen offsetof(struct mail_index_header, first_recent_uid),
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen &first_recent_uid, sizeof(first_recent_uid), FALSE);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (update != NULL && update->min_highest_modseq != 0 &&
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mail_index_modseq_get_highest(box->view) <
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen update->min_highest_modseq) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mail_index_modseq_enable(box->index);
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen mail_index_update_highest_modseq(trans,
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen update->min_highest_modseq);
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen }
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen sdbox_update_header(mbox, trans, update);
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if (new_trans != NULL) {
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if (mail_index_transaction_commit(&new_trans) < 0) {
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen mail_storage_set_internal_error(box->storage);
a1808be0774cbcb28fec45341aabf803ec44bae5Timo Sirainen mail_index_reset_error(box->index);
a1808be0774cbcb28fec45341aabf803ec44bae5Timo Sirainen return -1;
a1808be0774cbcb28fec45341aabf803ec44bae5Timo Sirainen }
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen }
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen return 0;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen}
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
c74ea62a27878910e3ca1614ca055d7e2b3b00d5Timo Sirainenstatic const char *
c74ea62a27878910e3ca1614ca055d7e2b3b00d5Timo Sirainensdbox_get_attachment_path_suffix(struct dbox_file *_file)
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen{
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen struct sdbox_file *file = (struct sdbox_file *)_file;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen return t_strdup_printf("-%s-%u",
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen mail_guid_128_to_string(file->mbox->mailbox_guid),
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen file->uid);
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen}
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenvoid sdbox_set_mailbox_corrupted(struct mailbox *box)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct sdbox_index_header hdr;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (sdbox_read_header(mbox, &hdr, TRUE) < 0 || hdr.rebuild_count == 0)
b2ecd50bb98c44816cb07c17aa17fae2b425f941Timo Sirainen mbox->corrupted_rebuild_count = 1;
db7c9201c88e3d9bee10485194ee5b0c67249916Timo Sirainen else
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mbox->corrupted_rebuild_count = hdr.rebuild_count;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic void sdbox_set_file_corrupted(struct dbox_file *_file)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct sdbox_file *file = (struct sdbox_file *)_file;
db7c9201c88e3d9bee10485194ee5b0c67249916Timo Sirainen
18565c69efcd7db003dbf27cf625ed822e889fb1Timo Sirainen sdbox_set_mailbox_corrupted(&file->mbox->box);
18565c69efcd7db003dbf27cf625ed822e889fb1Timo Sirainen}
18565c69efcd7db003dbf27cf625ed822e889fb1Timo Sirainen
185ed0142fbbfb86e7a98519e7c6f11ec00723cdTimo Sirainenstatic int sdbox_mailbox_open(struct mailbox *box)
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen{
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen struct sdbox_index_header hdr;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (dbox_mailbox_open(box) < 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen return -1;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (box->creating) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* wait for mailbox creation to initialize the index */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return 0;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen /* get/generate mailbox guid */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (sdbox_read_header(mbox, &hdr, FALSE) < 0) {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* it's possible that this mailbox is just now being created
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen by another process. lock it first and see if the header is
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen available then. */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct mail_index_sync_ctx *sync_ctx;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct mail_index_view *view;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct mail_index_transaction *trans;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if (mail_index_sync_begin(box->index, &sync_ctx,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen &view, &trans, 0) > 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen (void)mail_index_sync_commit(&sync_ctx);
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (sdbox_read_header(mbox, &hdr, TRUE) < 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen memset(&hdr, 0, sizeof(hdr));
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (mail_guid_128_is_empty(hdr.mailbox_guid)) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* regenerate it */
if (sdbox_mailbox_create_indexes(box, NULL, NULL) < 0 ||
sdbox_read_header(mbox, &hdr, TRUE) < 0)
return -1;
}
memcpy(mbox->mailbox_guid, hdr.mailbox_guid,
sizeof(mbox->mailbox_guid));
return 0;
}
static void sdbox_mailbox_close(struct mailbox *box)
{
struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
if (mbox->corrupted_rebuild_count != 0)
(void)sdbox_sync(mbox, 0);
index_storage_mailbox_close(box);
}
static int sdbox_mailbox_delete(struct mailbox *box)
{
struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
struct mail_search_context *ctx;
struct mailbox_transaction_context *t;
struct mail *mail;
struct mail_search_args *search_args;
struct dbox_file *file;
struct sdbox_file *sfile;
if (!box->opened || mbox->storage->storage.attachment_dir == NULL)
return index_storage_mailbox_delete(box);
/* mark the mailbox deleted to avoid race conditions */
if (mailbox_mark_index_deleted(box, TRUE) < 0)
return -1;
/* ulink all dbox mails and their attachements in the mailbox. */
t = mailbox_transaction_begin(box, 0);
search_args = mail_search_build_init();
mail_search_build_add_all(search_args);
ctx = mailbox_search_init(t, search_args, NULL);
mail_search_args_unref(&search_args);
mail = mail_alloc(t, 0, NULL);
while (mailbox_search_next(ctx, mail)) {
file = sdbox_file_init(mbox, mail->uid);
sfile = (struct sdbox_file *)file;
(void)sdbox_file_unlink_with_attachments(sfile);
dbox_file_unref(&file);
}
mail_free(&mail);
if (mailbox_search_deinit(&ctx) < 0) {
/* maybe we missed some mails. oh well, can't help it. */
}
mailbox_transaction_rollback(&t);
return index_storage_mailbox_delete(box);
}
static int
sdbox_mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE])
{
struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
memcpy(guid, mbox->mailbox_guid, MAIL_GUID_128_SIZE);
return 0;
}
static int
dbox_mailbox_update(struct mailbox *box, const struct mailbox_update *update)
{
if (!box->opened) {
if (mailbox_open(box) < 0)
return -1;
}
if (update->cache_fields != NULL)
index_storage_mailbox_update_cache_fields(box, update);
return sdbox_mailbox_create_indexes(box, update, NULL);
}
struct mail_storage sdbox_storage = {
.name = SDBOX_STORAGE_NAME,
.class_flags = 0,
.v = {
NULL,
sdbox_storage_alloc,
dbox_storage_create,
dbox_storage_destroy,
NULL,
dbox_storage_get_list_settings,
NULL,
sdbox_mailbox_alloc,
NULL
}
};
struct mail_storage dbox_storage = {
.name = "dbox", /* alias */
.class_flags = 0,
.v = {
NULL,
sdbox_storage_alloc,
dbox_storage_create,
dbox_storage_destroy,
NULL,
dbox_storage_get_list_settings,
NULL,
sdbox_mailbox_alloc,
NULL
}
};
struct mailbox sdbox_mailbox = {
.v = {
index_storage_is_readonly,
index_storage_allow_new_keywords,
index_storage_mailbox_enable,
sdbox_mailbox_open,
sdbox_mailbox_close,
index_storage_mailbox_free,
dbox_mailbox_create,
dbox_mailbox_update,
sdbox_mailbox_delete,
index_storage_mailbox_rename,
index_storage_get_status,
sdbox_mailbox_get_guid,
NULL,
NULL,
sdbox_storage_sync_init,
index_mailbox_sync_next,
index_mailbox_sync_deinit,
NULL,
dbox_notify_changes,
index_transaction_begin,
index_transaction_commit,
index_transaction_rollback,
index_transaction_set_max_modseq,
index_keywords_create,
index_keywords_create_from_indexes,
index_keywords_ref,
index_keywords_unref,
index_keyword_is_valid,
index_storage_get_seq_range,
index_storage_get_uid_range,
index_storage_get_expunges,
NULL,
NULL,
NULL,
dbox_mail_alloc,
index_header_lookup_init,
index_header_lookup_deinit,
index_storage_search_init,
index_storage_search_deinit,
index_storage_search_next_nonblock,
index_storage_search_next_update_seq,
sdbox_save_alloc,
sdbox_save_begin,
dbox_save_continue,
sdbox_save_finish,
sdbox_save_cancel,
sdbox_copy,
NULL,
index_storage_is_inconsistent
}
};
struct dbox_storage_vfuncs sdbox_dbox_storage_vfuncs = {
sdbox_file_free,
sdbox_file_create_fd,
sdbox_mail_open,
sdbox_mailbox_create_indexes,
sdbox_get_attachment_path_suffix,
sdbox_set_mailbox_corrupted,
sdbox_set_file_corrupted
};