doveadm-mail.c revision 949c3973edcf50aebf4b9039cf151e6ba601e849
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2009-2016 Dovecot authors, see the included COPYING file */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#define DOVEADM_MAIL_CMD_INPUT_TIMEOUT_MSECS (5*60*1000)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo SirainenARRAY_TYPE(doveadm_mail_cmd) doveadm_mail_cmds;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid (*hook_doveadm_mail_init)(struct doveadm_mail_cmd_context *ctx);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid doveadm_mail_failed_error(struct doveadm_mail_cmd_context *ctx,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* tempfail overrides all other exit codes, otherwise use whatever
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen error happened first */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (ctx->exit_code == 0 || exit_code == EX_TEMPFAIL)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid doveadm_mail_failed_storage(struct doveadm_mail_cmd_context *ctx,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid doveadm_mail_failed_mailbox(struct doveadm_mail_cmd_context *ctx,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen doveadm_mail_failed_storage(ctx, mailbox_get_storage(box));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid doveadm_mail_failed_list(struct doveadm_mail_cmd_context *ctx,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_assert(size >= sizeof(struct doveadm_mail_cmd_context));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen pool = pool_alloconly_create("doveadm mail cmd", 1024);
b78d8dbe4179aabcbf9fda41d282673558dae4d6Timo Sirainencmd_purge_run(struct doveadm_mail_cmd_context *ctx, struct mail_user *user)
a327d9301f593433c228c4cc8cca05c95b37f6fbTimo Sirainen for (ns = user->namespaces; ns != NULL; ns = ns->next) {
d48e40d6c77d673ad402d96571198d1cce4da225Timo Sirainen if (ns->type != MAIL_NAMESPACE_TYPE_PRIVATE ||
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen storage = mail_namespace_get_default_storage(ns);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_error("Purging namespace '%s' failed: %s", ns->prefix,
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainenstatic struct doveadm_mail_cmd_context *cmd_purge_alloc(void)
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainenstatic void doveadm_mail_cmd_input_input(struct doveadm_mail_cmd_context *ctx)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_stream_skip(ctx->cmd_input, i_stream_get_data_size(ctx->cmd_input));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void doveadm_mail_cmd_input_timeout(struct doveadm_mail_cmd_context *ctx)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen input = i_stream_create_error_str(ETIMEDOUT, "Timed out in %u secs",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_stream_set_name(input, i_stream_get_name(ctx->cmd_input));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void doveadm_mail_cmd_input_read(struct doveadm_mail_cmd_context *ctx)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen to = timeout_add(DOVEADM_MAIL_CMD_INPUT_TIMEOUT_MSECS,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* read the pending input from stream. */
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Boschvoid doveadm_mail_get_input(struct doveadm_mail_cmd_context *ctx)
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch inputs[0] = i_stream_create_dot(ctx->conn->input, FALSE);
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch inputs[0] = i_stream_create_fd(STDIN_FILENO, 1024*1024, FALSE);
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch ctx->cmd_input_fd = i_stream_get_fd(inputs[0]);
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch ctx->cmd_input = i_stream_create_seekable_path(inputs, 1024*256,
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch i_stream_set_name(ctx->cmd_input, i_stream_get_name(inputs[0]));
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Boschdoveadm_mailbox_find(struct mail_user *user, const char *mailbox)
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch ns = mail_namespace_find(user->namespaces, mailbox);
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch return mailbox_alloc(ns->list, mailbox, MAILBOX_FLAG_IGNORE_ACLS);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainendoveadm_mail_build_search_args(const char *const args[])
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen parser = mail_search_parser_init_cmdline(args);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (mail_search_build(mail_search_register_get_human(),
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic int cmd_force_resync_box(struct doveadm_mail_cmd_context *ctx,
4487c66123ca4830f8afbf4efcd7a260848d0e05Timo Sirainen box = mailbox_alloc(info->ns->list, info->vname,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_error("Opening mailbox %s failed: %s", info->vname,
cb3ab2fd5668700a89b274a43595cfbfa1616e4bTimo Sirainen } else if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FORCE_RESYNC |
6793538c389d3e725456e3eabb697e2743233646Stephan Bosch i_error("Forcing a resync on mailbox %s failed: %s",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen info->vname, mailbox_get_last_error(box, NULL));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic int cmd_force_resync_run(struct doveadm_mail_cmd_context *ctx,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const enum mailbox_list_iter_flags iter_flags =
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const enum mail_namespace_type ns_mask = MAIL_NAMESPACE_TYPE_MASK_ALL;
e25c9a57d651456a5f446a98e677c8c472c4ce98Timo Sirainen iter = mailbox_list_iter_init_namespaces(user->namespaces, ctx->args,
e25c9a57d651456a5f446a98e677c8c472c4ce98Timo Sirainen while ((info = mailbox_list_iter_next(iter)) != NULL) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen mailbox_list_get_last_error(user->namespaces->list, NULL));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen doveadm_mail_failed_list(ctx, user->namespaces->list);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainencmd_force_resync_init(struct doveadm_mail_cmd_context *_ctx ATTR_UNUSED,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char *const args[])
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic struct doveadm_mail_cmd_context *cmd_force_resync_alloc(void)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainendoveadm_mail_next_user(struct doveadm_mail_cmd_context *ctx,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const struct mail_storage_service_input *input,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char **error_r)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_set_failure_prefix("doveadm(%s): ", input->username);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_set_failure_prefix("doveadm(%s,%s): ", ip, input->username);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* see if we want to execute this command via (another)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen doveadm server */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ret = doveadm_mail_server_user(ctx, input, error_r);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ret = mail_storage_service_lookup(ctx->storage_service, input,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen *error_r = t_strdup_printf("User lookup failed: %s",
c61779cfa45c1684b1f7c462011088bad0b8318cTimo Sirainen if (ctx->v.prerun(ctx, ctx->cur_service_user, error_r) < 0) {
c61779cfa45c1684b1f7c462011088bad0b8318cTimo Sirainen mail_storage_service_user_free(&ctx->cur_service_user);
c61779cfa45c1684b1f7c462011088bad0b8318cTimo Sirainen ret = mail_storage_service_next(ctx->storage_service,
c61779cfa45c1684b1f7c462011088bad0b8318cTimo Sirainen mail_storage_service_user_free(&ctx->cur_service_user);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (ctx->v.run(ctx, ctx->cur_mail_user) < 0) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen mail_storage_service_user_free(&ctx->cur_service_user);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenint doveadm_mail_single_user(struct doveadm_mail_cmd_context *ctx,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const struct mail_storage_service_input *input,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char **error_r)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ctx->storage_service = mail_storage_service_init(master_service, NULL,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen lib_signals_set_handler(SIGINT, 0, sig_die, NULL);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen lib_signals_set_handler(SIGTERM, 0, sig_die, NULL);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return doveadm_mail_next_user(ctx, input, error_r);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainendoveadm_mail_all_users(struct doveadm_mail_cmd_context *ctx,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ctx->storage_service = mail_storage_service_init(master_service, NULL,
user_idx = 0;
T_BEGIN {
if (ret < 0)
else if (ret == 0)
} T_END;
if (doveadm_verbose) {
if (killed_signo != 0) {
if (doveadm_verbose)
if (ret < 0) {
const char **username_r)
struct doveadm_mail_cmd_context *
return ctx;
static struct doveadm_mail_cmd_context *
if (doveadm_debug)
return ctx;
const char *wildcard_user)
int ret;
const char *error;
if (ret < 0) {
} else if (ret == 0) {
const char *const **argv)
unsigned int len;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
const struct doveadm_mail_cmd *
const char *const **argv)
unsigned int cmd_name_len;
const char *const *orig_argv;
int orig_argc;
return cmd;
return cmd;
return NULL;
return FALSE;
return TRUE;
return cmd;
return NULL;
return TRUE;
return FALSE;
&cmd_copy,
&cmd_move,
void doveadm_mail_init(void)
&mod_set);
void doveadm_mail_deinit(void)
const char *wildcard_user;
const char *fieldstr;
for(i=0;i<argc;i++) {