]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Add setting to disable \NoSelect mailboxes
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 25 Jul 2017 13:10:51 +0000 (16:10 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 25 Jul 2017 19:15:40 +0000 (22:15 +0300)
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.

src/lib-storage/index/index-storage.c
src/lib-storage/list/mailbox-list-delete.c
src/lib-storage/list/mailbox-list-fs.c
src/lib-storage/mailbox-list.c
src/lib-storage/mailbox-list.h

index 6b0482f76dd003a837add1633c8ef1945a189a08..ea81cd433043c1c9b1ef9545e89d70b7180fd694 100644 (file)
@@ -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;
        }
index 5112c9e672b2af7d6a62c8a705b1a0788614b405..d4965dac51c38f12d90977c409822d544c49d8d1 100644 (file)
@@ -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
index 12db625813214e3dd5701500786ecf32dc77d943..fea5a4fa375d86f849b063720ee7049e62cab73c 100644 (file)
@@ -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);
index 744261a7c94364b9988c6fa2ffde8d0a1897c346..2ce4c4df07ae6a8ae3a673519673ef96ef6570c7 100644 (file)
@@ -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;
index a816b24189dcec44e05549d59ec55c17b6e46cfb..7b3235f9886865d27202b7bf7c8c7cfce77e9ed9 100644 (file)
@@ -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 {