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;
cmd->name, c);
ctx->v.deinit(ctx);
pool_unref(&ctx->pool);
- return NULL;
+ return -1;
}
}
}
cmd->name, argv[0]);
ctx->v.deinit(ctx);
pool_unref(&ctx->pool);
- return NULL;
+ return -1;
}
ctx->args = (const void *)argv;
DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
doveadm_print_sticky("username", input->username);
}
- return ctx;
+ *ctx_r = ctx;
+ return 0;
}
static void
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;
}
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 */
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 bool doveadm_try_run(const char *cmd_name, int argc, char *argv[])
+static const struct doveadm_cmd *
+doveadm_cmd_find(const char *cmd_name, int *argc, char **argv[])
{
- const struct doveadm_cmd *cmd;
+ const struct doveadm_cmd *cmd, *subcmd;
unsigned int cmd_name_len;
- i_assert(argc > 0);
+ 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;
- }
+ 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;
+ const char *subcmd_name = cmd->name + cmd_name_len + 1;
- if (doveadm_try_run_multi_word(cmd, subcmd,
- argc, argv))
- return TRUE;
+ 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;
- 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)