dovecot-2.0: lazy_expunge: Fixes to handling mailbox deletion an...

dovecot at dovecot.org dovecot at dovecot.org
Mon Feb 15 04:46:32 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/4fd02780d09f
changeset: 10724:4fd02780d09f
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Feb 15 04:46:29 2010 +0200
description:
lazy_expunge: Fixes to handling mailbox deletion and renames.

diffstat:

 src/plugins/lazy-expunge/lazy-expunge-plugin.c |  58 +++++++++++++++++++++++-----
 1 files changed, 47 insertions(+), 11 deletions(-)

diffs (129 lines):

diff -r eae6e4a7ee55 -r 4fd02780d09f src/plugins/lazy-expunge/lazy-expunge-plugin.c
--- a/src/plugins/lazy-expunge/lazy-expunge-plugin.c	Mon Feb 15 04:31:35 2010 +0200
+++ b/src/plugins/lazy-expunge/lazy-expunge-plugin.c	Mon Feb 15 04:46:29 2010 +0200
@@ -45,6 +45,7 @@
 struct lazy_expunge_mailbox_list {
 	union mailbox_list_module_context module_ctx;
 
+	unsigned int allow_rename:1;
 	unsigned int internal_namespace:1;
 };
 
@@ -234,12 +235,15 @@
 mailbox_move(struct mailbox *src_box, struct mailbox_list *dest_list,
 	     const char *wanted_destname, struct mailbox **dest_box_r)
 {
+	struct lazy_expunge_mailbox_list *src_llist =
+		LAZY_EXPUNGE_LIST_CONTEXT(src_box->list);
 	const char *dest_name = wanted_destname;
 	struct mailbox *dest_box;
 	const char *dir, *origin;
 	enum mail_error error;
 	mode_t mode;
 	gid_t gid;
+	int ret;
 
 	/* make sure the destination root directory exists */
 	mailbox_list_get_dir_permissions(dest_list, NULL, &mode, &gid, &origin);
@@ -254,7 +258,12 @@
 	for (;;) {
 		dest_box = mailbox_alloc(dest_list, dest_name,
 					 MAILBOX_FLAG_OPEN_DELETED);
-		if (mailbox_rename(src_box, dest_box, FALSE) == 0)
+
+		src_llist->allow_rename = TRUE;
+		ret = mailbox_rename(src_box, dest_box, FALSE);
+		src_llist->allow_rename = FALSE;
+
+		if (ret == 0)
 			break;
 		mailbox_free(&dest_box);
 
@@ -353,9 +362,11 @@
 
 static int lazy_expunge_mailbox_delete(struct mailbox *box)
 {
+	union mailbox_module_context *lbox =
+		LAZY_EXPUNGE_CONTEXT(box);
+	struct lazy_expunge_mailbox_list *llist =
+		LAZY_EXPUNGE_LIST_CONTEXT(box->list);
 	struct mailbox_list *list = box->list;
-	struct lazy_expunge_mailbox_list *llist =
-		LAZY_EXPUNGE_LIST_CONTEXT(list);
 	struct mail_namespace *expunge_ns, *dest_ns;
 	struct mailbox *expunge_box;
 	const char *destname, *str;
@@ -365,7 +376,7 @@
 	int ret;
 
 	if (llist->internal_namespace)
-		return llist->module_ctx.super.delete_mailbox(list, box->name);
+		return lbox->super.delete(box);
 
 	expunge_ns = get_lazy_ns(list->ns->user, LAZY_NAMESPACE_EXPUNGE);
 	dest_ns = get_lazy_ns(list->ns->user, LAZY_NAMESPACE_DELETE);
@@ -385,8 +396,8 @@
 	}
 
 	/* first move the actual mailbox */
-	if ((ret = mailbox_move(box, dest_ns->list, destname,
-				&expunge_box)) < 0)
+	ret = mailbox_move(box, dest_ns->list, destname, &expunge_box);
+	if (ret < 0)
 		return -1;
 	if (ret == 0) {
 		mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
@@ -430,23 +441,48 @@
 	return ret < 0 ? -1 : 0;
 }
 
+static int
+lazy_expunge_mailbox_rename(struct mailbox *src, struct mailbox *dest,
+			    bool rename_children)
+{
+	union mailbox_module_context *lbox = LAZY_EXPUNGE_CONTEXT(src);
+	struct lazy_expunge_mailbox_list *src_llist =
+		LAZY_EXPUNGE_LIST_CONTEXT(src->list);
+	struct lazy_expunge_mailbox_list *dest_llist =
+		LAZY_EXPUNGE_LIST_CONTEXT(dest->list);
+
+	if (!src_llist->allow_rename &&
+	    (src_llist->internal_namespace ||
+	     dest_llist->internal_namespace)) {
+		mail_storage_set_error(src->storage, MAIL_ERROR_NOTPOSSIBLE,
+			"Can't rename mailboxes to/from expunge namespace.");
+		return -1;
+	}
+	return lbox->super.rename(src, dest, rename_children);
+}
+
 static void lazy_expunge_mailbox_allocated(struct mailbox *box)
 {
 	struct lazy_expunge_mailbox_list *llist =
 		LAZY_EXPUNGE_LIST_CONTEXT(box->list);
 	union mailbox_module_context *mbox;
 
-	if (llist != NULL && !llist->internal_namespace) {
-		mbox = p_new(box->pool, union mailbox_module_context, 1);
-		mbox->super = box->v;
+	if (llist == NULL)
+		return;
 
+	mbox = p_new(box->pool, union mailbox_module_context, 1);
+	mbox->super = box->v;
+	MODULE_CONTEXT_SET_SELF(box, lazy_expunge_mail_storage_module, mbox);
+
+	if (!llist->internal_namespace) {
 		box->v.transaction_begin = lazy_expunge_transaction_begin;
 		box->v.transaction_commit = lazy_expunge_transaction_commit;
 		box->v.transaction_rollback = lazy_expunge_transaction_rollback;
 		box->v.mail_alloc = lazy_expunge_mail_alloc;
 		box->v.delete = lazy_expunge_mailbox_delete;
-		MODULE_CONTEXT_SET_SELF(box, lazy_expunge_mail_storage_module,
-					mbox);
+		box->v.rename = lazy_expunge_mailbox_rename;
+	} else {
+		box->v.rename = lazy_expunge_mailbox_rename;
 	}
 }
 


More information about the dovecot-cvs mailing list