]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Replace LAYOUT with mailbox_list_layout setting
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 27 Oct 2023 12:38:57 +0000 (15:38 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:10 +0000 (12:34 +0200)
28 files changed:
src/lib-storage/fail-mail-storage.c
src/lib-storage/index/dbox-common/dbox-storage.c
src/lib-storage/index/imapc/imapc-list.c
src/lib-storage/index/imapc/imapc-list.h
src/lib-storage/index/imapc/imapc-settings.c
src/lib-storage/index/imapc/imapc-storage.c
src/lib-storage/index/maildir/maildir-settings.c
src/lib-storage/index/maildir/maildir-storage.c
src/lib-storage/index/mbox/mbox-storage.c
src/lib-storage/index/pop3c/pop3c-storage.c
src/lib-storage/index/raw/raw-storage.c
src/lib-storage/index/shared/shared-storage.c
src/lib-storage/list/mail-storage-list-index-rebuild.c
src/lib-storage/list/mailbox-list-index-backend.c
src/lib-storage/list/mailbox-list-index-iter.c
src/lib-storage/list/mailbox-list-index.c
src/lib-storage/mail-namespace.c
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage-settings.c
src/lib-storage/mail-storage-settings.h
src/lib-storage/mail-storage.c
src/lib-storage/mailbox-list.c
src/lib-storage/mailbox-list.h
src/lib-storage/test-mail-storage-common.c
src/lib-storage/test-mail-storage-common.h
src/lib-storage/test-mail-storage.c
src/plugins/acl/acl-mailbox.c
src/plugins/virtual/virtual-storage.c

index e143ef3a47b92fa609ff6128ca3f1738d42810a8..0bc034460f11d8a75c0fa76973b0b9deb5b18a79 100644 (file)
@@ -21,15 +21,6 @@ static void fail_storage_destroy(struct mail_storage *storage ATTR_UNUSED)
 {
 }
 
-static void
-fail_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
-                              struct mailbox_list_settings *set,
-                              const struct mail_storage_settings *mail_set ATTR_UNUSED)
-{
-       if (set->layout == NULL)
-               set->layout = "fail";
-}
-
 struct mail_storage fail_storage = {
        .name = "fail",
        .class_flags = MAIL_STORAGE_CLASS_FLAG_NO_ROOT,
@@ -39,7 +30,7 @@ struct mail_storage fail_storage = {
                NULL,
                fail_storage_destroy,
                NULL,
-               fail_storage_get_list_settings,
+               NULL,
                NULL,
                fail_mailbox_alloc,
                NULL,
index 230bbf1448192eafb7236968c249d9c6c64f8948..875d916023cc20a7a0eca739f9ad17802a7d69db 100644 (file)
@@ -22,8 +22,6 @@ void dbox_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
                                    struct mailbox_list_settings *set,
                                    const struct mail_storage_settings *mail_set ATTR_UNUSED)
 {
-       if (set->layout == NULL)
-               set->layout = MAILBOX_LIST_NAME_FS;
        if (*set->maildir_name == '\0')
                set->maildir_name = DBOX_MAILDIR_NAME;
 }
index 9876c268d67fce081b52eaa4f7cf5f158e6e2445..6f3d1a195567a664837775c9e9725842574dced8 100644 (file)
 #include "lib.h"
 #include "ioloop.h"
 #include "str.h"
+#include "settings.h"
 #include "settings-parser.h"
 #include "imap-arg.h"
 #include "imap-match.h"
 #include "imap-utf7.h"
+#include "mail-storage-service.h"
 #include "mailbox-tree.h"
 #include "mailbox-list-subscriptions.h"
 #include "imapc-storage.h"
@@ -122,6 +124,7 @@ static void imapc_list_deinit(struct mailbox_list *_list)
        }
        if (list->index_list != NULL)
                mailbox_list_destroy(&list->index_list);
+       settings_instance_free(&list->index_list_set_instance);
        mailbox_tree_deinit(&list->mailboxes);
        if (list->tmp_subscriptions != NULL)
                mailbox_tree_deinit(&list->tmp_subscriptions);
@@ -425,7 +428,6 @@ static struct mailbox_list *imapc_list_get_fs(struct imapc_mailbox_list *list)
                /* indexes disabled */
        } else if (list->index_list == NULL && !list->index_list_failed) {
                mailbox_list_settings_init_defaults(&list_set);
-               list_set.layout = MAILBOX_LIST_NAME_MAILDIRPLUSPLUS;
                list_set.root_dir = dir;
                list_set.index_pvt_dir = p_strdup_empty(list->list.pool, list->list.set.index_pvt_dir);
                /* Filesystem needs to be able to store any kind of a mailbox
@@ -433,16 +435,37 @@ static struct mailbox_list *imapc_list_get_fs(struct imapc_mailbox_list *list)
                list_set.storage_name_escape_char =
                        IMAPC_LIST_FS_NAME_ESCAPE_CHAR;
 
+               struct settings_instance *set_instance =
+                       mail_storage_service_user_get_settings_instance(
+                               list->list.ns->user->service_user);
+               list->index_list_set_instance =
+                       settings_instance_dup(set_instance);
+               mail_storage_2nd_settings_reset(list->index_list_set_instance, "*/");
+               settings_override(list->index_list_set_instance,
+                                 "*/mailbox_list_layout",
+                                 MAILBOX_LIST_NAME_MAILDIRPLUSPLUS,
+                                 SETTINGS_OVERRIDE_TYPE_CODE);
+
+               const struct mail_storage_settings *mail_set = NULL;
                struct event *event = event_create(list->list.event);
-               if (mailbox_list_create(list_set.layout, event, list->list.ns,
-                                       &list_set, list->list.mail_set,
-                                       MAILBOX_LIST_FLAG_SECONDARY,
-                                       &list->index_list, &error) < 0) {
+               event_set_ptr(event, SETTINGS_EVENT_INSTANCE,
+                             list->index_list_set_instance);
+               event_set_ptr(event, SETTINGS_EVENT_FILTER_NAME,
+                             MAILBOX_LIST_NAME_MAILDIRPLUSPLUS);
+               if (settings_get(event, &mail_storage_setting_parser_info, 0,
+                                &mail_set, &error) < 0) {
+                       e_error(list->list.event, "%s", error);
+                       list->index_list_failed = TRUE;
+               } else if (mailbox_list_create(event, list->list.ns,
+                                              &list_set, mail_set,
+                                              MAILBOX_LIST_FLAG_SECONDARY,
+                                              &list->index_list, &error) < 0) {
                        e_error(list->list.event,
                                "imapc: Couldn't create %s mailbox list: %s",
-                               list_set.layout, error);
+                               MAILBOX_LIST_NAME_MAILDIRPLUSPLUS, error);
                        list->index_list_failed = TRUE;
                }
+               settings_free(mail_set);
                event_unref(&event);
        }
        return list->index_list;
@@ -973,7 +996,7 @@ int imapc_list_get_mailbox_flags(struct mailbox_list *_list, const char *name,
        }
 
        if (list->mailboxes == NULL) {
-               /* imapc list isn't used, but e.g. LAYOUT=none */
+               /* imapc list isn't used, but e.g. mailbox_list_layout=none */
                *flags_r = 0;
                return 0;
        }
index b268fcb72bf5df9ce3e956d557fc73c2e5b21bb2..bec4bae555c89f3055995af4728270fd3f16ea2f 100644 (file)
@@ -12,6 +12,7 @@ struct imapc_mailbox_list {
        const struct imapc_settings *set; /* points to client->set */
        struct imapc_storage_client *client;
        struct mailbox_list *index_list;
+       struct settings_instance *index_list_set_instance;
 
        /* mailboxes are stored as vnames */
        struct mailbox_tree_context *mailboxes, *tmp_subscriptions;
index f24573c245e0dd4fbfc4037c598e9c69001484a9..b6288f48ec2b584933d45fd6e98614af17ced541 100644 (file)
@@ -62,11 +62,17 @@ static const struct imapc_settings imapc_default_settings = {
        .pop3_deleted_flag = ""
 };
 
+static const struct setting_keyvalue imapc_default_filter_settings_keyvalue[] = {
+       { "imapc/mailbox_list_layout", "imapc" },
+       { NULL, NULL }
+};
+
 const struct setting_parser_info imapc_setting_parser_info = {
        .name = "imapc",
 
        .defines = imapc_setting_defines,
        .defaults = &imapc_default_settings,
+       .default_filter_settings = imapc_default_filter_settings_keyvalue,
 
        .struct_size = sizeof(struct imapc_settings),
        .pool_offset1 = 1 + offsetof(struct imapc_settings, pool),
index 77915a4d90a1befddf125215ee42a2a17a8f8270..c8204b4db9813862e41ac700b1e7469b23447fb0 100644 (file)
@@ -518,8 +518,6 @@ imapc_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
                                struct mailbox_list_settings *set,
                                const struct mail_storage_settings *mail_set ATTR_UNUSED)
 {
-       if (set->layout == NULL)
-               set->layout = MAILBOX_LIST_NAME_IMAPC;
        set->storage_name_escape_char = IMAPC_LIST_STORAGE_NAME_ESCAPE_CHAR;
        /* We want to have all imapc mailboxes accessible, so escape them if
           necessary. */
index 1074aa63317051303f254d4bc89dcc4bcf98a5c7..80a0dd206e5ed286a2d0c0846078aa77983774c9 100644 (file)
@@ -26,11 +26,17 @@ static const struct maildir_settings maildir_default_settings = {
        .maildir_empty_new = FALSE
 };
 
+static const struct setting_keyvalue maildir_default_filter_settings_keyvalue[] = {
+       { "maildir/mailbox_list_layout", "maildir++" },
+       { NULL, NULL }
+};
+
 const struct setting_parser_info maildir_setting_parser_info = {
        .name = "maildir",
 
        .defines = maildir_setting_defines,
        .defaults = &maildir_default_settings,
+       .default_filter_settings = maildir_default_filter_settings_keyvalue,
 
        .struct_size = sizeof(struct maildir_settings),
        .pool_offset1 = 1 + offsetof(struct maildir_settings, pool),
index d3e259fde5290d6ee08c9335ba66cb70635edb37..6ae3bcabdd7494097c2667543bbd7a4eafd32554 100644 (file)
@@ -89,14 +89,11 @@ static void maildir_storage_destroy(struct mail_storage *_storage)
 static void
 maildir_storage_get_list_settings(const struct mail_namespace *ns,
                                  struct mailbox_list_settings *set,
-                                 const struct mail_storage_settings *mail_set ATTR_UNUSED)
+                                 const struct mail_storage_settings *mail_set)
 {
-       if (set->layout == NULL)
-               set->layout = MAILBOX_LIST_NAME_MAILDIRPLUSPLUS;
-
        if (set->inbox_path == NULL && *set->maildir_name == '\0' &&
-           (strcmp(set->layout, MAILBOX_LIST_NAME_MAILDIRPLUSPLUS) == 0 ||
-            strcmp(set->layout, MAILBOX_LIST_NAME_FS) == 0) &&
+           (strcmp(mail_set->mailbox_list_layout, MAILBOX_LIST_NAME_MAILDIRPLUSPLUS) == 0 ||
+            strcmp(mail_set->mailbox_list_layout, MAILBOX_LIST_NAME_FS) == 0) &&
            (ns->flags & NAMESPACE_FLAG_INBOX_ANY) != 0) {
                /* Maildir++ INBOX is the Maildir base itself */
                set->inbox_path = set->root_dir;
@@ -571,7 +568,7 @@ maildir_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
 {
        const char *root_dir, *shared_path;
        /* allow physical location to exist when we rebuild list index, this
-          happens with LAYOUT=INDEX only. */
+          happens with mailbox_list_layout=index only. */
        bool verify = box->storage->rebuilding_list_index;
        struct stat st;
        int ret;
index 1fd1667bad996828eebb7600f82e37a386cb8557..4a2250defa02422a139d758f90cf03e8ac4650ac 100644 (file)
@@ -213,14 +213,12 @@ static void mbox_storage_destroy(struct mail_storage *_storage)
 static void
 mbox_storage_get_list_settings(const struct mail_namespace *ns,
                               struct mailbox_list_settings *set,
-                              const struct mail_storage_settings *mail_set ATTR_UNUSED)
+                              const struct mail_storage_settings *mail_set)
 {
        struct event *event = ns->user->event;
-       if (set->layout == NULL)
-               set->layout = MAILBOX_LIST_NAME_FS;
 
        if (set->inbox_path == NULL &&
-           strcasecmp(set->layout, MAILBOX_LIST_NAME_FS) == 0) {
+           strcasecmp(mail_set->mailbox_list_layout, MAILBOX_LIST_NAME_FS) == 0) {
                set->inbox_path = t_strconcat(set->root_dir, "/inbox", NULL);
                e_debug(event, "mbox: INBOX defaulted to %s", set->inbox_path);
        }
index 8331ecc1c066934e4ddbecd16bc638e1e2e09f2a..bb9d5b34c31e01f549ee77b03d797dd3e7582f18 100644 (file)
@@ -110,7 +110,6 @@ pop3c_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
                                struct mailbox_list_settings *set,
                                const struct mail_storage_settings *mail_set ATTR_UNUSED)
 {
-       set->layout = MAILBOX_LIST_NAME_FS;
        if (set->root_dir != NULL && *set->root_dir != '\0' &&
            set->index_dir == NULL) {
               /* we don't really care about root_dir, but we
index 9f29f0716913ef239a2331cb1143a0556b3b0d16..bd0bda06370cd73e02484cb52ff4437082fb87f1 100644 (file)
@@ -36,7 +36,8 @@ raw_storage_create_from_set(struct mail_storage_service_ctx *ctx,
        const struct master_service_settings *service_set =
                master_service_get_service_settings(master_service);
        const char *const code_override_fields[] = {
-               "mail_location=raw::LAYOUT=none",
+               "mail_location=raw:",
+               "mailbox_list_layout=none",
                /* use unwritable home directory */
                t_strdup_printf("mail_home=%s/empty", service_set->base_dir),
                /* absolute paths are ok with raw storage */
@@ -143,15 +144,6 @@ static struct mail_storage *raw_storage_alloc(void)
        return &storage->storage;
 }
 
-static void
-raw_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
-                             struct mailbox_list_settings *set,
-                             const struct mail_storage_settings *mail_set ATTR_UNUSED)
-{
-       if (set->layout == NULL)
-               set->layout = MAILBOX_LIST_NAME_FS;
-}
-
 static struct mailbox *
 raw_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
                  const char *vname, enum mailbox_flags flags)
@@ -241,7 +233,7 @@ struct mail_storage raw_storage = {
                NULL,
                index_storage_destroy,
                NULL,
-               raw_storage_get_list_settings,
+               NULL,
                NULL,
                raw_mailbox_alloc,
                NULL,
index c467c5d375a0b548a687fb8b381dc63a3e0b8389..0866f31c78f4d51aad3e5db4a73eb1137568b903 100644 (file)
@@ -100,14 +100,6 @@ shared_storage_create(struct mail_storage *_storage, struct mail_namespace *ns,
        return 0;
 }
 
-static void
-shared_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
-                                struct mailbox_list_settings *set,
-                                const struct mail_storage_settings *mail_set ATTR_UNUSED)
-{
-       set->layout = "shared";
-}
-
 static const char *
 get_nonexistent_user_location(struct shared_storage *storage,
                              const char *username)
@@ -482,7 +474,7 @@ struct mail_storage shared_storage = {
                shared_storage_create,
                index_storage_destroy,
                NULL,
-               shared_storage_get_list_settings,
+               NULL,
                NULL,
                fail_mailbox_alloc,
                NULL,
index 928c04d5371d8fdd85b1001edb5de22f2cc0aa97..dec4089ea1c6ae0ab4509075fabff703eeeee33a 100644 (file)
@@ -205,8 +205,8 @@ mail_storage_list_remove_duplicate(struct mail_storage_list_index_rebuild_ctx *c
        const char *delete_name, *keep_name;
 
        if (strcmp(box->list->name, MAILBOX_LIST_NAME_INDEX) != 0) {
-               /* we're not using LAYOUT=index. not really supported now,
-                  but just ignore that in here. */
+               /* we're not using mailbox_list_layout=index. not really
+                  supported now, but just ignore that in here. */
                return 0;
        }
        /* we'll need to delete one of these entries. if one of them begins with
index cfc906d56495070f6fd5716f868549d15634fd77..692d86845faf4ef91ed5625b924ebe7fec33d824 100644 (file)
@@ -49,7 +49,7 @@ static struct mailbox_list *index_list_alloc(void)
 static int index_list_init(struct mailbox_list *_list, const char **error_r)
 {
        if (!_list->mail_set->mailbox_list_index) {
-               *error_r = "LAYOUT=index requires mailbox_list_index=yes";
+               *error_r = "mailbox_list_layout=index requires mailbox_list_index=yes";
                return -1;
        }
        return 0;
index c47732d166405c844bd618d3d2dbbf9ec4617239..066b1136a758385f381cced2fcd54d04c13309f7 100644 (file)
@@ -223,9 +223,11 @@ mailbox_list_index_iter_next(struct mailbox_list_iterate_context *_ctx)
                follow_children = (match & (IMAP_MATCH_YES |
                                            IMAP_MATCH_CHILDREN)) != 0;
                if (match == IMAP_MATCH_YES && iter_subscriptions_ok(ctx)) {
-                       /* If this is a) \NoSelect leaf, b) not LAYOUT=index
+                       /* If this is a) \NoSelect leaf,
+                          b) not mailbox_list_layout=index
                           and c) NO-NOSELECT is set, try to rmdir the leaf
-                          directories from filesystem. (With LAYOUT=index the
+                          directories from filesystem. (With
+                          mailbox_list_layout=index the
                           \NoSelect mailboxes aren't on the filesystem.) */
                        if (ilist->has_backing_store &&
                            mailbox_list_iter_try_delete_noselect(_ctx, &ctx->info,
index cdc9e27ea6b388485af48d6319c4f0055806c69b..47d46313285d1d2a4db77ae7344232e75e1401be 100644 (file)
@@ -71,8 +71,8 @@ int mailbox_list_index_index_open(struct mailbox_list *list)
 
        index_flags = mail_storage_settings_to_index_flags(set);
        if (strcmp(list->name, MAILBOX_LIST_NAME_INDEX) == 0) {
-               /* LAYOUT=index. this is the only location for the mailbox
-                  data, so we must never move it into memory. */
+               /* mailbox_list_layout=index. This is the only location for
+                  the mailbox data, so we must never move it into memory. */
                index_flags |= MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY;
        }
        lock_timeout = set->mail_max_lock_timeout == 0 ? UINT_MAX :
@@ -103,7 +103,7 @@ int mailbox_list_index_index_open(struct mailbox_list *list)
                if (mail_index_move_to_memory(ilist->index) < 0) {
                        /* try opening once more. it should be created
                           directly into memory now, except if it fails with
-                          LAYOUT=index backend. */
+                          mailbox_list_layout=index backend. */
                        if (mail_index_open_or_create(ilist->index,
                                                      index_flags) < 0) {
                                mailbox_list_set_internal_error(list);
index 7bcb38d079f43020c44a3147fd9b3a1bb30725e6..74e4463453ee7a7f795f3b853941b9b826de5e9f 100644 (file)
@@ -387,7 +387,9 @@ int mail_namespaces_init_finish(struct mail_namespace *namespaces,
                                user->service_user);
                set_instance = settings_instance_dup(set_instance);
                settings_override(set_instance,
-                                 "mail_location", "fail::LAYOUT=none",
+                                 "mail_location", "fail:",
+                                 SETTINGS_OVERRIDE_TYPE_CODE);
+               settings_override(set_instance, "*/mailbox_list_layout", "none",
                                  SETTINGS_OVERRIDE_TYPE_CODE);
 
                struct event *set_event = event_create(user->event);
index 3992b0605f4a60a7fa2693667e91f537657a391d..26baaddb632c08f7ce2343d676fd2841905b0d0d 100644 (file)
@@ -509,8 +509,9 @@ struct mailbox {
        bool update_first_saved:1;
        /* mailbox_verify_create_name() only checks for mailbox_verify_name() */
        bool skip_create_name_restrictions:1;
-       /* Using LAYOUT=index and mailbox is being opened with a corrupted
-          mailbox name. Try to revert to the previously known good name. */
+       /* Using mailbox_list_layout=index and mailbox is being opened with a
+          corrupted mailbox name. Try to revert to the previously known good
+          name. */
        bool corrupted_mailbox_name:1;
        /* mailbox_open() returned MAIL_ERROR_NOTFOUND because the mailbox
           doesn't have the LOOKUP ACL right. */
index dc95e03a21629466df6a2baa6a9c9c3c4a16ac0b..5fbb9281720177bd32f377a2bfa370c95fe0e72d 100644 (file)
@@ -76,6 +76,7 @@ static const struct setting_define mail_storage_setting_defines[] = {
        DEF(BOOL, mailbox_list_index),
        DEF(BOOL, mailbox_list_index_very_dirty_syncs),
        DEF(BOOL, mailbox_list_index_include_inbox),
+       DEF(STR, mailbox_list_layout),
        DEF(STR, mailbox_list_index_prefix),
        DEF(BOOL_HIDDEN, mailbox_list_iter_from_index_dir),
        DEF(BOOL_HIDDEN, mailbox_list_drop_noselect),
@@ -143,6 +144,7 @@ const struct mail_storage_settings mail_storage_default_settings = {
        .mailbox_list_index = TRUE,
        .mailbox_list_index_very_dirty_syncs = FALSE,
        .mailbox_list_index_include_inbox = FALSE,
+       .mailbox_list_layout = "fs",
        .mailbox_list_index_prefix = "dovecot.list.index",
        .mailbox_list_iter_from_index_dir = FALSE,
        .mailbox_list_drop_noselect = TRUE,
@@ -985,6 +987,7 @@ bool mail_user_set_get_postmaster_smtp(const struct mail_user_settings *set,
 #define OFFSET(name) offsetof(struct mail_storage_settings, name)
 static const size_t mail_storage_2nd_reset_offsets[] = {
        OFFSET(mail_location),
+       OFFSET(mailbox_list_layout),
        OFFSET(mailbox_list_index_prefix),
        OFFSET(mailbox_list_iter_from_index_dir),
        OFFSET(mailbox_root_directory_name),
index 752ebdce091c1fa576bfa634ead72d17cc805168..81fcf8464a127eb9e49ee0a5e9510daaf0ae7b8c 100644 (file)
@@ -56,6 +56,7 @@ struct mail_storage_settings {
        bool mailbox_list_index;
        bool mailbox_list_index_very_dirty_syncs;
        bool mailbox_list_index_include_inbox;
+       const char *mailbox_list_layout;
        const char *mailbox_list_index_prefix;
        bool mailbox_list_iter_from_index_dir;
        bool mailbox_list_drop_noselect;
index 0ec06571ecb90c56b74589f5aa8b419ac9d3a496..1af781a46cabc94599cf83ab3561802384c48da9 100644 (file)
@@ -201,8 +201,8 @@ mail_storage_get_class(struct mail_namespace *ns, const char *driver,
                /* no root directory given. is this allowed? */
                const struct mailbox_list *list;
 
-               list = list_set->layout == NULL ? NULL :
-                       mailbox_list_find_class(list_set->layout);
+               list = mail_set->mailbox_list_layout[0] == '\0' ? NULL :
+                       mailbox_list_find_class(mail_set->mailbox_list_layout);
                if (storage_class == NULL &&
                    (flags & MAIL_STORAGE_FLAG_NO_AUTODETECTION) == 0) {
                        /* autodetection should take care of this */
@@ -346,10 +346,25 @@ mail_storage_find(struct mail_user *user,
        return NULL;
 }
 
+static void
+mail_storage_create_ns_instance(struct mail_namespace *ns,
+                               struct event *set_event)
+{
+       if (ns->_set_instance != NULL)
+               return;
+
+       struct settings_instance *set_instance =
+               mail_storage_service_user_get_settings_instance(
+                       ns->user->service_user);
+       ns->_set_instance = settings_instance_dup(set_instance);
+       event_set_ptr(set_event, SETTINGS_EVENT_INSTANCE, ns->_set_instance);
+}
+
 static int
 mail_storage_create_list(struct mail_namespace *ns,
                         struct mail_storage *storage_class,
                         struct event *set_event,
+                        enum mail_storage_flags flags,
                         struct mailbox_list_settings *list_set,
                         const char **error_r)
 {
@@ -369,6 +384,13 @@ mail_storage_create_list(struct mail_namespace *ns,
                      (void *)storage_class->name);
        event_add_str(set_event, "namespace", ns->set->name);
 
+       if ((flags & MAIL_STORAGE_FLAG_SHARED_DYNAMIC) != 0) {
+               mail_storage_create_ns_instance(ns, set_event);
+               settings_override(ns->_set_instance,
+                                 "*/mailbox_list_layout", "shared",
+                                 SETTINGS_OVERRIDE_TYPE_CODE);
+       }
+
        const struct mail_storage_settings *mail_set;
        if (settings_get(set_event, &mail_storage_setting_parser_info, 0,
                         &mail_set, error_r) < 0) {
@@ -378,11 +400,13 @@ mail_storage_create_list(struct mail_namespace *ns,
 
        struct event *event = event_create(ns->user->event);
        event_add_str(event, "namespace", ns->set->name);
-       int ret = mailbox_list_create(list_set->layout, event, ns, list_set,
+       if (storage_class->v.get_list_settings != NULL)
+               storage_class->v.get_list_settings(ns, list_set, mail_set);
+       int ret = mailbox_list_create(event, ns, list_set,
                                      mail_set, list_flags, &list, error_r);
        if (ret < 0) {
-               *error_r = t_strdup_printf("Mailbox list driver %s: %s",
-                                          list_set->layout, *error_r);
+               *error_r = t_strdup_printf("mailbox_list_layout %s: %s",
+                       mail_set->mailbox_list_layout, *error_r);
        }
        settings_free(mail_set);
        event_unref(&event);
@@ -400,6 +424,9 @@ mail_storage_create_real(struct mail_namespace *ns, struct event *set_event,
        struct mailbox_list_settings list_set;
        const char *p, *data, *driver = NULL;
 
+       /* Lookup initial mailbox list settings. Once they're found, another
+          settings lookup is done with mailbox format as an additional
+          filter. */
        if (settings_get(set_event, &mail_storage_setting_parser_info, 0,
                         &mail_set, error_r) < 0)
                return -1;
@@ -425,13 +452,10 @@ mail_storage_create_real(struct mail_namespace *ns, struct event *set_event,
        if (storage_class == NULL)
                return -1;
 
-       storage_class->v.get_list_settings(ns, &list_set, NULL);
-       i_assert(list_set.layout != NULL);
-
        if (ns->list == NULL) {
                /* first storage for namespace */
-               if (mail_storage_create_list(ns, storage_class, set_event, &list_set,
-                                            error_r) < 0)
+               if (mail_storage_create_list(ns, storage_class, set_event,
+                                            flags, &list_set, error_r) < 0)
                        return -1;
                if ((storage_class->class_flags & MAIL_STORAGE_CLASS_FLAG_NO_ROOT) == 0) {
                        if (mail_storage_create_root(ns->list, flags, error_r) < 0)
@@ -1416,9 +1440,10 @@ static int mailbox_verify_name_int(struct mailbox *box)
        /* If namespace { separator } differs from the mailbox_list separator,
           the list separator can't actually be used in the mailbox name
           unless it's escaped with storage_name_escape_char. For example if
-          namespace separator is '/' and LAYOUT=Maildir++ has '.' as the
-          separator, there's no way to use '.' in the mailbox name (without
-          escaping) because it would end up becoming a hierarchy separator. */
+          namespace separator is '/' and mailbox_list_layout=Maildir++ has '.'
+          as the separator, there's no way to use '.' in the mailbox name
+          (without escaping) because it would end up becoming a hierarchy
+          separator. */
        if (ns_sep != list_sep &&
            box->list->set.storage_name_escape_char == '\0' &&
            strchr(vname, list_sep) != NULL) {
@@ -1914,7 +1939,8 @@ int mailbox_create(struct mailbox *box, const struct mailbox_update *update,
        struct event_reason *reason = event_reason_begin("mailbox:create");
 
        /* Avoid race conditions by keeping mailbox list locked during changes.
-          This especially fixes a race during INBOX creation with LAYOUT=index
+          This especially fixes a race during INBOX creation with
+          mailbox_list_layout=index
           because it scans for missing mailboxes if INBOX doesn't exist. The
           second process's scan can find a half-created INBOX and add it,
           causing the first process to become confused. */
@@ -2073,7 +2099,7 @@ static int mailbox_delete_real(struct mailbox *box)
        mailbox_close(box);
 
        /* if mailbox is reopened, its path may be different with
-          LAYOUT=index */
+          mailbox_list_layout=index */
        mailbox_close_reset_path(box);
        event_reason_end(&reason);
        return ret;
index 72c0f737e071bba55e0ae3592c2b980756722b66..052bc8d11489c7d57a65a9e7364fd29dcdac5210 100644 (file)
@@ -103,8 +103,7 @@ mailbox_list_find_class(const char *driver)
        return array_idx_elem(&mailbox_list_drivers, idx);
 }
 
-int mailbox_list_create(const char *driver, struct event *event,
-                       struct mail_namespace *ns,
+int mailbox_list_create(struct event *event, struct mail_namespace *ns,
                        const struct mailbox_list_settings *set,
                        const struct mail_storage_settings *mail_set,
                        enum mailbox_list_flags flags,
@@ -116,7 +115,7 @@ int mailbox_list_create(const char *driver, struct event *event,
        i_assert(ns->list == NULL ||
                 (flags & MAILBOX_LIST_FLAG_SECONDARY) != 0);
 
-       if ((class = mailbox_list_find_class(driver)) == NULL) {
+       if ((class = mailbox_list_find_class(mail_set->mailbox_list_layout)) == NULL) {
                *error_r = "Unknown driver name";
                return -1;
        }
@@ -315,9 +314,7 @@ mailbox_list_settings_parse_full(struct mail_user *user, const char *data,
                else if (strcmp(key, "ALTNOCHECK") == 0) {
                        set_r->alt_dir_nocheck = TRUE;
                        continue;
-               } else if (strcmp(key, "LAYOUT") == 0)
-                       dest = &set_r->layout;
-               else if (strcmp(key, "DIRNAME") == 0)
+               } else if (strcmp(key, "DIRNAME") == 0)
                        dest = &set_r->maildir_name;
                else if (strcmp(key, "FULLDIRNAME") == 0) {
                        set_r->index_control_use_maildir_name = TRUE;
index fecf633f28670e0a4cc25a3bc904a9f93e8666aa..ceda61f6729ca909a314efbaeed487e33deae2a2 100644 (file)
@@ -44,7 +44,8 @@ enum mailbox_list_flags {
        MAILBOX_LIST_FLAG_SECONDARY             = 0x02,
        /* There are no mail files, only index and/or control files. */
        MAILBOX_LIST_FLAG_NO_MAIL_FILES         = 0x04,
-       /* LAYOUT=index: Don't delete any files in delete_mailbox(). */
+       /* mailbox_list_layout=index: Don't delete any files in
+          delete_mailbox(). */
        MAILBOX_LIST_FLAG_NO_DELETES            = 0x08
 };
 
@@ -113,7 +114,6 @@ enum mailbox_list_get_storage_flags {
 };
 
 struct mailbox_list_settings {
-       const char *layout; /* FIXME: shouldn't be here */
        const char *root_dir;
        const char *index_dir;
        const char *index_pvt_dir;
@@ -190,9 +190,7 @@ void mailbox_list_unregister(const struct mailbox_list *list);
 const struct mailbox_list *
 mailbox_list_find_class(const char *driver);
 
-/* Returns 0 if ok, -1 if driver was unknown. */
-int mailbox_list_create(const char *driver, struct event *event,
-                       struct mail_namespace *ns,
+int mailbox_list_create(struct event *event, struct mail_namespace *ns,
                        const struct mailbox_list_settings *set,
                        const struct mail_storage_settings *mail_set,
                        enum mailbox_list_flags flags,
index e0b57f0459cd762d830545a5b20a746b7003b526..8fc132fc4f8208e48da8e7284729d91abf11759e 100644 (file)
@@ -70,8 +70,7 @@ void test_mail_storage_init_user(struct test_mail_storage_ctx *ctx,
        home = t_strdup_printf("%s%s", ctx->home_root, username);
 
        const char *const default_input[] = {
-               t_strdup_printf("mail=%s:~/%s", set->driver,
-                               set->driver_opts == NULL ? "" : set->driver_opts),
+               t_strdup_printf("mail=%s:~/", set->driver),
                "postmaster_address=postmaster@localhost",
                "namespace=inbox",
                "namespace/inbox/prefix=",
index 109fa688f9c4233e05004b0f15b49165f58effcc..a144eb59781d9edbf0e7e86ae5981655a8c445d6 100644 (file)
@@ -14,7 +14,6 @@ struct test_mail_storage_ctx {
 struct test_mail_storage_settings {
        const char *username;
        const char *driver;
-       const char *driver_opts;
        const char *hierarchy_sep;
        const char *const *extra_input;
 };
index 3e728678a69fce8f3c9ef622c9d27b2a820064de..d6eb53e003c00022d41bcfaaabbdb9886d3ed655 100644 (file)
@@ -402,25 +402,29 @@ test_mailbox_verify_name_continue(struct mailbox_verify_test_cases *test_cases,
        }
 }
 
-static void test_mailbox_verify_name_driver_slash(const char *driver,
-                                                 const char *driver_opts,
-                                                 struct test_mail_storage_ctx *ctx)
+static void
+test_mailbox_verify_name_driver_slash(const char *driver,
+                                     const char *mailbox_list_layout,
+                                     struct test_mail_storage_ctx *ctx)
 {
+       const char *layout_option =
+               mailbox_list_layout[0] == '\0' ? NULL :
+               t_strdup_printf("mailbox_list_layout=%s", mailbox_list_layout);
        const char *const ns2[] = {
                "namespace=subspace",
                "namespace/subspace/separator=/",
                "namespace/subspace/prefix=SubSpace/",
+               layout_option,
                NULL
        };
        struct test_mail_storage_settings set = {
                .driver = driver,
-               .driver_opts = driver_opts,
                .hierarchy_sep = "/",
                .extra_input = ns2,
        };
        test_mail_storage_init_user(ctx, &set);
 
-       if (strcmp(driver_opts, ":LAYOUT=INDEX") == 0)
+       if (strcmp(mailbox_list_layout, "index") == 0)
                test_mailbox_verify_name_continue(layout_index_test_cases, N_ELEMENTS(layout_index_test_cases), ctx);
        else
                test_mailbox_verify_name_continue(test_cases, N_ELEMENTS(test_cases), ctx);
@@ -428,25 +432,29 @@ static void test_mailbox_verify_name_driver_slash(const char *driver,
        test_mail_storage_deinit_user(ctx);
 }
 
-static void test_mailbox_verify_name_driver_dot(const char *driver,
-                                               const char *driver_opts,
-                                               struct test_mail_storage_ctx *ctx)
+static void
+test_mailbox_verify_name_driver_dot(const char *driver,
+                                   const char *mailbox_list_layout,
+                                   struct test_mail_storage_ctx *ctx)
 {
+       const char *layout_option =
+               mailbox_list_layout[0] == '\0' ? NULL :
+               t_strdup_printf("mailbox_list_layout=%s", mailbox_list_layout);
        const char *const ns2[] = {
                "namespace=subspace",
                "namespace/subspace/separator=.",
                "namespace/subspace/prefix=SubSpace.",
+               layout_option,
                NULL
        };
        struct test_mail_storage_settings set = {
                .driver = driver,
-               .driver_opts = driver_opts,
                .hierarchy_sep = ".",
                .extra_input = ns2,
        };
        test_mail_storage_init_user(ctx, &set);
 
-       if (strcmp(driver_opts, ":LAYOUT=INDEX") == 0)
+       if (strcmp(mailbox_list_layout, "index") == 0)
                test_mailbox_verify_name_continue(layout_index_test_cases, N_ELEMENTS(layout_index_test_cases), ctx);
        else
                test_mailbox_verify_name_continue(test_cases, N_ELEMENTS(test_cases), ctx);
@@ -459,27 +467,29 @@ static void test_mailbox_verify_name(void)
        struct {
                const char *name;
                const char *driver;
-               const char *opts;
+               const char *mailbox_list_layout;
        } test_cases[] = {
                { "mbox", "mbox", "" },
-               { "mbox LAYOUT=FS", "mbox", ":LAYOUT=FS" },
-               { "mbox LAYOUT=INDEX", "mbox", ":LAYOUT=INDEX" },
-               { "maildir LAYOUT=INDEX", "maildir", ":LAYOUT=INDEX" },
+               { "mbox mailbox_list_layout=fs", "mbox", "fs" },
+               { "mbox mailbox_list_layout=index", "mbox", "index" },
+               { "maildir mailbox_list_layout=index", "maildir", "index" },
                { "sdbox", "sdbox", "" },
-               { "sdbox LAYOUT=FS", "sdbox", ":LAYOUT=FS" },
-               { "sdbox LAYOUT=INDEX", "sdbox", ":LAYOUT=INDEX" },
+               { "sdbox mailbox_list_layout=fs", "sdbox", "fs" },
+               { "sdbox mailbox_list_layout=index", "sdbox", "index" },
                { "mdbox", "mdbox", "" },
-               { "mdbox LAYOUT=FS", "mdbox", ":LAYOUT=FS" },
-               { "mdbox LAYOUT=INDEX", "mdbox", ":LAYOUT=INDEX" },
+               { "mdbox mailbox_list_layout=fs", "mdbox", "fs" },
+               { "mdbox mailbox_list_layout=index", "mdbox", "index" },
        };
        struct test_mail_storage_ctx *ctx = test_mail_storage_init();
 
        for(unsigned int i = 0; i < N_ELEMENTS(test_cases); i++) T_BEGIN {
                test_begin(t_strdup_printf("mailbox_verify_name (%s SEP=.)", test_cases[i].name));
-               test_mailbox_verify_name_driver_dot(test_cases[i].driver, test_cases[i].opts, ctx);
+               test_mailbox_verify_name_driver_dot(test_cases[i].driver,
+                       test_cases[i].mailbox_list_layout, ctx);
                test_end();
                test_begin(t_strdup_printf("mailbox_verify_name (%s SEP=/)", test_cases[i].name));
-               test_mailbox_verify_name_driver_slash(test_cases[i].driver, test_cases[i].opts, ctx);
+               test_mailbox_verify_name_driver_slash(test_cases[i].driver,
+                       test_cases[i].mailbox_list_layout, ctx);
                test_end();
        } T_END;
 
@@ -537,19 +547,23 @@ static void test_mailbox_list_maildir_continue(struct test_mail_storage_ctx *ctx
 }
 
 static void test_mailbox_list_maildir_init(struct test_mail_storage_ctx *ctx,
-                                          const char *driver_opts, const char *sep)
+                                          const char *mailbox_list_layout,
+                                          const char *sep)
 {
        const char *error ATTR_UNUSED;
+       const char *layout_option =
+               mailbox_list_layout[0] == '\0' ? NULL :
+               t_strdup_printf("mailbox_list_layout=%s", mailbox_list_layout);
        const char *const ns2[] = {
                "namespace=subspace",
                t_strdup_printf("namespace/subspace/separator=%s", sep),
                t_strdup_printf("namespace/subspace/prefix=SubSpace%s", sep),
+               layout_option,
                NULL
        };
 
        struct test_mail_storage_settings set = {
                .driver = "maildir",
-               .driver_opts = driver_opts,
                .hierarchy_sep = sep,
                .extra_input = ns2,
        };
@@ -590,20 +604,20 @@ static void test_mailbox_list_maildir(void)
 {
        struct test_mail_storage_ctx *ctx = test_mail_storage_init();
 
-       test_begin("mailbox_verify_name (maildir SEP=.)");
+       test_begin("mailbox_verify_name (maildir separator=.)");
        test_mailbox_list_maildir_init(ctx, "", ".");
        test_end();
 
-       test_begin("mailbox_verify_name (maildir SEP=/)");
+       test_begin("mailbox_verify_name (maildir separator=/)");
        test_mailbox_list_maildir_init(ctx, "", "/");
        test_end();
 
-       test_begin("mailbox_verify_name (maildir SEP=. LAYOUT=FS)");
-       test_mailbox_list_maildir_init(ctx, "LAYOUT=FS", ".");
+       test_begin("mailbox_verify_name (maildir separator=. mailbox_list_layout=fs)");
+       test_mailbox_list_maildir_init(ctx, "fs", ".");
        test_end();
 
-       test_begin("mailbox_verify_name (maildir SEP=/ LAYOUT=FS)");
-       test_mailbox_list_maildir_init(ctx, "LAYOUT=FS", "/");
+       test_begin("mailbox_verify_name (maildir separator=/ mailbox_list_layout=fs)");
+       test_mailbox_list_maildir_init(ctx, "fs", "/");
        test_end();
 
        test_mail_storage_deinit(&ctx);
index 5977214ebe87a8892374a6edda5e53971a459818..ffe0159a5b046fde48c1416d7016332811bf807a 100644 (file)
@@ -154,8 +154,8 @@ acl_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
        abox->skip_acl_checks = TRUE;
        ret = abox->module_ctx.super.create_box(box, update, directory);
        abox->skip_acl_checks = FALSE;
-       /* update local acl object, otherwise with LAYOUT=INDEX, we end up
-          without local path to acl file, and copying fails. */
+       /* update local acl object, otherwise with mailbox_list_layout=index,
+          we end up without local path to acl file, and copying fails. */
        struct acl_backend *acl_be = abox->aclobj->backend;
        acl_object_deinit(&abox->aclobj);
        abox->aclobj = acl_object_init_from_name(acl_be, box->name);
index 8a0c7854d14f4ba7b036ec2b784e22de4902ee53..8b7c44038ae04b4ded15423f556a673ff6f18c4c 100644 (file)
@@ -104,15 +104,6 @@ virtual_storage_create(struct mail_storage *_storage,
        return 0;
 }
 
-static void
-virtual_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
-                                 struct mailbox_list_settings *set,
-                                 const struct mail_storage_settings *mail_set ATTR_UNUSED)
-{
-       if (set->layout == NULL)
-               set->layout = MAILBOX_LIST_NAME_FS;
-}
-
 struct virtual_backend_box *
 virtual_backend_box_lookup_name(struct virtual_mailbox *mbox, const char *name)
 {
@@ -931,7 +922,7 @@ struct mail_storage virtual_storage = {
                virtual_storage_create,
                index_storage_destroy,
                NULL,
-               virtual_storage_get_list_settings,
+               NULL,
                NULL,
                virtual_mailbox_alloc,
                NULL,