Systemd/src/systemctl/systemctl-compat-shutdown.c
Lennart Poettering daf71ef61c systemctl: split up humungous systemctl.c file
This is just some refactoring: shifting around of code, not change in
codeflow.

This splits up the way too huge systemctl.c in multiple more easily
digestable files. It roughly follows the rule that each family of verbs
gets its own .c/.h file pair, and so do all the compat executable names
we support. Plus three extra files for sysv compat (which existed before
already, but I renamed slightly, to get the systemctl- prefix lik
everything else), a -util file with generic stuff everything uses, and a
-logind file with everything that talks directly to logind instead of
PID1.

systemctl is still a bit too complex for my taste, but I think this way
itc omes in a more digestable bits at least.

No change of behaviour, just reshuffling of some code.
2020-10-07 23:12:15 +02:00

144 lines
4.6 KiB
C

/* SPDX-License-Identifier: LGPL-2.1+ */
#include <getopt.h>
#include "alloc-util.h"
#include "pretty-print.h"
#include "systemctl-compat-shutdown.h"
#include "systemctl-sysv-compat.h"
#include "systemctl.h"
#include "terminal-util.h"
static int shutdown_help(void) {
_cleanup_free_ char *link = NULL;
int r;
r = terminal_urlify_man("shutdown", "8", &link);
if (r < 0)
return log_oom();
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"
"\nSee the %s for details.\n"
, program_invocation_short_name
, ansi_highlight(), ansi_normal()
, link
);
return 0;
}
int shutdown_parse_argv(int argc, char *argv[]) {
enum {
ARG_HELP = 0x100,
ARG_NO_WALL
};
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 },
{}
};
char **wall = NULL;
int c, r;
assert(argc >= 0);
assert(argv);
while ((c = getopt_long(argc, argv, "HPrhkKat:fFc", options, NULL)) >= 0)
switch (c) {
case ARG_HELP:
return shutdown_help();
case 'H':
arg_action = ACTION_HALT;
break;
case 'P':
arg_action = ACTION_POWEROFF;
break;
case 'r':
if (kexec_loaded())
arg_action = ACTION_KEXEC;
else
arg_action = ACTION_REBOOT;
break;
case 'K':
arg_action = ACTION_KEXEC;
break;
case 'h':
if (arg_action != ACTION_HALT)
arg_action = ACTION_POWEROFF;
break;
case 'k':
arg_dry_run = true;
break;
case ARG_NO_WALL:
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':
arg_action = ACTION_CANCEL_SHUTDOWN;
break;
case '?':
return -EINVAL;
default:
assert_not_reached("Unhandled option");
}
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;
}
} else
arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
/* No time argument for shutdown cancel */
wall = argv + optind;
else if (argc > optind + 1)
/* We skip the time argument */
wall = argv + optind + 1;
if (wall) {
arg_wall = strv_copy(wall);
if (!arg_wall)
return log_oom();
}
optind = argc;
return 1;
}