doveadm_cmd_server_post(conn, cctx->cmd->name);
}
-static int
-doveadm_mail_cmd_server_parse(const struct doveadm_mail_cmd *cmd,
- const struct doveadm_settings *set,
- int argc, const char *const argv[],
- struct doveadm_cmd_context *cctx,
- struct doveadm_mail_cmd_context **mctx_r)
-{
- struct doveadm_mail_cmd_context *mctx;
- const char *getopt_args;
- bool add_username_header = FALSE;
- int c;
-
- mctx = doveadm_mail_cmd_init(cmd, set);
- mctx->cctx = cctx;
- mctx->full_args = argv+1;
- mctx->proxying = TRUE;
- mctx->service_flags |=
- MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT |
- MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
- if (doveadm_debug)
- mctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;
-
- i_getopt_reset();
- getopt_args = t_strconcat("AF:S:u:", mctx->getopt_args, NULL);
- while ((c = getopt(argc, (char **)argv, getopt_args)) > 0) {
- switch (c) {
- case 'A':
- case 'F':
- add_username_header = TRUE;
- break;
- case 'S':
- /* ignore */
- break;
- case 'u':
- if (strchr(optarg, '*') != NULL ||
- strchr(optarg, '?') != NULL)
- add_username_header = TRUE;
- break;
- default:
- if ((mctx->v.parse_arg == NULL ||
- !mctx->v.parse_arg(mctx, c))) {
- i_error("doveadm %s: "
- "Client sent unknown parameter: %c",
- cmd->name, c);
- mctx->v.deinit(mctx);
- pool_unref(&mctx->pool);
- return -1;
- }
- }
- }
-
- if (argv[optind] != NULL && cmd->usage_args == NULL) {
- i_error("doveadm %s: Client sent unknown parameter: %s",
- cmd->name, argv[optind]);
- mctx->v.deinit(mctx);
- pool_unref(&mctx->pool);
- return -1;
- }
- mctx->args = argv+optind;
-
- if (cctx->username != NULL) {
- if (strchr(cctx->username, '*') != NULL ||
- strchr(cctx->username, '?') != NULL) {
- add_username_header = TRUE;
- }
- }
-
- if (doveadm_print_is_initialized() && add_username_header) {
- doveadm_print_header("username", "Username",
- DOVEADM_PRINT_HEADER_FLAG_STICKY |
- DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
- doveadm_print_sticky("username", cctx->username);
- }
- *mctx_r = mctx;
- return 0;
-}
-
-static void
-doveadm_mail_cmd_server_run(struct client_connection_tcp *conn,
- struct doveadm_mail_cmd_context *mctx)
-{
- const char *error;
- int ret;
-
- o_stream_cork(conn->output);
-
- if (mctx->v.preinit != NULL)
- mctx->v.preinit(mctx);
-
- ret = doveadm_mail_single_user(mctx, &error);
- doveadm_mail_server_flush();
- mctx->v.deinit(mctx);
- doveadm_print_flush();
- mail_storage_service_deinit(&mctx->storage_service);
-
- if (ret < 0) {
- i_error("%s: %s", mctx->cmd->name, error);
- o_stream_nsend(conn->output, "\n-\n", 3);
- } else if (ret == 0) {
- o_stream_nsend_str(conn->output, "\n-NOUSER\n");
- } else if (mctx->exit_code == DOVEADM_EX_NOREPLICATE) {
- o_stream_nsend_str(conn->output, "\n-NOREPLICATE\n");
- } else if (mctx->exit_code != 0) {
- /* maybe not an error, but not a full success either */
- o_stream_nsend_str(conn->output,
- t_strdup_printf("\n-%u\n", mctx->exit_code));
- } else {
- o_stream_nsend(conn->output, "\n+\n", 3);
- }
- o_stream_uncork(conn->output);
- pool_unref(&mctx->pool);
-}
-
static int doveadm_cmd_handle(struct client_connection_tcp *conn,
const char *cmd_name,
int argc, const char *const argv[],
struct doveadm_cmd_context *cctx)
{
struct ioloop *prev_ioloop = current_ioloop;
- const struct doveadm_mail_cmd *mail_cmd;
- struct doveadm_mail_cmd_context *mctx = NULL;
const struct doveadm_cmd_ver2 *cmd_ver2;
if ((cmd_ver2 = doveadm_cmd_find_with_args_ver2(cmd_name, &argc, &argv)) == NULL) {
- mail_cmd = doveadm_mail_cmd_find(cmd_name);
- if (mail_cmd == NULL) {
- i_error("doveadm: Client sent unknown command: %s", cmd_name);
- return -1;
- } else {
- if (doveadm_mail_cmd_server_parse(mail_cmd, conn->conn.set,
- argc, argv,
- cctx, &mctx) < 0)
- return -1;
- }
- } else {
- cctx->cmd = cmd_ver2;
+ i_error("doveadm: Client sent unknown command: %s", cmd_name);
+ return -1;
}
+ cctx->cmd = cmd_ver2;
/* some commands will want to call io_loop_run(), but we're already
running one and we can't call the original one recursively, so
if (conn->log_out != NULL)
o_stream_switch_ioloop(conn->log_out);
- if (cmd_ver2 != NULL)
- doveadm_cmd_server_run_ver2(conn, argc, argv, cctx);
- else {
- i_assert(mctx != NULL);
- doveadm_mail_cmd_server_run(conn, mctx);
- }
+ doveadm_cmd_server_run_ver2(conn, argc, argv, cctx);
o_stream_switch_ioloop_to(conn->output, prev_ioloop);
if (conn->log_out != NULL)
int c;
cmd_ver2 = doveadm_cmd_find_with_args_ver2(argv[0], &argc, &argv);
-
if (cmd_ver2 == NULL)
- cmd = doveadm_mail_cmd_find_from_argv(argv[0], &argc, &argv);
- else {
- struct doveadm_mail_cmd *dyncmd =
- p_new(batchctx->ctx.pool, struct doveadm_mail_cmd, 1);
- dyncmd->usage_args = cmd_ver2->usage;
- dyncmd->name = cmd_ver2->name;
- dyncmd->alloc = cmd_ver2->mail_cmd;
- cmd = dyncmd;
- }
-
- if (cmd == NULL)
i_fatal_status(EX_USAGE, "doveadm batch: '%s' mail command doesn't exist", argv[0]);
+ struct doveadm_mail_cmd *dyncmd =
+ p_new(batchctx->ctx.pool, struct doveadm_mail_cmd, 1);
+ dyncmd->usage_args = cmd_ver2->usage;
+ dyncmd->name = cmd_ver2->name;
+ dyncmd->alloc = cmd_ver2->mail_cmd;
+ cmd = dyncmd;
+
subctx = doveadm_mail_cmd_init(cmd, doveadm_settings);
subctx->full_args = argv + 1;
subctx->service_flags |= batchctx->ctx.service_flags;
bool fsck;
};
-ARRAY_TYPE(doveadm_mail_cmd) doveadm_mail_cmds;
void (*hook_doveadm_mail_init)(struct doveadm_mail_cmd_context *ctx);
struct doveadm_mail_cmd_module_register
doveadm_mail_cmd_module_register = { 0 };
pool_unref(&ctx->pool);
}
-static void
-doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[])
-{
- struct doveadm_cmd_context cctx;
- struct doveadm_mail_cmd_context *ctx;
- const char *getopt_args, *wildcard_user;
- int c;
-
- i_zero(&cctx);
- cctx.conn_type = DOVEADM_CONNECTION_TYPE_CLI;
- cctx.username = getenv("USER");
-
- ctx = doveadm_mail_cmdline_init(cmd);
- ctx->cctx = &cctx;
- ctx->full_args = (const void *)(argv + 1);
-
- getopt_args = "AF:S:u:";
- /* keep context's getopt_args first in case it contains '+' */
- if (ctx->getopt_args != NULL)
- getopt_args = t_strconcat(ctx->getopt_args, getopt_args, NULL);
- i_assert(master_getopt_str_is_valid(getopt_args));
-
- wildcard_user = NULL;
- while ((c = getopt(argc, argv, getopt_args)) > 0) {
- switch (c) {
- case 'A':
- ctx->iterate_all_users = TRUE;
- break;
- case 'S':
- doveadm_settings->doveadm_socket_path = optarg;
- if (doveadm_settings->doveadm_worker_count == 0)
- doveadm_settings->doveadm_worker_count = 1;
- break;
- case 'u':
- ctx->service_flags |=
- MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
- cctx.username = optarg;
- if (strchr(cctx.username, '*') != NULL ||
- strchr(cctx.username, '?') != NULL) {
- wildcard_user = cctx.username;
- cctx.username = NULL;
- }
- break;
- case 'F':
- ctx->service_flags |=
- MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
- wildcard_user = "*";
- ctx->users_list_input =
- i_stream_create_file(optarg, 1024);
- break;
- default:
- if (ctx->v.parse_arg == NULL ||
- !ctx->v.parse_arg(ctx, c))
- doveadm_mail_help(cmd);
- }
- }
- argv += optind;
- if (argv[0] != NULL && cmd->usage_args == NULL) {
- i_fatal_status(EX_USAGE, "doveadm %s: Unknown parameter: %s",
- cmd->name, argv[0]);
- }
- ctx->args = (const void *)argv;
- doveadm_mail_cmd_exec(ctx, wildcard_user);
- doveadm_mail_cmd_free(ctx);
-}
-
-static bool
-doveadm_mail_cmd_try_find_multi_word(const struct doveadm_mail_cmd *cmd,
- const char *cmdname, int *argc,
- const char *const **argv)
-{
- size_t len;
-
- if (*argc < 2)
- return FALSE;
- *argc -= 1;
- *argv += 1;
-
- len = strlen((*argv)[0]);
- if (!str_begins(cmdname, (*argv)[0]))
- return FALSE;
-
- if (cmdname[len] == ' ') {
- /* more args */
- return doveadm_mail_cmd_try_find_multi_word(cmd, cmdname + len + 1,
- argc, argv);
- }
- if (cmdname[len] != '\0')
- return FALSE;
-
- /* match */
- return TRUE;
-}
-
-const struct doveadm_mail_cmd *
-doveadm_mail_cmd_find_from_argv(const char *cmd_name, int *argc,
- const char *const **argv)
-{
- const struct doveadm_mail_cmd *cmd;
- size_t cmd_name_len;
- const char *const *orig_argv;
- int orig_argc;
-
- i_assert(*argc > 0);
-
- cmd_name_len = strlen(cmd_name);
- array_foreach(&doveadm_mail_cmds, cmd) {
- if (strcmp(cmd->name, cmd_name) == 0)
- return cmd;
-
- /* see if it matches a multi-word command */
- if (strncmp(cmd->name, cmd_name, cmd_name_len) == 0 &&
- cmd->name[cmd_name_len] == ' ') {
- const char *subcmd = cmd->name + cmd_name_len + 1;
-
- orig_argc = *argc;
- orig_argv = *argv;
- if (doveadm_mail_cmd_try_find_multi_word(cmd, subcmd,
- argc, argv))
- return cmd;
- *argc = orig_argc;
- *argv = orig_argv;
- }
- }
-
- return NULL;
-}
-
-bool doveadm_mail_try_run(const char *cmd_name, int argc, char *argv[])
-{
- const struct doveadm_mail_cmd *cmd;
-
- cmd = doveadm_mail_cmd_find_from_argv(cmd_name, &argc, (void *)&argv);
- if (cmd == NULL)
- return FALSE;
- doveadm_mail_cmd(cmd, argc, argv);
- return TRUE;
-}
-
-void doveadm_mail_register_cmd(const struct doveadm_mail_cmd *cmd)
-{
- /* for now we'll just assume that cmd will be permanently in memory */
- array_push_back(&doveadm_mail_cmds, cmd);
-}
-
-const struct doveadm_mail_cmd *doveadm_mail_cmd_find(const char *cmd_name)
-{
- const struct doveadm_mail_cmd *cmd;
-
- array_foreach(&doveadm_mail_cmds, cmd) {
- if (strcmp(cmd->name, cmd_name) == 0)
- return cmd;
- }
- return NULL;
-}
-
-void doveadm_mail_usage(string_t *out)
-{
- const struct doveadm_mail_cmd *cmd;
-
- array_foreach(&doveadm_mail_cmds, cmd) {
- if (cmd->usage_args == &doveadm_mail_cmd_hide)
- continue;
- str_printfa(out, "%s\t"DOVEADM_CMD_MAIL_USAGE_PREFIX, cmd->name);
- if (cmd->usage_args != NULL)
- str_append(out, cmd->usage_args);
- str_append_c(out, '\n');
- }
-}
-
void doveadm_mail_help(const struct doveadm_mail_cmd *cmd)
{
fprintf(stderr, "doveadm %s "DOVEADM_CMD_MAIL_USAGE_PREFIX" %s\n",
void doveadm_mail_try_help_name(const char *cmd_name)
{
const struct doveadm_cmd_ver2 *cmd2;
- const struct doveadm_mail_cmd *cmd;
cmd2 = doveadm_cmd_find_ver2(cmd_name);
if (cmd2 != NULL)
help_ver2(cmd2);
-
- cmd = doveadm_mail_cmd_find(cmd_name);
- if (cmd != NULL)
- doveadm_mail_help(cmd);
-}
-
-bool doveadm_mail_has_subcommands(const char *cmd_name)
-{
- const struct doveadm_mail_cmd *cmd;
- size_t len = strlen(cmd_name);
-
- array_foreach(&doveadm_mail_cmds, cmd) {
- if (strncmp(cmd->name, cmd_name, len) == 0 &&
- cmd->name[len] == ' ')
- return TRUE;
- }
- return FALSE;
}
void doveadm_mail_help_name(const char *cmd_name)
DOVEADM_CMD_PARAMS_END
};
-static struct doveadm_mail_cmd *mail_commands[] = {
-};
-
static struct doveadm_cmd_ver2 *mail_commands_ver2[] = {
&doveadm_cmd_batch,
&doveadm_cmd_dsync_backup,
{
unsigned int i;
- i_array_init(&doveadm_mail_cmds, 32);
- for (i = 0; i < N_ELEMENTS(mail_commands); i++)
- doveadm_mail_register_cmd(mail_commands[i]);
-
for (i = 0; i < N_ELEMENTS(mail_commands_ver2); i++)
doveadm_cmd_register_ver2(mail_commands_ver2[i]);
}
void doveadm_mail_deinit(void)
{
mail_storage_deinit();
- array_free(&doveadm_mail_cmds);
}
static int doveadm_cmd_parse_arg(struct doveadm_mail_cmd_context *mctx,
const char *name;
const char *usage_args;
};
-ARRAY_DEFINE_TYPE(doveadm_mail_cmd, struct doveadm_mail_cmd);
-extern ARRAY_TYPE(doveadm_mail_cmd) doveadm_mail_cmds;
extern void (*hook_doveadm_mail_init)(struct doveadm_mail_cmd_context *ctx);
extern struct doveadm_mail_cmd_module_register doveadm_mail_cmd_module_register;
extern char doveadm_mail_cmd_hide;
bool doveadm_is_killed(void);
int doveadm_killed_signo(void);
-bool doveadm_mail_try_run(const char *cmd_name, int argc, char *argv[]);
-void doveadm_mail_register_cmd(const struct doveadm_mail_cmd *cmd);
-const struct doveadm_mail_cmd *doveadm_mail_cmd_find(const char *cmd_name);
-
-void doveadm_mail_usage(string_t *out);
void doveadm_mail_help(const struct doveadm_mail_cmd *cmd) ATTR_NORETURN;
void doveadm_mail_help_name(const char *cmd_name) ATTR_NORETURN;
void doveadm_mail_try_help_name(const char *cmd_name);
-bool doveadm_mail_has_subcommands(const char *cmd_name);
void doveadm_mail_init(void);
void doveadm_mail_init_finish(void);
void doveadm_mail_deinit(void);
-const struct doveadm_mail_cmd *
-doveadm_mail_cmd_find_from_argv(const char *cmd_name, int *argc,
- const char *const **argv);
struct doveadm_mail_cmd_context *
doveadm_mail_cmd_init(const struct doveadm_mail_cmd *cmd,
const struct doveadm_settings *set);
array_foreach(&doveadm_cmds_ver2, cmd2)
str_printfa(str, "%s\t%s\n", cmd2->name, cmd2->usage);
- doveadm_mail_usage(str);
doveadm_usage_compress_lines(out, str_c(str), prefix);
lib_exit(EX_USAGE);
cmd2->name[len] == ' ')
return TRUE;
}
- return doveadm_mail_has_subcommands(cmd_name);
+ return FALSE;
}
static struct doveadm_cmd_ver2 *doveadm_cmdline_commands_ver2[] = {
the env pointer */
cctx.username = getenv("USER");
- if (!doveadm_cmd_try_run_ver2(cmd_name, argc, (const char**)argv, &cctx) &&
- !doveadm_mail_try_run(cmd_name, argc, argv)) {
+ if (!doveadm_cmd_try_run_ver2(cmd_name, argc, (const char**)argv, &cctx)) {
if (doveadm_has_subcommands(cmd_name))
usage_to(stdout, cmd_name);
if (doveadm_has_unloaded_plugin(cmd_name)) {