changeset 12897:9949b7987409

lib-storage: mailbox_delete() for a symlink now removes the symlink instead of expunging mails.
author Timo Sirainen <tss@iki.fi>
date Sat, 30 Apr 2011 15:12:20 +0300
parents a8fe529ea72b
children 80eef14e9e15
files src/lib-storage/index/imapc/imapc-list.c src/lib-storage/index/index-storage.c src/lib-storage/index/shared/shared-list.c src/lib-storage/list/mailbox-list-delete.c src/lib-storage/list/mailbox-list-delete.h src/lib-storage/list/mailbox-list-fs.c src/lib-storage/list/mailbox-list-maildir.c src/lib-storage/list/mailbox-list-none.c src/lib-storage/mailbox-list-private.h src/lib-storage/mailbox-list.c src/lib-storage/mailbox-list.h
diffstat 11 files changed, 71 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/imapc/imapc-list.c	Sat Apr 30 15:00:42 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-list.c	Sat Apr 30 15:12:20 2011 +0300
@@ -497,6 +497,14 @@
 }
 
 static int
+imapc_list_delete_symlink(struct mailbox_list *list,
+			  const char *name ATTR_UNUSED)
+{
+	mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, "Not supported");
+	return -1;
+}
+
+static int
 imapc_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname,
 			  struct mailbox_list *newlist, const char *newname,
 			  bool rename_children)
@@ -560,6 +568,7 @@
 		imapc_list_create_mailbox_dir,
 		imapc_list_delete_mailbox,
 		imapc_list_delete_dir,
+		imapc_list_delete_symlink,
 		imapc_list_rename_mailbox
 	}
 };
--- a/src/lib-storage/index/index-storage.c	Sat Apr 30 15:00:42 2011 +0300
+++ b/src/lib-storage/index/index-storage.c	Sat Apr 30 15:12:20 2011 +0300
@@ -522,6 +522,11 @@
 		return index_storage_mailbox_delete_dir(box, FALSE);
 	}
 
+	/* specifically support symlinked shared mailboxes. a deletion will
+	   simply remove the symlink, not actually expunge any mails */
+	if (mailbox_list_delete_symlink(box->list, box->name) == 0)
+		return 0;
+
 	/* we can't easily atomically delete all mails and the mailbox. so:
 	   1) expunge all mails
 	   2) mark the mailbox deleted (modifications after this will fail)
--- a/src/lib-storage/index/shared/shared-list.c	Sat Apr 30 15:00:42 2011 +0300
+++ b/src/lib-storage/index/shared/shared-list.c	Sat Apr 30 15:12:20 2011 +0300
@@ -275,6 +275,20 @@
 	return ret;
 }
 
+static int
+shared_list_delete_symlink(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_symlink(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,
@@ -342,6 +356,7 @@
 		shared_list_create_mailbox_dir,
 		shared_list_delete_mailbox,
 		shared_list_delete_dir,
+		shared_list_delete_symlink,
 		shared_list_rename_mailbox
 	}
 };
--- a/src/lib-storage/list/mailbox-list-delete.c	Sat Apr 30 15:00:42 2011 +0300
+++ b/src/lib-storage/list/mailbox-list-delete.c	Sat Apr 30 15:12:20 2011 +0300
@@ -328,3 +328,25 @@
 	}
 	return 0;
 }
+
+int mailbox_list_delete_symlink_default(struct mailbox_list *list,
+					const char *name)
+{
+	const char *path;
+
+	path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_DIR);
+	if (unlink(path) == 0)
+		return 0;
+
+	if (errno == ENOENT) {
+		mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
+			T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
+	} else if (errno == EISDIR) {
+		mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE,
+				       "Mailbox isn't a symlink");
+	} else {
+		mailbox_list_set_critical(list, "stat(%s) failed: %m", path);
+	}
+	return -1;
+}
+
--- a/src/lib-storage/list/mailbox-list-delete.h	Sat Apr 30 15:00:42 2011 +0300
+++ b/src/lib-storage/list/mailbox-list-delete.h	Sat Apr 30 15:12:20 2011 +0300
@@ -17,4 +17,7 @@
 				    enum mailbox_list_path_type type);
 int mailbox_list_delete_trash(const char *path);
 
+int mailbox_list_delete_symlink_default(struct mailbox_list *list,
+					const char *name);
+
 #endif
--- a/src/lib-storage/list/mailbox-list-fs.c	Sat Apr 30 15:00:42 2011 +0300
+++ b/src/lib-storage/list/mailbox-list-fs.c	Sat Apr 30 15:12:20 2011 +0300
@@ -613,6 +613,7 @@
 		fs_list_create_mailbox_dir,
 		fs_list_delete_mailbox,
 		fs_list_delete_dir,
+		mailbox_list_delete_symlink_default,
 		fs_list_rename_mailbox
 	}
 };
--- a/src/lib-storage/list/mailbox-list-maildir.c	Sat Apr 30 15:00:42 2011 +0300
+++ b/src/lib-storage/list/mailbox-list-maildir.c	Sat Apr 30 15:12:20 2011 +0300
@@ -660,6 +660,7 @@
 		maildir_list_create_mailbox_dir,
 		maildir_list_delete_mailbox,
 		maildir_list_delete_dir,
+		mailbox_list_delete_symlink_default,
 		maildir_list_rename_mailbox
 	}
 };
@@ -694,6 +695,7 @@
 		maildir_list_create_mailbox_dir,
 		maildir_list_delete_mailbox,
 		maildir_list_delete_dir,
+		mailbox_list_delete_symlink_default,
 		maildir_list_rename_mailbox
 	}
 };
--- a/src/lib-storage/list/mailbox-list-none.c	Sat Apr 30 15:00:42 2011 +0300
+++ b/src/lib-storage/list/mailbox-list-none.c	Sat Apr 30 15:12:20 2011 +0300
@@ -210,6 +210,7 @@
 		none_list_create_mailbox_dir,
 		none_list_delete_mailbox,
 		none_list_delete_dir,
+		none_list_delete_dir,
 		none_list_rename_mailbox
 	}
 };
--- a/src/lib-storage/mailbox-list-private.h	Sat Apr 30 15:00:42 2011 +0300
+++ b/src/lib-storage/mailbox-list-private.h	Sat Apr 30 15:12:20 2011 +0300
@@ -82,6 +82,7 @@
 				  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 (*delete_symlink)(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	Sat Apr 30 15:00:42 2011 +0300
+++ b/src/lib-storage/mailbox-list.c	Sat Apr 30 15:12:20 2011 +0300
@@ -1404,6 +1404,16 @@
 	return list->v.delete_dir(list, name);
 }
 
+int mailbox_list_delete_symlink(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_symlink(list, name);
+}
+
 void mailbox_name_get_sha128(const char *name, uint8_t guid[MAIL_GUID_128_SIZE])
 {
 	unsigned char sha[SHA1_RESULTLEN];
--- a/src/lib-storage/mailbox-list.h	Sat Apr 30 15:00:42 2011 +0300
+++ b/src/lib-storage/mailbox-list.h	Sat Apr 30 15:12:20 2011 +0300
@@ -265,6 +265,8 @@
 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);
+/* Delete a symlinked mailbox. Fail if the mailbox isn't a symlink. */
+int mailbox_list_delete_symlink(struct mailbox_list *list, const char *name);
 
 /* Returns the error message of last occurred error. */
 const char *mailbox_list_get_last_error(struct mailbox_list *list,