mailbox-list.c revision 563273bdac80393af63b9520cbf4d24cc0efd028
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2006-2009 Dovecot authors, see the included COPYING file */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "lib.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "array.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "ioloop.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "str.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "home-expand.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "unlink-directory.h"
a85473f7c11c8734bdee9c2cbe4b767f144a18aaTimo Sirainen#include "imap-match.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "imap-utf7.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "mailbox-tree.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "mail-storage-private.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "mailbox-list-private.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include <time.h>
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include <unistd.h>
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen#include <dirent.h>
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen#include <sys/stat.h>
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen/* 20 * (200+1) < 4096 which is the standard PATH_MAX. Having these settings
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen prevents malicious user from creating eg. "a/a/a/.../a" mailbox name and
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen then start renaming them to larger names from end to beginning, which
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen eventually would start causing the failures when trying to use too
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen long mailbox names. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#define MAILBOX_MAX_HIERARCHY_LEVELS 20
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen#define MAILBOX_MAX_HIERARCHY_NAME_LENGTH 200
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainenstruct ns_list_iterate_context {
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen struct mailbox_list_iterate_context ctx;
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen struct mailbox_list_iterate_context *backend_ctx;
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen struct mail_namespace *namespaces;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen pool_t pool;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char **patterns;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen};
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstruct mailbox_list_module_register mailbox_list_module_register = { 0 };
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenvoid (*hook_mailbox_list_created)(struct mailbox_list *list);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainenstatic ARRAY_DEFINE(mailbox_list_drivers, const struct mailbox_list *);
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainenvoid mailbox_lists_init(void)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_array_init(&mailbox_list_drivers, 4);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenvoid mailbox_lists_deinit(void)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen array_free(&mailbox_list_drivers);
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen}
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic bool mailbox_list_driver_find(const char *name, unsigned int *idx_r)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct mailbox_list *const *drivers;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen unsigned int i, count;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen drivers = array_get(&mailbox_list_drivers, &count);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen for (i = 0; i < count; i++) {
3c73d884362b72c86753939551c94f8baa5702f8Timo Sirainen if (strcasecmp(drivers[i]->name, name) == 0) {
3c73d884362b72c86753939551c94f8baa5702f8Timo Sirainen *idx_r = i;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen return TRUE;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return FALSE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenvoid mailbox_list_register(const struct mailbox_list *list)
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen{
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen unsigned int idx;
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen if (mailbox_list_driver_find(list->name, &idx)) {
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen i_fatal("mailbox_list_register(%s): duplicate driver",
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen list->name);
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen }
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen array_append(&mailbox_list_drivers, &list, 1);
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen}
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainenvoid mailbox_list_unregister(const struct mailbox_list *list)
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen{
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen unsigned int idx;
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen if (!mailbox_list_driver_find(list->name, &idx)) {
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen i_fatal("mailbox_list_unregister(%s): unknown driver",
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen list->name);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen array_delete(&mailbox_list_drivers, idx, 1);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainenint mailbox_list_create(const char *driver, struct mail_namespace *ns,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct mailbox_list_settings *set,
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen enum mailbox_list_flags flags, const char **error_r)
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct mailbox_list *const *class_p;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox_list *list;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen unsigned int idx;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(ns->list == NULL);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen i_assert(set->root_dir == NULL || *set->root_dir != '\0');
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen i_assert(set->subscription_fname == NULL ||
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen *set->subscription_fname != '\0');
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen if (!mailbox_list_driver_find(driver, &idx)) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *error_r = t_strdup_printf("Unknown mailbox list driver: %s",
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen driver);
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen return -1;
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen }
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen class_p = array_idx(&mailbox_list_drivers, idx);
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen list = (*class_p)->v.alloc();
887a9fbbb2ca6afd53365ba2ccae0ef8728d6948Timo Sirainen array_create(&list->module_contexts, list->pool, sizeof(void *), 5);
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen list->ns = ns;
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen list->mail_set = ns->mail_set;
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen list->flags = flags;
887a9fbbb2ca6afd53365ba2ccae0ef8728d6948Timo Sirainen list->file_create_mode = (mode_t)-1;
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen list->dir_create_mode = (mode_t)-1;
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen list->file_create_gid = (gid_t)-1;
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen /* copy settings */
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen list->set.root_dir = p_strdup(list->pool, set->root_dir);
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen list->set.index_dir = set->index_dir == NULL ||
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen strcmp(set->index_dir, set->root_dir) == 0 ? NULL :
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen p_strdup(list->pool, set->index_dir);
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen list->set.control_dir = set->control_dir == NULL ||
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainen strcmp(set->control_dir, set->root_dir) == 0 ? NULL :
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen p_strdup(list->pool, set->control_dir);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen list->set.inbox_path = p_strdup(list->pool, set->inbox_path);
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen list->set.subscription_fname =
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen p_strdup(list->pool, set->subscription_fname);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen list->set.maildir_name = set->maildir_name == NULL ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen (list->props & MAILBOX_LIST_PROP_NO_MAILDIR_NAME) != 0 ? "" :
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen p_strdup(list->pool, set->maildir_name);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen list->set.mailbox_dir_name =
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen p_strdup(list->pool, set->mailbox_dir_name);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (set->mailbox_dir_name == NULL || *set->mailbox_dir_name == '\0')
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen list->set.mailbox_dir_name = "";
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen else if (set->mailbox_dir_name[strlen(set->mailbox_dir_name)-1] == '/') {
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen list->set.mailbox_dir_name =
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen p_strdup(list->pool, set->mailbox_dir_name);
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen } else {
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen list->set.mailbox_dir_name =
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen p_strconcat(list->pool, set->mailbox_dir_name, "/", NULL);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen if (ns->mail_set->mail_debug) {
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen i_info("%s: root=%s, index=%s, control=%s, inbox=%s",
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen list->name,
33bd898e7756b289e65f43133312d9637afc1371Timo Sirainen list->set.root_dir == NULL ? "" : list->set.root_dir,
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen list->set.index_dir == NULL ? "" : list->set.index_dir,
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen list->set.control_dir == NULL ?
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen "" : list->set.control_dir,
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen list->set.inbox_path == NULL ?
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "" : list->set.inbox_path);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainen mail_namespace_finish_list_init(ns, list);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainen if (hook_mailbox_list_created != NULL)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen hook_mailbox_list_created(list);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic int fix_path(struct mail_namespace *ns, const char *path,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char **path_r)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainen size_t len = strlen(path);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen if (len > 1 && path[len-1] == '/')
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen path = t_strndup(path, len-1);
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen if (mail_user_try_home_expand(ns->user, &path) < 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *path_r = path;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint mailbox_list_settings_parse(const char *data,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox_list_settings *set,
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainen struct mail_namespace *ns, const char **error_r)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *const *tmp, *key, *value, **dest;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *error_r = NULL;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (*data == '\0')
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen return 0;
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen /* <root dir> */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen tmp = t_strsplit(data, ":");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (fix_path(ns, *tmp, &set->root_dir) < 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *error_r = t_strdup_printf(
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Home directory not set, can't expand ~/ for "
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "mail root dir in: %s", data);
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen tmp++;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen for (; *tmp != NULL; tmp++) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen value = strchr(*tmp, '=');
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (value == NULL) {
887a9fbbb2ca6afd53365ba2ccae0ef8728d6948Timo Sirainen key = *tmp;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen value = "";
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen } else {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen key = t_strdup_until(*tmp, value);
36723cf206a7b64b9d972ab0719bbfaacc9316faTimo Sirainen value++;
efeb13303798b47d2c4295468d233c1bcfd79c94Timo Sirainen }
307ec6c2c319e3335ddb1a7aca2d2884fe17fae0Timo Sirainen
307ec6c2c319e3335ddb1a7aca2d2884fe17fae0Timo Sirainen if (strcmp(key, "INBOX") == 0)
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen dest = &set->inbox_path;
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen else if (strcmp(key, "INDEX") == 0)
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen dest = &set->index_dir;
975a784c2e02ecdcb56efb7a1db5e4769c7756d8Timo Sirainen else if (strcmp(key, "CONTROL") == 0)
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen dest = &set->control_dir;
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen else if (strcmp(key, "ALT") == 0)
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen dest = &set->alt_dir;
14b1d2a2634e75b988078baee1e8ad678de28a04Timo Sirainen else if (strcmp(key, "LAYOUT") == 0)
14b1d2a2634e75b988078baee1e8ad678de28a04Timo Sirainen dest = &set->layout;
45af47783693b3ba2768c5ad34eeff68132382d0Timo Sirainen else if (strcmp(key, "SUBSCRIPTIONS") == 0)
45af47783693b3ba2768c5ad34eeff68132382d0Timo Sirainen dest = &set->subscription_fname;
afd6d387ea65843b59fb6051fb567719d2a5279cAki Tuomi else if (strcmp(key, "DIRNAME") == 0)
afd6d387ea65843b59fb6051fb567719d2a5279cAki Tuomi dest = &set->maildir_name;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen else if (strcmp(key, "MAILBOXDIR") == 0)
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen dest = &set->mailbox_dir_name;
70df8f39fb3db7c49b18c855178f8172176a037aTimo Sirainen else {
70df8f39fb3db7c49b18c855178f8172176a037aTimo Sirainen *error_r = t_strdup_printf("Unknown setting: %s", key);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (fix_path(ns, value, dest) < 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *error_r = t_strdup_printf(
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Home directory not set, can't expand ~/ for "
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen "%s in: %s", key, data);
3561c7bb472a78af74d755219cc0fc71c85ff5c2Timo Sirainen return -1;
ee8294dbc7bb549557f6ba1264d66b55fbef69b6Aki Tuomi }
ae949831f1f668b5501b4b125e7f7b1767fb109bTimo Sirainen }
2e652d2651b2800f99a17dcb3014a009fe4660d3Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (set->index_dir != NULL && strcmp(set->index_dir, "MEMORY") == 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen set->index_dir = "";
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return 0;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen}
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainenvoid mailbox_list_destroy(struct mailbox_list **_list)
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen{
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen struct mailbox_list *list = *_list;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen *_list = NULL;
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen i_free_and_null(list->error_string);
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen list->v.deinit(list);
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen}
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen
237a6211c7fc4d6dbb58dd0467da6dba1b8f21f6Timo Sirainenconst char *mailbox_list_get_driver_name(const struct mailbox_list *list)
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen{
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen return list->name;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen}
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainenchar mailbox_list_get_hierarchy_sep(const struct mailbox_list *list)
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen{
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen return list->hierarchy_sep;
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen}
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainenenum mailbox_list_flags mailbox_list_get_flags(const struct mailbox_list *list)
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen{
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen return list->flags;
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen}
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainenstruct mail_namespace *
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainenmailbox_list_get_namespace(const struct mailbox_list *list)
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen{
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen return list->ns;
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen}
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainenstatic mode_t get_dir_mode(mode_t mode)
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen{
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen /* add the execute bit if either read or write bit is set */
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen if ((mode & 0600) != 0) mode |= 0100;
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen if ((mode & 0060) != 0) mode |= 0010;
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen if ((mode & 0006) != 0) mode |= 0001;
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen return mode;
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen}
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainenstruct mail_user *
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainenmailbox_list_get_user(const struct mailbox_list *list)
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen{
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen return list->ns->user;
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen}
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainenint mailbox_list_get_storage(struct mailbox_list **list, const char **name,
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen struct mail_storage **storage_r)
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen{
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen if ((*list)->v.get_storage != NULL)
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen return (*list)->v.get_storage(list, name, storage_r);
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen else {
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen *storage_r = (*list)->ns->storage;
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen return 0;
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen }
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen}
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainenvoid mailbox_list_get_closest_storage(struct mailbox_list *list,
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen struct mail_storage **storage)
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen{
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen *storage = list->ns->storage;
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen}
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainenstatic void
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainenmailbox_list_get_permissions_full(struct mailbox_list *list, const char *name,
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen mode_t *file_mode_r, mode_t *dir_mode_r,
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen gid_t *gid_r)
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen{
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen const char *path;
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen struct stat st;
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_DIR);
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen if (stat(path, &st) < 0) {
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen if (!ENOTFOUND(errno)) {
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen mailbox_list_set_critical(list, "stat(%s) failed: %m",
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen path);
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen } else if (list->mail_set->mail_debug) {
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen i_info("Namespace %s: Permission lookup failed from %s",
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen list->ns->prefix, path);
d519a0449d0e536a32db93305516fdbd7db6773dTimo Sirainen }
d519a0449d0e536a32db93305516fdbd7db6773dTimo Sirainen /* return safe defaults */
ee8294dbc7bb549557f6ba1264d66b55fbef69b6Aki Tuomi *file_mode_r = 0600;
ee8294dbc7bb549557f6ba1264d66b55fbef69b6Aki Tuomi *dir_mode_r = 0700;
3561c7bb472a78af74d755219cc0fc71c85ff5c2Timo Sirainen *gid_r = (gid_t)-1;
ae949831f1f668b5501b4b125e7f7b1767fb109bTimo Sirainen } else {
ae949831f1f668b5501b4b125e7f7b1767fb109bTimo Sirainen *file_mode_r = st.st_mode & 0666;
45af47783693b3ba2768c5ad34eeff68132382d0Timo Sirainen *dir_mode_r = st.st_mode & 0777;
45af47783693b3ba2768c5ad34eeff68132382d0Timo Sirainen
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen if (!S_ISDIR(st.st_mode)) {
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen /* we're getting permissions from a file.
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen apply +x modes as necessary. */
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen *dir_mode_r = get_dir_mode(*dir_mode_r);
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen }
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen if (S_ISDIR(st.st_mode) && (st.st_mode & S_ISGID) != 0) {
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen /* directory's GID is used automatically for new
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen files */
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen *gid_r = (gid_t)-1;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen } else if ((st.st_mode & 0070) >> 3 == (st.st_mode & 0007)) {
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen /* group has same permissions as world, so don't bother
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen changing it */
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen *gid_r = (gid_t)-1;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen } else if (getegid() == st.st_gid) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* using our own gid, no need to change it */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *gid_r = (gid_t)-1;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen } else {
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen *gid_r = st.st_gid;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (name == NULL) {
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen list->file_create_mode = *file_mode_r;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen list->dir_create_mode = *dir_mode_r;
f43ce62fa945f597e8a48e09c53d46dcc95445d4Timo Sirainen list->file_create_gid = *gid_r;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen if (list->mail_set->mail_debug && name == NULL) {
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen i_info("Namespace %s: Using permissions from %s: "
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "mode=0%o gid=%ld", list->ns->prefix, path,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen (int)list->dir_create_mode,
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen list->file_create_gid == (gid_t)-1 ? -1L :
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen (long)list->file_create_gid);
805d7834412465268486c50711962407ad13fbf6Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenvoid mailbox_list_get_permissions(struct mailbox_list *list, const char *name,
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen mode_t *mode_r, gid_t *gid_r)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mode_t dir_mode;
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen if (list->file_create_mode != (mode_t)-1 && name == NULL) {
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen *mode_r = list->file_create_mode;
805d7834412465268486c50711962407ad13fbf6Timo Sirainen *gid_r = list->file_create_gid;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen return;
805d7834412465268486c50711962407ad13fbf6Timo Sirainen }
805d7834412465268486c50711962407ad13fbf6Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_get_permissions_full(list, name, mode_r, &dir_mode, gid_r);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenvoid mailbox_list_get_dir_permissions(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *name,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mode_t *mode_r, gid_t *gid_r)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mode_t file_mode;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen if (list->dir_create_mode != (mode_t)-1 && name == NULL) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *mode_r = list->dir_create_mode;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *gid_r = list->file_create_gid;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return;
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen }
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_get_permissions_full(list, name, &file_mode,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mode_r, gid_r);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenbool mailbox_list_is_valid_pattern(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *pattern)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return list->v.is_valid_pattern(list, pattern);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenbool mailbox_list_is_valid_existing_name(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *name)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return list->v.is_valid_existing_name(list, name);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenbool mailbox_list_is_valid_create_name(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *name)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen int ret;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen T_BEGIN {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen string_t *str = t_str_new(256);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ret = imap_utf7_to_utf8(name, str);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen } T_END;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return ret < 0 ? FALSE :
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen list->v.is_valid_create_name(list, name);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenconst char *mailbox_list_get_path(struct mailbox_list *list, const char *name,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen enum mailbox_list_path_type type)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_clear_error(list);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return list->v.get_path(list, name, type);
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen}
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainenconst char *mailbox_list_get_temp_prefix(struct mailbox_list *list)
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen{
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen return list->v.get_temp_prefix(list, FALSE);
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen}
cce2c665bb24537bb691f6cad6a36f8080e4a552Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenconst char *mailbox_list_get_global_temp_prefix(struct mailbox_list *list)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return list->v.get_temp_prefix(list, TRUE);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenconst char *mailbox_list_join_refpattern(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *ref, const char *pattern)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (list->v.join_refpattern != NULL)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return list->v.join_refpattern(list, ref, pattern);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* the default implementation: */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (*ref != '\0') {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* merge reference and pattern */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen pattern = t_strconcat(ref, pattern, NULL);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen return pattern;
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen}
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint mailbox_list_get_mailbox_name_status(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *name,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen enum mailbox_name_status *status)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_clear_error(list);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen if (!mailbox_list_is_valid_existing_name(list, name)) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *status = MAILBOX_NAME_INVALID;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen return list->v.get_mailbox_name_status(list, name, status);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstruct mailbox_list_iterate_context *
fbd671a3f51a5f92535923fcaf05fed1e5712ae4Timo Sirainenmailbox_list_iter_init(struct mailbox_list *list, const char *pattern,
fbd671a3f51a5f92535923fcaf05fed1e5712ae4Timo Sirainen enum mailbox_list_iter_flags flags)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *patterns[2];
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen patterns[0] = pattern;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen patterns[1] = NULL;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return mailbox_list_iter_init_multiple(list, patterns, flags);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstruct mailbox_list_iterate_context *
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmailbox_list_iter_init_multiple(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *const *patterns,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen enum mailbox_list_iter_flags flags)
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen{
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen i_assert(*patterns != NULL);
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen mailbox_list_clear_error(list);
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen return list->v.iter_init(list, patterns, flags);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainenstatic const struct mailbox_info *
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainenmailbox_list_ns_iter_next(struct mailbox_list_iterate_context *_ctx)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen struct ns_list_iterate_context *ctx =
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen (struct ns_list_iterate_context *)_ctx;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct mailbox_info *info;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen info = mailbox_list_iter_next(ctx->backend_ctx);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (info == NULL && ctx->namespaces != NULL) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* go to the next namespace */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0)
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen _ctx->failed = TRUE;
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen ctx->ctx.list->ns = ctx->namespaces;
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen ctx->backend_ctx =
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen mailbox_list_iter_init_multiple(ctx->namespaces->list,
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen ctx->patterns,
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen _ctx->flags);
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen ctx->namespaces = ctx->namespaces->next;
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen return mailbox_list_ns_iter_next(_ctx);
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen }
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen return info;
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic int
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmailbox_list_ns_iter_deinit(struct mailbox_list_iterate_context *_ctx)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct ns_list_iterate_context *ctx =
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen (struct ns_list_iterate_context *)_ctx;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen int ret;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen _ctx->failed = TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ret = _ctx->failed ? -1 : 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen pool_unref(&ctx->pool);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return ret;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstruct mailbox_list_iterate_context *
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmailbox_list_iter_init_namespaces(struct mail_namespace *namespaces,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *const *patterns,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen enum mailbox_list_iter_flags flags)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct ns_list_iterate_context *ctx;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen unsigned int i, count;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen pool_t pool;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(namespaces != NULL);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen pool = pool_alloconly_create("mailbox list namespaces", 256);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx = p_new(pool, struct ns_list_iterate_context, 1);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->pool = pool;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->ctx.flags = flags;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->ctx.list = p_new(pool, struct mailbox_list, 1);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->ctx.list->v.iter_next = mailbox_list_ns_iter_next;
a0ebe2a2271759599686f3480aee6a6fe445d16eTimo Sirainen ctx->ctx.list->v.iter_deinit = mailbox_list_ns_iter_deinit;
a0ebe2a2271759599686f3480aee6a6fe445d16eTimo Sirainen
a0ebe2a2271759599686f3480aee6a6fe445d16eTimo Sirainen count = str_array_length(patterns);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->patterns = p_new(pool, const char *, count + 1);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen for (i = 0; i < count; i++)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->patterns[i] = p_strdup(pool, patterns[i]);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->ctx.list->ns = namespaces;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->backend_ctx = mailbox_list_iter_init_multiple(namespaces->list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen patterns, flags);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->namespaces = namespaces->next;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return &ctx->ctx;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenconst struct mailbox_info *
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmailbox_list_iter_next(struct mailbox_list_iterate_context *ctx)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
24bd831901b8fd59718e353b36eaef6a950f09a2Timo Sirainen const struct mailbox_info *info;
b8e6e314eb2f9f1fc8ce2999034321bfeb7a2269Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen info = ctx->list->v.iter_next(ctx);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (info != NULL)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->list->ns->flags |= NAMESPACE_FLAG_USABLE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return info;
a85473f7c11c8734bdee9c2cbe4b767f144a18aaTimo Sirainen}
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint mailbox_list_iter_deinit(struct mailbox_list_iterate_context **_ctx)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox_list_iterate_context *ctx = *_ctx;
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainen
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainen *_ctx = NULL;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return ctx->list->v.iter_deinit(ctx);
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainen}
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainen
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainenint mailbox_list_set_subscribed(struct mailbox_list *list,
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainen const char *name, bool set)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen mailbox_list_clear_error(list);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return list->v.set_subscribed(list, name, set);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint mailbox_list_delete_mailbox(struct mailbox_list *list, const char *name)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (!mailbox_list_is_valid_existing_name(list, name)) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_PARAMS,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Invalid mailbox name");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (strcmp(name, "INBOX") == 0 &&
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen (list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "INBOX can't be deleted.");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return list->v.delete_mailbox(list, name);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic bool nullequals(const void *p1, const void *p2)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return (p1 == NULL && p2 == NULL) || (p1 != NULL && p2 != NULL);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint mailbox_list_rename_mailbox(struct mailbox_list *oldlist,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *oldname,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox_list *newlist,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *newname, bool rename_children)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mail_storage *oldstorage;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mail_storage *newstorage;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_list_get_storage(&oldlist, &oldname, &oldstorage) < 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen newstorage = oldstorage;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_get_closest_storage(newlist, &newstorage);
31a574fda352ef4f71dbff9c30e15e4744e132c0Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (!mailbox_list_is_valid_existing_name(oldlist, oldname) ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen !mailbox_list_is_valid_create_name(newlist, newname)) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(oldlist, MAIL_ERROR_PARAMS,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Invalid mailbox name");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (strcmp(oldstorage->name, newstorage->name) != 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(oldlist, MAIL_ERROR_NOTPOSSIBLE,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Can't rename mailbox to another storage type.");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (!nullequals(oldlist->set.index_dir, newlist->set.index_dir) ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen !nullequals(oldlist->set.control_dir, newlist->set.control_dir)) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(oldlist, MAIL_ERROR_NOTPOSSIBLE,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Can't rename mailboxes across specified storages.");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (oldlist->ns->type != NAMESPACE_PRIVATE ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen newlist->ns->type != NAMESPACE_PRIVATE) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(oldlist, MAIL_ERROR_NOTPOSSIBLE,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Renaming not supported across non-private namespaces.");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return oldlist->v.rename_mailbox(oldlist, oldname, newlist, newname,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen rename_children);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic int mailbox_list_try_delete(struct mailbox_list *list, const char *dir)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (unlink_directory(dir, TRUE) == 0 || errno == ENOENT)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (errno == ENOTEMPTY) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* We're most likely using NFS and we can't delete
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen .nfs* files. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_INUSE,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Mailbox is still open in another session, "
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "can't delete it.");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen } else {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_critical(list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "unlink_directory(%s) failed: %m", dir);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
31a574fda352ef4f71dbff9c30e15e4744e132c0Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint mailbox_list_delete_index_control(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *name)
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *path, *index_dir, *dir;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen path = mailbox_list_get_path(list, name,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* delete the index directory first, so that if we crash we don't
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen leave indexes for deleted mailboxes lying around */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen index_dir = mailbox_list_get_path(list, name,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen MAILBOX_LIST_PATH_TYPE_INDEX);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (*index_dir != '\0' && strcmp(index_dir, path) != 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_list_try_delete(list, index_dir) < 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* control directory next */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen dir = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_CONTROL);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (*dir != '\0' && strcmp(dir, path) != 0 &&
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen strcmp(dir, index_dir) != 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_list_try_delete(list, dir) < 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainenstatic void node_fix_parents(struct mailbox_node *node)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* If we happened to create any of the parents, we need to mark them
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen nonexistent. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen node = node->parent;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen for (; node != NULL; node = node->parent) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if ((node->flags & MAILBOX_MATCHED) == 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen node->flags |= MAILBOX_NONEXISTENT;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic void
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmailbox_list_iter_update_real(struct mailbox_list_iter_update_context *ctx,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *name)
63f01d5e4c9efe985fad63d5851dd1c5c153affaTimo Sirainen{
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen struct mail_namespace *ns = ctx->iter_ctx->list->ns;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox_node *node;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen enum mailbox_info_flags create_flags = 0, always_flags;
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen enum imap_match_result match;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *p;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen bool created, add_matched;
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen if (ctx->update_only ||
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen (ctx->iter_ctx->flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) == 0)
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen create_flags = MAILBOX_NONEXISTENT | MAILBOX_NOCHILDREN;
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen always_flags = ctx->leaf_flags;
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen add_matched = TRUE;
9ed42a54bed303c68106e59b2072e98930048177Timo Sirainen
9ed42a54bed303c68106e59b2072e98930048177Timo Sirainen for (;;) {
9ed42a54bed303c68106e59b2072e98930048177Timo Sirainen created = FALSE;
9ed42a54bed303c68106e59b2072e98930048177Timo Sirainen match = imap_match(ctx->glob, name);
9ed42a54bed303c68106e59b2072e98930048177Timo Sirainen if (match == IMAP_MATCH_YES) {
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen node = ctx->update_only ?
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen mailbox_tree_lookup(ctx->tree_ctx, name) :
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen mailbox_tree_get(ctx->tree_ctx, name, &created);
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen if (created) {
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen node->flags = create_flags;
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen if (create_flags != 0)
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen node_fix_parents(node);
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (node != NULL) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (!ctx->update_only && add_matched)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen node->flags |= MAILBOX_MATCHED;
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen node->flags |= always_flags;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen /* We don't want to show the parent mailboxes unless
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen something else matches them, but if they are matched
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen we want to show them having child subscriptions */
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen add_matched = FALSE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen } else {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if ((match & IMAP_MATCH_PARENT) == 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen break;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* We've a (possibly) non-subscribed parent mailbox
a85473f7c11c8734bdee9c2cbe4b767f144a18aaTimo Sirainen which has a subscribed child mailbox. Make sure we
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return the parent mailbox. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
24bd831901b8fd59718e353b36eaef6a950f09a2Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (!ctx->match_parents)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen break;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen /* see if parent matches */
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen p = strrchr(name, ns->sep);
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen if (p == NULL)
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen break;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen name = t_strdup_until(name, p);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen create_flags &= ~MAILBOX_NOCHILDREN;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen always_flags = MAILBOX_CHILDREN | ctx->parent_flags;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainenvoid mailbox_list_iter_update(struct mailbox_list_iter_update_context *ctx,
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen const char *name)
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen{
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen T_BEGIN {
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen mailbox_list_iter_update_real(ctx, name);
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen } T_END;
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen}
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainenbool mailbox_list_name_is_too_large(const char *name, char sep)
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen{
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen unsigned int levels = 1, level_len = 0;
311cbd9b1c81df050f5019600a2a809bc620be00Timo Sirainen
311cbd9b1c81df050f5019600a2a809bc620be00Timo Sirainen for (; *name != '\0'; name++) {
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen if (*name == sep) {
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen if (level_len > MAILBOX_MAX_HIERARCHY_NAME_LENGTH)
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen levels++;
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen level_len = 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen } else {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen level_len++;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen if (level_len > MAILBOX_MAX_HIERARCHY_NAME_LENGTH)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (levels > MAILBOX_MAX_HIERARCHY_LEVELS)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return FALSE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenenum mailbox_list_file_type
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmailbox_list_get_file_type(const struct dirent *d ATTR_UNUSED)
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen enum mailbox_list_file_type type;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#ifdef HAVE_DIRENT_D_TYPE
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen switch (d->d_type) {
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen case DT_UNKNOWN:
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen type = MAILBOX_LIST_FILE_TYPE_UNKNOWN;
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen break;
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen case DT_REG:
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen type = MAILBOX_LIST_FILE_TYPE_FILE;
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen break;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen case DT_DIR:
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen type = MAILBOX_LIST_FILE_TYPE_DIR;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen break;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen case DT_LNK:
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen type = MAILBOX_LIST_FILE_TYPE_SYMLINK;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen break;
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen default:
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen type = MAILBOX_LIST_FILE_TYPE_OTHER;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen break;
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#else
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen type = MAILBOX_LIST_FILE_TYPE_UNKNOWN;
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen#endif
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen return type;
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen}
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainenbool mailbox_list_try_get_absolute_path(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char **name)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (!list->mail_set->mail_full_filesystem_access)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return FALSE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainen if (**name == '/')
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen return TRUE;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen if (**name != '~')
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen return FALSE;
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen /* try to expand home directory */
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen if ((*name)[1] == '/') {
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen /* ~/dir - use the configured home directory */
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen if (mail_user_try_home_expand(list->ns->user, name) == 0)
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen } else {
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen /* ~otheruser/dir - assume we're using system users */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (home_try_expand(name) == 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
/* fallback to using ~dir */
return FALSE;
}
const char *mailbox_list_get_last_error(struct mailbox_list *list,
enum mail_error *error_r)
{
if (error_r != NULL)
*error_r = list->error;
return list->error_string != NULL ? list->error_string :
"Unknown internal list error";
}
void mailbox_list_clear_error(struct mailbox_list *list)
{
i_free_and_null(list->error_string);
list->error = MAIL_ERROR_NONE;
}
void mailbox_list_set_error(struct mailbox_list *list,
enum mail_error error, const char *string)
{
i_free(list->error_string);
list->error_string = i_strdup(string);
list->error = error;
}
void mailbox_list_set_internal_error(struct mailbox_list *list)
{
struct tm *tm;
char str[256];
tm = localtime(&ioloop_time);
i_free(list->error_string);
list->error_string =
strftime(str, sizeof(str),
MAIL_ERRSTR_CRITICAL_MSG_STAMP, tm) > 0 ?
i_strdup(str) : i_strdup(MAIL_ERRSTR_CRITICAL_MSG);
list->error = MAIL_ERROR_TEMP;
}
void mailbox_list_set_critical(struct mailbox_list *list, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
i_error("%s", t_strdup_vprintf(fmt, va));
va_end(va);
/* critical errors may contain sensitive data, so let user
see only "Internal error" with a timestamp to make it
easier to look from log files the actual error message. */
mailbox_list_set_internal_error(list);
}
bool mailbox_list_set_error_from_errno(struct mailbox_list *list)
{
const char *error_string;
enum mail_error error;
if (!mail_error_from_errno(&error, &error_string))
return FALSE;
mailbox_list_set_error(list, error, error_string);
return TRUE;
}
void mailbox_list_set_error_from_storage(struct mailbox_list *list,
struct mail_storage *storage)
{
const char *str;
enum mail_error error;
str = mail_storage_get_last_error(storage, &error);
mailbox_list_set_error(list, error, str);
}