dovecot: Convert only after namespaces are created. Convert mail...

dovecot at dovecot.org dovecot at dovecot.org
Sun Dec 9 15:47:07 EET 2007


details:   http://hg.dovecot.org/dovecot/rev/7cedc391e6c5
changeset: 6976:7cedc391e6c5
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Dec 09 15:47:03 2007 +0200
description:
Convert only after namespaces are created. Convert mailboxes to INBOX
namespace.

diffstat:

4 files changed, 91 insertions(+), 57 deletions(-)
src/plugins/convert/convert-plugin.c  |   29 ++++++---
src/plugins/convert/convert-storage.c |   96 +++++++++++++++++----------------
src/plugins/convert/convert-storage.h |    5 +
src/plugins/convert/convert-tool.c    |   18 +++++-

diffs (truncated from 361 to 300 lines):

diff -r f2c37fe48668 -r 7cedc391e6c5 src/plugins/convert/convert-plugin.c
--- a/src/plugins/convert/convert-plugin.c	Sun Dec 09 15:01:14 2007 +0200
+++ b/src/plugins/convert/convert-plugin.c	Sun Dec 09 15:47:03 2007 +0200
@@ -1,6 +1,7 @@
 /* Copyright (c) 2006-2007 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "mail-namespace.h"
 #include "convert-storage.h"
 #include "convert-plugin.h"
 
@@ -8,18 +9,18 @@
 
 const char *convert_plugin_version = PACKAGE_VERSION;
 
-void convert_plugin_init(void)
+static void (*convert_next_hook_mail_namespaces_created)
+	(struct mail_namespace *namespaces);
+
+static void
+convert_hook_mail_namespaces_created(struct mail_namespace *namespaces)
 {
-	const char *convert_mail, *mail, *str;
+	const char *convert_mail, *str;
 	struct convert_settings set;
 
 	convert_mail = getenv("CONVERT_MAIL");
 	if (convert_mail == NULL)
 		return;
-
-	mail = getenv("MAIL");
-	if (mail == NULL)
-		i_fatal("convert plugin: MAIL unset");
 
 	memset(&set, 0, sizeof(set));
 	set.user = getenv("USER");
@@ -29,16 +30,26 @@ void convert_plugin_init(void)
 	if (set.home == NULL)
 		i_fatal("convert plugin: HOME unset");
 
-	set.skip_broken_mailboxes = getenv("CONVERT_SKIP_BROKEN_MAILBOXES") != NULL;
+	set.skip_broken_mailboxes =
+		getenv("CONVERT_SKIP_BROKEN_MAILBOXES") != NULL;
 	set.skip_dotdirs = getenv("CONVERT_SKIP_DOTDIRS") != NULL;
 
 	str = getenv("CONVERT_ALT_HIERARCHY_CHAR");
 	set.alt_hierarchy_char = str != NULL && *str != '\0' ? *str : '_';
 
-	if (convert_storage(convert_mail, mail, &set) < 0)
-		exit(FATAL_DEFAULT);
+	if (convert_storage(convert_mail, namespaces, &set) < 0)
+		i_fatal("Mailbox conversion failed, exiting");
+}
+
+void convert_plugin_init(void)
+{
+	convert_next_hook_mail_namespaces_created =
+		hook_mail_namespaces_created;
+	hook_mail_namespaces_created = convert_hook_mail_namespaces_created;
 }
 
 void convert_plugin_deinit(void)
 {
+	hook_mail_namespaces_created =
+		convert_next_hook_mail_namespaces_created;
 }
diff -r f2c37fe48668 -r 7cedc391e6c5 src/plugins/convert/convert-storage.c
--- a/src/plugins/convert/convert-storage.c	Sun Dec 09 15:01:14 2007 +0200
+++ b/src/plugins/convert/convert-storage.c	Sun Dec 09 15:47:03 2007 +0200
@@ -22,8 +22,15 @@ struct dotlock_settings dotlock_settings
 	MEMBER(stale_timeout) 60*5
 };
 
+static const char *storage_error(struct mail_storage *storage)
+{
+	enum mail_error error;
+
+	return mail_storage_get_last_error(storage, &error);
+}
+
 static int mailbox_copy_mails(struct mailbox *srcbox, struct mailbox *destbox,
-			      struct dotlock *dotlock)
+			      struct dotlock *dotlock, const char **error_r)
 {
 	struct mail_search_context *ctx;
 	struct mailbox_transaction_context *src_trans, *dest_trans;
@@ -31,8 +38,11 @@ static int mailbox_copy_mails(struct mai
 	struct mail_search_arg search_arg;
 	int ret = 0;
 
-	if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ, 0, NULL) < 0)
-		return -1;
+	if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ, 0, NULL) < 0) {
+		*error_r = storage_error(srcbox->storage);
+		return -1;
+	}
+	*error_r = NULL;
 
 	memset(&search_arg, 0, sizeof(search_arg));
 	search_arg.type = SEARCH_ALL;
@@ -63,18 +73,25 @@ static int mailbox_copy_mails(struct mai
 		ret = mailbox_copy(dest_trans, mail, mail_get_flags(mail),
 				   keywords, NULL);
 		mailbox_keywords_free(destbox, &keywords);
-		if (ret < 0)
+		if (ret < 0) {
+			*error_r = storage_error(destbox->storage);
 			break;
+		}
 	}
 
 	mail_free(&mail);
-	if (mailbox_search_deinit(&ctx) < 0)
-		ret = -1;
+	if (mailbox_search_deinit(&ctx) < 0) {
+		ret = -1;
+		*error_r = storage_error(srcbox->storage);
+	}
 
 	if (ret < 0)
 		mailbox_transaction_rollback(&dest_trans);
-	else
+	else {
 		ret = mailbox_transaction_commit(&dest_trans);
+		if (ret < 0)
+			*error_r = storage_error(destbox->storage);
+	}
 
 	/* source transaction committing isn't all that important.
 	   ignore if it fails. */
@@ -82,14 +99,8 @@ static int mailbox_copy_mails(struct mai
 		mailbox_transaction_rollback(&src_trans);
 	else
 		(void)mailbox_transaction_commit(&src_trans);
-	return ret;
-}
-
-static const char *storage_error(struct mail_storage *storage)
-{
-	enum mail_error error;
-
-	return mail_storage_get_last_error(storage, &error);
+	i_assert(ret == 0 || *error_r != NULL);
+	return ret;
 }
 
 static const char *
@@ -221,7 +232,7 @@ static int mailbox_convert_list_item(str
 				     struct dotlock *dotlock,
 				     const struct convert_settings *set)
 {
-	const char *name, *dest_name;
+	const char *name, *dest_name, *error;
 	struct mailbox *srcbox, *destbox;
 	int ret = 0;
 
@@ -293,9 +304,9 @@ static int mailbox_convert_list_item(str
 		return -1;
 	}
 
-	if (mailbox_copy_mails(srcbox, destbox, dotlock) < 0) {
+	if (mailbox_copy_mails(srcbox, destbox, dotlock, &error) < 0) {
 		i_error("Mailbox conversion: Couldn't copy mailbox %s: %s",
-			mailbox_get_name(srcbox), storage_error(dest_storage));
+			mailbox_get_name(srcbox), error);
 	}
 
 	mailbox_close(&srcbox);
@@ -304,20 +315,22 @@ static int mailbox_convert_list_item(str
 }
 
 static int mailbox_list_copy(struct mail_storage *source_storage,
-			     struct mail_storage *dest_storage,
+			     struct mail_namespace *dest_namespaces,
 			     struct dotlock *dotlock,
 			     const struct convert_settings *set)
 {
 	struct mailbox_list_iterate_context *iter;
+	struct mail_namespace *dest_ns;
 	const struct mailbox_info *info;
 	int ret = 0;
 
+	dest_ns = mail_namespace_find_inbox(dest_namespaces);
 	iter = mailbox_list_iter_init(mail_storage_get_list(source_storage),
 				      "*", MAILBOX_LIST_ITER_RETURN_NO_FLAGS);
 	while ((info = mailbox_list_iter_next(iter)) != NULL) {
 		T_FRAME(
 			ret = mailbox_convert_list_item(source_storage,
-							dest_storage,
+							dest_ns->storage,
 							info, dotlock, set);
 		);
 		if (ret < 0)
@@ -332,22 +345,26 @@ static int mailbox_list_copy(struct mail
 	return ret;
 }
 
-static int mailbox_list_copy_subscriptions(struct mail_storage *source_storage,
-					   struct mail_storage *dest_storage,
-					   const struct convert_settings *set)
+static int
+mailbox_list_copy_subscriptions(struct mail_storage *source_storage,
+				struct mail_namespace *dest_namespaces,
+				const struct convert_settings *set)
 {
 	struct mailbox_list_iterate_context *iter;
+	struct mail_namespace *dest_ns;
 	const struct mailbox_info *info;
 	struct mailbox_list *dest_list;
 	const char *dest_name;
 	int ret = 0;
 
-	dest_list = mail_storage_get_list(dest_storage);
+	dest_ns = mail_namespace_find_inbox(dest_namespaces);
+	dest_list = mail_storage_get_list(dest_ns->storage);
 	iter = mailbox_list_iter_init(mail_storage_get_list(source_storage),
 				      "*", MAILBOX_LIST_ITER_SELECT_SUBSCRIBED |
 				      MAILBOX_LIST_ITER_RETURN_NO_FLAGS);
 	while ((info = mailbox_list_iter_next(iter)) != NULL) {
-		dest_name = mailbox_name_convert(dest_storage, source_storage,
+		dest_name = mailbox_name_convert(dest_ns->storage,
+						 source_storage,
 						 set, info->name);
 		if (mailbox_list_set_subscribed(dest_list, dest_name,
 						TRUE) < 0) {
@@ -360,37 +377,27 @@ static int mailbox_list_copy_subscriptio
 	return ret;
 }
 
-int convert_storage(const char *source_data, const char *dest_data,
+int convert_storage(const char *source_data,
+		    struct mail_namespace *dest_namespaces,
 		    const struct convert_settings *set)
 {
-	struct mail_namespace *source_ns, *dest_ns;
+	struct mail_namespace *source_ns, *dest_inbox_ns;
 	struct dotlock *dotlock;
-        enum mail_storage_flags src_flags, dest_flags;
+        enum mail_storage_flags src_flags;
         enum file_lock_method lock_method;
 	const char *path, *error;
 	int ret;
 
 	source_ns = mail_namespaces_init_empty(pool_datastack_create());
-	mail_storage_parse_env(&src_flags, &lock_method);
-	dest_flags = src_flags;
+	dest_inbox_ns = mail_namespace_find_inbox(dest_namespaces);
+	src_flags = dest_inbox_ns->storage->flags;
+	lock_method = dest_inbox_ns->storage->lock_method;
 
 	src_flags |= MAIL_STORAGE_FLAG_NO_AUTOCREATE;
 	if (mail_storage_create(source_ns, NULL, source_data, set->user,
 				src_flags, lock_method, &error) < 0) {
 		/* No need for conversion. */
 		return 0;
-	}
-
-	/* If home directory doesn't exist, creating the destination storage
-	   will most likely create it. So do this before locking. */
-	dest_ns = mail_namespaces_init_empty(pool_datastack_create());
-	if (mail_storage_create(dest_ns, NULL, dest_data, set->user,
-				dest_flags, lock_method, &error) < 0) {
-		i_error("Mailbox conversion: Failed to create destination "
-			"mail storage with data '%s': %s", dest_data, error);
-		mail_namespaces_deinit(&dest_ns);
-		mail_namespaces_deinit(&source_ns);
-		return -1;
 	}
 
         path = t_strconcat(set->home, "/"CONVERT_LOCK_FILENAME, NULL);
@@ -419,11 +426,11 @@ int convert_storage(const char *source_d
 		return 0;
 	}
 
-	ret = mailbox_list_copy(source_ns->storage, dest_ns->storage,
+	ret = mailbox_list_copy(source_ns->storage, dest_namespaces,
 				dotlock, set);
 	if (ret == 0) {
 		ret = mailbox_list_copy_subscriptions(source_ns->storage,
-						      dest_ns->storage, set);
+						      dest_namespaces, set);
 	}
 
 	if (ret == 0) {
@@ -446,7 +453,6 @@ int convert_storage(const char *source_d
 	}
 
 	file_dotlock_delete(&dotlock);
-	mail_namespaces_deinit(&dest_ns);
 	mail_namespaces_deinit(&source_ns);
 	return ret;
 }
diff -r f2c37fe48668 -r 7cedc391e6c5 src/plugins/convert/convert-storage.h
--- a/src/plugins/convert/convert-storage.h	Sun Dec 09 15:01:14 2007 +0200
+++ b/src/plugins/convert/convert-storage.h	Sun Dec 09 15:47:03 2007 +0200
@@ -1,5 +1,7 @@
 #ifndef CONVERT_STORAGE_H
 #define CONVERT_STORAGE_H
+
+struct mail_namespace;


More information about the dovecot-cvs mailing list