dbox-storage.c revision 6bc5fed79741503437c6d46d9f282b66bd029c6b
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
d6684856fb99e51bc22a6346e08b2d81c996f963Josef 'Jeff' Sipekstatic MODULE_CONTEXT_DEFINE_INIT(dbox_mailbox_list_module,
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainenstatic struct mail_storage *dbox_storage_alloc(void)
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen pool = pool_alloconly_create("dbox storage", 512+256);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen storage = p_new(pool, struct dbox_storage, 1);
b3fc5293379feb3640b23622bcc8f5f8d7f1e81dJosef 'Jeff' Sipekdbox_storage_create(struct mail_storage *_storage, struct mail_namespace *ns,
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen storage->set = mail_storage_get_driver_settings(_storage);
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen i_assert(storage->set->dbox_max_open_files >= 2);
5a1b498b646b5c5dbd1b3f3861df766f560578c5Timo Sirainen if (*ns->list->set.mailbox_dir_name == '\0') {
204ee6ed414f5e4eeb6f6c10763b55daf56f11acJosef 'Jeff' Sipek *error_r = "dbox: MAILBOXDIR must not be empty";
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen p_strdup(_storage->pool, ns->list->set.root_dir);
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,
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen storage->alt_storage_dir = p_strconcat(_storage->pool,
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen I_MIN(storage->set->dbox_max_open_files, 128));
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen mailbox_list_get_dir_permissions(ns->list, NULL, &storage->create_mode,
c28f6aa0b70af4811c9ace9114fe827c2f503455Timo Sirainen storage->create_gid_origin = p_strdup(_storage->pool, origin);
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainenstatic void dbox_storage_destroy(struct mail_storage *_storage)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainendbox_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen set->subscription_fname = DBOX_SUBSCRIPTION_FILE_NAME;
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen set->dir_guid_fname = DBOX_DIR_GUID_FILE_NAME;
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen set->mailbox_dir_name = DBOX_MAILBOX_DIR_NAME;
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainenstatic const char *
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainendbox_get_alt_path(struct mailbox_list *list, const char *path)
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen#if 0 // FIXME
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen unsigned int len;
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen root = mailbox_list_get_path(storage->storage.list, NULL,
0a49b316fc729e5d57268ffa63c7122ac73f994cTimo Sirainen if (strncmp(path, root, len) != 0 && path[len] == '/') {
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen /* can't determine the alt path - shouldn't happen */
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen return t_strconcat(storage->alt_dir, path + len, NULL);
0a49b316fc729e5d57268ffa63c7122ac73f994cTimo Sirainendbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen /* dbox can't work without index files */
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen pool = pool_alloconly_create("dbox mailbox", 1024+512);
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 index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen mbox->ibox.index_flags |= MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS |
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen mbox->storage = (struct dbox_storage *)storage;
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen p_strdup(pool, dbox_get_alt_path(list, mbox->ibox.box.path));
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen mail_index_ext_register(mbox->ibox.index, "dbox", 0,
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen mail_index_ext_register(mbox->ibox.index, "dbox-hdr",
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen sizeof(struct dbox_index_header), 0, 0);
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen mail_index_ext_register(mbox->ibox.index, "guid",
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen mbox->maildir_uidlist = maildir_uidlist_init_readonly(&mbox->ibox);
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainenuint32_t dbox_get_uidvalidity_next(struct mailbox_list *list)
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen path = t_strconcat(path, "/"DBOX_UIDVALIDITY_FILE_NAME, NULL);
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainenint dbox_read_header(struct dbox_mailbox *mbox, struct dbox_index_header *hdr)
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen mail_index_get_header_ext(mbox->ibox.view, mbox->dbox_hdr_ext_id,
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen mail_storage_set_critical(&mbox->storage->storage,
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen "dbox %s: Invalid dbox header size",
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr)));
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainenvoid dbox_update_header(struct dbox_mailbox *mbox,
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen if (update != NULL && !mail_guid_128_is_empty(update->mailbox_guid)) {
82ea464c113f43aaa2b2e23de334cf3081c332beTimo Sirainen memcpy(new_hdr.mailbox_guid, update->mailbox_guid,
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen } else if (mail_guid_128_is_empty(new_hdr.mailbox_guid)) {
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,
9e095dd6a77097356aca8216356d4d71ef1bea45Timo Sirainenstatic int dbox_write_index_header(struct mailbox *box,
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen if (dbox_map_open(mbox->storage->map, TRUE) < 0)
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen trans = mail_index_transaction_begin(mbox->ibox.view, 0);
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen if (update != NULL && update->uid_validity != 0)
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen /* set uidvalidity */
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen uid_validity = dbox_get_uidvalidity_next(box->list);
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen offsetof(struct mail_index_header, uid_validity),
e4c81823af1fc43ca3f2ce9eb4af7fc8f57b13a5Timo Sirainen if (update != NULL && hdr->next_uid < update->min_next_uid) {
fb502495e9306fe51e9d2c0019e622a98e9803abTimo Sirainen if (update != NULL && update->min_highest_modseq != 0 &&
fb502495e9306fe51e9d2c0019e622a98e9803abTimo Sirainen mail_index_modseq_get_highest(mbox->ibox.view) <
fb502495e9306fe51e9d2c0019e622a98e9803abTimo Sirainen if (mail_index_transaction_commit(&trans) < 0) {
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen mail_storage_set_internal_error(box->storage);
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainenstatic int dbox_mailbox_create_indexes(struct mailbox *box,
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
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 (!mail_storage_set_error_from_errno(box->storage)) {
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainendbox_cleanup_if_exists(struct mailbox_list *list, const char *path)
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 =
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen "dbox doesn't support streamed mailboxes");
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen if (dbox_cleanup_if_exists(box->list, box->path)) {
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)
52041ed691a26ca80e4e805765e9f55ec097c8f1Martti Rannanjärvi mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainenstatic void dbox_mailbox_close(struct mailbox *box)
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen maildir_uidlist_deinit(&mbox->maildir_uidlist);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void dbox_storage_get_status_guid(struct mailbox *box,
601f5f14c6cde28f0e0c6ca7c5d735315d3d48dfTimo Sirainen struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen if (mail_guid_128_is_empty(hdr.mailbox_guid)) {
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen /* regenerate it */
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen memcpy(status_r->mailbox_guid, hdr.mailbox_guid,
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainendbox_storage_get_status(struct mailbox *box, enum mailbox_status_items items,
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen index_storage_get_status(box, items, status_r);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainendbox_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen path = mailbox_list_get_path(box->list, box->name,
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen "Mailbox already exists");
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Sirainen mailbox_list_get_dir_permissions(box->list, NULL, &mode,
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Sirainen if (mkdir_parents_chgrp(path, mode, gid, origin) == 0)
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)) {
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 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");
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainen return dbox_mailbox_create_indexes(box, update);
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainendbox_mailbox_update(struct mailbox *box, const struct mailbox_update *update)
923115fd382904fa13bb09bf307bf2835b52df60Timo Sirainendbox_mailbox_unref_mails(struct mailbox_list *list, const char *path)
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)list->ns->storage;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen const struct dbox_mail_index_record *dbox_rec;
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen struct dbox_map_transaction_context *map_trans;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen box = dbox_mailbox_alloc(&storage->storage, list, path, NULL,
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen /* get a list of all map_uids in this mailbox */
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 /* no multi-mails */
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen array_append(&map_uids, &dbox_rec->map_uid, 1);
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 Sirainenstatic const char *dbox_get_trash_dest(const char *trash_dir)
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen binary_to_hex(randbuf, sizeof(randbuf)), NULL);
1036ad17ac837a451f6b045cac504d3efa2edb8eTimo Sirainendbox_list_delete_mailbox(struct mailbox_list *list, const char *name)
a0b6b441fc679e562e79be0fb2819ffc24ab5b74Timo Sirainen struct dbox_mailbox_list *mlist = DBOX_LIST_CONTEXT(list);
89c8d5f336e44cca091a1f588d51ba26e5145ad2Timo Sirainen const char *path, *alt_path, *trash_dir, *trash_dest;
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 /* delete the index and control directories */
1036ad17ac837a451f6b045cac504d3efa2edb8eTimo Sirainen if (mlist->module_ctx.super.delete_mailbox(list, name) < 0)
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen trash_dir = t_strconcat(trash_dir, "/"DBOX_TRASH_DIR_NAME, NULL);
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen /* first try renaming the actual mailbox to trash directory */
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen /* either source mailbox doesn't exist or trash directory
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen doesn't exist. try creating the trash and retrying. */
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen mailbox_list_get_dir_permissions(list, NULL, &mode,
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen if (mkdir_parents_chgrp(trash_dir, mode, gid, origin) < 0 &&
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen if (dbox_mailbox_unref_mails(list, trash_dest) < 0) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* we've already renamed it. there's no going back. */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "unlink_directory(%s) failed: %m", trash_dest);
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen /* if there's an alt path, delete it too */
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen /* try to delete the parent directory also */
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen mailbox_list_set_critical(list, "stat(%s) failed: %m", path);
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen /* mailbox not found - what about the directory? */
5965eaa2d972e6264cecaf54091cd43019bc7d1fTimo Sirainen /* delete the directory */
f5982bb5b0a704e88fa2b44b0b74e365d13103b9Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen } else if (!mailbox_list_set_error_from_errno(list)) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mailbox_list_set_critical(list, "stat(%s) failed: %m",
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen } else if (!mailbox_list_set_error_from_errno(list)) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mailbox_list_set_critical(list, "rmdir() failed for %s: %m",
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainendbox_list_rename_get_alt_paths(struct mailbox_list *oldlist,
37ab3cde96bfa4bc5304c0c348fc420aec79572dTimo Sirainen const char **oldpath_r, const char **newpath_r)
0b47e9f5e0181053b4d9ca7b426b0e5c185e820eTimo Sirainen path = mailbox_list_get_path(oldlist, oldname, path_type);
0b47e9f5e0181053b4d9ca7b426b0e5c185e820eTimo Sirainen *oldpath_r = dbox_get_alt_path(oldlist, path);
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen path = mailbox_list_get_path(newlist, newname, path_type);
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen *newpath_r = dbox_get_alt_path(newlist, path);
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.");
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainendbox_list_rename_mailbox_pre(struct mailbox_list *oldlist,
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen ret = dbox_list_rename_get_alt_paths(oldlist, oldname, newlist, newname,
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 mailbox_list_set_critical(oldlist, "stat(%s) failed: %m",
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainendbox_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname,
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen struct mailbox_list *newlist, const char *newname,
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen struct dbox_mailbox_list *oldmlist = DBOX_LIST_CONTEXT(oldlist);
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen rename_mailbox(oldlist, oldname, newlist, newname,
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen path_type = rename_children ? MAILBOX_LIST_PATH_TYPE_DIR :
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen ret = dbox_list_rename_get_alt_paths(oldlist, oldname, newlist, newname,
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen path = mailbox_list_get_path(oldlist, oldname,
7d5d50dd9a8c2539d7025a69e39d34fca56daeafTimo Sirainen /* renaming is done already, so just log the error */
7d5d50dd9a8c2539d7025a69e39d34fca56daeafTimo Sirainen mailbox_list_set_critical(oldlist, "rename(%s, %s) failed: %m",
dd2df6a67f10792ce31a3666197c0b6885893a3aTimo Sirainenstatic void dbox_notify_changes(struct mailbox *box)
14175321ddb88619015866978c05a27786ca4814Timo Sirainen struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen path = t_strdup_printf("%s/"DBOX_INDEX_PREFIX".log",
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainenstatic int dbox_list_iter_is_mailbox(struct mailbox_list_iterate_context *ctx
439dd06aec3301e65d650f6dc1d4a1a00b356b4fTimo Sirainen /* try to avoid stat() with these checks */
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen /* it's a file */
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen *flags |= MAILBOX_NOSELECT | MAILBOX_NOINFERIORS;
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen /* need to stat() then */
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen /* non-directory */
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen *flags |= MAILBOX_NOSELECT | MAILBOX_NOINFERIORS;
51d379cbc50242a13462d0fded50e013eb00cc07Timo Sirainen /* no subdirectories */
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 */
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen /* non-default configuration: all subdirectories are
5ca745ae8e9903ef5265360e4c882e9314595020Timo Sirainen child mailboxes. */
c7acd38cd4ef76a0f4652f9ca659ea5e64458b52Timo Sirainen /* doesn't exist - probably a non-existing subscribed mailbox */
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen /* non-selectable. probably either access denied, or symlink
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen destination not found. don't bother logging errors. */
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 if (st.st_nlink == 3 && *ctx->list->set.maildir_name != '\0') {
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen /* now we know what link count 3 means. */
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainenstatic void dbox_storage_add_list(struct mail_storage *storage,
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen mlist = p_new(list->pool, struct dbox_mailbox_list, 1);
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen mlist->set = mail_storage_get_driver_settings(storage);
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 MODULE_CONTEXT_SET(list, dbox_mailbox_list_module, mlist);
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen MEMBER(class_flags) MAIL_STORAGE_CLASS_FLAG_UNIQUE_ROOT, /* FIXME: for multi-dbox only.. */