From f23baa3b53b1dd4eb19729e99a43937fa3c7f309 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 28 Apr 2010 23:40:13 +0300 Subject: [PATCH] doveadm: Removed more code duplication from altmove/fetch commands. --HG-- branch : HEAD --- src/doveadm/Makefile.am | 2 + src/doveadm/doveadm-mail-altmove.c | 54 +++++------------- src/doveadm/doveadm-mail-fetch.c | 74 +++++++++++-------------- src/doveadm/doveadm-mail-iter.c | 89 ++++++++++++++++++++++++++++++ src/doveadm/doveadm-mail-iter.h | 15 +++++ 5 files changed, 151 insertions(+), 83 deletions(-) create mode 100644 src/doveadm/doveadm-mail-iter.c create mode 100644 src/doveadm/doveadm-mail-iter.h diff --git a/src/doveadm/Makefile.am b/src/doveadm/Makefile.am index 1ae592d579..c6e5bd6450 100644 --- a/src/doveadm/Makefile.am +++ b/src/doveadm/Makefile.am @@ -54,6 +54,7 @@ doveadm_SOURCES = \ doveadm-mail.c \ doveadm-mail-altmove.c \ doveadm-mail-fetch.c \ + doveadm-mail-iter.c \ doveadm-mail-list.c \ doveadm-mail-list-iter.c \ doveadm-penalty.c \ @@ -65,6 +66,7 @@ noinst_HEADERS = \ doveadm.h \ doveadm-dump.h \ doveadm-mail.h \ + doveadm-mail-iter.h \ doveadm-mail-list-iter.h \ doveadm-settings.h \ doveadm-who.h diff --git a/src/doveadm/doveadm-mail-altmove.c b/src/doveadm/doveadm-mail-altmove.c index 931d0da81f..8d1ce0b862 100644 --- a/src/doveadm/doveadm-mail-altmove.c +++ b/src/doveadm/doveadm-mail-altmove.c @@ -5,49 +5,32 @@ #include "mail-index.h" #include "mail-storage.h" #include "mail-namespace.h" -#include "mail-search.h" #include "doveadm-mail-list-iter.h" +#include "doveadm-mail-iter.h" #include "doveadm-mail.h" static int -cmd_altmove_box(struct mailbox *box, struct mail_search_args *search_args) +cmd_altmove_box(const struct mailbox_info *info, + struct mail_search_args *search_args) { - struct mail_storage *storage; - struct mailbox_transaction_context *t; - struct mail_search_context *search_ctx; + struct doveadm_mail_iter *iter; + struct mailbox_transaction_context *trans; struct mail *mail; - const char *box_name; - int ret = 0; - box_name = mailbox_get_vname(box); - storage = mailbox_get_storage(box); - if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) { - i_error("Syncing mailbox %s failed: %s", box_name, - mail_storage_get_last_error(storage, NULL)); + if (doveadm_mail_iter_init(info, search_args, &trans, &iter) < 0) return -1; - } - t = mailbox_transaction_begin(box, 0); - search_ctx = mailbox_search_init(t, search_args, NULL); - mail = mail_alloc(t, 0, NULL); - while (mailbox_search_next(search_ctx, mail)) { - if (doveadm_debug) - i_debug("altmove: box=%s uid=%u", box_name, mail->uid); + mail = mail_alloc(trans, 0, NULL); + while (doveadm_mail_iter_next(iter, mail)) { + if (doveadm_debug) { + i_debug("altmove: box=%s uid=%u", + info->name, mail->uid); + } mail_update_flags(mail, MODIFY_ADD, MAIL_INDEX_MAIL_FLAG_BACKEND); } mail_free(&mail); - if (mailbox_search_deinit(&search_ctx) < 0) { - i_error("Searching mailbox %s failed: %s", box_name, - mail_storage_get_last_error(storage, NULL)); - ret = -1; - } - if (mailbox_transaction_commit(&t) < 0) { - i_error("Commiting mailbox %s failed: %s", box_name, - mail_storage_get_last_error(storage, NULL)); - ret = -1; - } - return ret; + return doveadm_mail_iter_deinit(&iter); } static void ns_purge(struct mail_namespace *ns) @@ -69,9 +52,7 @@ void cmd_altmove(struct mail_user *user, const char *const args[]) struct doveadm_mail_list_iter *iter; const struct mailbox_info *info; struct mail_namespace *ns, *prev_ns = NULL; - struct mailbox *box; ARRAY_DEFINE(purged_storages, struct mail_storage *); - const char *storage_name; struct mail_storage *const *storages; unsigned int i, count; @@ -90,14 +71,7 @@ void cmd_altmove(struct mail_user *user, const char *const args[]) } prev_ns = info->ns; } - - storage_name = mail_namespace_get_storage_name(info->ns, - info->name); - box = mailbox_alloc(info->ns->list, storage_name, - MAILBOX_FLAG_KEEP_RECENT | - MAILBOX_FLAG_IGNORE_ACLS); - (void)cmd_altmove_box(box, search_args); - mailbox_free(&box); + (void)cmd_altmove_box(info, search_args); } T_END; doveadm_mail_list_iter_deinit(&iter); diff --git a/src/doveadm/doveadm-mail-fetch.c b/src/doveadm/doveadm-mail-fetch.c index f77f0dc36e..e01630e9da 100644 --- a/src/doveadm/doveadm-mail-fetch.c +++ b/src/doveadm/doveadm-mail-fetch.c @@ -9,11 +9,10 @@ #include "str.h" #include "message-size.h" #include "imap-util.h" -#include "mail-namespace.h" #include "mail-storage.h" -#include "mail-search.h" #include "doveadm-mail.h" #include "doveadm-mail-list-iter.h" +#include "doveadm-mail-iter.h" #include @@ -266,50 +265,47 @@ static void parse_fetch_fields(struct fetch_context *ctx, const char *str) } } -static void -cmd_fetch_box(struct fetch_context *ctx, struct mailbox *box) +static void cmd_fetch_mail(struct fetch_context *ctx) { - struct mail_storage *storage = mailbox_get_storage(box); - struct mailbox_transaction_context *t; - struct mail_search_context *search_ctx; - struct mail *mail; const struct fetch_field *field; + struct mail *mail = ctx->mail; + + array_foreach(&ctx->fields, field) { + str_printfa(ctx->hdr, "%s: ", field->name); + if (field->print(ctx) < 0) { + struct mail_storage *storage = + mailbox_get_storage(mail->box); - if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) { - i_error("Syncing mailbox %s failed: %s", mailbox_get_vname(box), - mail_storage_get_last_error(storage, NULL)); - return; + i_error("fetch(%s) failed for box=%s uid=%u: %s", + field->name, mailbox_get_vname(mail->box), + mail->uid, mail_storage_get_last_error(storage, NULL)); + } + str_append_c(ctx->hdr, '\n'); } + flush_hdr(ctx); +} - mail_search_args_init(ctx->search_args, box, FALSE, NULL); - t = mailbox_transaction_begin(box, 0); - search_ctx = mailbox_search_init(t, ctx->search_args, NULL); - mail = mail_alloc(t, ctx->wanted_fields, NULL); - while (mailbox_search_next(search_ctx, mail)) { +static int +cmd_fetch_box(struct fetch_context *ctx, const struct mailbox_info *info) +{ + struct doveadm_mail_iter *iter; + struct mailbox_transaction_context *trans; + struct mail *mail; + + if (doveadm_mail_iter_init(info, ctx->search_args, &trans, &iter) < 0) + return -1; + + mail = mail_alloc(trans, ctx->wanted_fields, NULL); + while (doveadm_mail_iter_next(iter, mail)) { str_truncate(ctx->hdr, 0); str_append(ctx->hdr, ctx->prefix); ctx->mail = mail; - array_foreach(&ctx->fields, field) { - str_printfa(ctx->hdr, "%s: ", field->name); - if (field->print(ctx) < 0) { - i_error("fetch(%s) failed for box=%s uid=%u: %s", - field->name, mailbox_get_vname(box), - mail->uid, mail_storage_get_last_error(storage, NULL)); - } - str_append_c(ctx->hdr, '\n'); - } - flush_hdr(ctx); - + cmd_fetch_mail(ctx); ctx->mail = NULL; } mail_free(&mail); - if (mailbox_search_deinit(&search_ctx) < 0) { - i_error("Search failed: %s", - mail_storage_get_last_error(storage, NULL)); - } - mail_search_args_deinit(ctx->search_args); - (void)mailbox_transaction_commit(&t); + return doveadm_mail_iter_deinit(&iter); } void cmd_fetch(struct mail_user *user, const char *const args[]) @@ -322,8 +318,6 @@ void cmd_fetch(struct mail_user *user, const char *const args[]) struct fetch_context ctx; struct doveadm_mail_list_iter *iter; const struct mailbox_info *info; - struct mailbox *box; - const char *storage_name; unsigned char prefix_buf[9]; memset(&ctx, 0, sizeof(ctx)); @@ -344,13 +338,7 @@ void cmd_fetch(struct mail_user *user, const char *const args[]) iter = doveadm_mail_list_iter_init(user, ctx.search_args, iter_flags); while ((info = doveadm_mail_list_iter_next(iter)) != NULL) T_BEGIN { - storage_name = mail_namespace_get_storage_name(info->ns, - info->name); - box = mailbox_alloc(info->ns->list, storage_name, - MAILBOX_FLAG_KEEP_RECENT | - MAILBOX_FLAG_IGNORE_ACLS); - (void)cmd_fetch_box(&ctx, box); - mailbox_free(&box); + (void)cmd_fetch_box(&ctx, info); } T_END; doveadm_mail_list_iter_deinit(&iter); o_stream_unref(&ctx.output); diff --git a/src/doveadm/doveadm-mail-iter.c b/src/doveadm/doveadm-mail-iter.c new file mode 100644 index 0000000000..f57433fb46 --- /dev/null +++ b/src/doveadm/doveadm-mail-iter.c @@ -0,0 +1,89 @@ +/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "mail-storage.h" +#include "mail-namespace.h" +#include "mail-search.h" +#include "doveadm-mail-iter.h" + +struct doveadm_mail_iter { + struct mail_search_args *search_args; + + struct mailbox *box; + struct mail_storage *storage; + struct mailbox_transaction_context *t; + struct mail_search_context *search_ctx; +}; + +int doveadm_mail_iter_init(const struct mailbox_info *info, + struct mail_search_args *search_args, + struct mailbox_transaction_context **trans_r, + struct doveadm_mail_iter **iter_r) +{ + struct doveadm_mail_iter *iter; + const char *storage_name; + + storage_name = mail_namespace_get_storage_name(info->ns, info->name); + + iter = i_new(struct doveadm_mail_iter, 1); + iter->box = mailbox_alloc(info->ns->list, storage_name, + MAILBOX_FLAG_KEEP_RECENT | + MAILBOX_FLAG_IGNORE_ACLS); + iter->storage = mailbox_get_storage(iter->box); + iter->search_args = search_args; + + if (mailbox_sync(iter->box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) { + i_error("Syncing mailbox %s failed: %s", info->name, + mail_storage_get_last_error(iter->storage, NULL)); + mailbox_free(&iter->box); + i_free(iter); + return -1; + } + + mail_search_args_init(search_args, iter->box, FALSE, NULL); + iter->t = mailbox_transaction_begin(iter->box, 0); + iter->search_ctx = mailbox_search_init(iter->t, search_args, NULL); + + *trans_r = iter->t; + *iter_r = iter; + return 0; +} + +static int +doveadm_mail_iter_deinit_transaction(struct doveadm_mail_iter *iter) +{ + int ret = 0; + + if (mailbox_search_deinit(&iter->search_ctx) < 0) { + i_error("Searching mailbox %s failed: %s", + mailbox_get_vname(iter->box), + mail_storage_get_last_error(iter->storage, NULL)); + ret = -1; + } + if (mailbox_transaction_commit(&iter->t) < 0) { + i_error("Commiting mailbox %s failed: %s", + mailbox_get_vname(iter->box), + mail_storage_get_last_error(iter->storage, NULL)); + ret = -1; + } + mail_search_args_deinit(iter->search_args); + return ret; +} + +int doveadm_mail_iter_deinit(struct doveadm_mail_iter **_iter) +{ + struct doveadm_mail_iter *iter = *_iter; + int ret; + + *_iter = NULL; + + ret = doveadm_mail_iter_deinit_transaction(iter); + mailbox_free(&iter->box); + i_free(iter); + return ret; +} + +bool doveadm_mail_iter_next(struct doveadm_mail_iter *iter, struct mail *mail) +{ + return mailbox_search_next(iter->search_ctx, mail); +} diff --git a/src/doveadm/doveadm-mail-iter.h b/src/doveadm/doveadm-mail-iter.h new file mode 100644 index 0000000000..98fa3c0acd --- /dev/null +++ b/src/doveadm/doveadm-mail-iter.h @@ -0,0 +1,15 @@ +#ifndef DOVEADM_MAIL_ITER_H +#define DOVEADM_MAIL_ITER_H + +struct doveadm_mail_iter; + +int doveadm_mail_iter_init(const struct mailbox_info *info, + struct mail_search_args *search_args, + struct mailbox_transaction_context **trans_r, + struct doveadm_mail_iter **iter_r); +int doveadm_mail_iter_deinit(struct doveadm_mail_iter **iter); + +bool doveadm_mail_iter_next(struct doveadm_mail_iter *iter, struct mail *mail); + +#endif + -- 2.47.3