1
/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
5
#include "doveadm-mail.h"
9
struct batch_cmd_context {
10
struct doveadm_mail_cmd_context ctx;
11
ARRAY(struct doveadm_mail_cmd_context *) commands;
14
static int cmd_batch_prerun(struct doveadm_mail_cmd_context *_ctx,
15
struct mail_storage_service_user *service_user,
18
struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx;
19
struct doveadm_mail_cmd_context *const *cmdp;
22
array_foreach(&ctx->commands, cmdp) {
23
if ((*cmdp)->v.prerun != NULL &&
24
(*cmdp)->v.prerun(*cmdp, service_user, error_r) < 0) {
32
static int cmd_batch_run(struct doveadm_mail_cmd_context *_ctx,
33
struct mail_user *user)
35
struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx;
36
struct doveadm_mail_cmd_context *const *cmdp;
39
array_foreach(&ctx->commands, cmdp) {
40
(*cmdp)->cur_mail_user = user;
41
if ((*cmdp)->v.run(*cmdp, user) < 0) {
42
i_assert((*cmdp)->exit_code != 0);
43
_ctx->exit_code = (*cmdp)->exit_code;
47
(*cmdp)->cur_mail_user = NULL;
53
cmd_batch_add(struct batch_cmd_context *batchctx,
54
int argc, const char *const *argv)
56
struct doveadm_mail_cmd_context *subctx;
57
const struct doveadm_mail_cmd *cmd;
58
const char *getopt_args;
61
cmd = doveadm_mail_cmd_find_from_argv(argv[0], &argc, &argv);
63
i_fatal_status(EX_USAGE, "doveadm batch: Unknown subcommand %s",
67
subctx = doveadm_mail_cmd_init(cmd, doveadm_settings);
68
subctx->full_args = argv + 1;
69
subctx->service_flags |= batchctx->ctx.service_flags;
72
getopt_args = subctx->getopt_args != NULL ? subctx->getopt_args : "";
73
while ((c = getopt(argc, (void *)argv, getopt_args)) > 0) {
74
if (subctx->v.parse_arg == NULL ||
75
!subctx->v.parse_arg(subctx, c))
76
doveadm_mail_help(cmd);
79
if (argv[0] != NULL && cmd->usage_args == NULL) {
80
i_fatal_status(EX_USAGE, "doveadm %s: Unknown parameter: %s",
84
if (subctx->v.preinit != NULL)
85
subctx->v.preinit(subctx);
86
array_append(&batchctx->commands, &subctx, 1);
90
cmd_batch_preinit(struct doveadm_mail_cmd_context *_ctx)
92
const char *const *args = _ctx->args;
93
struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx;
94
ARRAY_TYPE(const_string) sep_args;
95
const char *sep = args[0];
96
unsigned int i, start;
98
const char *const *argv;
100
if (sep == NULL || args[1] == NULL)
101
doveadm_mail_help_name("batch");
104
p_array_init(&ctx->commands, _ctx->pool, 8);
105
p_array_init(&sep_args, _ctx->pool, 16);
106
for (i = start = 0;; i++) {
107
if (args[i] != NULL && strcmp(args[i], sep) != 0) {
108
array_append(&sep_args, &args[i], 1);
112
(void)array_append_space(&sep_args);
114
argv = array_idx(&sep_args, start);
115
cmd_batch_add(ctx, argc, argv);
121
(void)array_append_space(&sep_args);
125
cmd_batch_init(struct doveadm_mail_cmd_context *_ctx,
126
const char *const args[] ATTR_UNUSED)
128
struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx;
129
struct doveadm_mail_cmd_context *const *cmdp;
130
struct batch_cmd_context *subctx;
132
array_foreach(&ctx->commands, cmdp) {
133
subctx = (struct batch_cmd_context *)*cmdp;
134
subctx->ctx.storage_service = _ctx->storage_service;
135
if (subctx->ctx.v.init != NULL)
136
subctx->ctx.v.init(&subctx->ctx, subctx->ctx.args);
140
static void cmd_batch_deinit(struct doveadm_mail_cmd_context *_ctx)
142
struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx;
143
struct doveadm_mail_cmd_context *const *cmdp;
145
array_foreach(&ctx->commands, cmdp) {
146
if ((*cmdp)->v.deinit != NULL)
147
(*cmdp)->v.deinit(*cmdp);
151
static struct doveadm_mail_cmd_context *cmd_batch_alloc(void)
153
struct batch_cmd_context *ctx;
155
ctx = doveadm_mail_cmd_alloc(struct batch_cmd_context);
156
ctx->ctx.getopt_args = "+"; /* disable processing -args in the middle */
157
ctx->ctx.v.preinit = cmd_batch_preinit;
158
ctx->ctx.v.init = cmd_batch_init;
159
ctx->ctx.v.prerun = cmd_batch_prerun;
160
ctx->ctx.v.run = cmd_batch_run;
161
ctx->ctx.v.deinit = cmd_batch_deinit;
165
struct doveadm_mail_cmd cmd_batch = {
166
cmd_batch_alloc, "batch", "<sep> <cmd1> [<sep> <cmd2> [..]]"