virtual-storage.c revision 8305127d1074cf9a1e25dec9be2735276462079d
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2008-2010 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "array.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "ioloop.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "str.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mkdir-parents.h"
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen#include "unlink-directory.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "index-mail.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-copy.h"
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen#include "mail-search.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "virtual-plugin.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "virtual-transaction.h"
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainen#include "virtual-storage.h"
56561d472db25ebda35ae6afdc7f7deb75c323fcTimo Sirainen
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen#include <stdio.h>
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen#include <stdlib.h>
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen#include <unistd.h>
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen#include <dirent.h>
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen#include <sys/stat.h>
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define VIRTUAL_LIST_CONTEXT(obj) \
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MODULE_CONTEXT(obj, virtual_mailbox_list_module)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct virtual_mailbox_list {
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen union mailbox_list_module_context module_ctx;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen};
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
b6612c334604eeb27e1ca2bd804ac66dcbc2eaadTimo Sirainenextern struct mail_storage virtual_storage;
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainenextern struct mailbox virtual_mailbox;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstruct virtual_storage_module virtual_storage_module =
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen MODULE_CONTEXT_INIT(&mail_storage_module_register);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(virtual_mailbox_list_module,
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen &mailbox_list_module_register);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainenstatic bool ns_is_visible(struct mail_namespace *ns)
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen{
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen return (ns->flags & NAMESPACE_FLAG_LIST_PREFIX) != 0 ||
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen (ns->flags & NAMESPACE_FLAG_LIST_CHILDREN) != 0 ||
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (ns->flags & NAMESPACE_FLAG_HIDDEN) == 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
49e9acb52bb5d328f8cf10bce1082c4bc213caeaTimo Sirainenstatic const char *get_user_visible_mailbox_name(struct mailbox *box)
407d64647d77771080eb75f800162014927f10c6Timo Sirainen{
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen if (ns_is_visible(box->list->ns))
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen return box->vname;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen else {
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen return t_strdup_printf("<hidden>%c%s",
1f4f81ba81bb9fa8abe2d94f344373c230066d67Timo Sirainen box->list->hierarchy_sep, box->name);
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen }
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen}
407d64647d77771080eb75f800162014927f10c6Timo Sirainen
407d64647d77771080eb75f800162014927f10c6Timo Sirainenvoid virtual_box_copy_error(struct mailbox *dest, struct mailbox *src)
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen{
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen const char *name, *str;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen enum mail_error error;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen name = get_user_visible_mailbox_name(src);
1da9587dfb6632ac6446ad12b09fdf77c8542e2cTimo Sirainen str = mail_storage_get_last_error(src->storage, &error);
1da9587dfb6632ac6446ad12b09fdf77c8542e2cTimo Sirainen
1da9587dfb6632ac6446ad12b09fdf77c8542e2cTimo Sirainen str = t_strdup_printf("%s (for backend mailbox %s)", str, name);
1da9587dfb6632ac6446ad12b09fdf77c8542e2cTimo Sirainen mail_storage_set_error(dest->storage, error, str);
1da9587dfb6632ac6446ad12b09fdf77c8542e2cTimo Sirainen}
1da9587dfb6632ac6446ad12b09fdf77c8542e2cTimo Sirainen
1da9587dfb6632ac6446ad12b09fdf77c8542e2cTimo Sirainenstatic struct mail_storage *virtual_storage_alloc(void)
1da9587dfb6632ac6446ad12b09fdf77c8542e2cTimo Sirainen{
1da9587dfb6632ac6446ad12b09fdf77c8542e2cTimo Sirainen struct virtual_storage *storage;
1da9587dfb6632ac6446ad12b09fdf77c8542e2cTimo Sirainen pool_t pool;
1da9587dfb6632ac6446ad12b09fdf77c8542e2cTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen pool = pool_alloconly_create("virtual storage", 1024);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen storage = p_new(pool, struct virtual_storage, 1);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen storage->storage = virtual_storage;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen storage->storage.pool = pool;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen p_array_init(&storage->open_stack, pool, 8);
1f4f81ba81bb9fa8abe2d94f344373c230066d67Timo Sirainen return &storage->storage;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainenstatic void
49e9acb52bb5d328f8cf10bce1082c4bc213caeaTimo Sirainenvirtual_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen struct mailbox_list_settings *set)
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (set->layout == NULL)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen set->layout = MAILBOX_LIST_NAME_FS;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen if (set->subscription_fname == NULL)
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen set->subscription_fname = VIRTUAL_SUBSCRIPTION_FILE_NAME;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen}
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainenstruct virtual_backend_box *
c680a6b35b459045e92814778908da5a93922107Timo Sirainenvirtual_backend_box_lookup_name(struct virtual_mailbox *mbox, const char *name)
c680a6b35b459045e92814778908da5a93922107Timo Sirainen{
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen struct virtual_backend_box *const *bboxes;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen unsigned int i, count;
407d64647d77771080eb75f800162014927f10c6Timo Sirainen
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen bboxes = array_get(&mbox->backend_boxes, &count);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen for (i = 0; i < count; i++) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (strcmp(bboxes[i]->name, name) == 0)
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen return bboxes[i];
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return NULL;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstruct virtual_backend_box *
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenvirtual_backend_box_lookup(struct virtual_mailbox *mbox, uint32_t mailbox_id)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct virtual_backend_box *const *bboxes;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen unsigned int i, count;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (mailbox_id == 0)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return NULL;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen bboxes = array_get(&mbox->backend_boxes, &count);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen for (i = 0; i < count; i++) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (bboxes[i]->mailbox_id == mailbox_id)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return bboxes[i];
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return NULL;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic bool virtual_mailbox_is_in_open_stack(struct virtual_storage *storage,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen const char *name)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen const char *const *names;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen unsigned int i, count;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen names = array_get(&storage->open_stack, &count);
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen for (i = 0; i < count; i++) {
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen if (strcmp(names[i], name) == 0)
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen return TRUE;
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen }
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen return FALSE;
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen}
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainenstatic int virtual_backend_box_open_failed(struct virtual_mailbox *mbox,
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen struct virtual_backend_box *bbox)
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen{
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen enum mail_error error;
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen const char *str, *name;
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen str = mail_storage_get_last_error(mailbox_get_storage(bbox->box),
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen &error);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen name = t_strdup(get_user_visible_mailbox_name(bbox->box));
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen mailbox_free(&bbox->box);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen if (bbox->wildcard &&
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen (error == MAIL_ERROR_PERM || error == MAIL_ERROR_NOTFOUND)) {
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen /* this mailbox wasn't explicitly specified. just skip it. */
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen return 0;
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen }
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen if (error == MAIL_ERROR_NOTFOUND) {
86bde2c1838d1ce967fa2b394bb952004a4adcb7Timo Sirainen /* the virtual mailbox exists, we just can't open it.
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen change the error type. */
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen error = MAIL_ERROR_NOTPOSSIBLE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen str = t_strdup_printf(
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen "Virtual mailbox open failed because of mailbox %s: %s",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen name, str);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_storage_set_error(mbox->box.storage, error, str);
659fe5d24825b160cae512538088020d97a60239Timo Sirainen return -1;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen}
659fe5d24825b160cae512538088020d97a60239Timo Sirainen
659fe5d24825b160cae512538088020d97a60239Timo Sirainenstatic int virtual_backend_box_open(struct virtual_mailbox *mbox,
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen struct virtual_backend_box *bbox,
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen enum mailbox_flags flags)
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen{
3f99d19bf3361a4b0952e4e3ad64d4d6988de469Timo Sirainen struct mail_user *user = mbox->storage->storage.user;
b43bb773ee6534c1013b01a62fbd5703e3b0d17dTimo Sirainen struct mail_namespace *ns;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen const char *mailbox;
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen flags |= MAILBOX_FLAG_KEEP_RECENT;
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen mailbox = bbox->name;
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen ns = mail_namespace_find(user->namespaces, &mailbox);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen bbox->box = mailbox_alloc(ns->list, mailbox, flags);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen if (mailbox_open(bbox->box) < 0)
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen return virtual_backend_box_open_failed(mbox, bbox);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen i_array_init(&bbox->uids, 64);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen i_array_init(&bbox->sync_pending_removes, 64);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen mail_search_args_init(bbox->search_args, bbox->box, FALSE, NULL);
659fe5d24825b160cae512538088020d97a60239Timo Sirainen return 1;
b43bb773ee6534c1013b01a62fbd5703e3b0d17dTimo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic int virtual_mailboxes_open(struct virtual_mailbox *mbox,
f4ca89823693b9faa82a0c39c24510a7b0e606afTimo Sirainen enum mailbox_flags flags)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct virtual_backend_box *const *bboxes;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen unsigned int i, count;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen int ret;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen bboxes = array_get(&mbox->backend_boxes, &count);
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen for (i = 0; i < count; ) {
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen ret = virtual_backend_box_open(mbox, bboxes[i], flags);
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen if (ret <= 0) {
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen if (ret < 0)
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen break;
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen mail_search_args_unref(&bboxes[i]->search_args);
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen array_delete(&mbox->backend_boxes, i, 1);
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen bboxes = array_get(&mbox->backend_boxes, &count);
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen } else {
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen i++;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen }
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen }
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen if (i == count)
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen return 0;
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen else {
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen /* failed */
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen for (; i > 0; i--) {
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen mailbox_free(&bboxes[i-1]->box);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen array_free(&bboxes[i-1]->uids);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen }
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen return -1;
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen }
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen}
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainenstatic struct mailbox *
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainenvirtual_mailbox_alloc(struct mail_storage *_storage, struct mailbox_list *list,
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen const char *name, enum mailbox_flags flags)
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen{
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen struct virtual_storage *storage = (struct virtual_storage *)_storage;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen struct virtual_mailbox *mbox;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen pool_t pool;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen pool = pool_alloconly_create("virtual mailbox", 1024+512);
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen mbox = p_new(pool, struct virtual_mailbox, 1);
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen mbox->box = virtual_mailbox;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen mbox->box.pool = pool;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen mbox->box.storage = _storage;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen mbox->box.list = list;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen mbox->box.mail_vfuncs = &virtual_mail_vfuncs;
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen index_storage_mailbox_alloc(&mbox->box, name, flags,
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen VIRTUAL_INDEX_PREFIX);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen mbox->storage = storage;
220195605754218b4d6e3a51f5a25be9d0e202e0Timo Sirainen mbox->vseq_lookup_prev_mailbox = i_strdup("");
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen mbox->virtual_ext_id =
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen mail_index_ext_register(mbox->box.index, "virtual", 0,
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen sizeof(struct virtual_mail_index_record),
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen sizeof(uint32_t));
220195605754218b4d6e3a51f5a25be9d0e202e0Timo Sirainen return &mbox->box;
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen}
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainenstatic void virtual_mailbox_close_internal(struct virtual_mailbox *mbox)
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen{
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen struct virtual_backend_box **bboxes;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen unsigned int i, count;
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen bboxes = array_get_modifiable(&mbox->backend_boxes, &count);
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen for (i = 0; i < count; i++) {
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen if (bboxes[i]->search_result != NULL)
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen mailbox_search_result_free(&bboxes[i]->search_result);
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen if (bboxes[i]->box == NULL)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen continue;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_search_args_deinit(bboxes[i]->search_args);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mailbox_free(&bboxes[i]->box);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (array_is_created(&bboxes[i]->sync_outside_expunges))
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen array_free(&bboxes[i]->sync_outside_expunges);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen array_free(&bboxes[i]->sync_pending_removes);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen array_free(&bboxes[i]->uids);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen i_free_and_null(mbox->vseq_lookup_prev_mailbox);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic int virtual_mailbox_open(struct mailbox *box)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct stat st;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen int ret = 0;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (virtual_mailbox_is_in_open_stack(mbox->storage, box->name)) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_storage_set_critical(box->storage,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen "Virtual mailbox loops: %s", box->name);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return -1;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
ee248252648e99f5d701ecd6e33640ea77e11cb7Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (stat(box->path, &st) == 0) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen /* exists, open it */
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen } else if (errno == ENOENT) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return -1;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen } else if (errno == EACCES) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_storage_set_critical(box->storage, "%s",
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_error_eacces_msg("stat", box->path));
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return -1;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen } else {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_storage_set_critical(box->storage,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen "stat(%s) failed: %m", box->path);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return -1;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (!array_is_created(&mbox->backend_boxes))
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen ret = virtual_config_read(mbox);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (ret == 0) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen array_append(&mbox->storage->open_stack, &box->name, 1);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen ret = virtual_mailboxes_open(mbox, box->flags);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen array_delete(&mbox->storage->open_stack,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen array_count(&mbox->storage->open_stack)-1, 1);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (ret < 0) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen virtual_mailbox_close_internal(mbox);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return -1;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return index_storage_mailbox_open(box, FALSE);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic void virtual_mailbox_close(struct mailbox *box)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen virtual_mailbox_close_internal(mbox);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen index_storage_mailbox_close(box);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic void virtual_mailbox_free(struct mailbox *box)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen virtual_config_free(mbox);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen index_storage_mailbox_free(box);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic int
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainenvirtual_mailbox_create(struct mailbox *box,
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen const struct mailbox_update *update ATTR_UNUSED,
b6612c334604eeb27e1ca2bd804ac66dcbc2eaadTimo Sirainen bool directory ATTR_UNUSED)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
1df526903ed039e8ff966a223c43b8d04eddf3c7Phil Carmody "Can't create virtual mailboxes");
1df526903ed039e8ff966a223c43b8d04eddf3c7Phil Carmody return -1;
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic int
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenvirtual_mailbox_update(struct mailbox *box,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen const struct mailbox_update *update ATTR_UNUSED)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen "Can't update virtual mailboxes");
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return -1;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic int
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenvirtual_mailbox_get_guid(struct mailbox *box,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen uint8_t guid[MAIL_GUID_128_SIZE] ATTR_UNUSED)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen "Virtual mailboxes have no GUIDs");
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return -1;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic void virtual_notify_changes(struct mailbox *box ATTR_UNUSED)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen /* FIXME: maybe some day */
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic int
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenvirtual_list_get_mailbox_flags(struct mailbox_list *list,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen const char *dir, const char *fname,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen enum mailbox_list_file_type type,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct stat *st_r,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen enum mailbox_info_flags *flags)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct virtual_mailbox_list *mlist = VIRTUAL_LIST_CONTEXT(list);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct stat st2;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen const char *virtual_path;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen int ret;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen ret = mlist->module_ctx.super.
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen get_mailbox_flags(list, dir, fname, type, st_r, flags);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (ret <= 0 || MAILBOX_INFO_FLAGS_FINISHED(*flags))
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen return ret;
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen /* see if it's a selectable mailbox */
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen virtual_path = t_strconcat(dir, "/", fname, "/"VIRTUAL_CONFIG_FNAME,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen NULL);
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen if (stat(virtual_path, &st2) < 0)
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen *flags |= MAILBOX_NOSELECT;
b6612c334604eeb27e1ca2bd804ac66dcbc2eaadTimo Sirainen return ret;
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen}
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainenstatic void virtual_storage_add_list(struct mail_storage *storage ATTR_UNUSED,
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen struct mailbox_list *list)
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen{
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen struct virtual_mailbox_list *mlist;
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen
b6612c334604eeb27e1ca2bd804ac66dcbc2eaadTimo Sirainen mlist = p_new(list->pool, struct virtual_mailbox_list, 1);
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen mlist->module_ctx.super = list->v;
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen list->ns->flags |= NAMESPACE_FLAG_NOQUOTA;
b6612c334604eeb27e1ca2bd804ac66dcbc2eaadTimo Sirainen list->v.get_mailbox_flags = virtual_list_get_mailbox_flags;
b6612c334604eeb27e1ca2bd804ac66dcbc2eaadTimo Sirainen
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen MODULE_CONTEXT_SET(list, virtual_mailbox_list_module, mlist);
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic int virtual_backend_uidmap_cmp(const uint32_t *uid,
86bde2c1838d1ce967fa2b394bb952004a4adcb7Timo Sirainen const struct virtual_backend_uidmap *map)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return *uid < map->real_uid ? -1 :
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen *uid > map->real_uid ? 1 : 0;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic bool
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenvirtual_get_virtual_uid(struct mailbox *box, const char *backend_mailbox,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen uint32_t backend_uidvalidity,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen uint32_t backend_uid, uint32_t *uid_r)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct virtual_backend_box *bbox;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct mailbox_status status;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen const struct virtual_backend_uidmap *uids;
7604ee75aa54ab2e400de45999e326c358bc2d24Phil Carmody
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (strcmp(mbox->vseq_lookup_prev_mailbox, backend_mailbox) == 0)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen bbox = mbox->vseq_lookup_prev_bbox;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen else {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen i_free(mbox->vseq_lookup_prev_mailbox);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mbox->vseq_lookup_prev_mailbox = i_strdup(backend_mailbox);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen bbox = virtual_backend_box_lookup_name(mbox, backend_mailbox);
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen mbox->vseq_lookup_prev_bbox = bbox;
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen }
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen if (bbox == NULL)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return FALSE;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mailbox_get_status(bbox->box, STATUS_UIDVALIDITY, &status);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (status.uidvalidity != backend_uidvalidity)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return FALSE;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
7604ee75aa54ab2e400de45999e326c358bc2d24Phil Carmody uids = array_bsearch(&bbox->uids, &backend_uid,
41a6be2852b10158e98934aa7e4922baf887a0c3Timo Sirainen virtual_backend_uidmap_cmp);
7604ee75aa54ab2e400de45999e326c358bc2d24Phil Carmody if (uids == NULL)
7604ee75aa54ab2e400de45999e326c358bc2d24Phil Carmody return FALSE;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen *uid_r = uids->virtual_uid;
7604ee75aa54ab2e400de45999e326c358bc2d24Phil Carmody return TRUE;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
7604ee75aa54ab2e400de45999e326c358bc2d24Phil Carmody
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic void
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenvirtual_get_virtual_backend_boxes(struct mailbox *box,
86bde2c1838d1ce967fa2b394bb952004a4adcb7Timo Sirainen ARRAY_TYPE(mailboxes) *mailboxes,
7604ee75aa54ab2e400de45999e326c358bc2d24Phil Carmody bool only_with_msgs)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct virtual_backend_box *const *bboxes;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen unsigned int i, count;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen bboxes = array_get(&mbox->backend_boxes, &count);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen for (i = 0; i < count; i++) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (!only_with_msgs || array_count(&bboxes[i]->uids) > 0)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen array_append(mailboxes, &bboxes[i]->box, 1);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
7604ee75aa54ab2e400de45999e326c358bc2d24Phil Carmody}
7604ee75aa54ab2e400de45999e326c358bc2d24Phil Carmody
86bde2c1838d1ce967fa2b394bb952004a4adcb7Timo Sirainenstatic void
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenvirtual_get_virtual_box_patterns(struct mailbox *box,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen ARRAY_TYPE(mailbox_virtual_patterns) *includes,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen ARRAY_TYPE(mailbox_virtual_patterns) *excludes)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
7604ee75aa54ab2e400de45999e326c358bc2d24Phil Carmody struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
7604ee75aa54ab2e400de45999e326c358bc2d24Phil Carmody
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen array_append_array(includes, &mbox->list_include_patterns);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen array_append_array(excludes, &mbox->list_exclude_patterns);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
7604ee75aa54ab2e400de45999e326c358bc2d24Phil Carmody
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic bool virtual_is_inconsistent(struct mailbox *box)
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen{
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (mbox->inconsistent)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return TRUE;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return index_storage_is_inconsistent(box);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstruct mail_storage virtual_storage = {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen .name = VIRTUAL_STORAGE_NAME,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen .class_flags = 0,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen .v = {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen NULL,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen virtual_storage_alloc,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen NULL,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen NULL,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen virtual_storage_add_list,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen virtual_storage_get_list_settings,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen NULL,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_mailbox_alloc,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen NULL
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen }
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen};
1f4f81ba81bb9fa8abe2d94f344373c230066d67Timo Sirainen
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainenstruct mailbox virtual_mailbox = {
1f4f81ba81bb9fa8abe2d94f344373c230066d67Timo Sirainen .v = {
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen index_storage_is_readonly,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen index_storage_allow_new_keywords,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen index_storage_mailbox_enable,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_mailbox_open,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_mailbox_close,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_mailbox_free,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_mailbox_create,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_mailbox_update,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen index_storage_mailbox_delete,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen index_storage_mailbox_rename,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen index_storage_get_status,
1f4f81ba81bb9fa8abe2d94f344373c230066d67Timo Sirainen virtual_mailbox_get_guid,
1f4f81ba81bb9fa8abe2d94f344373c230066d67Timo Sirainen NULL,
1f4f81ba81bb9fa8abe2d94f344373c230066d67Timo Sirainen NULL,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_storage_sync_init,
1f4f81ba81bb9fa8abe2d94f344373c230066d67Timo Sirainen index_mailbox_sync_next,
1f4f81ba81bb9fa8abe2d94f344373c230066d67Timo Sirainen index_mailbox_sync_deinit,
1f4f81ba81bb9fa8abe2d94f344373c230066d67Timo Sirainen NULL,
1f4f81ba81bb9fa8abe2d94f344373c230066d67Timo Sirainen virtual_notify_changes,
1f4f81ba81bb9fa8abe2d94f344373c230066d67Timo Sirainen virtual_transaction_begin,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_transaction_commit,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_transaction_rollback,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen index_transaction_set_max_modseq,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen index_keywords_create,
5a86309a6c58bdeb9921bf2989aaabaaa04a29abTimo Sirainen index_keywords_create_from_indexes,
5a86309a6c58bdeb9921bf2989aaabaaa04a29abTimo Sirainen index_keywords_ref,
5a86309a6c58bdeb9921bf2989aaabaaa04a29abTimo Sirainen index_keywords_unref,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_keyword_is_valid,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_storage_get_seq_range,
8bb360f9e5de1c25e4f875205bb06e8bf15dae14Timo Sirainen index_storage_get_uid_range,
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen index_storage_get_expunges,
407d64647d77771080eb75f800162014927f10c6Timo Sirainen virtual_get_virtual_uid,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen virtual_get_virtual_backend_boxes,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen virtual_get_virtual_box_patterns,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen virtual_mail_alloc,
d39c0e195c67be5f2b0a15f25a8d6039bef02711Timo Sirainen index_header_lookup_init,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_header_lookup_deinit,
5a86309a6c58bdeb9921bf2989aaabaaa04a29abTimo Sirainen virtual_search_init,
5a86309a6c58bdeb9921bf2989aaabaaa04a29abTimo Sirainen virtual_search_deinit,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_search_next_nonblock,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_search_next_update_seq,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_save_alloc,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_save_begin,
5a86309a6c58bdeb9921bf2989aaabaaa04a29abTimo Sirainen virtual_save_continue,
5a86309a6c58bdeb9921bf2989aaabaaa04a29abTimo Sirainen virtual_save_finish,
5a86309a6c58bdeb9921bf2989aaabaaa04a29abTimo Sirainen virtual_save_cancel,
5a86309a6c58bdeb9921bf2989aaabaaa04a29abTimo Sirainen mail_storage_copy,
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen virtual_is_inconsistent
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen};
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen