]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm: Code cleanups to prepare server code for non-mail commands.
authorTimo Sirainen <tss@iki.fi>
Tue, 11 Nov 2014 22:20:40 +0000 (00:20 +0200)
committerTimo Sirainen <tss@iki.fi>
Tue, 11 Nov 2014 22:20:40 +0000 (00:20 +0200)
src/doveadm/client-connection.c
src/doveadm/doveadm.c

index f1ae467d4c7afa95decb3cc0b86f4e50c01ac0c0..85f2148c1b4fee28a4591795627209276df6af69 100644 (file)
 
 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 @@ doveadm_mail_cmd_server_parse(const char *cmd_name,
                                        cmd->name, c);
                                ctx->v.deinit(ctx);
                                pool_unref(&ctx->pool);
-                               return NULL;
+                               return -1;
                        }
                }
        }
@@ -88,7 +82,7 @@ doveadm_mail_cmd_server_parse(const char *cmd_name,
                        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_mail_cmd_server_parse(const char *cmd_name,
                                     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 @@ static bool client_is_allowed_command(const struct doveadm_settings *set,
        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 @@ static bool client_handle_command(struct client_connection *conn, char **args)
        }
 
        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 */
index eb6416ea6fbeadef567b4261e117f9a11a2d8f2c..5863ce2017f0198fd4a96d95d24a987e8fd7a355 100644 (file)
@@ -199,58 +199,75 @@ static void cmd_exec(int argc ATTR_UNUSED, char *argv[])
        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)