From: Timo Sirainen Date: Fri, 27 Oct 2023 12:38:57 +0000 (+0300) Subject: lib-storage: Replace LAYOUT with mailbox_list_layout setting X-Git-Tag: 2.4.1~1239 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f13a5b87f0f8db827c7c7d416bd77700fef0ce08;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Replace LAYOUT with mailbox_list_layout setting --- diff --git a/src/lib-storage/fail-mail-storage.c b/src/lib-storage/fail-mail-storage.c index e143ef3a47..0bc034460f 100644 --- a/src/lib-storage/fail-mail-storage.c +++ b/src/lib-storage/fail-mail-storage.c @@ -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, diff --git a/src/lib-storage/index/dbox-common/dbox-storage.c b/src/lib-storage/index/dbox-common/dbox-storage.c index 230bbf1448..875d916023 100644 --- a/src/lib-storage/index/dbox-common/dbox-storage.c +++ b/src/lib-storage/index/dbox-common/dbox-storage.c @@ -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; } diff --git a/src/lib-storage/index/imapc/imapc-list.c b/src/lib-storage/index/imapc/imapc-list.c index 9876c268d6..6f3d1a1955 100644 --- a/src/lib-storage/index/imapc/imapc-list.c +++ b/src/lib-storage/index/imapc/imapc-list.c @@ -31,10 +31,12 @@ #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; } diff --git a/src/lib-storage/index/imapc/imapc-list.h b/src/lib-storage/index/imapc/imapc-list.h index b268fcb72b..bec4bae555 100644 --- a/src/lib-storage/index/imapc/imapc-list.h +++ b/src/lib-storage/index/imapc/imapc-list.h @@ -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; diff --git a/src/lib-storage/index/imapc/imapc-settings.c b/src/lib-storage/index/imapc/imapc-settings.c index f24573c245..b6288f48ec 100644 --- a/src/lib-storage/index/imapc/imapc-settings.c +++ b/src/lib-storage/index/imapc/imapc-settings.c @@ -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), diff --git a/src/lib-storage/index/imapc/imapc-storage.c b/src/lib-storage/index/imapc/imapc-storage.c index 77915a4d90..c8204b4db9 100644 --- a/src/lib-storage/index/imapc/imapc-storage.c +++ b/src/lib-storage/index/imapc/imapc-storage.c @@ -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. */ diff --git a/src/lib-storage/index/maildir/maildir-settings.c b/src/lib-storage/index/maildir/maildir-settings.c index 1074aa6331..80a0dd206e 100644 --- a/src/lib-storage/index/maildir/maildir-settings.c +++ b/src/lib-storage/index/maildir/maildir-settings.c @@ -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), diff --git a/src/lib-storage/index/maildir/maildir-storage.c b/src/lib-storage/index/maildir/maildir-storage.c index d3e259fde5..6ae3bcabdd 100644 --- a/src/lib-storage/index/maildir/maildir-storage.c +++ b/src/lib-storage/index/maildir/maildir-storage.c @@ -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; diff --git a/src/lib-storage/index/mbox/mbox-storage.c b/src/lib-storage/index/mbox/mbox-storage.c index 1fd1667bad..4a2250defa 100644 --- a/src/lib-storage/index/mbox/mbox-storage.c +++ b/src/lib-storage/index/mbox/mbox-storage.c @@ -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); } diff --git a/src/lib-storage/index/pop3c/pop3c-storage.c b/src/lib-storage/index/pop3c/pop3c-storage.c index 8331ecc1c0..bb9d5b34c3 100644 --- a/src/lib-storage/index/pop3c/pop3c-storage.c +++ b/src/lib-storage/index/pop3c/pop3c-storage.c @@ -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 diff --git a/src/lib-storage/index/raw/raw-storage.c b/src/lib-storage/index/raw/raw-storage.c index 9f29f07169..bd0bda0637 100644 --- a/src/lib-storage/index/raw/raw-storage.c +++ b/src/lib-storage/index/raw/raw-storage.c @@ -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, diff --git a/src/lib-storage/index/shared/shared-storage.c b/src/lib-storage/index/shared/shared-storage.c index c467c5d375..0866f31c78 100644 --- a/src/lib-storage/index/shared/shared-storage.c +++ b/src/lib-storage/index/shared/shared-storage.c @@ -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, diff --git a/src/lib-storage/list/mail-storage-list-index-rebuild.c b/src/lib-storage/list/mail-storage-list-index-rebuild.c index 928c04d537..dec4089ea1 100644 --- a/src/lib-storage/list/mail-storage-list-index-rebuild.c +++ b/src/lib-storage/list/mail-storage-list-index-rebuild.c @@ -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 diff --git a/src/lib-storage/list/mailbox-list-index-backend.c b/src/lib-storage/list/mailbox-list-index-backend.c index cfc906d564..692d86845f 100644 --- a/src/lib-storage/list/mailbox-list-index-backend.c +++ b/src/lib-storage/list/mailbox-list-index-backend.c @@ -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; diff --git a/src/lib-storage/list/mailbox-list-index-iter.c b/src/lib-storage/list/mailbox-list-index-iter.c index c47732d166..066b1136a7 100644 --- a/src/lib-storage/list/mailbox-list-index-iter.c +++ b/src/lib-storage/list/mailbox-list-index-iter.c @@ -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, diff --git a/src/lib-storage/list/mailbox-list-index.c b/src/lib-storage/list/mailbox-list-index.c index cdc9e27ea6..47d4631328 100644 --- a/src/lib-storage/list/mailbox-list-index.c +++ b/src/lib-storage/list/mailbox-list-index.c @@ -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); diff --git a/src/lib-storage/mail-namespace.c b/src/lib-storage/mail-namespace.c index 7bcb38d079..74e4463453 100644 --- a/src/lib-storage/mail-namespace.c +++ b/src/lib-storage/mail-namespace.c @@ -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); diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index 3992b0605f..26baaddb63 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -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. */ diff --git a/src/lib-storage/mail-storage-settings.c b/src/lib-storage/mail-storage-settings.c index dc95e03a21..5fbb928172 100644 --- a/src/lib-storage/mail-storage-settings.c +++ b/src/lib-storage/mail-storage-settings.c @@ -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), diff --git a/src/lib-storage/mail-storage-settings.h b/src/lib-storage/mail-storage-settings.h index 752ebdce09..81fcf8464a 100644 --- a/src/lib-storage/mail-storage-settings.h +++ b/src/lib-storage/mail-storage-settings.h @@ -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; diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index 0ec06571ec..1af781a46c 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -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; diff --git a/src/lib-storage/mailbox-list.c b/src/lib-storage/mailbox-list.c index 72c0f737e0..052bc8d114 100644 --- a/src/lib-storage/mailbox-list.c +++ b/src/lib-storage/mailbox-list.c @@ -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; diff --git a/src/lib-storage/mailbox-list.h b/src/lib-storage/mailbox-list.h index fecf633f28..ceda61f672 100644 --- a/src/lib-storage/mailbox-list.h +++ b/src/lib-storage/mailbox-list.h @@ -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, diff --git a/src/lib-storage/test-mail-storage-common.c b/src/lib-storage/test-mail-storage-common.c index e0b57f0459..8fc132fc4f 100644 --- a/src/lib-storage/test-mail-storage-common.c +++ b/src/lib-storage/test-mail-storage-common.c @@ -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=", diff --git a/src/lib-storage/test-mail-storage-common.h b/src/lib-storage/test-mail-storage-common.h index 109fa688f9..a144eb5978 100644 --- a/src/lib-storage/test-mail-storage-common.h +++ b/src/lib-storage/test-mail-storage-common.h @@ -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; }; diff --git a/src/lib-storage/test-mail-storage.c b/src/lib-storage/test-mail-storage.c index 3e728678a6..d6eb53e003 100644 --- a/src/lib-storage/test-mail-storage.c +++ b/src/lib-storage/test-mail-storage.c @@ -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); diff --git a/src/plugins/acl/acl-mailbox.c b/src/plugins/acl/acl-mailbox.c index 5977214ebe..ffe0159a5b 100644 --- a/src/plugins/acl/acl-mailbox.c +++ b/src/plugins/acl/acl-mailbox.c @@ -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); diff --git a/src/plugins/virtual/virtual-storage.c b/src/plugins/virtual/virtual-storage.c index 8a0c7854d1..8b7c44038a 100644 --- a/src/plugins/virtual/virtual-storage.c +++ b/src/plugins/virtual/virtual-storage.c @@ -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,