daf71ef61c
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.
144 lines
4.6 KiB
C
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;
|
|
}
|