sdbox-storage.c revision 7bafda1813454621e03615e83d55bccfa7cc56bd
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "lib.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "array.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "ioloop.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "hex-binary.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "randgen.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "mkdir-parents.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "unlink-directory.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "unlink-old-files.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "index-mail.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "mail-index-modseq.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "mailbox-uidvalidity.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "dbox-mail.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "dbox-save.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "sdbox-file.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "sdbox-sync.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "sdbox-storage.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include <stdio.h>
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include <unistd.h>
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include <sys/stat.h>
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define SDBOX_LIST_CONTEXT(obj) \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen MODULE_CONTEXT(obj, sdbox_mailbox_list_module)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct sdbox_mailbox_list {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen union mailbox_list_module_context module_ctx;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen};
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenextern struct mail_storage dbox_storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenextern struct mailbox sdbox_mailbox;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenextern struct dbox_storage_vfuncs sdbox_dbox_storage_vfuncs;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(sdbox_mailbox_list_module,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen &mailbox_list_module_register);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic struct mail_storage *sdbox_storage_alloc(void)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_storage *storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pool_t pool;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pool = pool_alloconly_create("dbox storage", 512+256);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage = p_new(pool, struct sdbox_storage, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage->storage.v = sdbox_dbox_storage_vfuncs;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage->storage.storage = dbox_storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage->storage.storage.pool = pool;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return &storage->storage.storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct mailbox *
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainensdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *name, struct istream *input,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen enum mailbox_flags flags)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_mailbox *mbox;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pool_t pool;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* dbox can't work without index files */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen flags &= ~MAILBOX_FLAG_NO_INDEX_FILES;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pool = pool_alloconly_create("dbox mailbox", 1024+512);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox = p_new(pool, struct sdbox_mailbox, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.box = sdbox_mailbox;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.box.pool = pool;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.box.storage = storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.box.list = list;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.mail_vfuncs = &sdbox_mail_vfuncs;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.save_commit_pre = sdbox_transaction_save_commit_pre;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.save_commit_post = sdbox_transaction_save_commit_post;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.save_rollback = sdbox_transaction_save_rollback;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen DBOX_INDEX_PREFIX);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_set_fsync_types(mbox->ibox.index,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen MAIL_INDEX_SYNC_TYPE_APPEND |
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen MAIL_INDEX_SYNC_TYPE_EXPUNGE);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.index_flags |= MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS |
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->storage = (struct sdbox_storage *)storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->alt_path =
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen p_strconcat(pool, list->set.alt_dir, "/",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen list->set.maildir_name, NULL);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->hdr_ext_id =
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_ext_register(mbox->ibox.index, "dbox-hdr",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sizeof(struct sdbox_index_header), 0, 0);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return &mbox->ibox.box;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint sdbox_read_header(struct sdbox_mailbox *mbox,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_index_header *hdr)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const void *data;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen size_t data_size;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_get_header_ext(mbox->ibox.view, mbox->hdr_ext_id,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen &data, &data_size);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (data_size < SDBOX_INDEX_HEADER_MIN_SIZE &&
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (!mbox->creating || data_size != 0)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_storage_set_critical(&mbox->storage->storage.storage,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "dbox %s: Invalid dbox header size",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.box.path);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memset(hdr, 0, sizeof(*hdr));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr)));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid sdbox_update_header(struct sdbox_mailbox *mbox,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_index_transaction *trans,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const struct mailbox_update *update)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_index_header hdr, new_hdr;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (sdbox_read_header(mbox, &hdr) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memset(&hdr, 0, sizeof(hdr));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen new_hdr = hdr;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (update != NULL && !mail_guid_128_is_empty(update->mailbox_guid)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memcpy(new_hdr.mailbox_guid, update->mailbox_guid,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sizeof(new_hdr.mailbox_guid));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen } else if (mail_guid_128_is_empty(new_hdr.mailbox_guid)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_generate_guid_128(new_hdr.mailbox_guid);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (memcmp(&hdr, &new_hdr, sizeof(hdr)) != 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_update_header_ext(trans, mbox->hdr_ext_id, 0,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen &new_hdr, sizeof(new_hdr));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int sdbox_write_index_header(struct mailbox *box,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const struct mailbox_update *update)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_index_transaction *trans;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const struct mail_index_header *hdr;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen uint32_t uid_validity, uid_next;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen hdr = mail_index_get_header(mbox->ibox.view);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen trans = mail_index_transaction_begin(mbox->ibox.view, 0);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_update_header(mbox, trans, update);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (update != NULL && update->uid_validity != 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen uid_validity = update->uid_validity;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen else if (hdr->uid_validity == 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* set uidvalidity */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen uid_validity = dbox_get_uidvalidity_next(box->list);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (hdr->uid_validity != uid_validity) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_update_header(trans,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen offsetof(struct mail_index_header, uid_validity),
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen &uid_validity, sizeof(uid_validity), TRUE);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (update != NULL && hdr->next_uid < update->min_next_uid) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen uid_next = update->min_next_uid;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_update_header(trans,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen offsetof(struct mail_index_header, next_uid),
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen &uid_next, sizeof(uid_next), TRUE);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (update != NULL && update->min_highest_modseq != 0 &&
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_modseq_get_highest(mbox->ibox.view) <
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen update->min_highest_modseq) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_update_highest_modseq(trans,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen update->min_highest_modseq);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (mail_index_transaction_commit(&trans) < 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_storage_set_internal_error(box->storage);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_reset_error(mbox->ibox.index);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int sdbox_mailbox_create_indexes(struct mailbox *box,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const struct mailbox_update *update)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *origin;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mode_t mode;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen gid_t gid;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen int ret;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mailbox_list_get_dir_permissions(box->list, NULL, &mode, &gid, &origin);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (mkdir_parents_chgrp(box->path, mode, gid, origin) == 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* create indexes immediately with the dbox header */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (index_storage_mailbox_open(box) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->creating = TRUE;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ret = sdbox_write_index_header(box, update);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->creating = FALSE;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (ret < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen } else if (errno != EEXIST) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!mail_storage_set_error_from_errno(box->storage)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_storage_set_critical(box->storage,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "mkdir(%s) failed: %m", box->path);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void sdbox_storage_get_status_guid(struct mailbox *box,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mailbox_status *status_r)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_index_header hdr;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (sdbox_read_header(mbox, &hdr) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memset(&hdr, 0, sizeof(hdr));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (mail_guid_128_is_empty(hdr.mailbox_guid)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* regenerate it */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (sdbox_write_index_header(box, NULL) < 0 ||
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_read_header(mbox, &hdr) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memcpy(status_r->mailbox_guid, hdr.mailbox_guid,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sizeof(status_r->mailbox_guid));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainendbox_storage_get_status(struct mailbox *box, enum mailbox_status_items items,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mailbox_status *status_r)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_get_status(box, items, status_r);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if ((items & STATUS_GUID) != 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_storage_get_status_guid(box, status_r);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainendbox_mailbox_update(struct mailbox *box, const struct mailbox_update *update)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!box->opened) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (index_storage_mailbox_open(box) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return sdbox_write_index_header(box, update);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainensdbox_list_delete_mailbox(struct mailbox_list *list, const char *name)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_mailbox_list *mlist = SDBOX_LIST_CONTEXT(list);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *trash_dest;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen int ret;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* Make sure the indexes are closed before trying to delete the
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen directory that contains them. It can still fail with some NFS
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen implementations if indexes are opened by another session, but
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen that can't really be helped. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_destroy_unrefed();
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* delete the index and control directories */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (mlist->module_ctx.super.delete_mailbox(list, name) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if ((ret = dbox_list_delete_mailbox1(list, name, &trash_dest)) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return dbox_list_delete_mailbox2(list, name, ret, trash_dest);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainensdbox_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mailbox_list *newlist, const char *newname,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen bool rename_children)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_mailbox_list *oldmlist = SDBOX_LIST_CONTEXT(oldlist);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (oldmlist->module_ctx.super.
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen rename_mailbox(oldlist, oldname, newlist, newname,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen rename_children) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return dbox_list_rename_mailbox(oldlist, oldname, newlist, newname,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen rename_children);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void sdbox_storage_add_list(struct mail_storage *storage ATTR_UNUSED,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mailbox_list *list)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_mailbox_list *mlist;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mlist = p_new(list->pool, struct sdbox_mailbox_list, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mlist->module_ctx.super = list->v;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen list->v.iter_is_mailbox = dbox_list_iter_is_mailbox;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen list->v.delete_mailbox = sdbox_list_delete_mailbox;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen list->v.rename_mailbox = sdbox_list_rename_mailbox;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen list->v.rename_mailbox_pre = dbox_list_rename_mailbox_pre;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen MODULE_CONTEXT_SET(list, sdbox_mailbox_list_module, mlist);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct mail_storage dbox_storage = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .name = SDBOX_STORAGE_NAME,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .class_flags = 0,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .v = {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_storage_alloc,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_destroy,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_storage_add_list,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_storage_get_list_settings,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_mailbox_alloc,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NULL
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen};
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct mailbox sdbox_mailbox = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .v = {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_is_readonly,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_allow_new_keywords,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_mailbox_enable,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_mailbox_open,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_mailbox_close,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_mailbox_create,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_mailbox_update,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_storage_get_status,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_storage_sync_init,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mailbox_sync_next,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mailbox_sync_deinit,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_notify_changes,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_transaction_begin,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_transaction_commit,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_transaction_rollback,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_transaction_set_max_modseq,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_keywords_create,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_keywords_create_from_indexes,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_keywords_ref,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_keywords_unref,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_keyword_is_valid,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_get_seq_range,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_get_uid_range,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_get_expunges,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_mail_alloc,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_header_lookup_init,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_header_lookup_deinit,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_search_init,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_search_deinit,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_search_next_nonblock,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_search_next_update_seq,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_save_alloc,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_save_begin,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_save_continue,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_save_finish,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_save_cancel,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_copy,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_is_inconsistent
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen};
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct dbox_storage_vfuncs sdbox_dbox_storage_vfuncs = {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_file_free,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_file_create_fd,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_mail_open,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_mailbox_create_indexes
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen};