From: Timo Sirainen Date: Tue, 25 Jul 2017 13:10:51 +0000 (+0300) Subject: lib-storage: Add setting to disable \NoSelect mailboxes X-Git-Tag: 2.2.32.rc1~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a90bb1283bed380572aa5ad89a935547e9fe5463;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Add setting to disable \NoSelect mailboxes Enabled using mail_location = ...:NO-NOSELECT Trying to create \NoSelect "dir/" will result just creating "dir", similar to how Maildir++ layout already did it. Deleting a mailbox will delete all of its \NoSelect parents. --- diff --git a/src/lib-storage/index/index-storage.c b/src/lib-storage/index/index-storage.c index 6b0482f76d..ea81cd4330 100644 --- a/src/lib-storage/index/index-storage.c +++ b/src/lib-storage/index/index-storage.c @@ -574,6 +574,12 @@ int index_storage_mailbox_create(struct mailbox *box, bool directory) bool create_parent_dir; int ret; + if ((box->list->props & MAILBOX_LIST_PROP_NO_NOSELECT) != 0) { + /* Layout doesn't support creating \NoSelect mailboxes. + Switch to creating a selectable mailbox. */ + directory = FALSE; + } + type = directory ? MAILBOX_LIST_PATH_TYPE_DIR : MAILBOX_LIST_PATH_TYPE_MAILBOX; if ((ret = mailbox_get_path_to(box, type, &path)) < 0) @@ -630,8 +636,7 @@ int index_storage_mailbox_create(struct mailbox *box, bool directory) return -1; } - if (directory && - (box->list->props & MAILBOX_LIST_PROP_NO_NOSELECT) == 0) { + if (directory) { /* we only wanted to create the directory and it's done now */ return 0; } diff --git a/src/lib-storage/list/mailbox-list-delete.c b/src/lib-storage/list/mailbox-list-delete.c index 5112c9e672..d4965dac51 100644 --- a/src/lib-storage/list/mailbox-list-delete.c +++ b/src/lib-storage/list/mailbox-list-delete.c @@ -276,7 +276,7 @@ void mailbox_list_delete_until_root(struct mailbox_list *list, const char *path, const char *root_dir, *p; size_t len; - if (list->set.iter_from_index_dir && + if (list->set.iter_from_index_dir && !list->set.no_noselect && mailbox_list_path_is_index(list, type)) { /* Don't auto-rmdir parent index directories with ITERINDEX. Otherwise it'll get us into inconsistent state with a diff --git a/src/lib-storage/list/mailbox-list-fs.c b/src/lib-storage/list/mailbox-list-fs.c index 12db625813..fea5a4fa37 100644 --- a/src/lib-storage/list/mailbox-list-fs.c +++ b/src/lib-storage/list/mailbox-list-fs.c @@ -255,17 +255,19 @@ static int fs_list_delete_mailbox(struct mailbox_list *list, const char *name) const char *path; int ret; + ret = mailbox_list_get_path(list, name, + MAILBOX_LIST_PATH_TYPE_MAILBOX, &path); + if (ret < 0) + return -1; + i_assert(ret > 0); + if ((list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0) { - ret = mailbox_list_get_path(list, name, - MAILBOX_LIST_PATH_TYPE_MAILBOX, - &path); - if (ret < 0) - return -1; - i_assert(ret > 0); ret = mailbox_list_delete_mailbox_file(list, name, path); } else { ret = fs_list_delete_maildir(list, name); } + if (ret == 0 && list->set.no_noselect) + mailbox_list_delete_until_root(list, path, MAILBOX_LIST_PATH_TYPE_MAILBOX); i_assert(ret <= 0); return mailbox_list_delete_finish_ret(list, name, ret == 0); diff --git a/src/lib-storage/mailbox-list.c b/src/lib-storage/mailbox-list.c index 744261a7c9..2ce4c4df07 100644 --- a/src/lib-storage/mailbox-list.c +++ b/src/lib-storage/mailbox-list.c @@ -146,6 +146,8 @@ int mailbox_list_create(const char *driver, struct mail_namespace *ns, list->root_permissions.dir_create_mode = (mode_t)-1; list->root_permissions.file_create_gid = (gid_t)-1; list->changelog_timestamp = (time_t)-1; + if (set->no_noselect) + list->props |= MAILBOX_LIST_PROP_NO_NOSELECT; /* copy settings */ if (set->root_dir != NULL) { @@ -178,6 +180,7 @@ int mailbox_list_create(const char *driver, struct mail_namespace *ns, list->set.index_control_use_maildir_name = set->index_control_use_maildir_name; list->set.iter_from_index_dir = set->iter_from_index_dir; + list->set.no_noselect = set->no_noselect; if (*set->mailbox_dir_name == '\0') list->set.mailbox_dir_name = ""; @@ -351,6 +354,9 @@ mailbox_list_settings_parse_full(struct mail_user *user, const char *data, } else if (strcmp(key, "ITERINDEX") == 0) { set_r->iter_from_index_dir = TRUE; continue; + } else if (strcmp(key, "NO-NOSELECT") == 0) { + set_r->no_noselect = TRUE; + continue; } else { *error_r = t_strdup_printf("Unknown setting: %s", key); return -1; diff --git a/src/lib-storage/mailbox-list.h b/src/lib-storage/mailbox-list.h index a816b24189..7b3235f988 100644 --- a/src/lib-storage/mailbox-list.h +++ b/src/lib-storage/mailbox-list.h @@ -152,6 +152,8 @@ struct mailbox_list_settings { faster storage. This could perhaps be made the default at some point, but for now since it's less tested it's optional. */ bool iter_from_index_dir; + /* Avoid creating or listing \NoSelect mailboxes. */ + bool no_noselect; }; struct mailbox_permissions {