]> 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)
committerAki Tuomi <aki.tuomi@dovecot.fi>
Tue, 25 Jul 2017 19:06:12 +0000 (22:06 +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 43b9c97c429d652865028f7fd0038093b71c0c51..8f27a2cf8d7cd3d734db8a957685b13e276a9e4d 100644 (file)
@@ -575,6 +575,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)
@@ -631,8 +637,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 ac5efa1bb9ce8443a0c3c654277322c71cbf01e8..d05567fa755eb8f3df24c48abc0e74f0c1b022db 100644 (file)
@@ -277,7 +277,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 8dc2b578fe63254f5cdf766f1ae3a401bf454f92..082d64dbe7e1189dff3f45b69b49b8a3a6062367 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 = "";
@@ -358,6 +361,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 {