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