1
/* Copyright (c) 2010-2011 Dovecot authors, see the included COPYING file */
1
/* Copyright (c) 2010-2012 Dovecot authors, see the included COPYING file */
5
5
#include "mail-storage.h"
6
6
#include "mail-storage-service.h"
7
7
#include "mail-namespace.h"
8
#include "doveadm-mail-list-iter.h"
8
#include "doveadm-mailbox-list-iter.h"
9
9
#include "doveadm-mail-iter.h"
10
10
#include "doveadm-mail.h"
24
25
struct mail_namespace *ns;
25
26
struct mailbox *box;
26
27
enum mail_error error;
27
const char *errstr, *storage_name;
29
30
if (*ctx->dest_parent != '\0') {
30
31
/* prefix destination mailbox name with given parent mailbox */
31
storage_name = ctx->dest_parent;
32
ns = mail_namespace_find(user->namespaces, &storage_name);
32
ns = mail_namespace_find(user->namespaces, ctx->dest_parent);
34
34
i_error("Can't find namespace for parent mailbox %s",
36
doveadm_mail_failed_error(&ctx->ctx, MAIL_ERROR_NOTFOUND);
38
39
name = t_strdup_printf("%s%c%s", ctx->dest_parent,
40
mail_namespace_get_sep(ns), name);
43
ns = mail_namespace_find(user->namespaces, &storage_name);
43
ns = mail_namespace_find(user->namespaces, name);
45
45
i_error("Can't find namespace for mailbox %s", name);
46
doveadm_mail_failed_error(&ctx->ctx, MAIL_ERROR_NOTFOUND);
49
box = mailbox_alloc(ns->list, storage_name, MAILBOX_FLAG_SAVEONLY |
50
MAILBOX_FLAG_KEEP_RECENT);
50
box = mailbox_alloc(ns->list, name, MAILBOX_FLAG_SAVEONLY);
51
51
if (mailbox_create(box, NULL, FALSE) < 0) {
52
errstr = mail_storage_get_last_error(mailbox_get_storage(box),
52
errstr = mailbox_get_last_error(box, &error);
54
53
if (error != MAIL_ERROR_EXISTS) {
55
54
i_error("Couldn't create mailbox %s: %s", name, errstr);
55
doveadm_mail_failed_mailbox(&ctx->ctx, box);
56
56
mailbox_free(&box);
61
if (mailbox_set_subscribed(box, TRUE) < 0) {
62
i_error("Couldn't subscribe to mailbox %s: %s",
63
name, mailbox_get_last_error(box, NULL));
60
66
if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
61
67
i_error("Syncing mailbox %s failed: %s", name,
62
mail_storage_get_last_error(mailbox_get_storage(box),
68
mailbox_get_last_error(box, NULL));
69
doveadm_mail_failed_mailbox(&ctx->ctx, box);
64
70
mailbox_free(&box);
72
78
cmd_import_box_contents(struct doveadm_mail_iter *iter, struct mail *src_mail,
73
79
struct mailbox *dest_box)
75
struct mail_storage *dest_storage = mailbox_get_storage(dest_box);
76
81
struct mail_save_context *save_ctx;
77
82
struct mailbox_transaction_context *dest_trans;
78
83
const char *mailbox = mailbox_get_vname(dest_box);
86
91
mailbox, src_mail->uid);
88
93
save_ctx = mailbox_save_alloc(dest_trans);
94
mailbox_save_copy_flags(save_ctx, src_mail);
89
95
if (mailbox_copy(&save_ctx, src_mail) < 0) {
90
96
i_error("Copying box=%s uid=%u failed: %s",
91
97
mailbox, src_mail->uid,
92
mail_storage_get_last_error(dest_storage, NULL));
98
mailbox_get_last_error(dest_box, NULL));
95
} while (doveadm_mail_iter_next(iter, src_mail));
101
} while (doveadm_mail_iter_next(iter, &src_mail));
97
103
if (mailbox_transaction_commit(&dest_trans) < 0) {
98
104
i_error("Committing copied mails to %s failed: %s", mailbox,
99
mail_storage_get_last_error(dest_storage, NULL));
105
mailbox_get_last_error(dest_box, NULL));
113
119
struct mail *mail;
116
if (doveadm_mail_iter_init(info, search_args, &trans, &iter) < 0)
122
if (doveadm_mail_iter_init(&ctx->ctx, info, search_args, 0, NULL,
119
mail = mail_alloc(trans, 0, NULL);
120
if (doveadm_mail_iter_next(iter, mail)) {
126
if (doveadm_mail_iter_next(iter, &mail)) {
121
127
/* at least one mail matches in this mailbox */
122
128
if (dest_mailbox_open_or_create(ctx, dest_user, info->name,
124
if (cmd_import_box_contents(iter, mail, box) < 0)
132
if (cmd_import_box_contents(iter, mail, box) < 0) {
133
doveadm_mail_failed_mailbox(&ctx->ctx, mail->box);
126
136
mailbox_free(&box);
130
139
if (doveadm_mail_iter_deinit_sync(&iter) < 0)
136
145
cmd_import_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
138
147
struct import_cmd_context *ctx = (struct import_cmd_context *)_ctx;
139
148
const enum mailbox_list_iter_flags iter_flags =
140
149
MAILBOX_LIST_ITER_RAW_LIST |
141
MAILBOX_LIST_ITER_NO_AUTO_INBOX |
150
MAILBOX_LIST_ITER_NO_AUTO_BOXES |
142
151
MAILBOX_LIST_ITER_RETURN_NO_FLAGS;
143
struct doveadm_mail_list_iter *iter;
152
struct doveadm_mailbox_list_iter *iter;
144
153
const struct mailbox_info *info;
146
iter = doveadm_mail_list_iter_init(ctx->src_user,
147
_ctx->search_args, iter_flags);
148
while ((info = doveadm_mail_list_iter_next(iter)) != NULL) T_BEGIN {
149
(void)cmd_import_box(ctx, user, info, _ctx->search_args);
156
iter = doveadm_mailbox_list_iter_init(_ctx, ctx->src_user,
157
_ctx->search_args, iter_flags);
158
while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN {
159
if (cmd_import_box(ctx, user, info, _ctx->search_args) < 0)
151
doveadm_mail_list_iter_deinit(&iter);
162
if (doveadm_mailbox_list_iter_deinit(&iter) < 0)
154
167
static void cmd_import_init(struct doveadm_mail_cmd_context *_ctx,
190
203
mail_user_unref(&ctx->src_user);
206
static bool cmd_import_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c)
208
struct import_cmd_context *ctx = (struct import_cmd_context *)_ctx;
212
ctx->subscribe = TRUE;
193
220
static struct doveadm_mail_cmd_context *cmd_import_alloc(void)
195
222
struct import_cmd_context *ctx;
197
224
ctx = doveadm_mail_cmd_alloc(struct import_cmd_context);
225
ctx->ctx.getopt_args = "s";
226
ctx->ctx.v.parse_arg = cmd_import_parse_arg;
198
227
ctx->ctx.v.init = cmd_import_init;
199
228
ctx->ctx.v.deinit = cmd_import_deinit;
200
229
ctx->ctx.v.run = cmd_import_run;