systemctl: convert shutdown_parse_argv to OPTION macros
Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user