]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm: Process subcommand "--help" options
authorKarl Fleischmann <karl.fleischmann@open-xchange.com>
Thu, 22 Jun 2023 10:18:07 +0000 (12:18 +0200)
committerKarl Fleischmann <karl.fleischmann@open-xchange.com>
Mon, 10 Jul 2023 10:10:42 +0000 (12:10 +0200)
Arguments are handled individually in different situations when invoking
doveadm with or without subcommands (specifically
doveadm_cmdline_find_with_args() may fail if "help" is passed). To
handle all necessary situtations the command context needs to be
expanded with a variable to differentiate whether a help argument (i.e.
"--help") or a help option (i.e. "help") is given. This is used
subsequently to print the help/usage text to stdout with a successful
return code if requested.

src/doveadm/doveadm-cmd-parse.h
src/doveadm/doveadm-cmd.c
src/doveadm/doveadm.c

index ce9d15302ebd5cfc0655258d36b3c615ed2bd7e4..54b2578add60196b43e5bbe714f37f663d8ba544 100644 (file)
@@ -90,12 +90,19 @@ struct doveadm_cmd_ver2 {
        const struct doveadm_cmd_param *parameters;
 };
 
+enum doveadm_cmd_ver2_help_requested {
+       DOVEADM_CMD_VER2_NO_HELP,
+       DOVEADM_CMD_VER2_HELP_ARGUMENT,
+       DOVEADM_CMD_VER2_HELP_COMMAND,
+};
+
 struct doveadm_cmd_context {
        const struct doveadm_cmd_ver2 *cmd; /* for help */
 
        pool_t pool;
        int argc;
        const struct doveadm_cmd_param *argv;
+       enum doveadm_cmd_ver2_help_requested help_requested;
 
        const char *username;
        struct ip_addr local_ip, remote_ip;
index 1f64fd3446e17cd4a7054c47b3e8d71012e13362..147d172001f8eb19c99a8a843f034f0cb3325c51 100644 (file)
@@ -124,17 +124,39 @@ void doveadm_cmds_deinit(void)
        array_free(&doveadm_cmds_ver2);
 }
 
+static void
+doveadm_cmdline_check_for_help_request(int argc, const char *const argv[],
+                                      struct doveadm_cmd_context *cctx) {
+       for (int i = 0; i < argc; i++) {
+               if (strcmp(argv[i], "--") == 0)
+                       break;
+
+               if (strcmp(argv[i], "--help") == 0) {
+                       cctx->help_requested = DOVEADM_CMD_VER2_HELP_ARGUMENT;
+                       break;
+               }
+
+               if (strcmp(argv[i], "help") == 0) {
+                       cctx->help_requested = DOVEADM_CMD_VER2_HELP_COMMAND;
+                       break;
+               }
+       }
+}
+
 bool doveadm_cmdline_try_run(const char *cmd_name,
                             int argc, const char *const argv[],
                             struct doveadm_cmd_context *cctx)
 {
        const struct doveadm_cmd_ver2 *cmd;
 
+       doveadm_cmdline_check_for_help_request(argc, argv, cctx);
        cmd = doveadm_cmdline_find_with_args(cmd_name, &argc, &argv);
        if (cmd == NULL)
                return FALSE;
 
        cctx->cmd = cmd;
+       if (cctx->help_requested == DOVEADM_CMD_VER2_HELP_ARGUMENT)
+               return FALSE;
        if (doveadm_cmdline_run(argc, argv, cctx) < 0)
                doveadm_exit_code = EX_USAGE;
        return TRUE;
index 30e8c25f36e567284447af857c06e2c6f5bab05a..45d7b54234d33a92a5b8bc6a57fc4bf5e1150bf6 100644 (file)
@@ -383,8 +383,16 @@ int main(int argc, char *argv[])
        cctx->username = getenv("USER");
 
        if (!doveadm_cmdline_try_run(cmd_name, argc, (const char**)argv, cctx)) {
+               help_requested = cctx->help_requested != DOVEADM_CMD_VER2_NO_HELP;
+               FILE *out = help_requested ? stdout : stderr;
+               int exit_code = help_requested ? EX_OK : EX_USAGE;
+               if (cctx->help_requested == DOVEADM_CMD_VER2_HELP_ARGUMENT &&
+                   cctx->cmd != NULL) {
+                       print_usage_and_exit(stdout, cctx->cmd, EX_OK);
+               }
                if (doveadm_has_subcommands(cmd_name))
-                       usage_prefix(stderr, cmd_name, EX_USAGE);
+                       usage_prefix(out, cmd_name, exit_code);
+
                if (doveadm_has_unloaded_plugin(cmd_name)) {
                        i_fatal("Unknown command '%s', but plugin %s exists. "
                                "Try to set mail_plugins=%s",