From: Zbigniew Jędrzejewski-Szmek Date: Wed, 13 May 2026 21:02:48 +0000 (+0200) Subject: systemctl: convert shutdown_parse_argv to OPTION macros X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=23ba690cca95e9f0226d55f9a0fbf42decb256c1;p=thirdparty%2Fsystemd.git systemctl: convert shutdown_parse_argv to OPTION macros Co-developed-by: Claude Opus 4.7 --- diff --git a/src/systemctl/systemctl-compat-shutdown.c b/src/systemctl/systemctl-compat-shutdown.c index cfc917073ae..f4dbd80473a 100644 --- a/src/systemctl/systemctl-compat-shutdown.c +++ b/src/systemctl/systemctl-compat-shutdown.c @@ -1,11 +1,11 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include - -#include "alloc-util.h" +#include "ansi-color.h" +#include "format-table.h" +#include "help-util.h" #include "log.h" +#include "options.h" #include "parse-util.h" -#include "pretty-print.h" #include "reboot-util.h" #include "string-util.h" #include "strv.h" @@ -14,38 +14,31 @@ #include "time-util.h" static int shutdown_help(void) { - _cleanup_free_ char *link = NULL; + _cleanup_(table_unrefp) Table *options = NULL; int r; - r = terminal_urlify_man("shutdown", "8", &link); + r = option_parser_get_help_table_ns("shutdown", &options); if (r < 0) - return log_oom(); + return r; /* Note: if you are tempted to add new command line switches here, please do not. Let this * compatibility command rest in peace. Its interface is not even owned by us as much as it is by * sysvinit. If you add something new, add it to "systemctl halt", "systemctl reboot", "systemctl * poweroff" instead. */ - printf("%s [OPTIONS...] [TIME] [WALL...]\n" - "\n%sShut down the system.%s\n" - "\nOptions:\n" - " --help Show this help\n" - " -H --halt Halt the machine\n" - " -P --poweroff Power-off the machine\n" - " -r --reboot Reboot the machine\n" - " -h Equivalent to --poweroff, overridden by --halt\n" - " -k Don't halt/power-off/reboot, just send warnings\n" - " --no-wall Don't send wall message before halt/power-off/reboot\n" - " -c Cancel a pending shutdown\n" - " --show Show pending shutdown\n" - "\n%sThis is a compatibility interface, please use the more powerful 'systemctl halt',\n" - "'systemctl poweroff', 'systemctl reboot' commands instead.%s\n" - "\nSee the %s for details.\n", - program_invocation_short_name, - ansi_highlight(), ansi_normal(), - ansi_highlight_red(), ansi_normal(), - link); + help_cmdline("[OPTIONS…] [TIME] [WALL…]"); + help_abstract("Shut down the system."); + + help_section("Options"); + r = table_print_or_warn(options); + if (r < 0) + return r; + + printf("\n%sThis is a compatibility interface, please use the more powerful 'systemctl halt',\n" + "'systemctl poweroff', 'systemctl reboot' commands instead.%s\n", + ansi_highlight_red(), ansi_normal()); + help_man_page_reference("shutdown", "8"); return 0; } @@ -124,104 +117,86 @@ static int parse_shutdown_time_spec(const char *t, usec_t *ret) { } int shutdown_parse_argv(int argc, char *argv[]) { - enum { - ARG_HELP = 0x100, - ARG_NO_WALL, - ARG_SHOW - }; - - static const struct option options[] = { - { "help", no_argument, NULL, ARG_HELP }, - { "halt", no_argument, NULL, 'H' }, - { "poweroff", no_argument, NULL, 'P' }, - { "reboot", no_argument, NULL, 'r' }, - { "kexec", no_argument, NULL, 'K' }, /* not documented extension */ - { "no-wall", no_argument, NULL, ARG_NO_WALL }, - { "show", no_argument, NULL, ARG_SHOW }, - {} - }; - - char **wall = NULL; - int c, r; + int r; assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "HPrhkKat:fFc", options, NULL)) >= 0) + OptionParser opts = { argc, argv, .namespace = "shutdown" }; + + FOREACH_OPTION_OR_RETURN(c, &opts) switch (c) { - case ARG_HELP: + OPTION_NAMESPACE("shutdown"): {} + + OPTION_LONG("help", NULL, "Show this help"): return shutdown_help(); - case 'H': + OPTION('H', "halt", NULL, "Halt the machine"): arg_action = ACTION_HALT; break; - case 'P': + OPTION('P', "poweroff", NULL, "Power-off the machine"): arg_action = ACTION_POWEROFF; break; - case 'r': + OPTION('r', "reboot", NULL, "Reboot the machine"): if (kexec_loaded()) arg_action = ACTION_KEXEC; else arg_action = ACTION_REBOOT; break; - case 'K': - arg_action = ACTION_KEXEC; - break; - - case 'h': + OPTION_SHORT('h', NULL, "Equivalent to --poweroff, overridden by --halt"): if (arg_action != ACTION_HALT) arg_action = ACTION_POWEROFF; break; - case 'k': + OPTION_SHORT('k', NULL, "Don't halt/power-off/reboot, just send warnings"): arg_dry_run = true; break; - case ARG_NO_WALL: + OPTION_LONG("no-wall", NULL, "Don't send wall message before halt/power-off/reboot"): arg_no_wall = true; break; - case 'a': - case 't': /* Note that we also ignore any passed argument to -t, not just the -t itself */ - case 'f': - case 'F': - /* Compatibility nops */ - break; - - case 'c': + OPTION_SHORT('c', NULL, "Cancel a pending shutdown"): arg_action = ACTION_CANCEL_SHUTDOWN; break; - case ARG_SHOW: + OPTION_LONG("show", NULL, "Show pending shutdown"): arg_action = ACTION_SHOW_SHUTDOWN; break; - case '?': - return -EINVAL; + /* Hidden compat options. */ + OPTION('K', "kexec", NULL, /* help= */ NULL): + arg_action = ACTION_KEXEC; + break; - default: - assert_not_reached(); + OPTION_SHORT('a', NULL, /* help= */ NULL): {} /* compatibility noops */ + OPTION_SHORT('f', NULL, /* help= */ NULL): {} + OPTION_SHORT('F', NULL, /* help= */ NULL): {} + OPTION_SHORT('t', "ARG", /* help= */ NULL): + break; } - if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) { - r = parse_shutdown_time_spec(argv[optind], &arg_when); - if (r < 0) { - log_error("Failed to parse time specification: %s", argv[optind]); - return r; - } + char **args = option_parser_get_args(&opts); + size_t n_args = option_parser_get_n_args(&opts); + + if (n_args > 0 && arg_action != ACTION_CANCEL_SHUTDOWN) { + r = parse_shutdown_time_spec(args[0], &arg_when); + if (r < 0) + return log_error_errno(r, "Failed to parse time specification: %s", args[0]); } else arg_when = USEC_INFINITY; /* logind chooses on server side */ - if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN) + char **wall = NULL; + if (n_args > 0 && arg_action == ACTION_CANCEL_SHUTDOWN) /* No time argument for shutdown cancel */ - wall = argv + optind; - else if (argc > optind + 1) + wall = args; + else if (n_args > 1) /* We skip the time argument */ - wall = argv + optind + 1; + wall = args + 1; if (wall) { char **copy = strv_copy(wall); @@ -230,7 +205,5 @@ int shutdown_parse_argv(int argc, char *argv[]) { strv_free_and_replace(arg_wall, copy); } - optind = argc; - return 1; }