virtual-storage.c revision 4ba9a1d3facc515b3feb5238a16bcf91f76fac61
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2008-2010 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"
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"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include <stdio.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include <stdlib.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include <unistd.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include <dirent.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include <sys/stat.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#define VIRTUAL_LIST_CONTEXT(obj) \
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen MODULE_CONTEXT(obj, virtual_mailbox_list_module)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstruct virtual_mailbox_list {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen union mailbox_list_module_context module_ctx;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen};
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenextern struct mail_storage virtual_storage;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenextern struct mailbox virtual_mailbox;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
f5a7396b31762a1f876517e13ce9065820139f7cTimo Sirainenstruct virtual_storage_module virtual_storage_module =
f5a7396b31762a1f876517e13ce9065820139f7cTimo Sirainen MODULE_CONTEXT_INIT(&mail_storage_module_register);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(virtual_mailbox_list_module,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen &mailbox_list_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",
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen box->list->hierarchy_sep, box->name);
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);
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen str = mail_storage_get_last_error(src->storage, &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
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;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen const char *str, *name;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen str = mail_storage_get_last_error(mailbox_get_storage(bbox->box),
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen &error);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen name = t_strdup(get_user_visible_mailbox_name(bbox->box));
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen mailbox_free(&bbox->box);
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen if (error == MAIL_ERROR_NOTFOUND) {
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen /* ignore this. it could be intentional. */
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen if (mbox->storage->storage.user->mail_debug) {
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen i_debug("virtual mailbox %s: "
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen "Skipping non-existing mailbox %s",
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen mbox->box.vname, name);
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen }
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen return 0;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen }
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 str = t_strdup_printf(
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen "Virtual mailbox open failed because of mailbox %s: %s",
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen name, str);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen mail_storage_set_error(mbox->box.storage, error, str);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen return -1;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen}
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainenstatic int virtual_backend_box_open(struct virtual_mailbox *mbox,
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen struct virtual_backend_box *bbox,
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo 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;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
596433ccbca59ce2328dc1d029586154cd937155Timo Sirainen i_assert(bbox->box == NULL);
596433ccbca59ce2328dc1d029586154cd937155Timo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen flags |= MAILBOX_FLAG_KEEP_RECENT;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen mailbox = bbox->name;
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen ns = mail_namespace_find(user->namespaces, &mailbox);
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen bbox->box = mailbox_alloc(ns->list, mailbox, flags);
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen if (mailbox_open(bbox->box) < 0)
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen return virtual_backend_box_open_failed(mbox, bbox);
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen i_array_init(&bbox->uids, 64);
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen i_array_init(&bbox->sync_pending_removes, 64);
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen mail_search_args_init(bbox->search_args, bbox->box, FALSE, NULL);
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; ) {
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen ret = virtual_backend_box_open(mbox, bboxes[i], flags);
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen if (ret <= 0) {
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen if (ret < 0)
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen break;
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen mail_search_args_unref(&bboxes[i]->search_args);
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,
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen const char *name, 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
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool = pool_alloconly_create("virtual mailbox", 1024+512);
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;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen index_storage_mailbox_alloc(&mbox->box, name, flags,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen VIRTUAL_INDEX_PREFIX);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mbox->storage = storage;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen mbox->vseq_lookup_prev_mailbox = i_strdup("");
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mbox->virtual_ext_id =
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mail_index_ext_register(mbox->box.index, "virtual", 0,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen sizeof(struct virtual_mail_index_record),
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen sizeof(uint32_t));
d22301419109ed4a38351715e6760011421dadecTimo Sirainen return &mbox->box;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo 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]->search_result != NULL)
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen mailbox_search_result_free(&bboxes[i]->search_result);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen if (bboxes[i]->box == NULL)
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen continue;
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen mail_search_args_deinit(bboxes[i]->search_args);
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 }
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen i_free_and_null(mbox->vseq_lookup_prev_mailbox);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen}
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic int virtual_mailbox_open(struct mailbox *box)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen int ret = 0;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (virtual_mailbox_is_in_open_stack(mbox->storage, box->name)) {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen mail_storage_set_critical(box->storage,
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 }
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen return index_storage_mailbox_open(box, FALSE);
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
d859478e8b106de6cea54f26861bd4232c92f62cTimo Sirainenstatic int
d859478e8b106de6cea54f26861bd4232c92f62cTimo Sirainenvirtual_mailbox_get_guid(struct mailbox *box,
d859478e8b106de6cea54f26861bd4232c92f62cTimo Sirainen uint8_t guid[MAIL_GUID_128_SIZE] ATTR_UNUSED)
d859478e8b106de6cea54f26861bd4232c92f62cTimo Sirainen{
d859478e8b106de6cea54f26861bd4232c92f62cTimo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
d859478e8b106de6cea54f26861bd4232c92f62cTimo Sirainen "Virtual mailboxes have no GUIDs");
d859478e8b106de6cea54f26861bd4232c92f62cTimo Sirainen return -1;
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
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainenstatic void virtual_notify_changes(struct mailbox *box)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen struct virtual_backend_box *const *bboxes;
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen unsigned int i, count;
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen bboxes = array_get(&mbox->backend_boxes, &count);
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen for (i = 0; i < count; i++) {
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen struct mailbox *bbox = bboxes[i]->box;
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen if (box->notify_callback == NULL)
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen mailbox_notify_changes_stop(bbox);
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen else {
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen mailbox_notify_changes(bbox, box->notify_min_interval,
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen virtual_notify_callback, box);
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen }
77d8223da3da23b731257596abefa77e4485b77dTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic int
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainenvirtual_list_get_mailbox_flags(struct mailbox_list *list,
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen const char *dir, const char *fname,
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen enum mailbox_list_file_type type,
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen struct stat *st_r,
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen enum mailbox_info_flags *flags)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen struct virtual_mailbox_list *mlist = VIRTUAL_LIST_CONTEXT(list);
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen struct stat st2;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen const char *virtual_path;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen int ret;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen ret = mlist->module_ctx.super.
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen get_mailbox_flags(list, dir, fname, type, st_r, flags);
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen if (ret <= 0 || MAILBOX_INFO_FLAGS_FINISHED(*flags))
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen return ret;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* see if it's a selectable mailbox */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen virtual_path = t_strconcat(dir, "/", fname, "/"VIRTUAL_CONFIG_FNAME,
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen NULL);
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen if (stat(virtual_path, &st2) < 0)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen *flags |= MAILBOX_NOSELECT;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return ret;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainenstatic void virtual_storage_add_list(struct mail_storage *storage ATTR_UNUSED,
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen struct mailbox_list *list)
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen{
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen struct mailbox_list_vfuncs *v = list->vlast;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen struct virtual_mailbox_list *mlist;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen mlist = p_new(list->pool, struct virtual_mailbox_list, 1);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen mlist->module_ctx.super = *v;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen list->vlast = &mlist->module_ctx.super;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->get_mailbox_flags = virtual_list_get_mailbox_flags;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen MODULE_CONTEXT_SET(list, virtual_mailbox_list_module, mlist);
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen}
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen
fde0b1793a2842da00eaa105d5e13fec465f0443Timo Sirainenstatic int virtual_backend_uidmap_cmp(const uint32_t *uid,
fde0b1793a2842da00eaa105d5e13fec465f0443Timo Sirainen const struct virtual_backend_uidmap *map)
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen{
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen return *uid < map->real_uid ? -1 :
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen *uid > map->real_uid ? 1 : 0;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen}
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenstatic bool
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenvirtual_get_virtual_uid(struct mailbox *box, const char *backend_mailbox,
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen uint32_t backend_uidvalidity,
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen uint32_t backend_uid, uint32_t *uid_r)
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen{
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen struct virtual_backend_box *bbox;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen struct mailbox_status status;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen const struct virtual_backend_uidmap *uids;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen if (strcmp(mbox->vseq_lookup_prev_mailbox, backend_mailbox) == 0)
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen bbox = mbox->vseq_lookup_prev_bbox;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen else {
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen i_free(mbox->vseq_lookup_prev_mailbox);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen mbox->vseq_lookup_prev_mailbox = i_strdup(backend_mailbox);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen bbox = virtual_backend_box_lookup_name(mbox, backend_mailbox);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen mbox->vseq_lookup_prev_bbox = bbox;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen }
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen if (bbox == NULL)
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen return FALSE;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen mailbox_get_status(bbox->box, STATUS_UIDVALIDITY, &status);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen if (status.uidvalidity != backend_uidvalidity)
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen return FALSE;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
fde0b1793a2842da00eaa105d5e13fec465f0443Timo Sirainen uids = array_bsearch(&bbox->uids, &backend_uid,
fde0b1793a2842da00eaa105d5e13fec465f0443Timo Sirainen virtual_backend_uidmap_cmp);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen if (uids == NULL)
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen return FALSE;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen *uid_r = uids->virtual_uid;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen return TRUE;
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
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenstatic void
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenvirtual_get_virtual_box_patterns(struct mailbox *box,
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen ARRAY_TYPE(mailbox_virtual_patterns) *includes,
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen ARRAY_TYPE(mailbox_virtual_patterns) *excludes)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen{
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen array_append_array(includes, &mbox->list_include_patterns);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen array_append_array(excludes, &mbox->list_exclude_patterns);
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
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,
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen NULL,
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen NULL,
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen virtual_storage_add_list,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen virtual_storage_get_list_settings,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen NULL,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen virtual_mailbox_alloc,
34f4c7610b846a945779b6be78d1ef575c7d0ca8Timo Sirainen NULL
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen};
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct mailbox virtual_mailbox = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .v = {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen index_storage_is_readonly,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen index_storage_allow_new_keywords,
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen index_storage_mailbox_enable,
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,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen index_storage_get_status,
d859478e8b106de6cea54f26861bd4232c92f62cTimo Sirainen virtual_mailbox_get_guid,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen NULL,
fbd918f47f591f8084fd52b207ef29515ddd11b9Timo Sirainen NULL,
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,
c1526c9903d3aaae653e6f173c7084ac62b8e76bTimo Sirainen index_transaction_set_max_modseq,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen index_keywords_create,
2f1a8d2d0008c63241143b67698cf1d523560bf9Timo Sirainen index_keywords_create_from_indexes,
84ed9f8f3d0e5ed47607ef417618e49e4f865557Timo Sirainen index_keywords_ref,
84ed9f8f3d0e5ed47607ef417618e49e4f865557Timo Sirainen index_keywords_unref,
6c40fee25bda974c0502e32ca70ca8ebb1c88a76Timo Sirainen index_keyword_is_valid,
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen index_storage_get_seq_range,
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen index_storage_get_uid_range,
80a1558bc44206376c3d55442179676d42f54584Timo Sirainen index_storage_get_expunges,
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen virtual_get_virtual_uid,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen virtual_get_virtual_backend_boxes,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen virtual_get_virtual_box_patterns,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen virtual_mail_alloc,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen index_header_lookup_init,
de58be41126e5d68008d2ea706d62ccdc1f29337Timo Sirainen index_header_lookup_deinit,
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,
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen NULL,
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen virtual_is_inconsistent
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen};