From 79bbb900ffba886779474dfb04c41408f0ba0602 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Fri, 26 Feb 2016 14:55:02 +0200 Subject: [PATCH] doveadm: Added struct doveadm_cmd_attributes, which is passed around instead of argc/argv --- src/doveadm/client-connection.c | 47 ++++++++++++++++++++------------- src/doveadm/doveadm-cmd.c | 22 ++++++++------- src/doveadm/doveadm-cmd.h | 13 ++++++--- src/doveadm/doveadm.c | 13 ++++++--- 4 files changed, 58 insertions(+), 37 deletions(-) diff --git a/src/doveadm/client-connection.c b/src/doveadm/client-connection.c index ccc6e2dd54..3492a78e80 100644 --- a/src/doveadm/client-connection.c +++ b/src/doveadm/client-connection.c @@ -69,22 +69,23 @@ doveadm_cmd_server_post(struct client_connection *conn, const char *cmd_name) static void doveadm_cmd_server_run_ver2(struct client_connection *conn, const struct doveadm_cmd_ver2 *cmd, - int argc, const char *argv[]) + const struct doveadm_cmd_attributes *attrs) { i_getopt_reset(); doveadm_exit_code = 0; - if (doveadm_cmd_run_ver2(cmd, argc, argv) < 0) + if (doveadm_cmd_run_ver2(cmd, attrs) < 0) doveadm_exit_code = EX_USAGE; doveadm_cmd_server_post(conn, cmd->name); } static void doveadm_cmd_server_run(struct client_connection *conn, - const struct doveadm_cmd *cmd, int argc, char *argv[]) + const struct doveadm_cmd *cmd, + const struct doveadm_cmd_attributes *attrs) { i_getopt_reset(); doveadm_exit_code = 0; - cmd->cmd(argc, argv); + cmd->cmd(attrs->argc, (char **)attrs->argv); doveadm_cmd_server_post(conn, cmd->name); } @@ -92,7 +93,7 @@ static int doveadm_mail_cmd_server_parse(const struct doveadm_mail_cmd *cmd, const struct doveadm_settings *set, const struct mail_storage_service_input *input, - int argc, char *argv[], + const struct doveadm_cmd_attributes *attrs, struct doveadm_mail_cmd_context **ctx_r) { struct doveadm_mail_cmd_context *ctx; @@ -101,7 +102,7 @@ doveadm_mail_cmd_server_parse(const struct doveadm_mail_cmd *cmd, int c; ctx = doveadm_mail_cmd_init(cmd, set); - ctx->full_args = (const void *)(argv + 1); + ctx->full_args = attrs->argv + 1; ctx->proxying = TRUE; ctx->service_flags |= @@ -112,7 +113,7 @@ doveadm_mail_cmd_server_parse(const struct doveadm_mail_cmd *cmd, i_getopt_reset(); getopt_args = t_strconcat("AF:S:u:", ctx->getopt_args, NULL); - while ((c = getopt(argc, argv, getopt_args)) > 0) { + while ((c = getopt(attrs->argc, (char **)attrs->argv, getopt_args)) > 0) { switch (c) { case 'A': case 'F': @@ -138,16 +139,15 @@ doveadm_mail_cmd_server_parse(const struct doveadm_mail_cmd *cmd, } } } - argv += optind; - if (argv[0] != NULL && cmd->usage_args == NULL) { + if (attrs->argv[optind] != NULL && cmd->usage_args == NULL) { i_error("doveadm %s: Client sent unknown parameter: %s", - cmd->name, argv[0]); + cmd->name, attrs->argv[optind]); ctx->v.deinit(ctx); pool_unref(&ctx->pool); return -1; } - ctx->args = (const void *)argv; + ctx->args = attrs->argv+optind; if (doveadm_print_is_initialized() && add_username_header) { doveadm_print_header("username", "Username", @@ -219,25 +219,29 @@ bool doveadm_client_is_allowed_command(const struct doveadm_settings *set, static int doveadm_cmd_handle(struct client_connection *conn, const char *cmd_name, const struct mail_storage_service_input *input, - int argc, char *argv[]) + const struct doveadm_cmd_attributes *attrs) { struct ioloop *ioloop, *prev_ioloop = current_ioloop; const struct doveadm_cmd *cmd = NULL; const struct doveadm_mail_cmd *mail_cmd; struct doveadm_mail_cmd_context *ctx; const struct doveadm_cmd_ver2 *cmd_ver2; + struct doveadm_cmd_attributes cmd_attrs; - if ((cmd_ver2 = doveadm_cmd_find_with_args_ver2(cmd_name, argc, (const char**)argv)) == NULL) { - cmd = doveadm_cmd_find_with_args(cmd_name, &argc, &argv); + if ((cmd_ver2 = doveadm_cmd_find_with_args_ver2(cmd_name, attrs->argc, attrs->argv)) == NULL) { + cmd_attrs = *attrs; + cmd = doveadm_cmd_find_with_args(cmd_name, &cmd_attrs.argc, &cmd_attrs.argv); if (cmd == 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; } - if (doveadm_mail_cmd_server_parse(mail_cmd, conn->set, input, - argc, argv, &ctx) < 0) + if (doveadm_mail_cmd_server_parse(mail_cmd, conn->set, + input, attrs, &ctx) < 0) return -1; + } else { + attrs = &cmd_attrs; } } @@ -248,9 +252,9 @@ static int doveadm_cmd_handle(struct client_connection *conn, lib_signals_reset_ioloop(); if (cmd_ver2 != NULL) - doveadm_cmd_server_run_ver2(conn, cmd_ver2, argc, (const char**)argv); + doveadm_cmd_server_run_ver2(conn, cmd_ver2, attrs); else if (cmd != NULL) - doveadm_cmd_server_run(conn, cmd, argc, argv); + doveadm_cmd_server_run(conn, cmd, attrs); else doveadm_mail_cmd_server_run(conn, ctx, input); @@ -268,6 +272,7 @@ static int doveadm_cmd_handle(struct client_connection *conn, static bool client_handle_command(struct client_connection *conn, char **args) { + struct doveadm_cmd_attributes attrs; struct mail_storage_service_input input; const char *flags, *cmd_name; unsigned int argc; @@ -286,6 +291,10 @@ static bool client_handle_command(struct client_connection *conn, char **args) i_error("doveadm client: No command given"); return FALSE; } + memset(&attrs, 0, sizeof(attrs)); + attrs.argv = (const char **)args; + attrs.argc = argc; + flags = args[0]; input.username = args[1]; cmd_name = args[2]; @@ -318,7 +327,7 @@ static bool client_handle_command(struct client_connection *conn, char **args) } o_stream_cork(conn->output); - if (doveadm_cmd_handle(conn, cmd_name, &input, argc, args) < 0) + if (doveadm_cmd_handle(conn, cmd_name, &input, &attrs) < 0) o_stream_nsend(conn->output, "\n-\n", 3); o_stream_uncork(conn->output); diff --git a/src/doveadm/doveadm-cmd.c b/src/doveadm/doveadm-cmd.c index b1533c05a9..c2f2f38b1a 100644 --- a/src/doveadm/doveadm-cmd.c +++ b/src/doveadm/doveadm-cmd.c @@ -97,10 +97,10 @@ doveadm_cmd_find_with_args_ver2(const char *cmd_name, int argc, const char *argv static const struct doveadm_cmd * doveadm_cmd_find_multi_word(const struct doveadm_cmd *cmd, - const char *cmdname, int *_argc, char **_argv[]) + const char *cmdname, int *_argc, const char **_argv[]) { int argc = *_argc; - char **argv = *_argv; + const char **argv = *_argv; const struct doveadm_cmd *subcmd; unsigned int len; @@ -129,7 +129,7 @@ doveadm_cmd_find_multi_word(const struct doveadm_cmd *cmd, } const struct doveadm_cmd * -doveadm_cmd_find_with_args(const char *cmd_name, int *argc, char **argv[]) +doveadm_cmd_find_with_args(const char *cmd_name, int *argc, const char **argv[]) { const struct doveadm_cmd *cmd, *subcmd; unsigned int cmd_name_len; @@ -396,20 +396,22 @@ static void doveadm_fill_param(struct doveadm_cmd_param *param, } } -bool doveadm_cmd_try_run_ver2(const char *cmd_name, int argc, const char *argv[]) +bool doveadm_cmd_try_run_ver2(const char *cmd_name, + const struct doveadm_cmd_attributes *attrs) { const struct doveadm_cmd_ver2 *cmd; - cmd = doveadm_cmd_find_with_args_ver2(cmd_name, argc, argv); + cmd = doveadm_cmd_find_with_args_ver2(cmd_name, attrs->argc, attrs->argv); if (cmd == NULL) return FALSE; - if (doveadm_cmd_run_ver2(cmd, argc, argv) < 0) + if (doveadm_cmd_run_ver2(cmd, attrs) < 0) doveadm_exit_code = EX_USAGE; return TRUE; } -int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd, int argc, const char *argv[]) +int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd, + const struct doveadm_cmd_attributes *attrs) { struct doveadm_cmd_param *param; ARRAY_TYPE(doveadm_cmd_param_arr_t) pargv; @@ -434,7 +436,7 @@ int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd, int argc, const cha } i_assert(pargc == array_count(&opts)-1); /* opts is NULL-terminated */ - while((c = getopt_long(argc, (char*const*)argv, str_c(optbuf), array_idx(&opts, 0), &li)) > -1) { + while((c = getopt_long(attrs->argc, (char*const*)attrs->argv, str_c(optbuf), array_idx(&opts, 0), &li)) > -1) { switch(c) { case 0: doveadm_fill_param(array_idx_modifiable(&pargv,li), optarg, pool); @@ -457,13 +459,13 @@ int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd, int argc, const cha while((cptr = strchr(cptr+1, ' ')) != NULL) optind++; /* process positional arguments */ - for(;optindargc;optind++) { struct doveadm_cmd_param *ptr; bool found = FALSE; array_foreach_modifiable(&pargv, ptr) { if ((ptr->flags & CMD_PARAM_FLAG_POSITIONAL) != 0 && (ptr->value_set == FALSE || ptr->type == CMD_PARAM_ARRAY)) { - doveadm_fill_param(ptr, argv[optind], pool); + doveadm_fill_param(ptr, attrs->argv[optind], pool); found = TRUE; break; } diff --git a/src/doveadm/doveadm-cmd.h b/src/doveadm/doveadm-cmd.h index 1f4cc629d5..a7f4b2854a 100644 --- a/src/doveadm/doveadm-cmd.h +++ b/src/doveadm/doveadm-cmd.h @@ -66,6 +66,11 @@ struct doveadm_cmd_ver2 { const struct doveadm_cmd_param *parameters; }; +struct doveadm_cmd_attributes { + int argc; + const char **argv; +}; + ARRAY_DEFINE_TYPE(doveadm_cmd, struct doveadm_cmd); extern ARRAY_TYPE(doveadm_cmd) doveadm_cmds; @@ -84,7 +89,7 @@ extern struct doveadm_cmd doveadm_cmd_zlibconnect; void doveadm_register_cmd(const struct doveadm_cmd *cmd); const struct doveadm_cmd * -doveadm_cmd_find_with_args(const char *cmd_name, int *argc, char **argv[]); +doveadm_cmd_find_with_args(const char *cmd_name, int *argc, const char **argv[]); void doveadm_register_auth_commands(void); void doveadm_register_director_commands(void); @@ -109,11 +114,11 @@ const struct doveadm_cmd_ver2 * doveadm_cmd_find_with_args_ver2(const char *cmd_name, int argc, const char *argv[]); const struct doveadm_cmd_ver2 *doveadm_cmd_find_ver2(const char *cmd_name); /* Returns FALSE if cmd_name doesn't exist, TRUE if it exists. */ -bool doveadm_cmd_try_run_ver2(const char *cmd_name, int argc, - const char *argv[]); +bool doveadm_cmd_try_run_ver2(const char *cmd_name, + const struct doveadm_cmd_attributes *attrs); /* Returns 0 if success, -1 if parameters were invalid. */ int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd, - int argc, const char *argv[]); + const struct doveadm_cmd_attributes *attrs); bool doveadm_cmd_param_bool(int argc, const struct doveadm_cmd_param *params, const char *name, bool *value_r); diff --git a/src/doveadm/doveadm.c b/src/doveadm/doveadm.c index c41b30b561..a7b97d1c37 100644 --- a/src/doveadm/doveadm.c +++ b/src/doveadm/doveadm.c @@ -210,14 +210,14 @@ static void cmd_exec(int argc ATTR_UNUSED, char *argv[]) i_fatal("execv(%s) failed: %m", argv[0]); } -static bool doveadm_try_run(const char *cmd_name, int argc, char *argv[]) +static bool doveadm_try_run(const char *cmd_name, int argc, const char *argv[]) { const struct doveadm_cmd *cmd; cmd = doveadm_cmd_find_with_args(cmd_name, &argc, &argv); if (cmd == NULL) return FALSE; - cmd->cmd(argc, argv); + cmd->cmd(argc, (char **)argv); return TRUE; } @@ -283,6 +283,7 @@ int main(int argc, char *argv[]) enum master_service_flags service_flags = MASTER_SERVICE_FLAG_STANDALONE | MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN; + struct doveadm_cmd_attributes attrs; const char *cmd_name; unsigned int i; bool quick_init = FALSE; @@ -364,8 +365,12 @@ int main(int argc, char *argv[]) i_set_debug_file("/dev/null"); } - if (!doveadm_cmd_try_run_ver2(cmd_name, argc, (const char**)argv) && - !doveadm_try_run(cmd_name, argc, argv) && + memset(&attrs, 0, sizeof(attrs)); + attrs.argc = argc; + attrs.argv = (const char **)argv; + + if (!doveadm_cmd_try_run_ver2(cmd_name, &attrs) && + !doveadm_try_run(cmd_name, argc, (const char **)argv) && !doveadm_mail_try_run(cmd_name, argc, argv)) { if (doveadm_has_subcommands(cmd_name)) usage_to(stdout, cmd_name);