dovecot-2.2: doveadm: Code cleanups to prepare server code for n...

dovecot at dovecot.org dovecot at dovecot.org
Tue Nov 11 23:08:52 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/b8a7fec1beeb
changeset: 18057:b8a7fec1beeb
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Nov 12 00:20:40 2014 +0200
description:
doveadm: Code cleanups to prepare server code for non-mail commands.

diffstat:

 src/doveadm/client-connection.c |  48 ++++++++++++++--------
 src/doveadm/doveadm.c           |  85 ++++++++++++++++++++++++----------------
 2 files changed, 81 insertions(+), 52 deletions(-)

diffs (218 lines):

diff -r 062230bdbc4d -r b8a7fec1beeb src/doveadm/client-connection.c
--- a/src/doveadm/client-connection.c	Tue Nov 11 05:06:09 2014 +0200
+++ b/src/doveadm/client-connection.c	Wed Nov 12 00:20:40 2014 +0200
@@ -26,24 +26,18 @@
 
 static void client_connection_input(struct client_connection *conn);
 
-static struct doveadm_mail_cmd_context *
-doveadm_mail_cmd_server_parse(const char *cmd_name,
+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[])
+			      int argc, char *argv[],
+			      struct doveadm_mail_cmd_context **ctx_r)
 {
 	struct doveadm_mail_cmd_context *ctx;
-	const struct doveadm_mail_cmd *cmd;
 	const char *getopt_args;
 	bool add_username_header = FALSE;
 	int c;
 
-	cmd = doveadm_mail_cmd_find(cmd_name);
-	if (cmd == NULL) {
-		i_error("doveadm: Client sent unknown command: %s", cmd_name);
-		return NULL;
-	}
-
 	ctx = doveadm_mail_cmd_init(cmd, set);
 	ctx->full_args = (const void *)(argv + 1);
 	ctx->proxying = TRUE;
@@ -77,7 +71,7 @@
 					cmd->name, c);
 				ctx->v.deinit(ctx);
 				pool_unref(&ctx->pool);
-				return NULL;
+				return -1;
 			}
 		}
 	}
@@ -88,7 +82,7 @@
 			cmd->name, argv[0]);
 		ctx->v.deinit(ctx);
 		pool_unref(&ctx->pool);
-		return NULL;
+		return -1;
 	}
 	ctx->args = (const void *)argv;
 
@@ -98,7 +92,8 @@
 				     DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
 		doveadm_print_sticky("username", input->username);
 	}
-	return ctx;
+	*ctx_r = ctx;
+	return 0;
 }
 
 static void
@@ -172,10 +167,30 @@
 	return ret;
 }
 
+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_mail_cmd *cmd;
+	struct doveadm_mail_cmd_context *ctx;
+
+	cmd = doveadm_mail_cmd_find(cmd_name);
+	if (cmd == NULL) {
+		i_error("doveadm: Client sent unknown command: %s", cmd_name);
+		return -1;
+	}
+
+	if (doveadm_mail_cmd_server_parse(cmd, conn->set, input,
+					  argc, argv, &ctx) < 0)
+		return -1;
+	doveadm_mail_cmd_server_run(conn, ctx, input);
+	return 0;
+}
+
 static bool client_handle_command(struct client_connection *conn, char **args)
 {
 	struct mail_storage_service_input input;
-	struct doveadm_mail_cmd_context *ctx;
 	const char *flags, *cmd_name;
 	unsigned int argc;
 
@@ -225,11 +240,8 @@
 	}
 
 	o_stream_cork(conn->output);
-	ctx = doveadm_mail_cmd_server_parse(cmd_name, conn->set, &input, argc, args);
-	if (ctx == NULL)
+	if (doveadm_cmd_handle(conn, cmd_name, &input, argc, args) < 0)
 		o_stream_nsend(conn->output, "\n-\n", 3);
-	else
-		doveadm_mail_cmd_server_run(conn, ctx, &input);
 	o_stream_uncork(conn->output);
 
 	/* flush the output and disconnect */
diff -r 062230bdbc4d -r b8a7fec1beeb src/doveadm/doveadm.c
--- a/src/doveadm/doveadm.c	Tue Nov 11 05:06:09 2014 +0200
+++ b/src/doveadm/doveadm.c	Wed Nov 12 00:20:40 2014 +0200
@@ -199,58 +199,75 @@
 	i_fatal("execv(%s) failed: %m", argv[0]);
 }
 
-static bool
-doveadm_try_run_multi_word(const struct doveadm_cmd *cmd,
-			   const char *cmdname, int argc, char *argv[])
+static const struct doveadm_cmd *
+doveadm_cmd_find_multi_word(const struct doveadm_cmd *cmd,
+			    const char *cmdname, int *_argc, char **_argv[])
 {
+	int argc = *_argc;
+	char **argv = *_argv;
+	const struct doveadm_cmd *subcmd;
 	unsigned int len;
 
 	if (argc < 2)
-		return FALSE;
+		return NULL;
 
 	len = strlen(argv[1]);
 	if (strncmp(cmdname, argv[1], len) != 0)
-		return FALSE;
+		return NULL;
 
+	argc--; argv++;
 	if (cmdname[len] == ' ') {
 		/* more args */
-		return doveadm_try_run_multi_word(cmd, cmdname + len + 1,
-						  argc - 1, argv + 1);
+		subcmd = doveadm_cmd_find_multi_word(cmd, cmdname + len + 1,
+						     &argc, &argv);
+		if (subcmd == NULL)
+			return NULL;
+	} else {
+		if (cmdname[len] != '\0')
+			return NULL;
 	}
-	if (cmdname[len] != '\0')
-		return FALSE;
 
-	/* match */
-	cmd->cmd(argc - 1, argv + 1);
-	return TRUE;
+	*_argc = argc;
+	*_argv = argv;
+	return cmd;
+}
+
+static const struct doveadm_cmd *
+doveadm_cmd_find(const char *cmd_name, int *argc, char **argv[])
+{
+	const struct doveadm_cmd *cmd, *subcmd;
+	unsigned int cmd_name_len;
+
+	i_assert(*argc > 0);
+
+	cmd_name_len = strlen(cmd_name);
+	array_foreach(&doveadm_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_name = cmd->name + cmd_name_len + 1;
+
+			subcmd = doveadm_cmd_find_multi_word(cmd, subcmd_name,
+							     argc, argv);
+			if (subcmd != NULL)
+				return subcmd;
+		}
+	}
+	return NULL;
 }
 
 static bool doveadm_try_run(const char *cmd_name, int argc, char *argv[])
 {
 	const struct doveadm_cmd *cmd;
-	unsigned int cmd_name_len;
 
-	i_assert(argc > 0);
-
-	cmd_name_len = strlen(cmd_name);
-	array_foreach(&doveadm_cmds, cmd) {
-		if (strcmp(cmd->name, cmd_name) == 0) {
-			cmd->cmd(argc, argv);
-			return TRUE;
-		}
-
-		/* 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;
-
-			if (doveadm_try_run_multi_word(cmd, subcmd,
-						       argc, argv))
-				return TRUE;
-		}
-	}
-
-	return FALSE;
+	cmd = doveadm_cmd_find(cmd_name, &argc, &argv);
+	if (cmd == NULL)
+		return FALSE;
+	cmd->cmd(argc, argv);
+	return TRUE;
 }
 
 static bool doveadm_has_subcommands(const char *cmd_name)


More information about the dovecot-cvs mailing list