changeset 19867:762c50005198

doveadm: Added struct doveadm_cmd_attributes, which is passed around instead of argc/argv
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Fri, 26 Feb 2016 14:55:02 +0200
parents 9b02eea350be
children 4499f7e2a642
files src/doveadm/client-connection.c src/doveadm/doveadm-cmd.c src/doveadm/doveadm-cmd.h src/doveadm/doveadm.c
diffstat 4 files changed, 58 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/src/doveadm/client-connection.c	Wed Feb 24 13:59:28 2016 +0200
+++ b/src/doveadm/client-connection.c	Fri Feb 26 14:55:02 2016 +0200
@@ -69,22 +69,23 @@
 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 @@
 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 @@
 	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 @@
 
 	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 @@
 			}
 		}
 	}
-	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 @@
 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 @@
 	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 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 @@
 		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 @@
 	}
 
 	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);
 
--- a/src/doveadm/doveadm-cmd.c	Wed Feb 24 13:59:28 2016 +0200
+++ b/src/doveadm/doveadm-cmd.c	Fri Feb 26 14:55:02 2016 +0200
@@ -97,10 +97,10 @@
 
 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 @@
 }
 
 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 @@
 	}
 }
 
-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 @@
 	}
 	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 @@
 	while((cptr = strchr(cptr+1, ' ')) != NULL) optind++;
 
 	/* process positional arguments */
-	for(;optind<argc;optind++) {
+	for(;optind<attrs->argc;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;
 			}
--- a/src/doveadm/doveadm-cmd.h	Wed Feb 24 13:59:28 2016 +0200
+++ b/src/doveadm/doveadm-cmd.h	Fri Feb 26 14:55:02 2016 +0200
@@ -66,6 +66,11 @@
 	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 @@
 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 @@
 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);
--- a/src/doveadm/doveadm.c	Wed Feb 24 13:59:28 2016 +0200
+++ b/src/doveadm/doveadm.c	Fri Feb 26 14:55:02 2016 +0200
@@ -210,14 +210,14 @@
 	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 @@
 	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 @@
 		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);