From: Timo Sirainen Date: Thu, 31 Dec 2009 22:18:00 +0000 (-0500) Subject: lib-storage: Added mailbox_list_delete_dir() to (try to) delete a \noselect mailbox. X-Git-Tag: 2.0.beta2~75 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2f30b72d49fbff0c4096125c139e4bdfef45669c;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Added mailbox_list_delete_dir() to (try to) delete a \noselect mailbox. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/shared/shared-list.c b/src/lib-storage/index/shared/shared-list.c index f900a758ca..2ef0185b05 100644 --- a/src/lib-storage/index/shared/shared-list.c +++ b/src/lib-storage/index/shared/shared-list.c @@ -244,6 +244,20 @@ shared_list_delete_mailbox(struct mailbox_list *list, const char *name) return ret; } +static int +shared_list_delete_dir(struct mailbox_list *list, const char *name) +{ + struct mail_namespace *ns = list->ns; + int ret; + + if (shared_storage_get_namespace(&ns, &name) < 0) + return -1; + ret = mailbox_list_delete_dir(ns->list, name); + if (ret < 0) + shared_list_copy_error(list, ns); + return ret; +} + static int shared_list_rename_get_ns(struct mailbox_list *oldlist, const char **oldname, struct mailbox_list *newlist, @@ -324,6 +338,7 @@ struct mailbox_list shared_mailbox_list = { NULL, shared_list_set_subscribed, shared_list_delete_mailbox, + shared_list_delete_dir, shared_list_rename_mailbox, shared_list_rename_mailbox_pre } diff --git a/src/lib-storage/list/mailbox-list-fs.c b/src/lib-storage/list/mailbox-list-fs.c index 67d889ae51..5186de5343 100644 --- a/src/lib-storage/list/mailbox-list-fs.c +++ b/src/lib-storage/list/mailbox-list-fs.c @@ -3,6 +3,7 @@ #include "lib.h" #include "hostpid.h" #include "mkdir-parents.h" +#include "mailbox-log.h" #include "subscription-file.h" #include "mail-storage.h" #include "mailbox-list-fs.h" @@ -280,6 +281,31 @@ static int fs_list_delete_mailbox(struct mailbox_list *list, const char *name) return mailbox_list_delete_index_control(list, name); } +static int fs_list_delete_dir(struct mailbox_list *list, const char *name) +{ + const char *path; + uint8_t dir_sha128[MAIL_GUID_128_SIZE]; + + path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_DIR); + if (rmdir(path) == 0) { + mailbox_name_get_sha128(name, dir_sha128); + mailbox_list_add_change(list, MAILBOX_LOG_RECORD_DELETE_DIR, + dir_sha128); + return 0; + } + + if (errno == ENOENT) { + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + } else if (errno == ENOTEMPTY) { + mailbox_list_set_error(list, MAIL_ERROR_EXISTS, + "Mailbox exists"); + } else { + mailbox_list_set_critical(list, "rmdir(%s) failed: %m", path); + } + return -1; +} + static int rename_dir(struct mailbox_list *oldlist, const char *oldname, struct mailbox_list *newlist, const char *newname, enum mailbox_list_path_type type, bool rmdir_parent) @@ -436,6 +462,7 @@ struct mailbox_list fs_mailbox_list = { NULL, fs_list_set_subscribed, fs_list_delete_mailbox, + fs_list_delete_dir, fs_list_rename_mailbox, NULL } diff --git a/src/lib-storage/list/mailbox-list-maildir.c b/src/lib-storage/list/mailbox-list-maildir.c index 6734d4df62..c2c156e5ca 100644 --- a/src/lib-storage/list/mailbox-list-maildir.c +++ b/src/lib-storage/list/mailbox-list-maildir.c @@ -387,6 +387,26 @@ maildir_list_delete_mailbox(struct mailbox_list *list, const char *name) return mailbox_list_delete_index_control(list, name); } +static int maildir_list_delete_dir(struct mailbox_list *list, const char *name) +{ + const char *path; + struct stat st; + + /* with maildir++ there aren't any non-selectable mailboxes. + we'll always fail. */ + path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_DIR); + if (stat(path, &st) == 0) { + mailbox_list_set_error(list, MAIL_ERROR_EXISTS, + "Mailbox exists"); + } else if (errno == ENOENT) { + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + } else { + mailbox_list_set_critical(list, "stat(%s) failed: %m", path); + } + return -1; +} + static int maildir_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname, struct mailbox_list *newlist, const char *newname, @@ -461,6 +481,7 @@ struct mailbox_list maildir_mailbox_list = { NULL, maildir_list_set_subscribed, maildir_list_delete_mailbox, + maildir_list_delete_dir, maildir_list_rename_mailbox, NULL } @@ -489,6 +510,7 @@ struct mailbox_list imapdir_mailbox_list = { NULL, maildir_list_set_subscribed, maildir_list_delete_mailbox, + maildir_list_delete_dir, maildir_list_rename_mailbox, NULL } diff --git a/src/lib-storage/mailbox-list-private.h b/src/lib-storage/mailbox-list-private.h index 9e0bf1f442..c718de5f25 100644 --- a/src/lib-storage/mailbox-list-private.h +++ b/src/lib-storage/mailbox-list-private.h @@ -58,6 +58,7 @@ struct mailbox_list_vfuncs { int (*set_subscribed)(struct mailbox_list *list, const char *name, bool set); 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, struct mailbox_list *newlist, const char *newname, bool rename_children); diff --git a/src/lib-storage/mailbox-list.c b/src/lib-storage/mailbox-list.c index d7053778d7..343c0aa3bf 100644 --- a/src/lib-storage/mailbox-list.c +++ b/src/lib-storage/mailbox-list.c @@ -746,6 +746,16 @@ int mailbox_list_delete_mailbox(struct mailbox_list *list, const char *name) return list->v.delete_mailbox(list, name); } +int mailbox_list_delete_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.delete_dir(list, name); +} + static bool nullequals(const void *p1, const void *p2) { return (p1 == NULL && p2 == NULL) || (p1 != NULL && p2 != NULL); diff --git a/src/lib-storage/mailbox-list.h b/src/lib-storage/mailbox-list.h index 7fb36a0128..91090f9c99 100644 --- a/src/lib-storage/mailbox-list.h +++ b/src/lib-storage/mailbox-list.h @@ -243,6 +243,8 @@ int mailbox_list_set_subscribed(struct mailbox_list *list, /* Delete the given mailbox. If it has children, they aren't deleted. */ int mailbox_list_delete_mailbox(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); /* Rename mailbox. Renaming across different mailbox lists is possible only between private namespaces and storages of the same type. If the rename fails, the error is set to oldlist. */