From a91bd6256b33729531c33ff8bc66ee1ae95840f9 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 14 Sep 2010 16:18:13 +0100 Subject: [PATCH] lib-storage: Added mailbox_list_create_dir() --- src/lib-storage/index/shared/shared-list.c | 4 ++-- src/lib-storage/list/mailbox-list-fs.c | 5 +++-- src/lib-storage/list/mailbox-list-maildir.c | 12 +++++++++--- src/lib-storage/list/mailbox-list-none.c | 2 +- src/lib-storage/mail-storage.c | 7 +++++-- src/lib-storage/mailbox-list-private.h | 10 +++++++++- src/lib-storage/mailbox-list.c | 11 +++++++++++ src/lib-storage/mailbox-list.h | 3 +++ src/plugins/acl/acl-mailbox-list.c | 5 ++--- 9 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/lib-storage/index/shared/shared-list.c b/src/lib-storage/index/shared/shared-list.c index 16ba96ff9e..6180506183 100644 --- a/src/lib-storage/index/shared/shared-list.c +++ b/src/lib-storage/index/shared/shared-list.c @@ -232,14 +232,14 @@ static int shared_list_set_subscribed(struct mailbox_list *list, static int shared_list_create_mailbox_dir(struct mailbox_list *list, const char *name, - bool directory) + enum mailbox_dir_create_type type) { struct mail_namespace *ns = list->ns; int ret; if (shared_storage_get_namespace(&ns, &name) < 0) return -1; - ret = ns->list->v.create_mailbox_dir(ns->list, name, directory); + ret = ns->list->v.create_mailbox_dir(ns->list, name, type); if (ret < 0) shared_list_copy_error(list, ns); return ret; diff --git a/src/lib-storage/list/mailbox-list-fs.c b/src/lib-storage/list/mailbox-list-fs.c index 0df5fd238b..0cb359d972 100644 --- a/src/lib-storage/list/mailbox-list-fs.c +++ b/src/lib-storage/list/mailbox-list-fs.c @@ -317,14 +317,15 @@ static int mailbox_is_selectable(struct mailbox_list *list, const char *name) static int fs_list_create_mailbox_dir(struct mailbox_list *list, const char *name, - bool directory) + enum mailbox_dir_create_type type) { const char *path, *gid_origin, *p; mode_t mode; gid_t gid; - bool create_parent_dir; + bool directory, create_parent_dir; int ret; + directory = type != MAILBOX_LIST_PATH_TYPE_MAILBOX; path = mailbox_list_get_path(list, name, directory ? MAILBOX_LIST_PATH_TYPE_DIR : MAILBOX_LIST_PATH_TYPE_MAILBOX); diff --git a/src/lib-storage/list/mailbox-list-maildir.c b/src/lib-storage/list/mailbox-list-maildir.c index f33beef6bd..6ba76f9127 100644 --- a/src/lib-storage/list/mailbox-list-maildir.c +++ b/src/lib-storage/list/mailbox-list-maildir.c @@ -323,16 +323,22 @@ maildir_list_create_maildirfolder_file(struct mailbox_list *list, static int maildir_list_create_mailbox_dir(struct mailbox_list *list, const char *name, - bool directory ATTR_UNUSED) + enum mailbox_dir_create_type type) { const char *path, *root_dir, *gid_origin, *p; mode_t mode; gid_t gid; bool create_parent_dir; + if (type == MAILBOX_DIR_CREATE_TYPE_ONLY_NOSELECT) { + mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, + "Can't create non-selectable mailbox"); + return -1; + } + path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX); - create_parent_dir = !directory && + create_parent_dir = type == MAILBOX_DIR_CREATE_TYPE_MAILBOX && (list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0; if (create_parent_dir) { /* we only need to make sure that the parent directory exists */ @@ -351,7 +357,7 @@ maildir_list_create_mailbox_dir(struct mailbox_list *list, const char *name, } else if (errno == EEXIST) { if (create_parent_dir) return 0; - if (!directory) { + if (type == MAILBOX_DIR_CREATE_TYPE_MAILBOX) { if (strcmp(path, root_dir) == 0) { /* even though the root directory exists, the mailbox might not */ diff --git a/src/lib-storage/list/mailbox-list-none.c b/src/lib-storage/list/mailbox-list-none.c index ea1d1fceb2..9246fa4ee9 100644 --- a/src/lib-storage/list/mailbox-list-none.c +++ b/src/lib-storage/list/mailbox-list-none.c @@ -84,7 +84,7 @@ static int none_list_set_subscribed(struct mailbox_list *list, static int none_list_create_mailbox_dir(struct mailbox_list *list, const char *name ATTR_UNUSED, - bool directory ATTR_UNUSED) + enum mailbox_dir_create_type type ATTR_UNUSED) { mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, "Not supported"); return -1; diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index 2241310353..77c3a40e4d 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -643,14 +643,17 @@ void mailbox_free(struct mailbox **_box) int mailbox_create(struct mailbox *box, const struct mailbox_update *update, bool directory) { + enum mailbox_dir_create_type type; + if (!mailbox_list_is_valid_create_name(box->list, box->name)) { mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS, "Invalid mailbox name"); return -1; } - if (box->list->v.create_mailbox_dir(box->list, box->name, - directory) < 0) { + type = directory ? MAILBOX_DIR_CREATE_TYPE_TRY_NOSELECT : + MAILBOX_DIR_CREATE_TYPE_MAILBOX; + if (box->list->v.create_mailbox_dir(box->list, box->name, type) < 0) { mail_storage_copy_list_error(box->storage, box->list); return -1; } diff --git a/src/lib-storage/mailbox-list-private.h b/src/lib-storage/mailbox-list-private.h index 46cfb87db7..dddeb87963 100644 --- a/src/lib-storage/mailbox-list-private.h +++ b/src/lib-storage/mailbox-list-private.h @@ -21,6 +21,14 @@ struct mailbox_tree_context; (((flags) & (MAILBOX_SELECT | MAILBOX_NOSELECT | \ MAILBOX_NONEXISTENT)) != 0) +enum mailbox_dir_create_type { + /* Creating a mailbox */ + MAILBOX_DIR_CREATE_TYPE_MAILBOX, + /* Create a \Noselect or a mailbox */ + MAILBOX_DIR_CREATE_TYPE_TRY_NOSELECT, + /* Create a \Noselect or fail */ + MAILBOX_DIR_CREATE_TYPE_ONLY_NOSELECT +}; struct mailbox_list_vfuncs { struct mailbox_list *(*alloc)(void); @@ -65,7 +73,7 @@ struct mailbox_list_vfuncs { int (*set_subscribed)(struct mailbox_list *list, const char *name, bool set); int (*create_mailbox_dir)(struct mailbox_list *list, const char *name, - bool directory); + enum mailbox_dir_create_type type); int (*delete_mailbox)(struct mailbox_list *list, const char *name); int (*delete_dir)(struct mailbox_list *list, const char *name); int (*rename_mailbox)(struct mailbox_list *oldlist, const char *oldname, diff --git a/src/lib-storage/mailbox-list.c b/src/lib-storage/mailbox-list.c index 273a957072..bf72db49bb 100644 --- a/src/lib-storage/mailbox-list.c +++ b/src/lib-storage/mailbox-list.c @@ -1160,6 +1160,17 @@ int mailbox_list_set_subscribed(struct mailbox_list *list, return 0; } +int mailbox_list_create_dir(struct mailbox_list *list, const char *name) +{ + if (!mailbox_list_is_valid_existing_name(list, name) || *name == '\0') { + mailbox_list_set_error(list, MAIL_ERROR_PARAMS, + "Invalid mailbox name"); + return -1; + } + return list->v.create_mailbox_dir(list, name, + MAILBOX_DIR_CREATE_TYPE_ONLY_NOSELECT); +} + int mailbox_list_delete_dir(struct mailbox_list *list, const char *name) { if (!mailbox_list_is_valid_existing_name(list, name) || *name == '\0') { diff --git a/src/lib-storage/mailbox-list.h b/src/lib-storage/mailbox-list.h index 3087162c13..984da51841 100644 --- a/src/lib-storage/mailbox-list.h +++ b/src/lib-storage/mailbox-list.h @@ -265,6 +265,9 @@ int mailbox_list_mailbox(struct mailbox_list *list, const char *name, int mailbox_list_set_subscribed(struct mailbox_list *list, const char *name, bool set); +/* Create a non-selectable mailbox. Fail with MAIL_ERROR_NOTPOSSIBLE if only + a selectable mailbox can be created. */ +int mailbox_list_create_dir(struct mailbox_list *list, const char *name); /* Delete a non-selectable mailbox. Fail if the mailbox is selectable. */ int mailbox_list_delete_dir(struct mailbox_list *list, const char *name); diff --git a/src/plugins/acl/acl-mailbox-list.c b/src/plugins/acl/acl-mailbox-list.c index 347c6d2e62..9a96e3c268 100644 --- a/src/plugins/acl/acl-mailbox-list.c +++ b/src/plugins/acl/acl-mailbox-list.c @@ -466,7 +466,7 @@ static int acl_get_mailbox_name_status(struct mailbox_list *list, static int acl_mailbox_list_create_dir(struct mailbox_list *list, const char *name, - bool directory) + enum mailbox_dir_create_type type) { struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(list); int ret; @@ -484,8 +484,7 @@ acl_mailbox_list_create_dir(struct mailbox_list *list, const char *name, MAIL_ERRSTR_NO_PERMISSION); return -1; } - return alist->module_ctx.super. - create_mailbox_dir(list, name, directory); + return alist->module_ctx.super.create_mailbox_dir(list, name, type); } static void acl_mailbox_list_init_shared(struct mailbox_list *list) -- 2.47.3