mdbox-storage.c revision e59faf65ce864fe95dc00f5d52b8323cdbd0608a
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "lib.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "array.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "ioloop.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "str.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "hex-binary.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "randgen.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "mkdir-parents.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "unlink-directory.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "unlink-old-files.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "index-mail.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "mail-copy.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "mail-index-modseq.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "mailbox-uidvalidity.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "dbox-mail.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "dbox-save.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "mdbox-map.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "mdbox-file.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "mdbox-sync.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "mdbox-storage-rebuild.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "mdbox-storage.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include <stdio.h>
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include <stdlib.h>
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include <unistd.h>
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include <dirent.h>
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include <sys/stat.h>
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#define MDBOX_LIST_CONTEXT(obj) \
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi MODULE_CONTEXT(obj, mdbox_mailbox_list_module)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistruct mdbox_mailbox_list {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi union mailbox_list_module_context module_ctx;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi};
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomiextern struct mail_storage mdbox_storage;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomiextern struct mailbox mdbox_mailbox;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomiextern struct dbox_storage_vfuncs mdbox_dbox_storage_vfuncs;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic MODULE_CONTEXT_DEFINE_INIT(mdbox_mailbox_list_module,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi &mailbox_list_module_register);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic struct mail_storage *mdbox_storage_alloc(void)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_storage *storage;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi pool_t pool;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi pool = pool_alloconly_create("dbox storage", 512+256);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi storage = p_new(pool, struct mdbox_storage, 1);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi storage->storage.v = mdbox_dbox_storage_vfuncs;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi storage->storage.storage = mdbox_storage;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi storage->storage.storage.pool = pool;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return &storage->storage.storage;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic int
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomimdbox_storage_create(struct mail_storage *_storage, struct mail_namespace *ns,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char **error_r)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_storage *storage = (struct mdbox_storage *)_storage;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *dir;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi storage->set = mail_storage_get_driver_settings(_storage);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi i_assert(storage->set->mdbox_max_open_files >= 2);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (*ns->list->set.mailbox_dir_name == '\0') {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi *error_r = "dbox: MAILBOXDIR must not be empty";
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi _storage->unique_root_dir =
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi p_strdup(_storage->pool, ns->list->set.root_dir);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi dir = mailbox_list_get_path(ns->list, NULL, MAILBOX_LIST_PATH_TYPE_DIR);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi storage->storage_dir = p_strconcat(_storage->pool, dir,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi "/"MDBOX_GLOBAL_DIR_NAME, NULL);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi storage->alt_storage_dir = p_strconcat(_storage->pool,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi ns->list->set.alt_dir,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi "/"MDBOX_GLOBAL_DIR_NAME, NULL);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi i_array_init(&storage->open_files,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi I_MIN(storage->set->mdbox_max_open_files, 128));
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi storage->map = dbox_map_init(storage, ns->list, storage->storage_dir);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return 0;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic void mdbox_storage_destroy(struct mail_storage *_storage)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_storage *storage = (struct mdbox_storage *)_storage;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (storage->storage.files_corrupted) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (mdbox_storage_rebuild(storage) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_files_free(storage);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi dbox_map_deinit(&storage->map);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi array_free(&storage->open_files);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_destroy(_storage);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistruct mailbox *
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomimdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *name, struct istream *input,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi enum mailbox_flags flags)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_mailbox *mbox;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi pool_t pool;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* dbox can't work without index files */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi flags &= ~MAILBOX_FLAG_NO_INDEX_FILES;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi pool = pool_alloconly_create("mdbox mailbox", 1024+512);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox = p_new(pool, struct mdbox_mailbox, 1);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->ibox.box = mdbox_mailbox;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->ibox.box.pool = pool;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->ibox.box.storage = storage;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->ibox.box.list = list;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->ibox.mail_vfuncs = &mdbox_mail_vfuncs;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->ibox.save_commit_pre = mdbox_transaction_save_commit_pre;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->ibox.save_commit_post = mdbox_transaction_save_commit_post;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->ibox.save_rollback = mdbox_transaction_save_rollback;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi DBOX_INDEX_PREFIX);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_index_set_fsync_types(mbox->ibox.index,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi MAIL_INDEX_SYNC_TYPE_APPEND |
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi MAIL_INDEX_SYNC_TYPE_EXPUNGE);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->ibox.index_flags |= MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS |
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->storage = (struct mdbox_storage *)storage;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->ext_id =
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_index_ext_register(mbox->ibox.index, "mdbox", 0,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi sizeof(struct mdbox_mail_index_record),
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi sizeof(uint32_t));
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->hdr_ext_id =
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_index_ext_register(mbox->ibox.index, "mdbox-hdr",
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi sizeof(struct mdbox_index_header), 0, 0);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->guid_ext_id =
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_index_ext_register(mbox->ibox.index, "guid",
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi 0, MAIL_GUID_128_SIZE, 1);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return &mbox->ibox.box;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomiint mdbox_read_header(struct mdbox_mailbox *mbox,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_index_header *hdr)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const void *data;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi size_t data_size;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_index_get_header_ext(mbox->ibox.view, mbox->hdr_ext_id,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi &data, &data_size);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (data_size < MDBOX_INDEX_HEADER_MIN_SIZE &&
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi (!mbox->creating || data_size != 0)) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_storage_set_critical(&mbox->storage->storage.storage,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi "dbox %s: Invalid dbox header size",
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->ibox.box.path);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi memset(hdr, 0, sizeof(*hdr));
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr)));
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return 0;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomivoid mdbox_update_header(struct mdbox_mailbox *mbox,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mail_index_transaction *trans,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const struct mailbox_update *update)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_index_header hdr, new_hdr;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (mdbox_read_header(mbox, &hdr) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi memset(&hdr, 0, sizeof(hdr));
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi new_hdr = hdr;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (update != NULL && !mail_guid_128_is_empty(update->mailbox_guid)) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi memcpy(new_hdr.mailbox_guid, update->mailbox_guid,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi sizeof(new_hdr.mailbox_guid));
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi } else if (mail_guid_128_is_empty(new_hdr.mailbox_guid)) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_generate_guid_128(new_hdr.mailbox_guid);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi new_hdr.map_uid_validity =
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi dbox_map_get_uid_validity(mbox->storage->map);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (memcmp(&hdr, &new_hdr, sizeof(hdr)) != 0) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_index_update_header_ext(trans, mbox->hdr_ext_id, 0,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi &new_hdr, sizeof(new_hdr));
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic int mdbox_write_index_header(struct mailbox *box,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const struct mailbox_update *update)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mail_index_transaction *trans;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const struct mail_index_header *hdr;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi uint32_t uid_validity, uid_next;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (dbox_map_open(mbox->storage->map, TRUE) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi hdr = mail_index_get_header(mbox->ibox.view);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi trans = mail_index_transaction_begin(mbox->ibox.view, 0);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_update_header(mbox, trans, update);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi uid_validity = hdr->uid_validity;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (update != NULL && update->uid_validity != 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi uid_validity = update->uid_validity;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi else if (uid_validity == 0) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* set uidvalidity */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi uid_validity = dbox_get_uidvalidity_next(box->list);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (hdr->uid_validity != uid_validity) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_index_update_header(trans,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi offsetof(struct mail_index_header, uid_validity),
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi &uid_validity, sizeof(uid_validity), TRUE);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (update != NULL && hdr->next_uid < update->min_next_uid) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi uid_next = update->min_next_uid;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_index_update_header(trans,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi offsetof(struct mail_index_header, next_uid),
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi &uid_next, sizeof(uid_next), TRUE);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (update != NULL && update->min_highest_modseq != 0 &&
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_index_modseq_get_highest(mbox->ibox.view) <
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi update->min_highest_modseq) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_index_update_highest_modseq(trans,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi update->min_highest_modseq);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (mail_index_transaction_commit(&trans) < 0) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_storage_set_internal_error(box->storage);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_index_reset_error(mbox->ibox.index);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return 0;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic int mdbox_mailbox_create_indexes(struct mailbox *box,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const struct mailbox_update *update)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *origin;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mode_t mode;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi gid_t gid;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi int ret;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mailbox_list_get_dir_permissions(box->list, NULL, &mode, &gid, &origin);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (mkdir_parents_chgrp(box->path, mode, gid, origin) == 0) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* create indexes immediately with the dbox header */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (index_storage_mailbox_open(box) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->creating = TRUE;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi ret = mdbox_write_index_header(box, update);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox->creating = FALSE;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (ret < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi } else if (errno != EEXIST) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (!mail_storage_set_error_from_errno(box->storage)) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_storage_set_critical(box->storage,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi "mkdir(%s) failed: %m", box->path);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return 0;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic void mdbox_storage_get_status_guid(struct mailbox *box,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mailbox_status *status_r)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_index_header hdr;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (mdbox_read_header(mbox, &hdr) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi memset(&hdr, 0, sizeof(hdr));
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (mail_guid_128_is_empty(hdr.mailbox_guid)) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* regenerate it */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (mdbox_write_index_header(box, NULL) < 0 ||
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_read_header(mbox, &hdr) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi memcpy(status_r->mailbox_guid, hdr.mailbox_guid,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi sizeof(status_r->mailbox_guid));
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic void
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomimdbox_storage_get_status(struct mailbox *box, enum mailbox_status_items items,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mailbox_status *status_r)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_get_status(box, items, status_r);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if ((items & STATUS_GUID) != 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_storage_get_status_guid(box, status_r);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic int
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomimdbox_mailbox_update(struct mailbox *box, const struct mailbox_update *update)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (!box->opened) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (index_storage_mailbox_open(box) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return mdbox_write_index_header(box, update);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic int
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomimdbox_mailbox_unref_mails(struct mailbox_list *list, const char *path)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_storage *storage =
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi (struct mdbox_storage *)list->ns->storage;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const struct mail_storage_settings *old_set;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mail_storage_settings tmp_set;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mailbox *box;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_mailbox *mbox;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const struct mail_index_header *hdr;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const struct mdbox_mail_index_record *dbox_rec;
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi struct dbox_map_transaction_context *map_trans;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi ARRAY_TYPE(uint32_t) map_uids;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const void *data;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi bool expunged;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi uint32_t seq;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi int ret;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi old_set = list->mail_set;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi tmp_set = *list->mail_set;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi tmp_set.mail_full_filesystem_access = TRUE;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi list->mail_set = &tmp_set;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi box = mdbox_mailbox_alloc(&storage->storage.storage, list, path, NULL,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi MAILBOX_FLAG_IGNORE_ACLS |
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi MAILBOX_FLAG_KEEP_RECENT);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi ret = mailbox_open(box);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi list->mail_set = old_set;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (ret < 0) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mailbox_close(&box);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mbox = (struct mdbox_mailbox *)box;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* get a list of all map_uids in this mailbox */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi i_array_init(&map_uids, 128);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi hdr = mail_index_get_header(mbox->ibox.view);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi for (seq = 1; seq <= hdr->messages_count; seq++) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_index_lookup_ext(mbox->ibox.view, seq, mbox->ext_id,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi &data, &expunged);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi dbox_rec = data;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (dbox_rec == NULL) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* no multi-mails */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi break;
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (dbox_rec->map_uid != 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi array_append(&map_uids, &dbox_rec->map_uid, 1);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* unreference the map_uids */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi map_trans = dbox_map_transaction_begin(storage->map, FALSE);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi ret = dbox_map_update_refcounts(map_trans, &map_uids, -1);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (ret == 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi ret = dbox_map_transaction_commit(map_trans);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi dbox_map_transaction_free(&map_trans);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi array_free(&map_uids);
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_close(&box);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return ret;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic int
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomimdbox_list_delete_mailbox(struct mailbox_list *list, const char *name)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_mailbox_list *mlist = MDBOX_LIST_CONTEXT(list);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *trash_dest;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi int ret;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* Make sure the indexes are closed before trying to delete the
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi directory that contains them. It can still fail with some NFS
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi implementations if indexes are opened by another session, but
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi that can't really be helped. */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_destroy_unrefed();
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* delete the index and control directories */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (mlist->module_ctx.super.delete_mailbox(list, name) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if ((ret = dbox_list_delete_mailbox1(list, name, &trash_dest)) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (ret > 0) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (mdbox_mailbox_unref_mails(list, trash_dest) < 0) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* we've already renamed it. there's no going back. */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mailbox_list_set_internal_error(list);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi ret = -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi return dbox_list_delete_mailbox2(list, name, ret, trash_dest);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic int
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomimdbox_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mailbox_list *newlist, const char *newname,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi bool rename_children)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_mailbox_list *oldmlist = MDBOX_LIST_CONTEXT(oldlist);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (oldmlist->module_ctx.super.
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi rename_mailbox(oldlist, oldname, newlist, newname,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi rename_children) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return dbox_list_rename_mailbox(oldlist, oldname, newlist, newname,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi rename_children);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic void dbox_storage_add_list(struct mail_storage *storage ATTR_UNUSED,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mailbox_list *list)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mdbox_mailbox_list *mlist;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mlist = p_new(list->pool, struct mdbox_mailbox_list, 1);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mlist->module_ctx.super = list->v;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi list->v.iter_is_mailbox = dbox_list_iter_is_mailbox;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi list->v.delete_mailbox = mdbox_list_delete_mailbox;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi list->v.rename_mailbox = mdbox_list_rename_mailbox;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi list->v.rename_mailbox_pre = dbox_list_rename_mailbox_pre;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi MODULE_CONTEXT_SET(list, mdbox_mailbox_list_module, mlist);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistruct mail_storage mdbox_storage = {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi .name = MDBOX_STORAGE_NAME,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi .class_flags = MAIL_STORAGE_CLASS_FLAG_UNIQUE_ROOT,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi .v = {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_get_setting_parser_info,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_storage_alloc,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_storage_create,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_storage_destroy,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi dbox_storage_add_list,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi dbox_storage_get_list_settings,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi NULL,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_mailbox_alloc,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_sync_purge
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi};
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistruct mailbox mdbox_mailbox = {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi .v = {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_is_readonly,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_allow_new_keywords,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_mailbox_enable,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi dbox_mailbox_open,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_mailbox_close,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi dbox_mailbox_create,
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mdbox_mailbox_update,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_storage_get_status,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi NULL,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi NULL,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_storage_sync_init,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_mailbox_sync_next,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_mailbox_sync_deinit,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi NULL,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi dbox_notify_changes,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_transaction_begin,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_transaction_commit,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_transaction_rollback,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_transaction_set_max_modseq,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_keywords_create,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_keywords_create_from_indexes,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_keywords_ref,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_keywords_unref,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_keyword_is_valid,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_get_seq_range,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_get_uid_range,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_get_expunges,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi NULL,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi NULL,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi NULL,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi dbox_mail_alloc,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_header_lookup_init,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_header_lookup_deinit,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_search_init,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_search_deinit,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_search_next_nonblock,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_search_next_update_seq,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_save_alloc,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_save_begin,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi dbox_save_continue,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_save_finish,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_save_cancel,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_copy,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi index_storage_is_inconsistent
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi};
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvistruct dbox_storage_vfuncs mdbox_dbox_storage_vfuncs = {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_file_unrefed,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_file_create_fd,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mdbox_mail_open,
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi mdbox_mailbox_create_indexes
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi};
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi