bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2008-2018 Dovecot authors, see the included COPYING file */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "lib.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "array.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "ioloop.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "str.h"
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen#include "llist.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "mkdir-parents.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "unlink-directory.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "index-mail.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "mail-copy.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "mail-search.h"
7a7d2aa11e46195e2d92d6c337d7e78052a5ce67Timo Sirainen#include "mailbox-list-private.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "virtual-plugin.h"
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen#include "virtual-transaction.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "virtual-storage.h"
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi#include "mailbox-list-notify.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include <stdio.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include <unistd.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include <dirent.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include <sys/stat.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen#define VIRTUAL_DEFAULT_MAX_OPEN_MAILBOXES 64
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen#define VIRTUAL_BACKEND_CONTEXT(obj) \
109c39ab66c5aa85bf37d5bbf4ce91c6f966268bAki Tuomi MODULE_CONTEXT_REQUIRE(obj, virtual_backend_storage_module)
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainenstruct virtual_backend_mailbox {
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen union mailbox_module_context module_ctx;
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen};
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenextern struct mail_storage virtual_storage;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenextern struct mailbox virtual_mailbox;
499fec3443374cc89fb8c83b8027c1614097d7a3Timo Sirainenextern struct virtual_mailbox_vfuncs virtual_mailbox_vfuncs;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
f5a7396b31762a1f876517e13ce9065820139f7cTimo Sirainenstruct virtual_storage_module virtual_storage_module =
f5a7396b31762a1f876517e13ce9065820139f7cTimo Sirainen MODULE_CONTEXT_INIT(&mail_storage_module_register);
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(virtual_backend_storage_module,
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen &mail_storage_module_register);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainenstatic bool ns_is_visible(struct mail_namespace *ns)
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen{
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen return (ns->flags & NAMESPACE_FLAG_LIST_PREFIX) != 0 ||
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen (ns->flags & NAMESPACE_FLAG_LIST_CHILDREN) != 0 ||
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen (ns->flags & NAMESPACE_FLAG_HIDDEN) == 0;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen}
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainenstatic const char *get_user_visible_mailbox_name(struct mailbox *box)
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen{
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen if (ns_is_visible(box->list->ns))
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen return box->vname;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen else {
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen return t_strdup_printf("<hidden>%c%s",
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen mail_namespace_get_sep(box->list->ns),
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen box->vname);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen }
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen}
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
942302b0247403645394d848b3c620ead262a2a5Timo Sirainenvoid virtual_box_copy_error(struct mailbox *dest, struct mailbox *src)
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen{
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen const char *name, *str;
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen enum mail_error error;
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen name = get_user_visible_mailbox_name(src);
11352dc3e4b29f3d2763c82f8ea4f99e8daf4fa3Timo Sirainen str = mailbox_get_last_error(src, &error);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen str = t_strdup_printf("%s (for backend mailbox %s)", str, name);
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen mail_storage_set_error(dest->storage, error, str);
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen}
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic struct mail_storage *virtual_storage_alloc(void)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_storage *storage;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool_t pool;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
cd8507179823de33d6e8242e10dbc15d136245b5Timo Sirainen pool = pool_alloconly_create("virtual storage", 1024);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen storage = p_new(pool, struct virtual_storage, 1);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen storage->storage = virtual_storage;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen storage->storage.pool = pool;
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen p_array_init(&storage->open_stack, pool, 8);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return &storage->storage;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainenstatic int
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainenvirtual_storage_create(struct mail_storage *_storage,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen struct mail_namespace *ns ATTR_UNUSED,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen const char **error_r)
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen{
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen struct virtual_storage *storage = (struct virtual_storage *)_storage;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen const char *value;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen value = mail_user_plugin_getenv(_storage->user, "virtual_max_open_mailboxes");
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen if (value == NULL)
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen storage->max_open_mailboxes = VIRTUAL_DEFAULT_MAX_OPEN_MAILBOXES;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen else if (str_to_uint(value, &storage->max_open_mailboxes) < 0) {
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen *error_r = "Invalid virtual_max_open_mailboxes setting";
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen return -1;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen }
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen return 0;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen}
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic void
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenvirtual_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mailbox_list_settings *set)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (set->layout == NULL)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen set->layout = MAILBOX_LIST_NAME_FS;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (set->subscription_fname == NULL)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen set->subscription_fname = VIRTUAL_SUBSCRIPTION_FILE_NAME;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen}
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstruct virtual_backend_box *
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenvirtual_backend_box_lookup_name(struct virtual_mailbox *mbox, const char *name)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct virtual_backend_box *const *bboxes;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen unsigned int i, count;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen bboxes = array_get(&mbox->backend_boxes, &count);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen for (i = 0; i < count; i++) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (strcmp(bboxes[i]->name, name) == 0)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen return bboxes[i];
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen return NULL;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct virtual_backend_box *
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvirtual_backend_box_lookup(struct virtual_mailbox *mbox, uint32_t mailbox_id)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_backend_box *const *bboxes;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int i, count;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (mailbox_id == 0)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return NULL;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen bboxes = array_get(&mbox->backend_boxes, &count);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen for (i = 0; i < count; i++) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (bboxes[i]->mailbox_id == mailbox_id)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return bboxes[i];
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return NULL;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainenstatic bool virtual_mailbox_is_in_open_stack(struct virtual_storage *storage,
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen const char *name)
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen{
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen const char *const *names;
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen unsigned int i, count;
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen names = array_get(&storage->open_stack, &count);
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen for (i = 0; i < count; i++) {
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen if (strcmp(names[i], name) == 0)
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen return TRUE;
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen }
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen return FALSE;
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen}
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainenstatic int virtual_backend_box_open_failed(struct virtual_mailbox *mbox,
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen struct virtual_backend_box *bbox)
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen{
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen enum mail_error error;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen const char *str;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen str = t_strdup_printf(
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen "Virtual mailbox open failed because of mailbox %s: %s",
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen get_user_visible_mailbox_name(bbox->box),
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen mailbox_get_last_error(bbox->box, &error));
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen mail_storage_set_error(mbox->box.storage, error, str);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen mailbox_free(&bbox->box);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen if (error == MAIL_ERROR_PERM && bbox->wildcard) {
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen /* this mailbox wasn't explicitly specified. just skip it. */
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen return 0;
8305127d1074cf9a1e25dec9be2735276462079dTimo Sirainen }
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen return -1;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen}
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainenstatic int virtual_backend_box_alloc(struct virtual_mailbox *mbox,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen struct virtual_backend_box *bbox,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen enum mailbox_flags flags)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mail_user *user = mbox->storage->storage.user;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mail_namespace *ns;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen const char *mailbox;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen enum mailbox_existence existence;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
596433ccbca59ce2328dc1d029586154cd937155Timo Sirainen i_assert(bbox->box == NULL);
596433ccbca59ce2328dc1d029586154cd937155Timo Sirainen
15b5076a239682277b44880e33ea23b55fff7e71Timo Sirainen if (!bbox->clear_recent)
15b5076a239682277b44880e33ea23b55fff7e71Timo Sirainen flags &= ~MAILBOX_FLAG_DROP_RECENT;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen mailbox = bbox->name;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen ns = mail_namespace_find(user->namespaces, mailbox);
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen bbox->box = mailbox_alloc(ns->list, mailbox, flags);
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen MODULE_CONTEXT_SET(bbox->box, virtual_storage_module, bbox);
15a2661c25010c7397f224ac83fa30433cb718ddAki Tuomi mailbox_set_reason(bbox->box, mbox->box.reason == NULL ?
15a2661c25010c7397f224ac83fa30433cb718ddAki Tuomi t_strdup_printf("virtual mailbox %s", mailbox_get_vname(&mbox->box)) :
15a2661c25010c7397f224ac83fa30433cb718ddAki Tuomi t_strdup_printf("virtual mailbox %s: %s", mailbox_get_vname(&mbox->box), mbox->box.reason));
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen
ca0cfbcd16563416b37e3c3e9062349a9d1c9cf7Timo Sirainen if (bbox == mbox->save_bbox) {
ca0cfbcd16563416b37e3c3e9062349a9d1c9cf7Timo Sirainen /* Assume that the save_bbox exists, whether or not it truly
ca0cfbcd16563416b37e3c3e9062349a9d1c9cf7Timo Sirainen does. This at least gives a better error message than crash
ca0cfbcd16563416b37e3c3e9062349a9d1c9cf7Timo Sirainen later on. */
ca0cfbcd16563416b37e3c3e9062349a9d1c9cf7Timo Sirainen existence = MAILBOX_EXISTENCE_SELECT;
ca0cfbcd16563416b37e3c3e9062349a9d1c9cf7Timo Sirainen } else {
ca0cfbcd16563416b37e3c3e9062349a9d1c9cf7Timo Sirainen if (mailbox_exists(bbox->box, TRUE, &existence) < 0)
ca0cfbcd16563416b37e3c3e9062349a9d1c9cf7Timo Sirainen return virtual_backend_box_open_failed(mbox, bbox);
ca0cfbcd16563416b37e3c3e9062349a9d1c9cf7Timo Sirainen }
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen if (existence != MAILBOX_EXISTENCE_SELECT) {
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen /* ignore this. it could be intentional. */
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen if (mbox->storage->storage.user->mail_debug) {
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen i_debug("virtual mailbox %s: "
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen "Skipping non-existing mailbox %s",
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen mbox->box.vname, bbox->box->vname);
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen }
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen mailbox_free(&bbox->box);
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen return 0;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen }
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen i_array_init(&bbox->uids, 64);
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen i_array_init(&bbox->sync_pending_removes, 64);
074055dadbca01626437cc4724853a374acab6a8Timo Sirainen /* we use modseqs for being able to check quickly if backend mailboxes
074055dadbca01626437cc4724853a374acab6a8Timo Sirainen have changed. make sure the backend has them enabled. */
963842c00ef1714db2855c8952f1b46d78cba1caTimo Sirainen (void)mailbox_enable(bbox->box, MAILBOX_FEATURE_CONDSTORE);
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen return 1;
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen}
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainenstatic int virtual_mailboxes_open(struct virtual_mailbox *mbox,
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen enum mailbox_flags flags)
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen{
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen struct virtual_backend_box *const *bboxes;
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen unsigned int i, count;
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen int ret;
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen bboxes = array_get(&mbox->backend_boxes, &count);
7f3b826a89bcb7a72759912e99f574b28309fe1bTimo Sirainen for (i = 0; i < count; ) {
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen ret = virtual_backend_box_alloc(mbox, bboxes[i], flags);
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen if (ret <= 0) {
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen if (ret < 0)
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen break;
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen array_delete(&mbox->backend_boxes, i, 1);
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen bboxes = array_get(&mbox->backend_boxes, &count);
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen } else {
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen i++;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (i == count)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return 0;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen else {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* failed */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen for (; i > 0; i--) {
e10d8b1291090c26b9ef499637e6e632485ca5beTimo Sirainen mailbox_free(&bboxes[i-1]->box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen array_free(&bboxes[i-1]->uids);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return -1;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic struct mailbox *
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenvirtual_mailbox_alloc(struct mail_storage *_storage, struct mailbox_list *list,
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen const char *vname, enum mailbox_flags flags)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
18ccd19c244f49665fe03cda785efa066d2c38dfTimo Sirainen struct virtual_storage *storage = (struct virtual_storage *)_storage;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mailbox *mbox;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool_t pool;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
c529313e1cbc22244d4528e80aa3e485f8806cd3Timo Sirainen pool = pool_alloconly_create("virtual mailbox", 2048);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mbox = p_new(pool, struct virtual_mailbox, 1);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box = virtual_mailbox;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box.pool = pool;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box.storage = _storage;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box.list = list;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box.mail_vfuncs = &virtual_mail_vfuncs;
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen mbox->box.virtual_vfuncs = &virtual_mailbox_vfuncs;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen index_storage_mailbox_alloc(&mbox->box, vname, flags, MAIL_INDEX_PREFIX);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mbox->storage = storage;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mbox->virtual_ext_id = (uint32_t)-1;
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi mbox->virtual_guid_ext_id = (uint32_t)-1;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen return &mbox->box;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainenvoid virtual_backend_box_sync_mail_unset(struct virtual_backend_box *bbox)
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen{
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen struct mailbox_transaction_context *trans;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen if (bbox->sync_mail != NULL) {
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen trans = bbox->sync_mail->transaction;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen mail_free(&bbox->sync_mail);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen (void)mailbox_transaction_commit(&trans);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen }
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen}
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainenstatic bool virtual_backend_box_can_close(struct virtual_backend_box *bbox)
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainen{
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainen if (bbox->box->notify_callback != NULL) {
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi /* we can close it if notify is set
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi because we have no need to keep it open
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi for tracking changes */
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi return bbox->notify != NULL;
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainen }
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainen if (array_count(&bbox->sync_pending_removes) > 0) {
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainen /* FIXME: we could probably close this by making
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainen syncing support it? */
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainen return FALSE;
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainen }
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainen return TRUE;
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainen}
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainenstatic bool
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainenvirtual_backend_box_close_any_except(struct virtual_mailbox *mbox,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen struct virtual_backend_box *except_bbox)
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen{
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen struct virtual_backend_box *bbox;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen /* first try to close a mailbox without any transactions.
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen we'll also skip any mailbox that has notifications enabled (ideally
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen these would be handled by mailbox list index) */
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen for (bbox = mbox->open_backend_boxes_head; bbox != NULL; bbox = bbox->next_open) {
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen i_assert(bbox->box->opened);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen if (bbox != except_bbox &&
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen bbox->box->transaction_count == 0 &&
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainen virtual_backend_box_can_close(bbox)) {
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen i_assert(bbox->sync_mail == NULL);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen virtual_backend_box_close(mbox, bbox);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen return TRUE;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen }
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen }
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen /* next try to close a mailbox that has sync_mail, but no
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen other transactions */
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen for (bbox = mbox->open_backend_boxes_head; bbox != NULL; bbox = bbox->next_open) {
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen if (bbox != except_bbox &&
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen bbox->sync_mail != NULL &&
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen bbox->box->transaction_count == 1 &&
ce930f99c6a78f2c74b00df1ad2337095978a9dbTimo Sirainen virtual_backend_box_can_close(bbox)) {
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen virtual_backend_box_sync_mail_unset(bbox);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen i_assert(bbox->box->transaction_count == 0);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen virtual_backend_box_close(mbox, bbox);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen return TRUE;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen }
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen }
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen return FALSE;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen}
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainenstatic void virtual_backend_mailbox_close(struct mailbox *box)
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen{
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen struct virtual_backend_box *bbox = VIRTUAL_CONTEXT(box);
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen struct virtual_backend_mailbox *vbox = VIRTUAL_BACKEND_CONTEXT(box);
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen if (bbox != NULL && bbox->open_tracked) {
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen /* we could have gotten here from e.g. mailbox_autocreate()
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen without going through virtual_mailbox_close() */
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen virtual_backend_box_close(bbox->virtual_mbox, bbox);
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen }
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen vbox->module_ctx.super.close(box);
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen}
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainenvoid virtual_backend_mailbox_allocated(struct mailbox *box)
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen{
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen struct mailbox_vfuncs *v = box->vlast;
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen struct virtual_backend_mailbox *vbox;
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen vbox = p_new(box->pool, struct virtual_backend_mailbox, 1);
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen vbox->module_ctx.super = *v;
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen box->vlast = &vbox->module_ctx.super;
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen v->close = virtual_backend_mailbox_close;
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen MODULE_CONTEXT_SET(box, virtual_backend_storage_module, vbox);
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen}
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainen
a18335e18aac7fc219b6f18dde083359155cc524Timo Sirainenvoid virtual_backend_mailbox_opened(struct mailbox *box)
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen{
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen struct virtual_backend_box *bbox = VIRTUAL_CONTEXT(box);
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen struct virtual_mailbox *mbox;
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen if (bbox == NULL) {
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen /* not a backend for a virtual mailbox */
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen return;
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen }
9cb0fe28ae6f59b9f075e1edfc30f417e846c4a2Timo Sirainen i_assert(!bbox->open_tracked);
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen mbox = bbox->virtual_mbox;
9cb0fe28ae6f59b9f075e1edfc30f417e846c4a2Timo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen /* the backend mailbox was already opened. if we didn't get here
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen from virtual_backend_box_open() we may need to close a mailbox */
613d69eb09ed2b4d20720e7023b25f55c2215fbeTimo Sirainen while (mbox->backends_open_count >= mbox->storage->max_open_mailboxes &&
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen virtual_backend_box_close_any_except(mbox, bbox))
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen ;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
9cb0fe28ae6f59b9f075e1edfc30f417e846c4a2Timo Sirainen bbox->open_tracked = TRUE;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen mbox->backends_open_count++;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen DLLIST2_APPEND_FULL(&mbox->open_backend_boxes_head,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen &mbox->open_backend_boxes_tail, bbox,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen prev_open, next_open);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen}
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainenint virtual_backend_box_open(struct virtual_mailbox *mbox,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen struct virtual_backend_box *bbox)
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen{
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen i_assert(!bbox->box->opened);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen /* try to keep the number of open mailboxes below the threshold
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen before opening the mailbox */
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen while (mbox->backends_open_count >= mbox->storage->max_open_mailboxes &&
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen virtual_backend_box_close_any_except(mbox, bbox))
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen ;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen return mailbox_open(bbox->box);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen}
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainenvoid virtual_backend_box_close(struct virtual_mailbox *mbox,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen struct virtual_backend_box *bbox)
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen{
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen i_assert(bbox->box->opened);
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen i_assert(bbox->open_tracked);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen if (bbox->search_result != NULL)
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen mailbox_search_result_free(&bbox->search_result);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen if (bbox->search_args != NULL &&
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen bbox->search_args_initialized) {
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen mail_search_args_deinit(bbox->search_args);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen bbox->search_args_initialized = FALSE;
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen }
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen i_assert(mbox->backends_open_count > 0);
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen mbox->backends_open_count--;
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen bbox->open_tracked = FALSE;
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen DLLIST2_REMOVE_FULL(&mbox->open_backend_boxes_head,
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen &mbox->open_backend_boxes_tail, bbox,
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen prev_open, next_open);
0d318fe07ea8846330b6fe6b6b281ef0ccfbaacdAki Tuomi
0d318fe07ea8846330b6fe6b6b281ef0ccfbaacdAki Tuomi /* stop receiving notifications */
0d318fe07ea8846330b6fe6b6b281ef0ccfbaacdAki Tuomi if (bbox->notify_changes_started)
0d318fe07ea8846330b6fe6b6b281ef0ccfbaacdAki Tuomi mailbox_notify_changes_stop(bbox->box);
0d318fe07ea8846330b6fe6b6b281ef0ccfbaacdAki Tuomi bbox->notify_changes_started = FALSE;
0d318fe07ea8846330b6fe6b6b281ef0ccfbaacdAki Tuomi
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen mailbox_close(bbox->box);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen}
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainenvoid virtual_backend_box_accessed(struct virtual_mailbox *mbox,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen struct virtual_backend_box *bbox)
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen{
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen DLLIST2_REMOVE_FULL(&mbox->open_backend_boxes_head,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen &mbox->open_backend_boxes_tail, bbox,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen prev_open, next_open);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen DLLIST2_APPEND_FULL(&mbox->open_backend_boxes_head,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen &mbox->open_backend_boxes_tail, bbox,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen prev_open, next_open);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen}
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainenstatic void virtual_mailbox_close_internal(struct virtual_mailbox *mbox)
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen{
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen struct virtual_backend_box **bboxes;
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen unsigned int i, count;
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen bboxes = array_get_modifiable(&mbox->backend_boxes, &count);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen for (i = 0; i < count; i++) {
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen if (bboxes[i]->box == NULL)
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen continue;
2f691d6dd1b98f605043744846534b828a43994dAki Tuomi if (bboxes[i]->notify != NULL)
2f691d6dd1b98f605043744846534b828a43994dAki Tuomi mailbox_list_notify_deinit(&bboxes[i]->notify);
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen if (bboxes[i]->box->opened)
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen virtual_backend_box_close(mbox, bboxes[i]);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen mailbox_free(&bboxes[i]->box);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen if (array_is_created(&bboxes[i]->sync_outside_expunges))
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen array_free(&bboxes[i]->sync_outside_expunges);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen array_free(&bboxes[i]->sync_pending_removes);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen array_free(&bboxes[i]->uids);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen }
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen i_assert(mbox->backends_open_count == 0);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen}
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen
c4bb0320ab43ea35fa6df88fc745fdad906cee44Timo Sirainenstatic int
c4bb0320ab43ea35fa6df88fc745fdad906cee44Timo Sirainenvirtual_mailbox_exists(struct mailbox *box, bool auto_boxes ATTR_UNUSED,
c4bb0320ab43ea35fa6df88fc745fdad906cee44Timo Sirainen enum mailbox_existence *existence_r)
047e3bbb00e68a0d43355e11a67b2e912e06de19Timo Sirainen{
c4bb0320ab43ea35fa6df88fc745fdad906cee44Timo Sirainen return index_storage_mailbox_exists_full(box, VIRTUAL_CONFIG_FNAME,
047e3bbb00e68a0d43355e11a67b2e912e06de19Timo Sirainen existence_r);
047e3bbb00e68a0d43355e11a67b2e912e06de19Timo Sirainen}
047e3bbb00e68a0d43355e11a67b2e912e06de19Timo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic int virtual_mailbox_open(struct mailbox *box)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen bool broken;
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen int ret = 0;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (virtual_mailbox_is_in_open_stack(mbox->storage, box->name)) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(box,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen "Virtual mailbox loops: %s", box->name);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return -1;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen }
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen if (!array_is_created(&mbox->backend_boxes))
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen ret = virtual_config_read(mbox);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen if (ret == 0) {
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen array_append(&mbox->storage->open_stack, &box->name, 1);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen ret = virtual_mailboxes_open(mbox, box->flags);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen array_delete(&mbox->storage->open_stack,
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen array_count(&mbox->storage->open_stack)-1, 1);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen }
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen if (ret < 0) {
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen virtual_mailbox_close_internal(mbox);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen return -1;
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (index_storage_mailbox_open(box, FALSE) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return -1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mbox->virtual_ext_id =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mail_index_ext_register(mbox->box.index, "virtual", 0,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen sizeof(struct virtual_mail_index_record),
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen sizeof(uint32_t));
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi mbox->virtual_guid_ext_id =
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi mail_index_ext_register(mbox->box.index, "virtual-guid", GUID_128_SIZE,
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi 0, 0);
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen if (virtual_mailbox_ext_header_read(mbox, box->view, &broken) < 0) {
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen virtual_mailbox_close_internal(mbox);
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen index_storage_mailbox_close(box);
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen return -1;
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen }
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi /* if GUID is missing write it here */
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi if (guid_128_is_empty(mbox->guid)) {
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi guid_128_generate(mbox->guid);
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi struct mail_index_transaction *t =
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi mail_index_transaction_begin(box->view, 0);
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi mail_index_update_header_ext(t, mbox->virtual_guid_ext_id,
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi 0, mbox->guid, GUID_128_SIZE);
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi if (mail_index_transaction_commit(&t) < 0) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(box,
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi "Cannot write GUID for virtual mailbox to index");
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi virtual_mailbox_close_internal(mbox);
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi index_storage_mailbox_close(box);
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi return -1;
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi }
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi }
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic void virtual_mailbox_close(struct mailbox *box)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen virtual_mailbox_close_internal(mbox);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen index_storage_mailbox_close(box);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen}
18ccd19c244f49665fe03cda785efa066d2c38dfTimo Sirainen
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainenstatic void virtual_mailbox_free(struct mailbox *box)
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen{
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen virtual_config_free(mbox);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen index_storage_mailbox_free(box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenstatic int
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenvirtual_mailbox_create(struct mailbox *box,
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen const struct mailbox_update *update ATTR_UNUSED,
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen bool directory ATTR_UNUSED)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen "Can't create virtual mailboxes");
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return -1;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenstatic int
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenvirtual_mailbox_update(struct mailbox *box,
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen const struct mailbox_update *update ATTR_UNUSED)
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen{
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen "Can't update virtual mailboxes");
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen return -1;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen}
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainenstatic int virtual_storage_set_have_guid_flags(struct virtual_mailbox *mbox)
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen{
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen struct virtual_backend_box *const *bboxes;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen unsigned int i, count;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen struct mailbox_status status;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen
ca203035ecc37b94ba6b4ee3eb786cdafb46503aTimo Sirainen if (!mbox->box.opened) {
ca203035ecc37b94ba6b4ee3eb786cdafb46503aTimo Sirainen if (mailbox_open(&mbox->box) < 0)
ca203035ecc37b94ba6b4ee3eb786cdafb46503aTimo Sirainen return -1;
ca203035ecc37b94ba6b4ee3eb786cdafb46503aTimo Sirainen }
ca203035ecc37b94ba6b4ee3eb786cdafb46503aTimo Sirainen
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen mbox->have_guids = TRUE;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen mbox->have_save_guids = TRUE;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen bboxes = array_get(&mbox->backend_boxes, &count);
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen for (i = 0; i < count; i++) {
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen if (mailbox_get_status(bboxes[i]->box, 0, &status) < 0) {
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen const char *errstr;
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen enum mail_error error;
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen errstr = mailbox_get_last_error(bboxes[i]->box, &error);
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen if (error == MAIL_ERROR_NOTFOUND) {
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen /* backend mailbox was just lost - skip it */
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen continue;
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen }
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen /* Not expected to happen, but we can't return failure
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen since this could be called from
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen mailbox_get_open_status() and it would panic.
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen So just log the error and skip the mailbox. */
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(&mbox->box,
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi "Virtual mailbox: Failed to get have_guid existence for backend mailbox %s: %s",
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen mailbox_get_vname(bboxes[i]->box), errstr);
d5282594ec73c953ffb23096a2cddf373cc15f46Timo Sirainen continue;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen }
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen if (!status.have_guids)
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen mbox->have_guids = FALSE;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen if (!status.have_save_guids)
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen mbox->have_save_guids = FALSE;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen }
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen return 0;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen}
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenstatic int
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenvirtual_storage_get_status(struct mailbox *box,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen enum mailbox_status_items items,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct mailbox_status *status_r)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen{
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if ((items & STATUS_LAST_CACHED_SEQ) != 0)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen items |= STATUS_MESSAGES;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (index_storage_get_status(box, items, status_r) < 0)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return -1;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if ((items & STATUS_LAST_CACHED_SEQ) != 0) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* Virtual mailboxes have no cached data of their own, so the
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen current value is always 0. The most important use for this
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen functionality is for "doveadm index" to do FTS indexing and
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen it doesn't really matter there if we set this value
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen correctly or not. So for now just assume that everything is
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen indexed. */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen status_r->last_cached_seq = status_r->messages;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen if (!mbox->have_guid_flags_set) {
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen if (virtual_storage_set_have_guid_flags(mbox) < 0)
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen return -1;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen mbox->have_guid_flags_set = TRUE;
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen }
18a41cbd38f83429b790414c1159c097af4a59b8Timo Sirainen
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen if (mbox->have_guids)
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen status_r->have_guids = TRUE;
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen if (mbox->have_save_guids)
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen status_r->have_save_guids = TRUE;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return 0;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen}
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
d859478e8b106de6cea54f26861bd4232c92f62cTimo Sirainenstatic int
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainenvirtual_mailbox_get_metadata(struct mailbox *box,
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen enum mailbox_metadata_items items,
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen struct mailbox_metadata *metadata_r)
d859478e8b106de6cea54f26861bd4232c92f62cTimo Sirainen{
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
206ed2f6fa3a6fb291498627b2da626581c07a18Timo Sirainen if (index_mailbox_get_metadata(box, items, metadata_r) < 0)
206ed2f6fa3a6fb291498627b2da626581c07a18Timo Sirainen return -1;
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi i_assert(box->opened);
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen if ((items & MAILBOX_METADATA_GUID) != 0) {
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi if (guid_128_is_empty(mbox->guid)) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(box, "GUID missing for virtual folder");
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi return -1;
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi }
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi guid_128_copy(metadata_r->guid, mbox->guid);
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen }
206ed2f6fa3a6fb291498627b2da626581c07a18Timo Sirainen return 0;
d859478e8b106de6cea54f26861bd4232c92f62cTimo Sirainen}
d859478e8b106de6cea54f26861bd4232c92f62cTimo Sirainen
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainenstatic void
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainenvirtual_notify_callback(struct mailbox *bbox ATTR_UNUSED, struct mailbox *box)
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen{
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen box->notify_callback(box, box->notify_context);
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen}
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomistatic void virtual_backend_box_changed(struct virtual_backend_box *bbox)
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi{
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi virtual_notify_callback(bbox->box, &bbox->virtual_mbox->box);
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi}
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomistatic int virtual_notify_start(struct virtual_backend_box *bbox)
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi{
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi i_assert(bbox->notify == NULL);
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi if (mailbox_list_notify_init(bbox->box->list, MAILBOX_LIST_NOTIFY_STATUS,
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi &bbox->notify) < 0)
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi /* did not support notifications */
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi return -1;
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi mailbox_list_notify_wait(bbox->notify, virtual_backend_box_changed, bbox);
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi return 0;
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi}
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainenstatic void virtual_notify_changes(struct mailbox *box)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi struct virtual_backend_box **bboxp;
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen
a385399497bdb50d4dfce729ffc852b75ed46a36Timo Sirainen if (box->notify_callback == NULL) {
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi array_foreach_modifiable(&mbox->backend_boxes, bboxp) {
0d318fe07ea8846330b6fe6b6b281ef0ccfbaacdAki Tuomi if ((*bboxp)->notify_changes_started) {
0d318fe07ea8846330b6fe6b6b281ef0ccfbaacdAki Tuomi mailbox_notify_changes_stop((*bboxp)->box);
0d318fe07ea8846330b6fe6b6b281ef0ccfbaacdAki Tuomi (*bboxp)->notify_changes_started = FALSE;
0d318fe07ea8846330b6fe6b6b281ef0ccfbaacdAki Tuomi }
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi if ((*bboxp)->notify != NULL)
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi mailbox_list_notify_deinit(&(*bboxp)->notify);
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi }
a385399497bdb50d4dfce729ffc852b75ed46a36Timo Sirainen return;
a385399497bdb50d4dfce729ffc852b75ed46a36Timo Sirainen }
a385399497bdb50d4dfce729ffc852b75ed46a36Timo Sirainen
43dfd44ec2e993e175c4b50e9804c90a50f56d66Aki Tuomi array_foreach_modifiable(&mbox->backend_boxes, bboxp) {
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen if (array_count(&mbox->backend_boxes) == 1 &&
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen (*bboxp)->box->opened) {
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen /* There's only a single backend mailbox and its
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen indexes are already opened. Might as well use the
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen backend directly for notifications. */
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen } else {
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen /* we are already waiting for notifications */
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen if ((*bboxp)->notify != NULL)
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen continue;
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen /* wait for notifications */
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen if (virtual_notify_start(*bboxp) == 0)
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen continue;
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen /* it did not work, so open the mailbox and use
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen alternative method */
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen }
81e832796cdc6af790ed7be8a6c150889f03171cTimo Sirainen
d979c1179d55ad86e40f869e48ef3e4db9c817b5Timo Sirainen if (!(*bboxp)->box->opened &&
d979c1179d55ad86e40f869e48ef3e4db9c817b5Timo Sirainen virtual_backend_box_open(mbox, *bboxp) < 0) {
a385399497bdb50d4dfce729ffc852b75ed46a36Timo Sirainen /* we can't report error in here, so do it later */
a385399497bdb50d4dfce729ffc852b75ed46a36Timo Sirainen (*bboxp)->open_failed = TRUE;
a385399497bdb50d4dfce729ffc852b75ed46a36Timo Sirainen continue;
a385399497bdb50d4dfce729ffc852b75ed46a36Timo Sirainen }
a385399497bdb50d4dfce729ffc852b75ed46a36Timo Sirainen mailbox_notify_changes((*bboxp)->box,
a385399497bdb50d4dfce729ffc852b75ed46a36Timo Sirainen virtual_notify_callback, box);
0d318fe07ea8846330b6fe6b6b281ef0ccfbaacdAki Tuomi (*bboxp)->notify_changes_started = TRUE;
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvirtual_get_virtual_uids(struct mailbox *box,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mailbox *backend_mailbox,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const ARRAY_TYPE(seq_range) *backend_uids,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ARRAY_TYPE(seq_range) *virtual_uids_r)
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct virtual_backend_box *bbox;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct virtual_backend_uidmap *uids;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct seq_range_iter iter;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unsigned int n, i, count;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen uint32_t uid;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (mbox->lookup_prev_bbox != NULL &&
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen strcmp(mbox->lookup_prev_bbox->box->vname, backend_mailbox->vname) == 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen bbox = mbox->lookup_prev_bbox;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen else {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen bbox = virtual_backend_box_lookup_name(mbox, backend_mailbox->vname);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mbox->lookup_prev_bbox = bbox;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (bbox == NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen uids = array_get(&bbox->uids, &count); i = 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_iter_init(&iter, backend_uids); n = 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen while (seq_range_array_iter_nth(&iter, n++, &uid)) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen while (i < count && uids[i].real_uid < uid) i++;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (i < count && uids[i].real_uid == uid) {
cc7e2c3903f8fadb7474f09665b2280463850bebTimo Sirainen i_assert(uids[i].virtual_uid > 0);
86bde2c1838d1ce967fa2b394bb952004a4adcb7Timo Sirainen seq_range_array_add(virtual_uids_r,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen uids[i].virtual_uid);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i++;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen}
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvirtual_get_virtual_uid_map(struct mailbox *box,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mailbox *backend_mailbox,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const ARRAY_TYPE(seq_range) *backend_uids,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ARRAY_TYPE(uint32_t) *virtual_uids_r)
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen{
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen struct virtual_backend_box *bbox;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen const struct virtual_backend_uidmap *uids;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct seq_range_iter iter;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unsigned int n, i, count;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen uint32_t uid;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (mbox->lookup_prev_bbox != NULL &&
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen strcmp(mbox->lookup_prev_bbox->box->vname, backend_mailbox->vname) == 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen bbox = mbox->lookup_prev_bbox;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen else {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen bbox = virtual_backend_box_lookup_name(mbox, backend_mailbox->vname);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mbox->lookup_prev_bbox = bbox;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen }
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen if (bbox == NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen uids = array_get(&bbox->uids, &count); i = 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_iter_init(&iter, backend_uids); n = 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen while (seq_range_array_iter_nth(&iter, n++, &uid)) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen while (i < count && uids[i].real_uid < uid) i++;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (i == count || uids[i].real_uid > uid) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen uint32_t zero = 0;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_append(virtual_uids_r, &zero, 1);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen } else {
cc7e2c3903f8fadb7474f09665b2280463850bebTimo Sirainen i_assert(uids[i].virtual_uid > 0);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_append(virtual_uids_r, &uids[i].virtual_uid, 1);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i++;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen}
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenstatic void
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenvirtual_get_virtual_backend_boxes(struct mailbox *box,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen ARRAY_TYPE(mailboxes) *mailboxes,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen bool only_with_msgs)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen{
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen struct virtual_backend_box *const *bboxes;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen unsigned int i, count;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen bboxes = array_get(&mbox->backend_boxes, &count);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen for (i = 0; i < count; i++) {
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (!only_with_msgs || array_count(&bboxes[i]->uids) > 0)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen array_append(mailboxes, &bboxes[i]->box, 1);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen }
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen}
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainenstatic bool virtual_is_inconsistent(struct mailbox *box)
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen{
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen if (mbox->inconsistent)
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen return TRUE;
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen return index_storage_is_inconsistent(box);
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen}
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainenstatic int
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainenvirtual_list_index_has_changed(struct mailbox *box ATTR_UNUSED,
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen struct mail_index_view *list_view ATTR_UNUSED,
22d6302b54300d87a877675ca8fd97a1da4e5fb8Timo Sirainen uint32_t seq ATTR_UNUSED, bool quick ATTR_UNUSED)
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen{
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen /* we don't have any quick and easy optimizations for tracking
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen virtual folders. ideally we'd completely disable mailbox list
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen indexes for them, but this is the easiest way to do it for now. */
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen return 1;
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen}
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainenstatic void
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainenvirtual_list_index_update_sync(struct mailbox *box ATTR_UNUSED,
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen struct mail_index_transaction *trans ATTR_UNUSED,
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen uint32_t seq ATTR_UNUSED)
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen{
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen}
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct mail_storage virtual_storage = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .name = VIRTUAL_STORAGE_NAME,
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen .class_flags = MAIL_STORAGE_CLASS_FLAG_NOQUOTA,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .v = {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen NULL,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen virtual_storage_alloc,
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen virtual_storage_create,
c6afd726060aae56b6622c6c52aec10231c4bf1cTimo Sirainen index_storage_destroy,
047e3bbb00e68a0d43355e11a67b2e912e06de19Timo Sirainen NULL,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen virtual_storage_get_list_settings,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen NULL,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen virtual_mailbox_alloc,
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen NULL,
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen NULL,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen};
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct mailbox virtual_mailbox = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .v = {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen index_storage_is_readonly,
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen index_storage_mailbox_enable,
047e3bbb00e68a0d43355e11a67b2e912e06de19Timo Sirainen virtual_mailbox_exists,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen virtual_mailbox_open,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen virtual_mailbox_close,
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen virtual_mailbox_free,
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen virtual_mailbox_create,
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen virtual_mailbox_update,
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen index_storage_mailbox_delete,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen index_storage_mailbox_rename,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen virtual_storage_get_status,
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen virtual_mailbox_get_metadata,
6469cf211a57433335641725dc236ebb2b9fdd3bTimo Sirainen index_storage_set_subscribed,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_set,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_get,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_iter_init,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_iter_next,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_iter_deinit,
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen virtual_list_index_has_changed,
013c0431b58809e16fd0afea0429d0b7bb1ef8a1Timo Sirainen virtual_list_index_update_sync,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen virtual_storage_sync_init,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen index_mailbox_sync_next,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen index_mailbox_sync_deinit,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen NULL,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen virtual_notify_changes,
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen virtual_transaction_begin,
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen virtual_transaction_commit,
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen virtual_transaction_rollback,
8a13b020f90e080570658b18c042e7e352c8b14fTimo Sirainen NULL,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen virtual_mail_alloc,
f5a7396b31762a1f876517e13ce9065820139f7cTimo Sirainen virtual_search_init,
f5a7396b31762a1f876517e13ce9065820139f7cTimo Sirainen virtual_search_deinit,
f5a7396b31762a1f876517e13ce9065820139f7cTimo Sirainen virtual_search_next_nonblock,
f5a7396b31762a1f876517e13ce9065820139f7cTimo Sirainen virtual_search_next_update_seq,
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen virtual_save_alloc,
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen virtual_save_begin,
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen virtual_save_continue,
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen virtual_save_finish,
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen virtual_save_cancel,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mail_storage_copy,
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen NULL,
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen NULL,
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen NULL,
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen virtual_is_inconsistent
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen};
499fec3443374cc89fb8c83b8027c1614097d7a3Timo Sirainen
499fec3443374cc89fb8c83b8027c1614097d7a3Timo Sirainenstruct virtual_mailbox_vfuncs virtual_mailbox_vfuncs = {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen virtual_get_virtual_uids,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen virtual_get_virtual_uid_map,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen virtual_get_virtual_backend_boxes
499fec3443374cc89fb8c83b8027c1614097d7a3Timo Sirainen};