dovecot-2.0: doveadm fetch: Added support for fetching mails fro...

dovecot at dovecot.org dovecot at dovecot.org
Wed Apr 28 22:26:20 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/dab4fb9f8140
changeset: 11205:dab4fb9f8140
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Apr 28 22:26:15 2010 +0300
description:
doveadm fetch: Added support for fetching mails from multiple mailboxes.

diffstat:

 src/doveadm/doveadm-mail-fetch.c |  101 +++++++++++++++++++++++----------
 src/doveadm/doveadm-mail.c       |    2 +-
 2 files changed, 71 insertions(+), 32 deletions(-)

diffs (158 lines):

diff -r f986a5b1f500 -r dab4fb9f8140 src/doveadm/doveadm-mail-fetch.c
--- a/src/doveadm/doveadm-mail-fetch.c	Wed Apr 28 22:25:33 2010 +0300
+++ b/src/doveadm/doveadm-mail-fetch.c	Wed Apr 28 22:26:15 2010 +0300
@@ -6,10 +6,20 @@
 #include "base64.h"
 #include "randgen.h"
 #include "str.h"
+#include "mail-namespace.h"
 #include "mail-storage.h"
 #include "mail-search-build.h"
 #include "mail-search-parser.h"
 #include "doveadm-mail.h"
+#include "doveadm-mail-list-iter.h"
+
+struct fetch_context {
+	struct mail_search_args *search_args;
+	struct ostream *output;
+
+	string_t *prefix;
+	unsigned int prefix_len;
+};
 
 static struct mail_search_args *build_search_args(const char *const args[])
 {
@@ -25,38 +35,24 @@
 	return sargs;
 }
 
-void cmd_fetch(struct mail_user *user, const char *const args[])
+static void
+cmd_fetch_box(struct fetch_context *ctx, struct mailbox *box)
 {
-	const char *mailbox = args[0];
-	struct mail_storage *storage;
-	struct mailbox *box;
-	struct mail_search_args *search_args;
+	struct mail_storage *storage = mailbox_get_storage(box);
 	struct mailbox_transaction_context *t;
 	struct mail_search_context *search_ctx;
 	struct mail *mail;
 	struct istream *input;
-	struct ostream *output;
-	string_t *prefix;
-	unsigned char prefix_buf[9];
-	unsigned int prefix_len;
 
-	if (mailbox == NULL || args[1] == NULL)
-		doveadm_mail_help_name("fetch");
-	search_args = build_search_args(args+1);
+	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;
+	}
 
-	random_fill_weak(prefix_buf, sizeof(prefix_buf));
-	prefix = t_str_new(32);
-	str_append(prefix, "===");
-	base64_encode(prefix_buf, sizeof(prefix_buf), prefix);
-	str_append_c(prefix, ' ');
-	prefix_len = str_len(prefix);
-
-	output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE);
-	box = doveadm_mailbox_find_and_sync(user, mailbox);
-	storage = mailbox_get_storage(box);
-
+	mail_search_args_init(ctx->search_args, box, FALSE, NULL);
 	t = mailbox_transaction_begin(box, 0);
-	search_ctx = mailbox_search_init(t, search_args, NULL);
+	search_ctx = mailbox_search_init(t, ctx->search_args, NULL);
 	mail = mail_alloc(t, 0, NULL);
 	while (mailbox_search_next(search_ctx, mail)) {
 		if (mail_get_stream(mail, NULL, NULL, &input) < 0) {
@@ -65,22 +61,65 @@
 			continue;
 		}
 
-		str_truncate(prefix, prefix_len);
-		str_printfa(prefix, "seq=%u uid=%u\n", mail->seq, mail->uid);
-		if (o_stream_send(output, str_data(prefix), str_len(prefix)) < 0)
+		str_truncate(ctx->prefix, ctx->prefix_len);
+		str_printfa(ctx->prefix, "seq=%u uid=%u\n",
+			    mail->seq, mail->uid);
+		if (o_stream_send(ctx->output, str_data(ctx->prefix),
+				  str_len(ctx->prefix)) < 0)
 			i_fatal("write(stdout) failed: %m");
 
 		while (!i_stream_is_eof(input)) {
-			if (o_stream_send_istream(output, input) <= 0)
+			if (o_stream_send_istream(ctx->output, input) <= 0)
 				i_fatal("write(stdout) failed: %m");
 		}
 	}
 	mail_free(&mail);
 	if (mailbox_search_deinit(&search_ctx) < 0) {
-		i_fatal("Search failed: %s",
+		i_error("Search failed: %s",
 			mail_storage_get_last_error(storage, NULL));
 	}
+	mail_search_args_deinit(ctx->search_args);
 	(void)mailbox_transaction_commit(&t);
-	mailbox_free(&box);
-	o_stream_unref(&output);
 }
+
+void cmd_fetch(struct mail_user *user, const char *const args[])
+{
+	const enum mailbox_list_iter_flags iter_flags =
+		MAILBOX_LIST_ITER_VIRTUAL_NAMES |
+		MAILBOX_LIST_ITER_NO_AUTO_INBOX |
+		MAILBOX_LIST_ITER_RETURN_NO_FLAGS;
+	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));
+	ctx.output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE);
+
+	random_fill_weak(prefix_buf, sizeof(prefix_buf));
+	ctx.prefix = str_new(default_pool, 512);
+	str_append(ctx.prefix, "===");
+	base64_encode(prefix_buf, sizeof(prefix_buf), ctx.prefix);
+	str_append_c(ctx.prefix, ' ');
+	ctx.prefix_len = str_len(ctx.prefix);
+
+	if (args[0] == NULL)
+		doveadm_mail_help_name("fetch");
+	ctx.search_args = build_search_args(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);
+	} T_END;
+	doveadm_mail_list_iter_deinit(&iter);
+	o_stream_unref(&ctx.output);
+	str_free(&ctx.prefix);
+}
diff -r f986a5b1f500 -r dab4fb9f8140 src/doveadm/doveadm-mail.c
--- a/src/doveadm/doveadm-mail.c	Wed Apr 28 22:25:33 2010 +0300
+++ b/src/doveadm/doveadm-mail.c	Wed Apr 28 22:26:15 2010 +0300
@@ -312,7 +312,7 @@
 static struct doveadm_mail_cmd mail_commands[] = {
 	{ cmd_purge, "purge", NULL },
 	{ cmd_force_resync, "force-resync", "<mailbox>" },
-	{ cmd_fetch, "fetch", "<mailbox> <search query>" },
+	{ cmd_fetch, "fetch", "<search query>" },
 	{ cmd_altmove, "altmove", "<search query>" },
 	{ cmd_list, "list", "[<mailbox> [...]]" }
 };


More information about the dovecot-cvs mailing list