dbox-storage.c revision 6bc5fed79741503437c6d46d9f282b66bd029c6b
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "lib.h"
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen#include "array.h"
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen#include "ioloop.h"
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen#include "str.h"
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen#include "hex-binary.h"
0536ccb51d41e3078c3a9fa33e509fb4b2420f95Timo Sirainen#include "randgen.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "mkdir-parents.h"
c2cda8cd0043443566efc5da30f79865508a1947Timo Sirainen#include "unlink-directory.h"
c2cda8cd0043443566efc5da30f79865508a1947Timo Sirainen#include "unlink-old-files.h"
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include "index-mail.h"
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include "mail-copy.h"
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include "mail-index-modseq.h"
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include "mailbox-uidvalidity.h"
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include "maildir/maildir-uidlist.h"
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include "dbox-map.h"
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include "dbox-file.h"
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include "dbox-sync.h"
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include "dbox-storage-rebuild.h"
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include "dbox-storage.h"
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include <stdio.h>
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include <stdlib.h>
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include <unistd.h>
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include <dirent.h>
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen#include <sys/stat.h>
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen#define DBOX_LIST_CONTEXT(obj) \
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen MODULE_CONTEXT(obj, dbox_mailbox_list_module)
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainenstruct dbox_mailbox_list {
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen union mailbox_list_module_context module_ctx;
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen const struct dbox_settings *set;
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen};
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainenextern struct mail_storage dbox_storage;
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainenextern struct mailbox dbox_mailbox;
d6684856fb99e51bc22a6346e08b2d81c996f963Josef 'Jeff' Sipek
d6684856fb99e51bc22a6346e08b2d81c996f963Josef 'Jeff' Sipekstatic MODULE_CONTEXT_DEFINE_INIT(dbox_mailbox_list_module,
d6684856fb99e51bc22a6346e08b2d81c996f963Josef 'Jeff' Sipek &mailbox_list_module_register);
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainenstatic struct mail_storage *dbox_storage_alloc(void)
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen{
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen struct dbox_storage *storage;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen pool_t pool;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen pool = pool_alloconly_create("dbox storage", 512+256);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen storage = p_new(pool, struct dbox_storage, 1);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen storage->storage = dbox_storage;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen storage->storage.pool = pool;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen return &storage->storage;
b3fc5293379feb3640b23622bcc8f5f8d7f1e81dJosef 'Jeff' Sipek}
b3fc5293379feb3640b23622bcc8f5f8d7f1e81dJosef 'Jeff' Sipek
b3fc5293379feb3640b23622bcc8f5f8d7f1e81dJosef 'Jeff' Sipekstatic int
b3fc5293379feb3640b23622bcc8f5f8d7f1e81dJosef 'Jeff' Sipekdbox_storage_create(struct mail_storage *_storage, struct mail_namespace *ns,
b3fc5293379feb3640b23622bcc8f5f8d7f1e81dJosef 'Jeff' Sipek const char **error_r)
b3fc5293379feb3640b23622bcc8f5f8d7f1e81dJosef 'Jeff' Sipek{
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen const char *dir, *origin;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen storage->set = mail_storage_get_driver_settings(_storage);
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen i_assert(storage->set->dbox_max_open_files >= 2);
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen
5a1b498b646b5c5dbd1b3f3861df766f560578c5Timo Sirainen if (*ns->list->set.mailbox_dir_name == '\0') {
204ee6ed414f5e4eeb6f6c10763b55daf56f11acJosef 'Jeff' Sipek *error_r = "dbox: MAILBOXDIR must not be empty";
5a1b498b646b5c5dbd1b3f3861df766f560578c5Timo Sirainen return -1;
5a1b498b646b5c5dbd1b3f3861df766f560578c5Timo Sirainen }
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen _storage->unique_root_dir =
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen p_strdup(_storage->pool, ns->list->set.root_dir);
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen dir = mailbox_list_get_path(ns->list, NULL, MAILBOX_LIST_PATH_TYPE_DIR);
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen storage->storage_dir = p_strconcat(_storage->pool, dir,
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen "/"DBOX_GLOBAL_DIR_NAME, NULL);
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen storage->alt_storage_dir = p_strconcat(_storage->pool,
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen ns->list->set.alt_dir,
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen "/"DBOX_GLOBAL_DIR_NAME, NULL);
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen i_array_init(&storage->open_files,
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen I_MIN(storage->set->dbox_max_open_files, 128));
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen
c28f6aa0b70af4811c9ace9114fe827c2f503455Timo Sirainen storage->map = dbox_map_init(storage);
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen mailbox_list_get_dir_permissions(ns->list, NULL, &storage->create_mode,
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen &storage->create_gid, &origin);
c28f6aa0b70af4811c9ace9114fe827c2f503455Timo Sirainen storage->create_gid_origin = p_strdup(_storage->pool, origin);
c28f6aa0b70af4811c9ace9114fe827c2f503455Timo Sirainen return 0;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen}
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainenstatic void dbox_storage_destroy(struct mail_storage *_storage)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen{
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (storage->sync_rebuild) {
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen if (dbox_storage_rebuild(storage) < 0)
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen return;
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen }
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen
46ce4d9273e6df12ef1912bbdb1c8b84b104f394Timo Sirainen dbox_files_free(storage);
46ce4d9273e6df12ef1912bbdb1c8b84b104f394Timo Sirainen dbox_map_deinit(&storage->map);
46ce4d9273e6df12ef1912bbdb1c8b84b104f394Timo Sirainen array_free(&storage->open_files);
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen index_storage_destroy(_storage);
46ce4d9273e6df12ef1912bbdb1c8b84b104f394Timo Sirainen}
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainenstatic void
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainendbox_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen struct mailbox_list_settings *set)
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen{
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen if (set->layout == NULL)
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen set->layout = MAILBOX_LIST_NAME_FS;
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen if (set->subscription_fname == NULL)
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen set->subscription_fname = DBOX_SUBSCRIPTION_FILE_NAME;
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen if (set->dir_guid_fname == NULL)
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen set->dir_guid_fname = DBOX_DIR_GUID_FILE_NAME;
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen if (set->maildir_name == NULL)
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen set->maildir_name = DBOX_MAILDIR_NAME;
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen if (set->mailbox_dir_name == NULL)
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen set->mailbox_dir_name = DBOX_MAILBOX_DIR_NAME;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen}
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainenstatic const char *
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainendbox_get_alt_path(struct mailbox_list *list, const char *path)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen{
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen#if 0 // FIXME
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen const char *root;
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen unsigned int len;
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen if (storage->alt_dir == NULL)
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen return NULL;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen root = mailbox_list_get_path(storage->storage.list, NULL,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAILBOX_LIST_PATH_TYPE_DIR);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
0a49b316fc729e5d57268ffa63c7122ac73f994cTimo Sirainen len = strlen(root);
0a49b316fc729e5d57268ffa63c7122ac73f994cTimo Sirainen if (strncmp(path, root, len) != 0 && path[len] == '/') {
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen /* can't determine the alt path - shouldn't happen */
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen return NULL;
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen }
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen return t_strconcat(storage->alt_dir, path + len, NULL);
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen#endif
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen return NULL;
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen}
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen
0a49b316fc729e5d57268ffa63c7122ac73f994cTimo Sirainenstruct mailbox *
0a49b316fc729e5d57268ffa63c7122ac73f994cTimo Sirainendbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen const char *name, struct istream *input,
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen enum mailbox_flags flags)
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen{
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen struct dbox_mailbox *mbox;
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen pool_t pool;
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen /* dbox can't work without index files */
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen flags &= ~MAILBOX_FLAG_NO_INDEX_FILES;
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen pool = pool_alloconly_create("dbox mailbox", 1024+512);
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen mbox = p_new(pool, struct dbox_mailbox, 1);
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen mbox->ibox.box = dbox_mailbox;
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen mbox->ibox.box.pool = pool;
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen mbox->ibox.box.storage = storage;
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen mbox->ibox.box.list = list;
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen mbox->ibox.mail_vfuncs = &dbox_mail_vfuncs;
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen mbox->ibox.save_commit_pre = dbox_transaction_save_commit_pre;
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen mbox->ibox.save_commit_post = dbox_transaction_save_commit_post;
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen mbox->ibox.save_rollback = dbox_transaction_save_rollback;
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen DBOX_INDEX_PREFIX);
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen mail_index_set_fsync_types(mbox->ibox.index,
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen MAIL_INDEX_SYNC_TYPE_APPEND |
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen MAIL_INDEX_SYNC_TYPE_EXPUNGE);
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen mbox->ibox.index_flags |= MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS |
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY;
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen mbox->storage = (struct dbox_storage *)storage;
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen mbox->alt_path =
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen p_strdup(pool, dbox_get_alt_path(list, mbox->ibox.box.path));
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen mbox->dbox_ext_id =
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen mail_index_ext_register(mbox->ibox.index, "dbox", 0,
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen sizeof(struct dbox_mail_index_record),
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen sizeof(uint32_t));
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen mbox->dbox_hdr_ext_id =
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen mail_index_ext_register(mbox->ibox.index, "dbox-hdr",
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen sizeof(struct dbox_index_header), 0, 0);
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen mbox->guid_ext_id =
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen mail_index_ext_register(mbox->ibox.index, "guid",
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen 0, MAIL_GUID_128_SIZE, 1);
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen mbox->maildir_uidlist = maildir_uidlist_init_readonly(&mbox->ibox);
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen return &mbox->ibox.box;
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen}
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainenuint32_t dbox_get_uidvalidity_next(struct mailbox_list *list)
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen{
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen const char *path;
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen path = mailbox_list_get_path(list, NULL,
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen MAILBOX_LIST_PATH_TYPE_CONTROL);
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen path = t_strconcat(path, "/"DBOX_UIDVALIDITY_FILE_NAME, NULL);
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen return mailbox_uidvalidity_next(path);
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen}
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainenint dbox_read_header(struct dbox_mailbox *mbox, struct dbox_index_header *hdr)
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen{
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen const void *data;
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen size_t data_size;
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen mail_index_get_header_ext(mbox->ibox.view, mbox->dbox_hdr_ext_id,
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen &data, &data_size);
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen if (data_size < DBOX_INDEX_HEADER_MIN_SIZE &&
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen (!mbox->creating || data_size != 0)) {
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen mail_storage_set_critical(&mbox->storage->storage,
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen "dbox %s: Invalid dbox header size",
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen mbox->ibox.box.path);
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen return -1;
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen }
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen memset(hdr, 0, sizeof(*hdr));
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr)));
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen return 0;
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen}
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainenvoid dbox_update_header(struct dbox_mailbox *mbox,
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen struct mail_index_transaction *trans,
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen const struct mailbox_update *update)
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen{
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen struct dbox_index_header hdr, new_hdr;
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen if (dbox_read_header(mbox, &hdr) < 0)
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen memset(&hdr, 0, sizeof(hdr));
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen new_hdr = hdr;
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen if (update != NULL && !mail_guid_128_is_empty(update->mailbox_guid)) {
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen memcpy(new_hdr.mailbox_guid, update->mailbox_guid,
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen sizeof(new_hdr.mailbox_guid));
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen } else if (mail_guid_128_is_empty(new_hdr.mailbox_guid)) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mail_generate_guid_128(new_hdr.mailbox_guid);
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen }
0892446b45c195461bb7be6599f02d97e1e2c9b2Timo Sirainen
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen new_hdr.map_uid_validity =
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen dbox_map_get_uid_validity(mbox->storage->map);
a2738cdb6d2733fb3e186331d68009421a19ea00Timo Sirainen if (memcmp(&hdr, &new_hdr, sizeof(hdr)) != 0) {
fb502495e9306fe51e9d2c0019e622a98e9803abTimo Sirainen mail_index_update_header_ext(trans, mbox->dbox_hdr_ext_id, 0,
d66ef20c30fee728899ee168c75fcc5ff8fbdac1Timo Sirainen &new_hdr, sizeof(new_hdr));
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen }
d66ef20c30fee728899ee168c75fcc5ff8fbdac1Timo Sirainen}
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
9e095dd6a77097356aca8216356d4d71ef1bea45Timo Sirainenstatic int dbox_write_index_header(struct mailbox *box,
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen const struct mailbox_update *update)
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen{
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen struct mail_index_transaction *trans;
0892446b45c195461bb7be6599f02d97e1e2c9b2Timo Sirainen const struct mail_index_header *hdr;
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen uint32_t uid_validity, uid_next;
7af4788b402346c94496095dd819f95ce03fe431Timo Sirainen
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen if (dbox_map_open(mbox->storage->map, TRUE) < 0)
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen return -1;
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen hdr = mail_index_get_header(mbox->ibox.view);
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen trans = mail_index_transaction_begin(mbox->ibox.view, 0);
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen dbox_update_header(mbox, trans, update);
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen if (update != NULL && update->uid_validity != 0)
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen uid_validity = update->uid_validity;
d66ef20c30fee728899ee168c75fcc5ff8fbdac1Timo Sirainen else if (hdr->uid_validity == 0) {
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen /* set uidvalidity */
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen uid_validity = dbox_get_uidvalidity_next(box->list);
c24ef531ca58abad996482f5c2e8992be9ae8981Timo Sirainen }
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen if (hdr->uid_validity != uid_validity) {
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen mail_index_update_header(trans,
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen offsetof(struct mail_index_header, uid_validity),
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen &uid_validity, sizeof(uid_validity), TRUE);
e4c81823af1fc43ca3f2ce9eb4af7fc8f57b13a5Timo Sirainen }
e4c81823af1fc43ca3f2ce9eb4af7fc8f57b13a5Timo Sirainen if (update != NULL && hdr->next_uid < update->min_next_uid) {
2524ef7b34965a1b1895d6140fd8296bf57c78d2Timo Sirainen uid_next = update->min_next_uid;
0892446b45c195461bb7be6599f02d97e1e2c9b2Timo Sirainen mail_index_update_header(trans,
e4c81823af1fc43ca3f2ce9eb4af7fc8f57b13a5Timo Sirainen offsetof(struct mail_index_header, next_uid),
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen &uid_next, sizeof(uid_next), TRUE);
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen }
fb502495e9306fe51e9d2c0019e622a98e9803abTimo Sirainen if (update != NULL && update->min_highest_modseq != 0 &&
fb502495e9306fe51e9d2c0019e622a98e9803abTimo Sirainen mail_index_modseq_get_highest(mbox->ibox.view) <
fb502495e9306fe51e9d2c0019e622a98e9803abTimo Sirainen update->min_highest_modseq) {
fb502495e9306fe51e9d2c0019e622a98e9803abTimo Sirainen mail_index_update_highest_modseq(trans,
fb502495e9306fe51e9d2c0019e622a98e9803abTimo Sirainen update->min_highest_modseq);
fb502495e9306fe51e9d2c0019e622a98e9803abTimo Sirainen }
fb502495e9306fe51e9d2c0019e622a98e9803abTimo Sirainen
fb502495e9306fe51e9d2c0019e622a98e9803abTimo Sirainen if (mail_index_transaction_commit(&trans) < 0) {
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen mail_storage_set_internal_error(box->storage);
c2cda8cd0043443566efc5da30f79865508a1947Timo Sirainen mail_index_reset_error(mbox->ibox.index);
c2cda8cd0043443566efc5da30f79865508a1947Timo Sirainen return -1;
c2cda8cd0043443566efc5da30f79865508a1947Timo Sirainen }
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen return 0;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen}
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainenstatic int dbox_mailbox_create_indexes(struct mailbox *box,
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen const struct mailbox_update *update)
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen{
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen const char *origin;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen mode_t mode;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen gid_t gid;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen int ret;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen mailbox_list_get_dir_permissions(box->list, NULL, &mode, &gid, &origin);
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen if (mkdir_parents_chgrp(box->path, mode, gid, origin) == 0) {
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen /* create indexes immediately with the dbox header */
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen if (index_storage_mailbox_open(box) < 0)
66dc739bb67d678770e1b7a7bc75f4f6f9523d2aTimo Sirainen return -1;
66dc739bb67d678770e1b7a7bc75f4f6f9523d2aTimo Sirainen mbox->creating = TRUE;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen ret = dbox_write_index_header(box, update);
66dc739bb67d678770e1b7a7bc75f4f6f9523d2aTimo Sirainen mbox->creating = FALSE;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen if (ret < 0)
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen return -1;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen } else if (errno != EEXIST) {
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen if (!mail_storage_set_error_from_errno(box->storage)) {
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen mail_storage_set_critical(box->storage,
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen "mkdir(%s) failed: %m", box->path);
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen }
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen return -1;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen }
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen return 0;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen}
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainenstatic bool
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainendbox_cleanup_if_exists(struct mailbox_list *list, const char *path)
c6b6ac7819931dfa92c0182ffaa7db07ac6ab0daTimo Sirainen{
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen struct stat st;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen if (stat(path, &st) < 0)
785ee8becdb11e41abaaf64c28eb3923215d1f27Timo Sirainen return FALSE;
785ee8becdb11e41abaaf64c28eb3923215d1f27Timo Sirainen
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen /* check once in a while if there are temp files to clean up */
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen if (st.st_atime > st.st_ctime + DBOX_TMP_DELETE_SECS) {
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen /* there haven't been any changes to this directory since we
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen last checked it. */
785ee8becdb11e41abaaf64c28eb3923215d1f27Timo Sirainen } else if (st.st_atime < ioloop_time - DBOX_TMP_SCAN_SECS) {
785ee8becdb11e41abaaf64c28eb3923215d1f27Timo Sirainen /* time to scan */
785ee8becdb11e41abaaf64c28eb3923215d1f27Timo Sirainen const char *prefix =
785ee8becdb11e41abaaf64c28eb3923215d1f27Timo Sirainen mailbox_list_get_global_temp_prefix(list);
785ee8becdb11e41abaaf64c28eb3923215d1f27Timo Sirainen
785ee8becdb11e41abaaf64c28eb3923215d1f27Timo Sirainen (void)unlink_old_files(path, prefix,
785ee8becdb11e41abaaf64c28eb3923215d1f27Timo Sirainen ioloop_time - DBOX_TMP_DELETE_SECS);
785ee8becdb11e41abaaf64c28eb3923215d1f27Timo Sirainen }
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen return TRUE;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen}
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenint dbox_mailbox_open(struct mailbox *box)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen{
20344c0e814139e3c365fbb9287478f91512089eTimo Sirainen if (box->input != NULL) {
20344c0e814139e3c365fbb9287478f91512089eTimo Sirainen mail_storage_set_critical(box->storage,
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen "dbox doesn't support streamed mailboxes");
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen return -1;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen }
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen if (dbox_cleanup_if_exists(box->list, box->path)) {
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen return index_storage_mailbox_open(box);
54bd0fec0be357266e299466a582f3c9269884e9Timo Sirainen } else if (errno == ENOENT) {
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen if (strcmp(box->name, "INBOX") == 0 &&
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen (box->list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* INBOX always exists, create it */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (dbox_mailbox_create_indexes(box, NULL) < 0)
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen return -1;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen return box->opened ? 0 :
20344c0e814139e3c365fbb9287478f91512089eTimo Sirainen index_storage_mailbox_open(box);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen }
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
52041ed691a26ca80e4e805765e9f55ec097c8f1Martti Rannanjärvi mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen return -1;
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen } else if (errno == EACCES) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mail_storage_set_critical(box->storage, "%s",
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mail_error_eacces_msg("stat", box->path));
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen return -1;
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen } else {
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen mail_storage_set_critical(box->storage,
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen "stat(%s) failed: %m", box->path);
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen return -1;
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen }
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen}
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainenstatic void dbox_mailbox_close(struct mailbox *box)
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen{
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen maildir_uidlist_deinit(&mbox->maildir_uidlist);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen index_storage_mailbox_close(box);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen}
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void dbox_storage_get_status_guid(struct mailbox *box,
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen struct mailbox_status *status_r)
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen{
601f5f14c6cde28f0e0c6ca7c5d735315d3d48dfTimo Sirainen struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen struct dbox_index_header hdr;
a85c629c5d75a5fd9489ba14d5d4f54f3cddd591Aki Tuomi
a85c629c5d75a5fd9489ba14d5d4f54f3cddd591Aki Tuomi if (dbox_read_header(mbox, &hdr) < 0)
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen memset(&hdr, 0, sizeof(hdr));
a85c629c5d75a5fd9489ba14d5d4f54f3cddd591Aki Tuomi
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen if (mail_guid_128_is_empty(hdr.mailbox_guid)) {
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen /* regenerate it */
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen if (dbox_write_index_header(box, NULL) < 0 ||
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen dbox_read_header(mbox, &hdr) < 0)
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen return;
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen }
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen memcpy(status_r->mailbox_guid, hdr.mailbox_guid,
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen sizeof(status_r->mailbox_guid));
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen}
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen
52041ed691a26ca80e4e805765e9f55ec097c8f1Martti Rannanjärvistatic void
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainendbox_storage_get_status(struct mailbox *box, enum mailbox_status_items items,
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen struct mailbox_status *status_r)
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen{
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen index_storage_get_status(box, items, status_r);
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if ((items & STATUS_GUID) != 0)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen dbox_storage_get_status_guid(box, status_r);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen}
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainenstatic int
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainendbox_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
52041ed691a26ca80e4e805765e9f55ec097c8f1Martti Rannanjärvi bool directory)
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen{
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen const char *path, *alt_path, *origin;
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen struct stat st;
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen path = mailbox_list_get_path(box->list, box->name,
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen directory ? MAILBOX_LIST_PATH_TYPE_DIR :
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen if (stat(path, &st) == 0) {
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen "Mailbox already exists");
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen return -1;
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen }
52041ed691a26ca80e4e805765e9f55ec097c8f1Martti Rannanjärvi
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Sirainen if (directory) {
548e394330621952db0f03dd667b70184c4a37b6Timo Sirainen mode_t mode;
a85c629c5d75a5fd9489ba14d5d4f54f3cddd591Aki Tuomi gid_t gid;
a85c629c5d75a5fd9489ba14d5d4f54f3cddd591Aki Tuomi
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Sirainen mailbox_list_get_dir_permissions(box->list, NULL, &mode,
a85c629c5d75a5fd9489ba14d5d4f54f3cddd591Aki Tuomi &gid, &origin);
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Sirainen if (mkdir_parents_chgrp(path, mode, gid, origin) == 0)
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Sirainen return 0;
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen else if (errno == EEXIST) {
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS,
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen "Mailbox already exists");
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen } else if (!mail_storage_set_error_from_errno(box->storage)) {
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen mail_storage_set_critical(box->storage,
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen "mkdir(%s) failed: %m", path);
52041ed691a26ca80e4e805765e9f55ec097c8f1Martti Rannanjärvi }
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen return -1;
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen }
a85c629c5d75a5fd9489ba14d5d4f54f3cddd591Aki Tuomi
a85c629c5d75a5fd9489ba14d5d4f54f3cddd591Aki Tuomi /* make sure the alt path doesn't exist yet. it shouldn't (except with
a85c629c5d75a5fd9489ba14d5d4f54f3cddd591Aki Tuomi race conditions with RENAME/DELETE), but if something crashed and
a85c629c5d75a5fd9489ba14d5d4f54f3cddd591Aki Tuomi left it lying around we don't want to start overwriting files in
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen it. */
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen alt_path = dbox_get_alt_path(box->list, path);
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen if (alt_path != NULL && stat(alt_path, &st) == 0) {
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS,
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen "Mailbox already exists");
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen return -1;
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen }
1bc075e2e4ed422f9590c95c3ae223422b97ce6aTimo Sirainen
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainen return dbox_mailbox_create_indexes(box, update);
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen}
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainen
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainenstatic int
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainendbox_mailbox_update(struct mailbox *box, const struct mailbox_update *update)
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainen{
923115fd382904fa13bb09bf307bf2835b52df60Timo Sirainen if (!box->opened) {
923115fd382904fa13bb09bf307bf2835b52df60Timo Sirainen if (index_storage_mailbox_open(box) < 0)
d28179fd78550a58be44dcb1e3e830ab7d33172dTimo Sirainen return -1;
d28179fd78550a58be44dcb1e3e830ab7d33172dTimo Sirainen }
d28179fd78550a58be44dcb1e3e830ab7d33172dTimo Sirainen return dbox_write_index_header(box, update);
d28179fd78550a58be44dcb1e3e830ab7d33172dTimo Sirainen}
d28179fd78550a58be44dcb1e3e830ab7d33172dTimo Sirainen
d28179fd78550a58be44dcb1e3e830ab7d33172dTimo Sirainenstatic int
923115fd382904fa13bb09bf307bf2835b52df60Timo Sirainendbox_mailbox_unref_mails(struct mailbox_list *list, const char *path)
923115fd382904fa13bb09bf307bf2835b52df60Timo Sirainen{
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)list->ns->storage;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen const struct mail_storage_settings *old_set;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen struct mail_storage_settings tmp_set;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen struct mailbox *box;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen struct dbox_mailbox *mbox;
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen const struct mail_index_header *hdr;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen const struct dbox_mail_index_record *dbox_rec;
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen struct dbox_map_transaction_context *map_trans;
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen ARRAY_TYPE(uint32_t) map_uids;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen const void *data;
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen bool expunged;
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen uint32_t seq;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen int ret;
e6bc5e739360377c5badf0da24208f4836722eaeStephan Bosch
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen old_set = list->mail_set;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen tmp_set = *list->mail_set;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen tmp_set.mail_full_filesystem_access = TRUE;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen list->mail_set = &tmp_set;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen box = dbox_mailbox_alloc(&storage->storage, list, path, NULL,
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen MAILBOX_FLAG_IGNORE_ACLS |
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen MAILBOX_FLAG_KEEP_RECENT);
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen ret = mailbox_open(box);
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen list->mail_set = old_set;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen if (ret < 0) {
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen mailbox_close(&box);
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen return -1;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen }
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen mbox = (struct dbox_mailbox *)box;
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen /* get a list of all map_uids in this mailbox */
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen i_array_init(&map_uids, 128);
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen hdr = mail_index_get_header(mbox->ibox.view);
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen for (seq = 1; seq <= hdr->messages_count; seq++) {
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen mail_index_lookup_ext(mbox->ibox.view, seq, mbox->dbox_ext_id,
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen &data, &expunged);
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen dbox_rec = data;
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen if (dbox_rec == NULL) {
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen /* no multi-mails */
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen break;
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen }
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen if (dbox_rec->map_uid != 0)
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen array_append(&map_uids, &dbox_rec->map_uid, 1);
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen }
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen /* unreference the map_uids */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen map_trans = dbox_map_transaction_begin(storage->map, FALSE);
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen ret = dbox_map_update_refcounts(map_trans, &map_uids, -1);
7b42d6cbee8186195d8c5e66078043a0fa1f25c1Timo Sirainen if (ret == 0)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen ret = dbox_map_transaction_commit(map_trans);
7a77b948806106b46a33f3e6a3869657f49877fdTimo Sirainen dbox_map_transaction_free(&map_trans);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen array_free(&map_uids);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mailbox_close(&box);
7b42d6cbee8186195d8c5e66078043a0fa1f25c1Timo Sirainen return ret;
7b42d6cbee8186195d8c5e66078043a0fa1f25c1Timo Sirainen}
b7651d283ca261015ef3c445f1f27f340f0864e2Timo Sirainen
7b42d6cbee8186195d8c5e66078043a0fa1f25c1Timo Sirainenstatic const char *dbox_get_trash_dest(const char *trash_dir)
7b42d6cbee8186195d8c5e66078043a0fa1f25c1Timo Sirainen{
7b42d6cbee8186195d8c5e66078043a0fa1f25c1Timo Sirainen const char *path;
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen unsigned char randbuf[16];
7b42d6cbee8186195d8c5e66078043a0fa1f25c1Timo Sirainen struct stat st;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen do {
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen random_fill_weak(randbuf, sizeof(randbuf));
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen path = t_strconcat(trash_dir, "/",
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen binary_to_hex(randbuf, sizeof(randbuf)), NULL);
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen } while (lstat(path, &st) == 0);
1036ad17ac837a451f6b045cac504d3efa2edb8eTimo Sirainen return path;
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen}
1036ad17ac837a451f6b045cac504d3efa2edb8eTimo Sirainen
1036ad17ac837a451f6b045cac504d3efa2edb8eTimo Sirainenstatic int
1036ad17ac837a451f6b045cac504d3efa2edb8eTimo Sirainendbox_list_delete_mailbox(struct mailbox_list *list, const char *name)
a0b6b441fc679e562e79be0fb2819ffc24ab5b74Timo Sirainen{
a0b6b441fc679e562e79be0fb2819ffc24ab5b74Timo Sirainen struct dbox_mailbox_list *mlist = DBOX_LIST_CONTEXT(list);
89c8d5f336e44cca091a1f588d51ba26e5145ad2Timo Sirainen struct stat st;
89c8d5f336e44cca091a1f588d51ba26e5145ad2Timo Sirainen const char *path, *alt_path, *trash_dir, *trash_dest;
89c8d5f336e44cca091a1f588d51ba26e5145ad2Timo Sirainen bool deleted = FALSE;
89c8d5f336e44cca091a1f588d51ba26e5145ad2Timo Sirainen int ret;
f20e7fbdc9bdbe8fecb9c661c9b8175f3bb78c69Timo Sirainen
c0b1543512bc3e0a3a9f526056a3678a07ce32f5Timo Sirainen /* Make sure the indexes are closed before trying to delete the
a0b6b441fc679e562e79be0fb2819ffc24ab5b74Timo Sirainen directory that contains them. It can still fail with some NFS
a0b6b441fc679e562e79be0fb2819ffc24ab5b74Timo Sirainen implementations if indexes are opened by another session, but
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen that can't really be helped. */
a0b6b441fc679e562e79be0fb2819ffc24ab5b74Timo Sirainen index_storage_destroy_unrefed();
a0b6b441fc679e562e79be0fb2819ffc24ab5b74Timo Sirainen
a0b6b441fc679e562e79be0fb2819ffc24ab5b74Timo Sirainen /* delete the index and control directories */
1036ad17ac837a451f6b045cac504d3efa2edb8eTimo Sirainen if (mlist->module_ctx.super.delete_mailbox(list, name) < 0)
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen return -1;
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen path = mailbox_list_get_path(list, name,
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen trash_dir = mailbox_list_get_path(list, NULL,
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen MAILBOX_LIST_PATH_TYPE_DIR);
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen trash_dir = t_strconcat(trash_dir, "/"DBOX_TRASH_DIR_NAME, NULL);
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen trash_dest = dbox_get_trash_dest(trash_dir);
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen /* first try renaming the actual mailbox to trash directory */
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen ret = rename(path, trash_dest);
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen if (ret < 0 && errno == ENOENT) {
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen /* either source mailbox doesn't exist or trash directory
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen doesn't exist. try creating the trash and retrying. */
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen const char *origin;
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen mode_t mode;
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen gid_t gid;
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen mailbox_list_get_dir_permissions(list, NULL, &mode,
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen &gid, &origin);
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen if (mkdir_parents_chgrp(trash_dir, mode, gid, origin) < 0 &&
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen errno != EEXIST) {
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen mailbox_list_set_critical(list,
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen "mkdir(%s) failed: %m", trash_dir);
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen return -1;
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen }
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen ret = rename(path, trash_dest);
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen }
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen if (ret == 0) {
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen if (dbox_mailbox_unref_mails(list, trash_dest) < 0) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* we've already renamed it. there's no going back. */
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen mailbox_list_set_internal_error(list);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen ret = -1;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen }
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen if (unlink_directory(trash_dest, TRUE) < 0) {
5965eaa2d972e6264cecaf54091cd43019bc7d1fTimo Sirainen mailbox_list_set_critical(list,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "unlink_directory(%s) failed: %m", trash_dest);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen ret = -1;
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen }
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen /* if there's an alt path, delete it too */
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen alt_path = dbox_get_alt_path(list, path);
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen if (alt_path != NULL) {
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen if (unlink_directory(alt_path, TRUE) < 0) {
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen mailbox_list_set_critical(list,
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen "unlink_directory(%s) failed: %m", alt_path);
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen ret = -1;
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen }
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen }
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen /* try to delete the parent directory also */
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen deleted = TRUE;
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen path = mailbox_list_get_path(list, name,
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen MAILBOX_LIST_PATH_TYPE_DIR);
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen } else if (errno != ENOENT) {
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen mailbox_list_set_critical(list, "stat(%s) failed: %m", path);
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen return -1;
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen } else {
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen /* mailbox not found - what about the directory? */
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen path = mailbox_list_get_path(list, name,
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen MAILBOX_LIST_PATH_TYPE_DIR);
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen if (stat(path, &st) == 0) {
5965eaa2d972e6264cecaf54091cd43019bc7d1fTimo Sirainen /* delete the directory */
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen } else if (errno == ENOENT) {
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen return -1;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen } else if (!mailbox_list_set_error_from_errno(list)) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mailbox_list_set_critical(list, "stat(%s) failed: %m",
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen path);
3785910c303507db5f629684e6dde2cc7f83668eTimo Sirainen return -1;
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen }
3785910c303507db5f629684e6dde2cc7f83668eTimo Sirainen ret = 0;
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen }
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen
3785910c303507db5f629684e6dde2cc7f83668eTimo Sirainen alt_path = dbox_get_alt_path(list, path);
3785910c303507db5f629684e6dde2cc7f83668eTimo Sirainen if (alt_path != NULL)
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen (void)rmdir(alt_path);
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (rmdir(path) == 0)
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen return ret;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen else if (errno == ENOTEMPTY) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (deleted)
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen return ret;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen t_strdup_printf("Directory %s isn't empty, "
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "can't delete it.", name));
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen } else if (!mailbox_list_set_error_from_errno(list)) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mailbox_list_set_critical(list, "rmdir() failed for %s: %m",
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen path);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen }
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen return -1;
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen}
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic int
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainendbox_list_rename_get_alt_paths(struct mailbox_list *oldlist,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen const char *oldname,
37ab3cde96bfa4bc5304c0c348fc420aec79572dTimo Sirainen struct mailbox_list *newlist,
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen const char *newname,
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen enum mailbox_list_path_type path_type,
37ab3cde96bfa4bc5304c0c348fc420aec79572dTimo Sirainen const char **oldpath_r, const char **newpath_r)
37ab3cde96bfa4bc5304c0c348fc420aec79572dTimo Sirainen{
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen const char *path;
f4bbeadda12fbd7c219063db68f3e78646d83c2cTimo Sirainen
0b47e9f5e0181053b4d9ca7b426b0e5c185e820eTimo Sirainen path = mailbox_list_get_path(oldlist, oldname, path_type);
0b47e9f5e0181053b4d9ca7b426b0e5c185e820eTimo Sirainen *oldpath_r = dbox_get_alt_path(oldlist, path);
abe8754852e70763e92f74caabbcc13d0917714cTimo Sirainen if (*oldpath_r == NULL)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen return 0;
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen path = mailbox_list_get_path(newlist, newname, path_type);
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen *newpath_r = dbox_get_alt_path(newlist, path);
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen if (*newpath_r == NULL) {
90b8f131849540fa374aede95edd86d47d35c09dTimo Sirainen /* destination dbox storage doesn't have alt-path defined.
90b8f131849540fa374aede95edd86d47d35c09dTimo Sirainen we can't do the rename easily. */
90b8f131849540fa374aede95edd86d47d35c09dTimo Sirainen mailbox_list_set_error(oldlist, MAIL_ERROR_NOTPOSSIBLE,
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen "Can't rename mailboxes across specified storages.");
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen return -1;
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen }
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen return 1;
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen}
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainenstatic int
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainendbox_list_rename_mailbox_pre(struct mailbox_list *oldlist,
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen const char *oldname,
90b8f131849540fa374aede95edd86d47d35c09dTimo Sirainen struct mailbox_list *newlist,
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen const char *newname)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen{
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen const char *alt_oldpath, *alt_newpath;
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen struct stat st;
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen int ret;
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen ret = dbox_list_rename_get_alt_paths(oldlist, oldname, newlist, newname,
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen MAILBOX_LIST_PATH_TYPE_DIR,
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen &alt_oldpath, &alt_newpath);
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen if (ret <= 0)
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen return ret;
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen if (stat(alt_newpath, &st) == 0) {
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen /* race condition or a directory left there lying around?
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen safest to just report error. */
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen mailbox_list_set_error(oldlist, MAIL_ERROR_EXISTS,
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen "Target mailbox already exists");
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen return -1;
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen } else if (errno != ENOENT) {
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen mailbox_list_set_critical(oldlist, "stat(%s) failed: %m",
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen alt_newpath);
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen return -1;
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen }
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen return 0;
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen}
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainenstatic int
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainendbox_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname,
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen struct mailbox_list *newlist, const char *newname,
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen bool rename_children)
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen{
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen struct dbox_mailbox_list *oldmlist = DBOX_LIST_CONTEXT(oldlist);
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen enum mailbox_list_path_type path_type;
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen const char *alt_oldpath, *alt_newpath, *path;
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen int ret;
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen ret = oldmlist->module_ctx.super.
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen rename_mailbox(oldlist, oldname, newlist, newname,
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen rename_children);
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen if (ret < 0)
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen return -1;
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen path_type = rename_children ? MAILBOX_LIST_PATH_TYPE_DIR :
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX;
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen ret = dbox_list_rename_get_alt_paths(oldlist, oldname, newlist, newname,
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen path_type, &alt_oldpath,
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen &alt_newpath);
0928812e725cd3a4debab2a93d0c9b0436a4de9fTimo Sirainen if (ret <= 0)
97e62b2b36dda0acb3215667042f5c80cdee8155Timo Sirainen return ret;
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen if (rename(alt_oldpath, alt_newpath) == 0) {
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen /* ok */
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen if (!rename_children) {
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen path = mailbox_list_get_path(oldlist, oldname,
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainen MAILBOX_LIST_PATH_TYPE_DIR);
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainen if (rmdir(path) < 0 &&
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen errno != ENOENT && errno != ENOTEMPTY) {
0928812e725cd3a4debab2a93d0c9b0436a4de9fTimo Sirainen mailbox_list_set_critical(oldlist,
0928812e725cd3a4debab2a93d0c9b0436a4de9fTimo Sirainen "rmdir(%s) failed: %m", path);
0928812e725cd3a4debab2a93d0c9b0436a4de9fTimo Sirainen }
0928812e725cd3a4debab2a93d0c9b0436a4de9fTimo Sirainen }
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen } else if (errno != ENOENT) {
7d5d50dd9a8c2539d7025a69e39d34fca56daeafTimo Sirainen /* renaming is done already, so just log the error */
7d5d50dd9a8c2539d7025a69e39d34fca56daeafTimo Sirainen mailbox_list_set_critical(oldlist, "rename(%s, %s) failed: %m",
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen alt_oldpath, alt_newpath);
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen }
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen return 0;
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen}
dd2df6a67f10792ce31a3666197c0b6885893a3aTimo Sirainen
dd2df6a67f10792ce31a3666197c0b6885893a3aTimo Sirainenstatic void dbox_notify_changes(struct mailbox *box)
14175321ddb88619015866978c05a27786ca4814Timo Sirainen{
14175321ddb88619015866978c05a27786ca4814Timo Sirainen struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
14175321ddb88619015866978c05a27786ca4814Timo Sirainen const char *path;
14175321ddb88619015866978c05a27786ca4814Timo Sirainen
14175321ddb88619015866978c05a27786ca4814Timo Sirainen if (box->notify_callback == NULL)
14175321ddb88619015866978c05a27786ca4814Timo Sirainen index_mailbox_check_remove_all(&mbox->ibox);
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen else {
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen path = t_strdup_printf("%s/"DBOX_INDEX_PREFIX".log",
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen mbox->ibox.box.path);
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen index_mailbox_check_add(&mbox->ibox, path);
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen }
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen}
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainenstatic int dbox_list_iter_is_mailbox(struct mailbox_list_iterate_context *ctx
0928812e725cd3a4debab2a93d0c9b0436a4de9fTimo Sirainen ATTR_UNUSED,
14175321ddb88619015866978c05a27786ca4814Timo Sirainen const char *dir, const char *fname,
14175321ddb88619015866978c05a27786ca4814Timo Sirainen const char *mailbox_name ATTR_UNUSED,
14175321ddb88619015866978c05a27786ca4814Timo Sirainen enum mailbox_list_file_type type,
14175321ddb88619015866978c05a27786ca4814Timo Sirainen enum mailbox_info_flags *flags)
14175321ddb88619015866978c05a27786ca4814Timo Sirainen{
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen const char *path, *maildir_path;
439dd06aec3301e65d650f6dc1d4a1a00b356b4fTimo Sirainen struct stat st, st2;
439dd06aec3301e65d650f6dc1d4a1a00b356b4fTimo Sirainen int ret = 1;
439dd06aec3301e65d650f6dc1d4a1a00b356b4fTimo Sirainen
439dd06aec3301e65d650f6dc1d4a1a00b356b4fTimo Sirainen /* try to avoid stat() with these checks */
14175321ddb88619015866978c05a27786ca4814Timo Sirainen if (type != MAILBOX_LIST_FILE_TYPE_DIR &&
14175321ddb88619015866978c05a27786ca4814Timo Sirainen type != MAILBOX_LIST_FILE_TYPE_SYMLINK &&
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen type != MAILBOX_LIST_FILE_TYPE_UNKNOWN) {
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen /* it's a file */
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen *flags |= MAILBOX_NOSELECT | MAILBOX_NOINFERIORS;
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen return 0;
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen }
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen /* need to stat() then */
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen path = t_strconcat(dir, "/", fname, NULL);
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen if (stat(path, &st) == 0) {
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen if (!S_ISDIR(st.st_mode)) {
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen /* non-directory */
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen *flags |= MAILBOX_NOSELECT | MAILBOX_NOINFERIORS;
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen ret = 0;
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen } else if (st.st_nlink == 2) {
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen /* no subdirectories */
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen *flags |= MAILBOX_NOCHILDREN;
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen } else if (*ctx->list->set.maildir_name != '\0') {
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen /* default configuration: we have one directory
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen containing the mailboxes. if there are 3 links,
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen either this is a selectable mailbox without children
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen or non-selectable mailbox with children */
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen if (st.st_nlink > 3)
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen *flags |= MAILBOX_CHILDREN;
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen } else {
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen /* non-default configuration: all subdirectories are
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen child mailboxes. */
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen if (st.st_nlink > 2)
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen *flags |= MAILBOX_CHILDREN;
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen }
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen } else if (errno == ENOENT) {
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen /* doesn't exist - probably a non-existing subscribed mailbox */
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen *flags |= MAILBOX_NONEXISTENT;
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen } else {
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen /* non-selectable. probably either access denied, or symlink
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen destination not found. don't bother logging errors. */
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen *flags |= MAILBOX_NOSELECT;
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen }
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen if ((*flags & (MAILBOX_NOSELECT | MAILBOX_NONEXISTENT)) == 0) {
dd2df6a67f10792ce31a3666197c0b6885893a3aTimo Sirainen /* make sure it's a selectable mailbox */
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen maildir_path = t_strconcat(path, "/"DBOX_MAILDIR_NAME, NULL);
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen if (stat(maildir_path, &st2) < 0 || !S_ISDIR(st2.st_mode))
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen *flags |= MAILBOX_NOSELECT;
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen if (st.st_nlink == 3 && *ctx->list->set.maildir_name != '\0') {
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen /* now we know what link count 3 means. */
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen if ((*flags & MAILBOX_NOSELECT) != 0)
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen *flags |= MAILBOX_CHILDREN;
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen else
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen *flags |= MAILBOX_NOCHILDREN;
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen }
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen }
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen return ret;
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen}
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainenstatic void dbox_storage_add_list(struct mail_storage *storage,
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen struct mailbox_list *list)
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen{
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen struct dbox_mailbox_list *mlist;
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen mlist = p_new(list->pool, struct dbox_mailbox_list, 1);
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen mlist->module_ctx.super = list->v;
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen mlist->set = mail_storage_get_driver_settings(storage);
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen list->v.iter_is_mailbox = dbox_list_iter_is_mailbox;
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen list->v.delete_mailbox = dbox_list_delete_mailbox;
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen list->v.rename_mailbox = dbox_list_rename_mailbox;
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen list->v.rename_mailbox_pre = dbox_list_rename_mailbox_pre;
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen MODULE_CONTEXT_SET(list, dbox_mailbox_list_module, mlist);
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen}
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainenstruct mail_storage dbox_storage = {
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen MEMBER(name) DBOX_STORAGE_NAME,
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen MEMBER(class_flags) MAIL_STORAGE_CLASS_FLAG_UNIQUE_ROOT, /* FIXME: for multi-dbox only.. */
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen {
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen dbox_get_setting_parser_info,
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen dbox_storage_alloc,
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen dbox_storage_create,
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen dbox_storage_destroy,
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen dbox_storage_add_list,
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen dbox_storage_get_list_settings,
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen NULL,
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen dbox_mailbox_alloc,
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen dbox_sync_purge
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen }
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen};
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainenstruct mailbox dbox_mailbox = {
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen MEMBER(name) NULL,
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen MEMBER(storage) NULL,
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen MEMBER(list) NULL,
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen {
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen index_storage_is_readonly,
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen index_storage_allow_new_keywords,
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen index_storage_mailbox_enable,
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen dbox_mailbox_open,
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen dbox_mailbox_close,
01e606cda5192c4254c090624a0b2ca92da6da8eTimo Sirainen dbox_mailbox_create,
01e606cda5192c4254c090624a0b2ca92da6da8eTimo Sirainen dbox_mailbox_update,
01e606cda5192c4254c090624a0b2ca92da6da8eTimo Sirainen dbox_storage_get_status,
01e606cda5192c4254c090624a0b2ca92da6da8eTimo Sirainen NULL,
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen NULL,
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen dbox_storage_sync_init,
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen index_mailbox_sync_next,
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen index_mailbox_sync_deinit,
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen NULL,
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen dbox_notify_changes,
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen index_transaction_begin,
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen index_transaction_commit,
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen index_transaction_rollback,
01e606cda5192c4254c090624a0b2ca92da6da8eTimo Sirainen index_transaction_set_max_modseq,
01e606cda5192c4254c090624a0b2ca92da6da8eTimo Sirainen index_keywords_create,
01e606cda5192c4254c090624a0b2ca92da6da8eTimo Sirainen index_keywords_create_from_indexes,
01e606cda5192c4254c090624a0b2ca92da6da8eTimo Sirainen index_keywords_ref,
54bd0fec0be357266e299466a582f3c9269884e9Timo Sirainen index_keywords_unref,
204ee6ed414f5e4eeb6f6c10763b55daf56f11acJosef 'Jeff' Sipek index_keyword_is_valid,
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen index_storage_get_seq_range,
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen index_storage_get_uid_range,
032964c7cc6788188b63ae6270fc26cbd4a3ca26Timo Sirainen index_storage_get_expunges,
032964c7cc6788188b63ae6270fc26cbd4a3ca26Timo Sirainen NULL,
032964c7cc6788188b63ae6270fc26cbd4a3ca26Timo Sirainen NULL,
032964c7cc6788188b63ae6270fc26cbd4a3ca26Timo Sirainen NULL,
032964c7cc6788188b63ae6270fc26cbd4a3ca26Timo Sirainen dbox_mail_alloc,
032964c7cc6788188b63ae6270fc26cbd4a3ca26Timo Sirainen index_header_lookup_init,
032964c7cc6788188b63ae6270fc26cbd4a3ca26Timo Sirainen index_header_lookup_deinit,
032964c7cc6788188b63ae6270fc26cbd4a3ca26Timo Sirainen index_storage_search_init,
032964c7cc6788188b63ae6270fc26cbd4a3ca26Timo Sirainen index_storage_search_deinit,
032964c7cc6788188b63ae6270fc26cbd4a3ca26Timo Sirainen index_storage_search_next_nonblock,
12a3540693ab69ec622e04d1b3b66962b8b2a3d9Timo Sirainen index_storage_search_next_update_seq,
12a3540693ab69ec622e04d1b3b66962b8b2a3d9Timo Sirainen dbox_save_alloc,
12a3540693ab69ec622e04d1b3b66962b8b2a3d9Timo Sirainen dbox_save_begin,
12a3540693ab69ec622e04d1b3b66962b8b2a3d9Timo Sirainen dbox_save_continue,
66d84e6f0ae34a3cf5b8fa8e009d6caf025b6a2aTimo Sirainen dbox_save_finish,
66d84e6f0ae34a3cf5b8fa8e009d6caf025b6a2aTimo Sirainen dbox_save_cancel,
12a3540693ab69ec622e04d1b3b66962b8b2a3d9Timo Sirainen dbox_copy,
12a3540693ab69ec622e04d1b3b66962b8b2a3d9Timo Sirainen index_storage_is_inconsistent
12a3540693ab69ec622e04d1b3b66962b8b2a3d9Timo Sirainen }
12a3540693ab69ec622e04d1b3b66962b8b2a3d9Timo Sirainen};
12a3540693ab69ec622e04d1b3b66962b8b2a3d9Timo Sirainen