summarylogtreecommitdiffstats
path: root/shutdown
blob: 09151f5d9b36e8adf232fbf1f3c9749e1c541367 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#!/usr/bin/env bash

PIDFILE="/run/shutdown.pid"
NOLOGINFILE="/run/nologin"
name="${0##*/}"

abort() {
	printf "%s\n" "$1" >&2
	exit 1
}

usage() {
	abort "$name [-hHPrkc] [time] [warning message]"
}

cancel() {
	kill "$(< "$PIDFILE")"
	rm -f "$PIDFILE" "$NOLOGINFILE"
	echo "${*:-shutdown cancelled}" | wall
	exit
}

action=poweroff
mesg="${2:-The system is shutting down}"
while getopts HPrhkc opt; do
	case "$opt" in
		h|H|P) action=poweroff;;
		r)     action=reboot; mesg="${2:-The system is rebooting}";;
		k)     action=true mesg="${2:-A shutdown test will happen}";;
		c)     cancel ;;
		[?])   usage ;;
	esac
done
shift $((OPTIND - 1))

time="${1:-+1}"

[ -e "$PIDFILE" ] && abort "A shutdown is already pending"
echo "$$" > "$PIDFILE" || abort "Not enough permissions to execute $name"

case "$time" in
	now) time=0 ;;
	+*)  time="$((${time#+} * 60))" ;;
	*:*) time="$(($(date +%s -d "$time") - $(date +%s)))" ;;
	*)   abort "Invalid time" ;;
esac

((time < 0)) && abort "Absolute time must lie in the future"

echo "$mesg at $(date +"%H:%M:%S" -d "@$(($(date +%s) + time))") (in $((time / 60)) minutes)" | wall

if ((time > 300)); then
	sleep "$((time - 300))"
	touch "$NOLOGINFILE"
	sleep 300
else
	touch "$NOLOGINFILE"
	sleep "$time"
fi

echo "$mesg NOW!" | wall
"$action"