dovecot-2.1: doveadm: Added "copy" command.

dovecot at dovecot.org dovecot at dovecot.org
Thu Aug 23 21:29:54 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/9d35aca14c81
changeset: 14678:9d35aca14c81
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Aug 23 21:29:40 2012 +0300
description:
doveadm: Added "copy" command.

diffstat:

 src/doveadm/Makefile.am             |    2 +-
 src/doveadm/doveadm-mail-copymove.c |  159 ++++++++++++++++++++++++++++++++++++
 src/doveadm/doveadm-mail-move.c     |  144 --------------------------------
 src/doveadm/doveadm-mail.c          |    1 +
 src/doveadm/doveadm-mail.h          |    1 +
 5 files changed, 162 insertions(+), 145 deletions(-)

diffs (truncated from 345 to 300 lines):

diff -r 7bdbca7b0913 -r 9d35aca14c81 src/doveadm/Makefile.am
--- a/src/doveadm/Makefile.am	Thu Aug 23 11:56:56 2012 +0300
+++ b/src/doveadm/Makefile.am	Thu Aug 23 21:29:40 2012 +0300
@@ -74,7 +74,7 @@
 	doveadm-mail-iter.c \
 	doveadm-mail-mailbox.c \
 	doveadm-mail-mailbox-status.c \
-	doveadm-mail-move.c \
+	doveadm-mail-copymove.c \
 	doveadm-mailbox-list-iter.c \
 	doveadm-mail-search.c \
 	doveadm-mail-server.c \
diff -r 7bdbca7b0913 -r 9d35aca14c81 src/doveadm/doveadm-mail-copymove.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/doveadm/doveadm-mail-copymove.c	Thu Aug 23 21:29:40 2012 +0300
@@ -0,0 +1,159 @@
+/* Copyright (c) 2011-2012 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "mail-storage.h"
+#include "mail-namespace.h"
+#include "doveadm-print.h"
+#include "doveadm-mailbox-list-iter.h"
+#include "doveadm-mail-iter.h"
+#include "doveadm-mail.h"
+
+#include <stdio.h>
+
+struct copy_cmd_context {
+	struct doveadm_mail_cmd_context ctx;
+
+	const char *destname;
+	bool move;
+};
+
+static int
+cmd_copy_box(struct copy_cmd_context *ctx, struct mailbox *destbox,
+	     const struct mailbox_info *info)
+{
+	struct doveadm_mail_iter *iter;
+	struct mailbox_transaction_context *trans;
+	struct mailbox_transaction_context *desttrans;
+	struct mail_save_context *save_ctx;
+	struct mail *mail;
+	int ret = 0;
+
+	if (doveadm_mail_iter_init(&ctx->ctx, info, ctx->ctx.search_args, 0,
+				   NULL, &trans, &iter) < 0)
+		return -1;
+
+	/* use a separately committed transaction for each mailbox.
+	   this guarantees that mails aren't expunged without actually having
+	   been copied. */
+	desttrans = mailbox_transaction_begin(destbox,
+					MAILBOX_TRANSACTION_FLAG_EXTERNAL);
+
+	while (doveadm_mail_iter_next(iter, &mail)) {
+		save_ctx = mailbox_save_alloc(desttrans);
+		mailbox_save_copy_flags(save_ctx, mail);
+		if (mailbox_copy(&save_ctx, mail) == 0) {
+			if (ctx->move)
+				mail_expunge(mail);
+		} else {
+			i_error("Copying message UID %u from '%s' failed: %s",
+				mail->uid, info->name,
+				mailbox_get_last_error(destbox, NULL));
+			doveadm_mail_failed_mailbox(&ctx->ctx, destbox);
+			ret = -1;
+		}
+	}
+
+	if (mailbox_transaction_commit(&desttrans) < 0) {
+		i_error("Committing %s mails failed: %s",
+			ctx->move ? "moved" : "copied",
+			mailbox_get_last_error(destbox, NULL));
+		doveadm_mail_failed_mailbox(&ctx->ctx, destbox);
+		/* rollback expunges */
+		doveadm_mail_iter_deinit_rollback(&iter);
+		ret = -1;
+	} else {
+		if (doveadm_mail_iter_deinit_sync(&iter) < 0)
+			ret = -1;
+	}
+	return ret;
+}
+
+static int
+cmd_copy_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
+{
+	struct copy_cmd_context *ctx = (struct copy_cmd_context *)_ctx;
+	const enum mailbox_list_iter_flags iter_flags =
+		MAILBOX_LIST_ITER_RAW_LIST |
+		MAILBOX_LIST_ITER_NO_AUTO_BOXES |
+		MAILBOX_LIST_ITER_RETURN_NO_FLAGS;
+	struct doveadm_mailbox_list_iter *iter;
+	struct mail_namespace *ns;
+	struct mailbox *destbox;
+	const struct mailbox_info *info;
+	int ret = 0;
+
+	ns = mail_namespace_find(user->namespaces, ctx->destname);
+	if (ns == NULL) {
+		i_fatal_status(DOVEADM_EX_NOTFOUND,
+			       "Can't find namespace for: %s", ctx->destname);
+	}
+
+	destbox = mailbox_alloc(ns->list, ctx->destname, MAILBOX_FLAG_SAVEONLY);
+	if (mailbox_open(destbox) < 0) {
+		i_error("Can't open mailbox '%s': %s", ctx->destname,
+			mailbox_get_last_error(destbox, NULL));
+		doveadm_mail_failed_mailbox(&ctx->ctx, destbox);
+		mailbox_free(&destbox);
+		return -1;
+	}
+
+	iter = doveadm_mailbox_list_iter_init(_ctx, user, _ctx->search_args,
+					      iter_flags);
+	while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN {
+		if (cmd_copy_box(ctx, destbox, info) < 0)
+			ret = -1;
+	} T_END;
+	if (doveadm_mailbox_list_iter_deinit(&iter) < 0)
+		ret = -1;
+
+	if (mailbox_sync(destbox, 0) < 0) {
+		i_error("Syncing mailbox '%s' failed: %s", ctx->destname,
+			mailbox_get_last_error(destbox, NULL));
+		doveadm_mail_failed_mailbox(&ctx->ctx, destbox);
+		ret = -1;
+	}
+	mailbox_free(&destbox);
+	return ret;
+
+}
+
+static void cmd_copy_init(struct doveadm_mail_cmd_context *_ctx,
+			  const char *const args[])
+{
+	struct copy_cmd_context *ctx = (struct copy_cmd_context *)_ctx;
+	const char *destname = args[0], *cmdname = ctx->move ? "move" : "copy";
+
+	if (destname == NULL || args[1] == NULL)
+		doveadm_mail_help_name(cmdname);
+
+	ctx->destname = p_strdup(ctx->ctx.pool, destname);
+	ctx->ctx.search_args = doveadm_mail_build_search_args(args + 1);
+	expunge_search_args_check(ctx->ctx.search_args, cmdname);
+}
+
+static struct doveadm_mail_cmd_context *cmd_copy_alloc(void)
+{
+	struct copy_cmd_context *ctx;
+
+	ctx = doveadm_mail_cmd_alloc(struct copy_cmd_context);
+	ctx->ctx.v.init = cmd_copy_init;
+	ctx->ctx.v.run = cmd_copy_run;
+	doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW);
+	return &ctx->ctx;
+}
+
+static struct doveadm_mail_cmd_context *cmd_move_alloc(void)
+{
+	struct copy_cmd_context *ctx;
+
+	ctx = (struct copy_cmd_context *)cmd_copy_alloc();
+	ctx->move = TRUE;
+	return &ctx->ctx;
+}
+
+struct doveadm_mail_cmd cmd_copy = {
+	cmd_copy_alloc, "copy", "<destination> <search query>"
+};
+struct doveadm_mail_cmd cmd_move = {
+	cmd_move_alloc, "move", "<destination> <search query>"
+};
diff -r 7bdbca7b0913 -r 9d35aca14c81 src/doveadm/doveadm-mail-move.c
--- a/src/doveadm/doveadm-mail-move.c	Thu Aug 23 11:56:56 2012 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/* Copyright (c) 2011-2012 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "mail-storage.h"
-#include "mail-namespace.h"
-#include "doveadm-print.h"
-#include "doveadm-mailbox-list-iter.h"
-#include "doveadm-mail-iter.h"
-#include "doveadm-mail.h"
-
-#include <stdio.h>
-
-struct move_cmd_context {
-	struct doveadm_mail_cmd_context ctx;
-
-	const char *destname;
-};
-
-static int
-cmd_move_box(struct move_cmd_context *ctx, struct mailbox *destbox,
-	     const struct mailbox_info *info)
-{
-	struct doveadm_mail_iter *iter;
-	struct mailbox_transaction_context *trans;
-	struct mailbox_transaction_context *desttrans;
-	struct mail_save_context *save_ctx;
-	struct mail *mail;
-	int ret = 0;
-
-	if (doveadm_mail_iter_init(&ctx->ctx, info, ctx->ctx.search_args, 0,
-				   NULL, &trans, &iter) < 0)
-		return -1;
-
-	/* use a separately committed transaction for each mailbox.
-	   this guarantees that mails aren't expunged without actually having
-	   been copied. */
-	desttrans = mailbox_transaction_begin(destbox,
-					MAILBOX_TRANSACTION_FLAG_EXTERNAL);
-
-	while (doveadm_mail_iter_next(iter, &mail)) {
-		save_ctx = mailbox_save_alloc(desttrans);
-		mailbox_save_copy_flags(save_ctx, mail);
-		if (mailbox_copy(&save_ctx, mail) == 0)
-			mail_expunge(mail);
-		else {
-			i_error("Copying message UID %u from '%s' failed: %s",
-				mail->uid, info->name,
-				mailbox_get_last_error(destbox, NULL));
-			doveadm_mail_failed_mailbox(&ctx->ctx, destbox);
-			ret = -1;
-		}
-	}
-
-	if (mailbox_transaction_commit(&desttrans) < 0) {
-		i_error("Committing moved mails failed: %s",
-			mailbox_get_last_error(destbox, NULL));
-		doveadm_mail_failed_mailbox(&ctx->ctx, destbox);
-		/* rollback expunges */
-		doveadm_mail_iter_deinit_rollback(&iter);
-		ret = -1;
-	} else {
-		if (doveadm_mail_iter_deinit_sync(&iter) < 0)
-			ret = -1;
-	}
-	return ret;
-}
-
-static int
-cmd_move_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
-{
-	struct move_cmd_context *ctx = (struct move_cmd_context *)_ctx;
-	const enum mailbox_list_iter_flags iter_flags =
-		MAILBOX_LIST_ITER_RAW_LIST |
-		MAILBOX_LIST_ITER_NO_AUTO_BOXES |
-		MAILBOX_LIST_ITER_RETURN_NO_FLAGS;
-	struct doveadm_mailbox_list_iter *iter;
-	struct mail_namespace *ns;
-	struct mailbox *destbox;
-	const struct mailbox_info *info;
-	int ret = 0;
-
-	ns = mail_namespace_find(user->namespaces, ctx->destname);
-	if (ns == NULL) {
-		i_fatal_status(DOVEADM_EX_NOTFOUND,
-			       "Can't find namespace for: %s", ctx->destname);
-	}
-
-	destbox = mailbox_alloc(ns->list, ctx->destname, MAILBOX_FLAG_SAVEONLY);
-	if (mailbox_open(destbox) < 0) {
-		i_error("Can't open mailbox '%s': %s", ctx->destname,
-			mailbox_get_last_error(destbox, NULL));
-		doveadm_mail_failed_mailbox(&ctx->ctx, destbox);
-		mailbox_free(&destbox);
-		return -1;
-	}
-
-	iter = doveadm_mailbox_list_iter_init(_ctx, user, _ctx->search_args,
-					      iter_flags);
-	while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN {
-		if (cmd_move_box(ctx, destbox, info) < 0)
-			ret = -1;
-	} T_END;
-	if (doveadm_mailbox_list_iter_deinit(&iter) < 0)
-		ret = -1;
-
-	if (mailbox_sync(destbox, 0) < 0) {
-		i_error("Syncing mailbox '%s' failed: %s", ctx->destname,
-			mailbox_get_last_error(destbox, NULL));
-		doveadm_mail_failed_mailbox(&ctx->ctx, destbox);
-		ret = -1;
-	}
-	mailbox_free(&destbox);
-	return ret;
-
-}
-
-static void cmd_move_init(struct doveadm_mail_cmd_context *_ctx,
-			  const char *const args[])
-{
-	struct move_cmd_context *ctx = (struct move_cmd_context *)_ctx;
-	const char *destname = args[0];


More information about the dovecot-cvs mailing list