changeset 10544:3c12d0376cef HEAD

lib-storage: Added mailbox_list_delete_dir() to (try to) delete a \noselect mailbox.
author Timo Sirainen <tss@iki.fi>
date Thu, 31 Dec 2009 17:18:00 -0500
parents f20bced53213
children 96db209efe22
files 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
diffstat 6 files changed, 77 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/shared/shared-list.c	Thu Dec 31 13:46:24 2009 -0500
+++ b/src/lib-storage/index/shared/shared-list.c	Thu Dec 31 17:18:00 2009 -0500
@@ -244,6 +244,20 @@
 	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 @@
 		NULL,
 		shared_list_set_subscribed,
 		shared_list_delete_mailbox,
+		shared_list_delete_dir,
 		shared_list_rename_mailbox,
 		shared_list_rename_mailbox_pre
 	}
--- a/src/lib-storage/list/mailbox-list-fs.c	Thu Dec 31 13:46:24 2009 -0500
+++ b/src/lib-storage/list/mailbox-list-fs.c	Thu Dec 31 17:18:00 2009 -0500
@@ -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 @@
 	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 @@
 		NULL,
 		fs_list_set_subscribed,
 		fs_list_delete_mailbox,
+		fs_list_delete_dir,
 		fs_list_rename_mailbox,
 		NULL
 	}
--- a/src/lib-storage/list/mailbox-list-maildir.c	Thu Dec 31 13:46:24 2009 -0500
+++ b/src/lib-storage/list/mailbox-list-maildir.c	Thu Dec 31 17:18:00 2009 -0500
@@ -387,6 +387,26 @@
 	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 @@
 		NULL,
 		maildir_list_set_subscribed,
 		maildir_list_delete_mailbox,
+		maildir_list_delete_dir,
 		maildir_list_rename_mailbox,
 		NULL
 	}
@@ -489,6 +510,7 @@
 		NULL,
 		maildir_list_set_subscribed,
 		maildir_list_delete_mailbox,
+		maildir_list_delete_dir,
 		maildir_list_rename_mailbox,
 		NULL
 	}
--- a/src/lib-storage/mailbox-list-private.h	Thu Dec 31 13:46:24 2009 -0500
+++ b/src/lib-storage/mailbox-list-private.h	Thu Dec 31 17:18:00 2009 -0500
@@ -58,6 +58,7 @@
 	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);
--- a/src/lib-storage/mailbox-list.c	Thu Dec 31 13:46:24 2009 -0500
+++ b/src/lib-storage/mailbox-list.c	Thu Dec 31 17:18:00 2009 -0500
@@ -746,6 +746,16 @@
 	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);
--- a/src/lib-storage/mailbox-list.h	Thu Dec 31 13:46:24 2009 -0500
+++ b/src/lib-storage/mailbox-list.h	Thu Dec 31 17:18:00 2009 -0500
@@ -243,6 +243,8 @@
 
 /* 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. */