this guarantees that mails aren't expunged without actually having
been copied. */
desttrans = mailbox_transaction_begin(destbox,
- MAILBOX_TRANSACTION_FLAG_EXTERNAL,
- __func__);
+ MAILBOX_TRANSACTION_FLAG_EXTERNAL |
+ ctx->ctx.transaction_flags, __func__);
while (doveadm_mail_iter_next(iter, &mail)) {
save_ctx = mailbox_save_alloc(desttrans);
arg = mail_search_build_add(search_args, SEARCH_UIDSET);
arg->value.seqset = uids;
- trans = mailbox_transaction_begin(box, 0, __func__);
+ trans = mailbox_transaction_begin(box, _ctx->transaction_flags, __func__);
search_ctx = mailbox_search_init(trans, search_args, NULL, 0, NULL);
mail_search_args_unref(&search_args);
}
static int
-cmd_import_box_contents(struct doveadm_mail_iter *iter, struct mail *src_mail,
+cmd_import_box_contents(struct doveadm_mail_cmd_context *ctx,
+ struct doveadm_mail_iter *iter, struct mail *src_mail,
struct mailbox *dest_box)
{
struct mail_save_context *save_ctx;
int ret = 0;
dest_trans = mailbox_transaction_begin(dest_box,
- MAILBOX_TRANSACTION_FLAG_EXTERNAL,
- __func__);
+ MAILBOX_TRANSACTION_FLAG_EXTERNAL |
+ ctx->transaction_flags, __func__);
do {
if (doveadm_debug) {
i_debug("import: box=%s uid=%u",
if (dest_mailbox_open_or_create(ctx, dest_user, info, &box) < 0)
ret = -1;
else {
- if (cmd_import_box_contents(iter, mail, box) < 0) {
+ if (cmd_import_box_contents(&ctx->ctx, iter, mail, box) < 0) {
doveadm_mail_failed_mailbox(&ctx->ctx, mail->box);
ret = -1;
}
bool have_wildcards:1;
};
-static int cmd_index_box_precache(struct mailbox *box)
+static int cmd_index_box_precache(struct doveadm_mail_cmd_context *dctx,
+ struct mailbox *box)
{
struct mailbox_status status;
struct mailbox_transaction_context *trans;
mailbox_get_vname(box), seq, status.messages);
}
- trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC,
- __func__);
+ trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC |
+ dctx->transaction_flags, __func__);
search_args = mail_search_build_init();
mail_search_build_add_seqset(search_args, seq, status.messages);
ctx = mailbox_search_init(trans, search_args, NULL,
doveadm_mail_failed_mailbox(&ctx->ctx, box);
ret = -1;
} else {
- if (cmd_index_box_precache(box) < 0) {
+ if (cmd_index_box_precache(&ctx->ctx, box) < 0) {
doveadm_mail_failed_mailbox(&ctx->ctx, box);
ret = -1;
}
NULL : mailbox_header_lookup_init(iter->box, wanted_headers);
mail_search_args_init(search_args, iter->box, FALSE, NULL);
- iter->t = mailbox_transaction_begin(iter->box, 0, ctx->cmd->name);
+ iter->t = mailbox_transaction_begin(iter->box, ctx->transaction_flags,
+ ctx->cmd->name);
iter->search_ctx = mailbox_search_init(iter->t, search_args, NULL,
wanted_fields, headers_ctx);
mailbox_header_lookup_unref(&headers_ctx);
struct mailbox *box)
{
struct mailbox_transaction_context *t =
- mailbox_transaction_begin(box, 0, "mailbox cache decision");
+ mailbox_transaction_begin(box, ctx->ctx.transaction_flags,
+ "mailbox cache decision");
struct mail_cache *cache = t->box->cache;
struct mail_cache_view *view;
{
struct mailbox_transaction_context *t =
mailbox_transaction_begin(box,
- MAILBOX_TRANSACTION_FLAG_EXTERNAL,
+ MAILBOX_TRANSACTION_FLAG_EXTERNAL |
+ ctx->ctx.transaction_flags,
"mailbox cache purge");
struct mail_cache *cache = t->box->cache;
struct mail_cache_compress_lock *lock;
if (ret != 0)
return ret;
- trans = mailbox_transaction_begin(box, ctx->empty_mailbox_name ?
- MAILBOX_TRANSACTION_FLAG_EXTERNAL : 0,
- __func__);
+ trans = mailbox_transaction_begin(box, (ctx->empty_mailbox_name ?
+ MAILBOX_TRANSACTION_FLAG_EXTERNAL : 0) |
+ ctx->ctx.transaction_flags, __func__);
ret = ctx->value.value == NULL ?
mailbox_attribute_unset(trans, ctx->key_type, ctx->key) :
return -1;
}
- trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL,
- __func__);
+ trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL |
+ ctx->ctx.transaction_flags, __func__);
save_ctx = mailbox_save_alloc(trans);
if (mailbox_save_begin(&save_ctx, input) < 0) {
i_error("Saving failed: %s",
mctx->cmd_input = arg->value.v_istream;
i_stream_ref(mctx->cmd_input);
+ } else if (strcmp(arg->name, "trans-flags") == 0) {
+ /* This parameter allows to set additional
+ * mailbox transaction flags. */
+ mctx->transaction_flags = arg->value.v_int64;
+
/* Keep all named special parameters above this line */
} else if (mctx->v.parse_arg != NULL && arg->short_opt != '\0') {
#include "doveadm-util.h"
#include "module-context.h"
#include "mail-error.h"
+#include "mail-storage.h"
#include "mail-storage-service.h"
struct mailbox;
const char *getopt_args;
const struct doveadm_settings *set;
enum mail_storage_service_flags service_flags;
+ enum mailbox_transaction_flags transaction_flags;
struct mail_storage_service_ctx *storage_service;
struct mail_storage_service_input storage_service_input;
/* search args aren't set for all mail commands */
DOVEADM_CMD_PARAM('A', "all-users", CMD_PARAM_BOOL, 0) \
DOVEADM_CMD_PARAM('S', "socket-path", CMD_PARAM_STR, 0) \
DOVEADM_CMD_PARAM('u', "user", CMD_PARAM_STR, 0) \
+DOVEADM_CMD_PARAM('\0', "trans-flags", CMD_PARAM_INT64, 0) \
DOVEADM_CMD_PARAM('F', "user-file", CMD_PARAM_ISTREAM, 0)
#define DOVEADM_CMD_MAIL_USAGE_PREFIX \
}
static int
-cmd_acl_mailbox_update(struct mailbox *box,
+cmd_acl_mailbox_update(struct doveadm_mail_cmd_context *ctx, struct mailbox *box,
const struct acl_rights_update *update)
{
struct mailbox_transaction_context *t;
int ret;
- t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL,
- __func__);
+ t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL |
+ ctx->transaction_flags, __func__);
ret = acl_mailbox_update_acl(t, update);
if (mailbox_transaction_commit(&t) < 0)
ret = -1;
update.neg_modify_mode = ctx->modify_mode;
if (acl_rights_update_import(&update, id, rights, &error) < 0)
i_fatal_status(EX_USAGE, "%s", error);
- if ((ret = cmd_acl_mailbox_update(box, &update)) < 0) {
+ if ((ret = cmd_acl_mailbox_update(&ctx->ctx, box, &update)) < 0) {
i_error("Failed to set ACL: %s",
mailbox_get_last_internal_error(box, NULL));
doveadm_mail_failed_error(_ctx, MAIL_ERROR_TEMP);
i_zero(&update);
if (acl_rights_update_import(&update, id, NULL, &error) < 0)
i_fatal_status(EX_USAGE, "%s", error);
- if ((ret = cmd_acl_mailbox_update(box, &update)) < 0) {
+ if ((ret = cmd_acl_mailbox_update(ctx, box, &update)) < 0) {
i_error("Failed to delete ACL: %s",
mailbox_get_last_internal_error(box, NULL));
doveadm_mail_failed_error(ctx, MAIL_ERROR_TEMP);
return ret;
}
-static int mcp_update_shared_keys(struct mailbox *box, struct mail_user *user,
+static int mcp_update_shared_keys(struct doveadm_mail_cmd_context *ctx,
+ struct mailbox *box, struct mail_user *user,
const char *pubid, struct dcrypt_private_key *key)
{
const char *error;
string_t *uid = t_str_new(64);
struct mailbox_transaction_context *t =
- mailbox_transaction_begin(box, 0, __func__);
+ mailbox_transaction_begin(box, ctx->transaction_flags, __func__);
ret = 0;
res->success = TRUE;
res->id = pubid;
T_BEGIN {
- mcp_update_shared_keys(box, user, pubid, pair.priv);
+ mcp_update_shared_keys(&ctx->ctx, box, user,
+ pubid, pair.priv);
} T_END;
if (pair.pub != NULL)
dcrypt_key_unref_public(&pair.pub);
if (ret == 1) {
struct mailbox_transaction_context *t =
- mailbox_transaction_begin(box, 0, __func__);
+ mailbox_transaction_begin(box, _ctx->transaction_flags,
+ __func__);
struct dcrypt_private_key *key;
const struct raw_key *raw_key;
const char *algo = ctx->new_password != NULL ?