Mercurial > dovecot > original-hg > dovecot-1.2
changeset 6976:7cedc391e6c5 HEAD
Convert only after namespaces are created. Convert mailboxes to INBOX
namespace.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 09 Dec 2007 15:47:03 +0200 |
parents | f2c37fe48668 |
children | 038467bffcbd |
files | 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 | 4 files changed, 88 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- 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,19 +9,19 @@ 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"); if (set.user == NULL) @@ -29,16 +30,26 @@ 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; }
--- 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 @@ 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 @@ struct mail_search_arg search_arg; int ret = 0; - if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ, 0, NULL) < 0) + 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 @@ 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) + 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,16 +99,10 @@ mailbox_transaction_rollback(&src_trans); else (void)mailbox_transaction_commit(&src_trans); + i_assert(ret == 0 || *error_r != NULL); return ret; } -static const char *storage_error(struct mail_storage *storage) -{ - enum mail_error error; - - return mail_storage_get_last_error(storage, &error); -} - static const char * mailbox_name_convert(struct mail_storage *dest_storage, struct mail_storage *source_storage, @@ -221,7 +232,7 @@ 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 @@ 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_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 @@ 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,19 +377,21 @@ 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, @@ -381,18 +400,6 @@ 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); dotlock_settings.use_excl_lock = (source_ns->storage->flags & @@ -419,11 +426,11 @@ 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 @@ } file_dotlock_delete(&dotlock); - mail_namespaces_deinit(&dest_ns); mail_namespaces_deinit(&source_ns); return ret; }
--- 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,6 +1,8 @@ #ifndef CONVERT_STORAGE_H #define CONVERT_STORAGE_H +struct mail_namespace; + struct convert_settings { const char *user; const char *home; @@ -9,7 +11,8 @@ char alt_hierarchy_char; }; -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); #endif
--- a/src/plugins/convert/convert-tool.c Sun Dec 09 15:01:14 2007 +0200 +++ b/src/plugins/convert/convert-tool.c Sun Dec 09 15:47:03 2007 +0200 @@ -4,7 +4,8 @@ #include "ioloop.h" #include "randgen.h" #include "lib-signals.h" -#include "mail-storage.h" +#include "mail-namespace.h" +#include "mail-storage-private.h" #include "convert-storage.h" #include <stdlib.h> @@ -17,6 +18,10 @@ { struct ioloop *ioloop; struct convert_settings set; + struct mail_namespace *dest_ns; + enum mail_storage_flags dest_flags; + enum file_lock_method lock_method; + const char *error; int i, ret = 0; lib_init(); @@ -44,13 +49,22 @@ set.alt_hierarchy_char = argv[i][19]; } - ret = convert_storage(argv[3], argv[4], &set); + mail_storage_parse_env(&dest_flags, &lock_method); + dest_ns = mail_namespaces_init_empty(pool_datastack_create()); + if (mail_storage_create(dest_ns, NULL, argv[4], set.user, + dest_flags, lock_method, &error) < 0) { + i_fatal("Failed to create destination " + "mail storage with data '%s': %s", argv[4], error); + } + + ret = convert_storage(argv[3], dest_ns, &set); if (ret > 0) i_info("Successfully converted"); else if (ret == 0) i_error("Source storage not found"); else i_error("Internal failure"); + mail_namespaces_deinit(&dest_ns); io_loop_destroy(&ioloop); mail_storage_deinit();