changeset 4860:87ae4d41bc10 HEAD

Create storages with MAIL_STORAGE_FLAG_NO_AUTOCREATE flag so we don't keep recreating the old storage and converting it all the time. Also added convert_skip_broken_mailboxes flag.
author Timo Sirainen <tss@iki.fi>
date Sun, 03 Dec 2006 15:35:18 +0200
parents 92c0994a1fcf
children a688269c0dd4
files dovecot-example.conf src/plugins/convert/convert-plugin.c src/plugins/convert/convert-storage.c src/plugins/convert/convert-storage.h src/plugins/convert/convert-tool.c
diffstat 5 files changed, 43 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/dovecot-example.conf	Sun Dec 03 15:29:56 2006 +0200
+++ b/dovecot-example.conf	Sun Dec 03 15:35:18 2006 +0200
@@ -1023,8 +1023,11 @@
   #acl = vfile:/etc/dovecot-acls
 
   # Convert plugin. If set, specifies the source storage path which is
-  # converted to destination storage (mail_location).
+  # converted to destination storage (mail_location) when the user logs in.
+  # The existing mail directory is renamed to <dir>-converted.
   #convert_mail = mbox:%h/mail
+  # Skip mailboxes which we can't open successfully instead of aborting.
+  #convert_skip_broken_mailboxes = no
 
   # Trash plugin. When saving a message would make user go over quota, this
   # plugin automatically deletes the oldest mails from configured mailboxes
--- a/src/plugins/convert/convert-plugin.c	Sun Dec 03 15:29:56 2006 +0200
+++ b/src/plugins/convert/convert-plugin.c	Sun Dec 03 15:35:18 2006 +0200
@@ -9,11 +9,14 @@
 void convert_plugin_init(void)
 {
 	const char *convert_mail, *mail, *home, *user;
+	bool skip_broken_mailboxes;
 
 	convert_mail = getenv("CONVERT_MAIL");
 	if (convert_mail == NULL)
 		return;
 
+	skip_broken_mailboxes = getenv("CONVERT_SKIP_BROKEN_MAILBOXES") != NULL;
+
 	mail = getenv("MAIL");
 	if (mail == NULL)
 		i_fatal("convert plugin: MAIL unset");
@@ -24,7 +27,8 @@
 	if (mail == NULL)
 		i_fatal("convert plugin: HOME unset");
 
-	if (convert_storage(user, home, convert_mail, mail) < 0)
+	if (convert_storage(user, home, convert_mail, mail,
+			    skip_broken_mailboxes) < 0)
 		exit(FATAL_DEFAULT);
 }
 
--- a/src/plugins/convert/convert-storage.c	Sun Dec 03 15:29:56 2006 +0200
+++ b/src/plugins/convert/convert-storage.c	Sun Dec 03 15:35:18 2006 +0200
@@ -100,7 +100,8 @@
 static int mailbox_convert_list_item(struct mail_storage *source_storage,
 				     struct mail_storage *dest_storage,
 				     struct mailbox_info *info,
-				     struct dotlock *dotlock)
+				     struct dotlock *dotlock,
+				     bool skip_broken_mailboxes)
 {
 	const char *name;
 	struct mailbox *srcbox, *destbox;
@@ -111,6 +112,7 @@
 
 	name = strcasecmp(info->name, "INBOX") == 0 ? "INBOX" : info->name;
 	if ((info->flags & MAILBOX_NOSELECT) != 0) {
+		/* \NoSelect mailbox, so it's probably a "directory" */
 		if (mail_storage_mailbox_create(dest_storage, name, TRUE) < 0) {
 			i_error("Mailbox conversion: Couldn't create mailbox "
 				"directory %s", name);
@@ -119,18 +121,23 @@
 		return 0;
 	}
 
-	/* It's a real mailbox. First create the destination mailbox. */
-	if (mail_storage_mailbox_create(dest_storage, name, FALSE) < 0) {
-		i_error("Mailbox conversion: Couldn't create mailbox %s", name);
+	/* First open the source mailbox. If we can't open it, don't create
+	   the destination mailbox either. */
+	srcbox = mailbox_open(source_storage, name, NULL,
+			      MAILBOX_OPEN_READONLY | MAILBOX_OPEN_KEEP_RECENT);
+	if (srcbox == NULL) {
+		if (skip_broken_mailboxes)
+			return 0;
+
+		i_error("Mailbox conversion: Couldn't open source mailbox %s",
+			name);
 		return -1;
 	}
 
-	/* Open both the mailboxes.. */
-	srcbox = mailbox_open(source_storage, name, NULL,
-			   MAILBOX_OPEN_READONLY | MAILBOX_OPEN_KEEP_RECENT);
-	if (srcbox == NULL) {
-		i_error("Mailbox conversion: Couldn't open source mailbox %s",
-			name);
+	/* Create and open the destination mailbox. */
+	if (mail_storage_mailbox_create(dest_storage, name, FALSE) < 0) {
+		i_error("Mailbox conversion: Couldn't create mailbox %s", name);
+		mailbox_close(&srcbox);
 		return -1;
 	}
 
@@ -155,7 +162,8 @@
 
 static int mailbox_list_copy(struct mail_storage *source_storage,
 			     struct mail_storage *dest_storage,
-			     struct dotlock *dotlock)
+			     struct dotlock *dotlock,
+			     bool skip_broken_mailboxes)
 {
 	struct mailbox_list_iterate_context *iter;
 	struct mailbox_info *info;
@@ -165,7 +173,8 @@
 				      "*", MAILBOX_LIST_ITER_FAST_FLAGS);
 	while ((info = mailbox_list_iter_next(iter)) != NULL) {
 		if (mailbox_convert_list_item(source_storage, dest_storage,
-					      info, dotlock) < 0) {
+					      info, dotlock,
+					      skip_broken_mailboxes) < 0) {
 			ret = -1;
 			break;
 		}
@@ -204,7 +213,8 @@
 }
 
 int convert_storage(const char *user, const char *home_dir,
-		    const char *source_data, const char *dest_data)
+		    const char *source_data, const char *dest_data,
+		    bool skip_broken_mailboxes)
 {
 	struct mail_storage *source_storage, *dest_storage;
 	struct dotlock *dotlock;
@@ -214,6 +224,7 @@
 	int ret;
 
 	mail_storage_parse_env(&flags, &lock_method);
+	flags |= MAIL_STORAGE_FLAG_NO_AUTOCREATE;
 	source_storage = mail_storage_create_with_data(source_data, user,
 						       flags, lock_method);
 	if (source_storage == NULL) {
@@ -247,7 +258,8 @@
 			"storage with data: %s", dest_data);
 		ret = -1;
 	} else {
-		ret = mailbox_list_copy(source_storage, dest_storage, dotlock);
+		ret = mailbox_list_copy(source_storage, dest_storage, dotlock,
+					skip_broken_mailboxes);
 		if (ret == 0) {
 			ret = mailbox_list_copy_subscriptions(source_storage,
 							      dest_storage);
--- a/src/plugins/convert/convert-storage.h	Sun Dec 03 15:29:56 2006 +0200
+++ b/src/plugins/convert/convert-storage.h	Sun Dec 03 15:35:18 2006 +0200
@@ -2,6 +2,7 @@
 #define __CONVERT_STORAGE_H
 
 int convert_storage(const char *user, const char *home_dir,
-		    const char *source_data, const char *dest_data);
+		    const char *source_data, const char *dest_data,
+		    bool skip_broken_mailboxes);
 
 #endif
--- a/src/plugins/convert/convert-tool.c	Sun Dec 03 15:29:56 2006 +0200
+++ b/src/plugins/convert/convert-tool.c	Sun Dec 03 15:35:18 2006 +0200
@@ -7,6 +7,8 @@
 #include "mail-storage.h"
 #include "convert-storage.h"
 
+#include <stdlib.h>
+
 int main(int argc, const char *argv[])
 {
 	struct ioloop *ioloop;
@@ -20,12 +22,14 @@
 
 	if (argc <= 4) {
 		i_fatal("Usage: <username> <home dir> "
-			"<source mail env> <dest mail env>");
+			"<source mail env> <dest mail env> "
+			"[<1=skip broken mailboxes>]");
 	}
 
 	ioloop = io_loop_create(system_pool);
 
-	ret = convert_storage(argv[1], argv[2], argv[3], argv[4]);
+	ret = convert_storage(argv[1], argv[2], argv[3], argv[4],
+			      argv[5] != NULL && atoi(argv[5]) == 1);
 	if (ret > 0)
 		i_info("Successfully converted");
 	else if (ret == 0)