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