bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "lib.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "array.h"
f242fa00989e452ecffba917f20f885f509d0f8fTimo Sirainen#include "ioloop.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "mkdir-parents.h"
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen#include "master-service.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "mail-index-modseq.h"
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen#include "mail-index-alloc-cache.h"
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen#include "mailbox-log.h"
7a7d2aa11e46195e2d92d6c337d7e78052a5ce67Timo Sirainen#include "mailbox-list-private.h"
a956137aa86d16e5a90b9d4a9e69d3854d824380Timo Sirainen#include "index-pop3-uidl.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "dbox-mail.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "dbox-save.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "mdbox-map.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "mdbox-file.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "mdbox-sync.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "mdbox-storage-rebuild.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "mdbox-storage.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenextern struct mail_storage mdbox_storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenextern struct mailbox mdbox_mailbox;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic struct mail_storage *mdbox_storage_alloc(void)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mdbox_storage *storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pool_t pool;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
4c1deab456fe8877bf025d11843167ac1f36327aTimo Sirainen pool = pool_alloconly_create("mdbox storage", 2048);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage = p_new(pool, struct mdbox_storage, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage->storage.v = mdbox_dbox_storage_vfuncs;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage->storage.storage = mdbox_storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage->storage.storage.pool = pool;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return &storage->storage.storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
b90c23a9862b91594959b918b035d73f7bc0b265Timo Sirainenint mdbox_storage_create(struct mail_storage *_storage,
b90c23a9862b91594959b918b035d73f7bc0b265Timo Sirainen struct mail_namespace *ns, const char **error_r)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
b67974c4b89ab6950c2694cce8dfb1b6561cc084Josef 'Jeff' Sipek struct mdbox_storage *storage = MDBOX_STORAGE(_storage);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *dir;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
46e917c9fa05cbe7bddf805d3a9838b61e3960e1Timo Sirainen storage->set = mail_namespace_get_driver_settings(ns, _storage);
f6aaada6101dd43cd80fe965ff1ab9bfaf776252Timo Sirainen storage->preallocate_space = storage->set->mdbox_preallocate_space;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (*ns->list->set.mailbox_dir_name == '\0') {
ddb018bc886680f462463b2c87f983fdedbf6cf0Timo Sirainen *error_r = "mdbox: MAILBOXDIR must not be empty";
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen _storage->unique_root_dir =
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen p_strdup(_storage->pool, ns->list->set.root_dir);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen dir = mailbox_list_get_root_forced(ns->list, MAILBOX_LIST_PATH_TYPE_DIR);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage->storage_dir = p_strconcat(_storage->pool, dir,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "/"MDBOX_GLOBAL_DIR_NAME, NULL);
7279da2bd6f969071743fbb8b35b934215365833Baofeng if (ns->list->set.alt_dir != NULL) {
7279da2bd6f969071743fbb8b35b934215365833Baofeng storage->alt_storage_dir = p_strconcat(_storage->pool,
7279da2bd6f969071743fbb8b35b934215365833Baofeng ns->list->set.alt_dir,
7279da2bd6f969071743fbb8b35b934215365833Baofeng "/"MDBOX_GLOBAL_DIR_NAME, NULL);
7279da2bd6f969071743fbb8b35b934215365833Baofeng }
04c3ac276103b56185119bcff9a66de7a8bb0e68Timo Sirainen i_array_init(&storage->open_files, 64);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
02d72ab3d606033e9a720274ddc3dd83a0ad070dTimo Sirainen storage->map = mdbox_map_init(storage, ns->list);
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen return dbox_storage_create(_storage, ns, error_r);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
b90c23a9862b91594959b918b035d73f7bc0b265Timo Sirainenvoid mdbox_storage_destroy(struct mail_storage *_storage)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
b67974c4b89ab6950c2694cce8dfb1b6561cc084Josef 'Jeff' Sipek struct mdbox_storage *storage = MDBOX_STORAGE(_storage);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_files_free(storage);
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen mdbox_map_deinit(&storage->map);
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek timeout_remove(&storage->to_close_unused_files);
5fb3f13537dffd15a31e997da133a721c0728af8Timo Sirainen
5fb3f13537dffd15a31e997da133a721c0728af8Timo Sirainen if (array_is_created(&storage->move_from_alt_map_uids))
5fb3f13537dffd15a31e997da133a721c0728af8Timo Sirainen array_free(&storage->move_from_alt_map_uids);
5fb3f13537dffd15a31e997da133a721c0728af8Timo Sirainen if (array_is_created(&storage->move_to_alt_map_uids))
5fb3f13537dffd15a31e997da133a721c0728af8Timo Sirainen array_free(&storage->move_to_alt_map_uids);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen array_free(&storage->open_files);
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen dbox_storage_destroy(_storage);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainenstatic const char *
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainenmdbox_storage_find_root_dir(const struct mail_namespace *ns)
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen{
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen bool debug = ns->mail_set->mail_debug;
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen const char *home, *path;
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen
860e6dd603921f61b0cd53c1cc16e1d66d312699Timo Sirainen if (ns->owner != NULL &&
860e6dd603921f61b0cd53c1cc16e1d66d312699Timo Sirainen mail_user_get_home(ns->owner, &home) > 0) {
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen path = t_strconcat(home, "/mdbox", NULL);
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen if (access(path, R_OK|W_OK|X_OK) == 0) {
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen if (debug)
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen i_debug("mdbox: root exists (%s)", path);
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen return path;
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen }
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen if (debug)
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen i_debug("mdbox: access(%s, rwx): failed: %m", path);
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen }
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen return NULL;
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen}
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainenstatic bool mdbox_storage_autodetect(const struct mail_namespace *ns,
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen struct mailbox_list_settings *set)
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen{
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen bool debug = ns->mail_set->mail_debug;
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen struct stat st;
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen const char *path, *root_dir;
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen if (set->root_dir != NULL)
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen root_dir = set->root_dir;
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen else {
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen root_dir = mdbox_storage_find_root_dir(ns);
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen if (root_dir == NULL) {
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen if (debug)
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen i_debug("mdbox: couldn't find root dir");
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen return FALSE;
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen }
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen }
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen path = t_strconcat(root_dir, "/"MDBOX_GLOBAL_DIR_NAME, NULL);
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen if (stat(path, &st) < 0) {
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen if (debug)
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen i_debug("mdbox autodetect: stat(%s) failed: %m", path);
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen return FALSE;
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen }
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen if (!S_ISDIR(st.st_mode)) {
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen if (debug)
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen i_debug("mdbox autodetect: %s not a directory", path);
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen return FALSE;
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen }
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen set->root_dir = root_dir;
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen dbox_storage_get_list_settings(ns, set);
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen return TRUE;
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen}
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainenstatic struct mailbox *
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenmdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen const char *vname, enum mailbox_flags flags)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mdbox_mailbox *mbox;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen struct index_mailbox_context *ibox;
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
3b32bc12710240f86465a00fbb2bd1ef030e6c40Timo Sirainen pool = pool_alloconly_create("mdbox mailbox", 1024*3);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox = p_new(pool, struct mdbox_mailbox, 1);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box = mdbox_mailbox;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box.pool = pool;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box.storage = storage;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box.list = list;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box.mail_vfuncs = &mdbox_mail_vfuncs;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen index_storage_mailbox_alloc(&mbox->box, vname, flags, MAIL_INDEX_PREFIX);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainen ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen ibox->index_flags |= MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS |
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
b67974c4b89ab6950c2694cce8dfb1b6561cc084Josef 'Jeff' Sipek mbox->storage = MDBOX_STORAGE(storage);
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen return &mbox->box;
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen}
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen
b90c23a9862b91594959b918b035d73f7bc0b265Timo Sirainenint mdbox_mailbox_open(struct mailbox *box)
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen{
b67974c4b89ab6950c2694cce8dfb1b6561cc084Josef 'Jeff' Sipek struct mdbox_mailbox *mbox = MDBOX_MAILBOX(box);
7b15788793354ca0fd4fdb4dda8e426ca1e9e9d7Timo Sirainen time_t path_ctime;
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen
7b15788793354ca0fd4fdb4dda8e426ca1e9e9d7Timo Sirainen if (dbox_mailbox_check_existence(box, &path_ctime) < 0)
50bf6cfe2aa6111fb38af37970f9551b2286638cTimo Sirainen return -1;
7b15788793354ca0fd4fdb4dda8e426ca1e9e9d7Timo Sirainen if (dbox_mailbox_open(box, path_ctime) < 0)
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen return -1;
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ext_id =
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mail_index_ext_register(mbox->box.index, "mdbox", 0,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sizeof(struct mdbox_mail_index_record),
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sizeof(uint32_t));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->hdr_ext_id =
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mail_index_ext_register(mbox->box.index, "mdbox-hdr",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sizeof(struct mdbox_index_header), 0, 0);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->guid_ext_id =
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mail_index_ext_register(mbox->box.index, "guid",
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen 0, GUID_128_SIZE, 1);
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen return 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1dd054126238349e1a7d3d1ffe7f8bc5fdbacb7aTimo Sirainenstatic void mdbox_mailbox_close(struct mailbox *box)
1dd054126238349e1a7d3d1ffe7f8bc5fdbacb7aTimo Sirainen{
b67974c4b89ab6950c2694cce8dfb1b6561cc084Josef 'Jeff' Sipek struct mdbox_storage *mstorage = MDBOX_STORAGE(box->storage);
1dd054126238349e1a7d3d1ffe7f8bc5fdbacb7aTimo Sirainen
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen if (mstorage->corrupted && !mstorage->rebuilding_storage)
1dd054126238349e1a7d3d1ffe7f8bc5fdbacb7aTimo Sirainen (void)mdbox_storage_rebuild(mstorage);
1dd054126238349e1a7d3d1ffe7f8bc5fdbacb7aTimo Sirainen
1dd054126238349e1a7d3d1ffe7f8bc5fdbacb7aTimo Sirainen index_storage_mailbox_close(box);
1dd054126238349e1a7d3d1ffe7f8bc5fdbacb7aTimo Sirainen}
1dd054126238349e1a7d3d1ffe7f8bc5fdbacb7aTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint mdbox_read_header(struct mdbox_mailbox *mbox,
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen struct mdbox_index_header *hdr, bool *need_resize_r)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const void *data;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen size_t data_size;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen i_assert(mbox->box.opened);
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mail_index_get_header_ext(mbox->box.view, mbox->hdr_ext_id,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen &data, &data_size);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (data_size < MDBOX_INDEX_HEADER_MIN_SIZE &&
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (!mbox->creating || data_size != 0)) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(&mbox->box,
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi "mdbox: Invalid dbox header size: %"PRIuSIZE_T,
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi data_size);
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen mdbox_storage_set_corrupted(mbox->storage);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(hdr);
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen if (data_size > 0)
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr)));
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen *need_resize_r = data_size < sizeof(*hdr);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid mdbox_update_header(struct mdbox_mailbox *mbox,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_index_transaction *trans,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const struct mailbox_update *update)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mdbox_index_header hdr, new_hdr;
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen bool need_resize;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
737ddab12d0d1b2ba09a23eb4ff2cd6f6838f414Timo Sirainen if (mdbox_read_header(mbox, &hdr, &need_resize) < 0) {
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&hdr);
a81f34a27b12cd11ebb68d58c255730e44b2ed68Timo Sirainen need_resize = TRUE;
737ddab12d0d1b2ba09a23eb4ff2cd6f6838f414Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen new_hdr = hdr;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen if (update != NULL && !guid_128_is_empty(update->mailbox_guid)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memcpy(new_hdr.mailbox_guid, update->mailbox_guid,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sizeof(new_hdr.mailbox_guid));
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen } else if (guid_128_is_empty(new_hdr.mailbox_guid)) {
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen guid_128_generate(new_hdr.mailbox_guid);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen new_hdr.map_uid_validity =
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen mdbox_map_get_uid_validity(mbox->storage->map);
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen if (need_resize) {
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen mail_index_ext_resize_hdr(trans, mbox->hdr_ext_id,
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen sizeof(new_hdr));
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo 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
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainenstatic int ATTR_NULL(2, 3)
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainenmdbox_write_index_header(struct mailbox *box,
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen const struct mailbox_update *update,
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen struct mail_index_transaction *trans)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box;
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen struct mail_index_transaction *new_trans = NULL;
14e4afa9f52bc2150fe92b5cc737ad0354078391Timo Sirainen struct mail_index_view *view;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const struct mail_index_header *hdr;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen uint32_t uid_validity, uid_next;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen if (mdbox_map_open_or_create(mbox->storage->map) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen if (trans == NULL) {
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen new_trans = mail_index_transaction_begin(box->view, 0);
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen trans = new_trans;
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
14e4afa9f52bc2150fe92b5cc737ad0354078391Timo Sirainen view = mail_index_view_open(box->index);
14e4afa9f52bc2150fe92b5cc737ad0354078391Timo Sirainen hdr = mail_index_get_header(view);
6d2c938f017a2fc55ae476f88839f03a3d3c5fbdTimo Sirainen uid_validity = hdr->uid_validity;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (update != NULL && update->uid_validity != 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen uid_validity = update->uid_validity;
6d2c938f017a2fc55ae476f88839f03a3d3c5fbdTimo Sirainen else if (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 }
ee9254cc7875519a9c71cc58a40610e6f320e907Timo Sirainen if (update != NULL && update->min_first_recent_uid != 0 &&
29337701451b9c9f9dd26b2aec23a31ab5203822Timo Sirainen hdr->first_recent_uid < update->min_first_recent_uid) {
29337701451b9c9f9dd26b2aec23a31ab5203822Timo Sirainen uint32_t first_recent_uid = update->min_first_recent_uid;
29337701451b9c9f9dd26b2aec23a31ab5203822Timo Sirainen
29337701451b9c9f9dd26b2aec23a31ab5203822Timo Sirainen mail_index_update_header(trans,
29337701451b9c9f9dd26b2aec23a31ab5203822Timo Sirainen offsetof(struct mail_index_header, first_recent_uid),
29337701451b9c9f9dd26b2aec23a31ab5203822Timo Sirainen &first_recent_uid, sizeof(first_recent_uid), FALSE);
29337701451b9c9f9dd26b2aec23a31ab5203822Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (update != NULL && update->min_highest_modseq != 0 &&
14e4afa9f52bc2150fe92b5cc737ad0354078391Timo Sirainen mail_index_modseq_get_highest(view) < update->min_highest_modseq) {
fa7c76955c6bc62689fbdf39318194f85905e6e2Timo Sirainen mail_index_modseq_enable(box->index);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_update_highest_modseq(trans,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen update->min_highest_modseq);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
14e4afa9f52bc2150fe92b5cc737ad0354078391Timo Sirainen mail_index_view_close(&view);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
5bcac2212ca86e72289faa7db2c509841fbdbd59Timo Sirainen if (box->inbox_user && box->creating) {
5bcac2212ca86e72289faa7db2c509841fbdbd59Timo Sirainen /* initialize pop3-uidl header when creating mailbox
5bcac2212ca86e72289faa7db2c509841fbdbd59Timo Sirainen (not on mailbox_update()) */
a956137aa86d16e5a90b9d4a9e69d3854d824380Timo Sirainen index_pop3_uidl_set_max_uid(box, trans, 0);
5bcac2212ca86e72289faa7db2c509841fbdbd59Timo Sirainen }
a956137aa86d16e5a90b9d4a9e69d3854d824380Timo Sirainen
46219292a55094fa49aae33eee681ed075d30e17Timo Sirainen mdbox_update_header(mbox, trans, update);
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen if (new_trans != NULL) {
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen if (mail_index_transaction_commit(&new_trans) < 0) {
1f1ee8db68d9ae1604350801cd8dc33ebe29fe8aTimo Sirainen mailbox_set_index_error(box);
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen return -1;
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
f605df8a4c15cc7a11e16fdde994d51473700890Timo Sirainenint mdbox_mailbox_create_indexes(struct mailbox *box,
f605df8a4c15cc7a11e16fdde994d51473700890Timo Sirainen const struct mailbox_update *update,
f605df8a4c15cc7a11e16fdde994d51473700890Timo Sirainen struct mail_index_transaction *trans)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
b67974c4b89ab6950c2694cce8dfb1b6561cc084Josef 'Jeff' Sipek struct mdbox_mailbox *mbox = MDBOX_MAILBOX(box);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen int ret;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
888ab4e17f7441b4dcca4a01886d055b57f4586dTimo Sirainen mbox->creating = TRUE;
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen ret = mdbox_write_index_header(box, update, trans);
888ab4e17f7441b4dcca4a01886d055b57f4586dTimo Sirainen mbox->creating = FALSE;
888ab4e17f7441b4dcca4a01886d055b57f4586dTimo Sirainen return ret;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainenvoid mdbox_storage_set_corrupted(struct mdbox_storage *storage)
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen{
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen if (storage->corrupted) {
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen /* already set it corrupted (possibly recursing back here) */
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen return;
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen }
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen storage->corrupted = TRUE;
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen storage->corrupted_rebuild_count = (uint32_t)-1;
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen if (mdbox_map_open(storage->map) > 0 &&
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen mdbox_map_refresh(storage->map) == 0) {
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen storage->corrupted_rebuild_count =
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen mdbox_map_get_rebuild_count(storage->map);
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen }
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen}
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainenstatic const char *
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainenmdbox_get_attachment_path_suffix(struct dbox_file *file ATTR_UNUSED)
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen{
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen return "";
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen}
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen
b90c23a9862b91594959b918b035d73f7bc0b265Timo Sirainenvoid mdbox_set_mailbox_corrupted(struct mailbox *box)
57bf90f66f393c2807b2fc543655013f61d1d9e4Timo Sirainen{
b67974c4b89ab6950c2694cce8dfb1b6561cc084Josef 'Jeff' Sipek struct mdbox_storage *mstorage = MDBOX_STORAGE(box->storage);
57bf90f66f393c2807b2fc543655013f61d1d9e4Timo Sirainen
57bf90f66f393c2807b2fc543655013f61d1d9e4Timo Sirainen mdbox_storage_set_corrupted(mstorage);
57bf90f66f393c2807b2fc543655013f61d1d9e4Timo Sirainen}
57bf90f66f393c2807b2fc543655013f61d1d9e4Timo Sirainen
b90c23a9862b91594959b918b035d73f7bc0b265Timo Sirainenvoid mdbox_set_file_corrupted(struct dbox_file *file)
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen{
b67974c4b89ab6950c2694cce8dfb1b6561cc084Josef 'Jeff' Sipek struct mdbox_storage *mstorage = MDBOX_DBOX_STORAGE(file->storage);
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen mdbox_storage_set_corrupted(mstorage);
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen}
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen
fbd918f47f591f8084fd52b207ef29515ddd11b9Timo Sirainenstatic int
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainenmdbox_mailbox_get_guid(struct mdbox_mailbox *mbox, guid_128_t guid_r)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
d6d4d8beede5f8efbba052c1e3e4f964ce489bd2Timo Sirainen const struct mail_index_header *idx_hdr;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mdbox_index_header hdr;
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen bool need_resize;
d6d4d8beede5f8efbba052c1e3e4f964ce489bd2Timo Sirainen int ret = 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
d6d4d8beede5f8efbba052c1e3e4f964ce489bd2Timo Sirainen i_assert(!mbox->creating);
d6d4d8beede5f8efbba052c1e3e4f964ce489bd2Timo Sirainen
d6d4d8beede5f8efbba052c1e3e4f964ce489bd2Timo Sirainen /* there's a race condition between mkdir and getting the mailbox GUID.
d6d4d8beede5f8efbba052c1e3e4f964ce489bd2Timo Sirainen normally this is handled by mdbox syncing, but GUID can be looked up
48d8312488089dc1a8360991f0881d91095c21eaTimo Sirainen without syncing. when we detect this situation we'll try to finish
48d8312488089dc1a8360991f0881d91095c21eaTimo Sirainen creating the indexes first, which usually means just waiting for
48d8312488089dc1a8360991f0881d91095c21eaTimo Sirainen the sync lock to get unlocked by the other process creating them. */
d6d4d8beede5f8efbba052c1e3e4f964ce489bd2Timo Sirainen idx_hdr = mail_index_get_header(mbox->box.view);
48d8312488089dc1a8360991f0881d91095c21eaTimo Sirainen if (idx_hdr->uid_validity == 0 && idx_hdr->next_uid == 1) {
48d8312488089dc1a8360991f0881d91095c21eaTimo Sirainen if (dbox_mailbox_create_indexes(&mbox->box, NULL) < 0)
48d8312488089dc1a8360991f0881d91095c21eaTimo Sirainen return -1;
48d8312488089dc1a8360991f0881d91095c21eaTimo Sirainen }
48d8312488089dc1a8360991f0881d91095c21eaTimo Sirainen
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen if (mdbox_read_header(mbox, &hdr, &need_resize) < 0)
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&hdr);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen if (guid_128_is_empty(hdr.mailbox_guid)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* regenerate it */
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen if (mdbox_write_index_header(&mbox->box, NULL, NULL) < 0 ||
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen mdbox_read_header(mbox, &hdr, &need_resize) < 0)
d6d4d8beede5f8efbba052c1e3e4f964ce489bd2Timo Sirainen ret = -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
d6d4d8beede5f8efbba052c1e3e4f964ce489bd2Timo Sirainen if (ret == 0)
d6d4d8beede5f8efbba052c1e3e4f964ce489bd2Timo Sirainen memcpy(guid_r, hdr.mailbox_guid, GUID_128_SIZE);
d6d4d8beede5f8efbba052c1e3e4f964ce489bd2Timo Sirainen return ret;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainenstatic int
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainenmdbox_mailbox_get_metadata(struct mailbox *box,
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen enum mailbox_metadata_items items,
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen struct mailbox_metadata *metadata_r)
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen{
b67974c4b89ab6950c2694cce8dfb1b6561cc084Josef 'Jeff' Sipek struct mdbox_mailbox *mbox = MDBOX_MAILBOX(box);
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen
206ed2f6fa3a6fb291498627b2da626581c07a18Timo Sirainen if (index_mailbox_get_metadata(box, items, metadata_r) < 0)
206ed2f6fa3a6fb291498627b2da626581c07a18Timo Sirainen return -1;
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen if ((items & MAILBOX_METADATA_GUID) != 0) {
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen if (mdbox_mailbox_get_guid(mbox, metadata_r->guid) < 0)
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen return -1;
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen }
206ed2f6fa3a6fb291498627b2da626581c07a18Timo Sirainen return 0;
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen}
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenmdbox_mailbox_update(struct mailbox *box, const struct mailbox_update *update)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!box->opened) {
84e49ad7d7a840d600a961daeca60802e3d69cd0Timo Sirainen if (mailbox_open(box) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen if (mdbox_write_index_header(box, update, NULL) < 0)
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen return -1;
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen return index_storage_mailbox_update_common(box, update);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct mail_storage mdbox_storage = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .name = MDBOX_STORAGE_NAME,
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen .class_flags = MAIL_STORAGE_CLASS_FLAG_UNIQUE_ROOT |
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen MAIL_STORAGE_CLASS_FLAG_HAVE_MAIL_GUIDS |
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen MAIL_STORAGE_CLASS_FLAG_HAVE_MAIL_SAVE_GUIDS |
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen MAIL_STORAGE_CLASS_FLAG_BINARY_DATA,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .v = {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_get_setting_parser_info,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_storage_alloc,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_storage_create,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_storage_destroy,
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_storage_get_list_settings,
13307d0b3f41c6d940ae263f4828cf557258f9b9Timo Sirainen mdbox_storage_autodetect,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_mailbox_alloc,
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen mdbox_purge,
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen};
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct mailbox mdbox_mailbox = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .v = {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_is_readonly,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_mailbox_enable,
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen index_storage_mailbox_exists,
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen mdbox_mailbox_open,
1dd054126238349e1a7d3d1ffe7f8bc5fdbacb7aTimo Sirainen mdbox_mailbox_close,
438f12d7a776da695019114884b48188d94613efTimo Sirainen index_storage_mailbox_free,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_mailbox_create,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_mailbox_update,
af9edddbb704a640055898846add4e386e83fe43Timo Sirainen index_storage_mailbox_delete,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen index_storage_mailbox_rename,
fbd918f47f591f8084fd52b207ef29515ddd11b9Timo Sirainen index_storage_get_status,
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen mdbox_mailbox_get_metadata,
6469cf211a57433335641725dc236ebb2b9fdd3bTimo Sirainen index_storage_set_subscribed,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_set,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_get,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_iter_init,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_iter_next,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_iter_deinit,
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen index_storage_list_index_has_changed,
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen index_storage_list_index_update_sync,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_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 NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_mail_alloc,
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 mdbox_save_alloc,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_save_begin,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_save_continue,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_save_finish,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_save_cancel,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_copy,
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen mdbox_transaction_save_commit_pre,
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen mdbox_transaction_save_commit_post,
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen mdbox_transaction_save_rollback,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_is_inconsistent
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen};
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct dbox_storage_vfuncs mdbox_dbox_storage_vfuncs = {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_file_unrefed,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_file_create_fd,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mdbox_mail_open,
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen mdbox_mailbox_create_indexes,
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen mdbox_get_attachment_path_suffix,
57bf90f66f393c2807b2fc543655013f61d1d9e4Timo Sirainen mdbox_set_mailbox_corrupted,
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen mdbox_set_file_corrupted
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen};