]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Added mailbox_list_delete_dir() to (try to) delete a \noselect mailbox.
authorTimo Sirainen <tss@iki.fi>
Thu, 31 Dec 2009 22:18:00 +0000 (17:18 -0500)
committerTimo Sirainen <tss@iki.fi>
Thu, 31 Dec 2009 22:18:00 +0000 (17:18 -0500)
--HG--
branch : HEAD

src/lib-storage/index/shared/shared-list.c
src/lib-storage/list/mailbox-list-fs.c
src/lib-storage/list/mailbox-list-maildir.c
src/lib-storage/mailbox-list-private.h
src/lib-storage/mailbox-list.c
src/lib-storage/mailbox-list.h

index f900a758cae885f161a22e616d0604ac7331a46b..2ef0185b0511893e37049ed01a5e378ae1272afb 100644 (file)
@@ -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
        }
index 67d889ae51ec1b2889121662c94a9e8c7d66e6f4..5186de53434125321ca840ddbbfff1a93e909afa 100644 (file)
@@ -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
        }
index 6734d4df6210f6561ee6e92fca68458e07b493a5..c2c156e5ca2933a1145a1b82ed45b0aec97ce796 100644 (file)
@@ -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
        }
index 9e0bf1f442afd8b59ecc7c8531e5d84e8a6eaef4..c718de5f25d5f3cb1972d26a929f645936d72350 100644 (file)
@@ -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);
index d7053778d7002ff1facd3c4de26b505943fd7187..343c0aa3bff4de99e7fea993d405169ff5129257 100644 (file)
@@ -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);
index 7fb36a0128a3a9b8bd9c4473ee7929a1580f0cc9..91090f9c995e88d7a1b87d0e3958509f941d6441 100644 (file)
@@ -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. */