diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2020-11-06 17:11:28 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2020-11-06 17:11:28 +0000 |
commit | 7aa18bcbd83c4342bc2eefa4d6d96756ae7541a0 (patch) | |
tree | 157e1787d165dd052b2d49772887e31f49394c68 | |
parent | 4d47d83042e0844da2fcfff9bd73de60124e7902 (diff) | |
download | s6-linux-init-7aa18bcbd83c4342bc2eefa4d6d96756ae7541a0.tar.xz |
Add -i option to shutdown and hpr
-rw-r--r-- | doc/s6-linux-init-hpr.html | 6 | ||||
-rw-r--r-- | doc/s6-linux-init-shutdown.html | 6 | ||||
-rw-r--r-- | package/deps.mak | 5 | ||||
-rw-r--r-- | src/shutdown/deps-lib/hpr | 1 | ||||
-rw-r--r-- | src/shutdown/hpr.h | 1 | ||||
-rw-r--r-- | src/shutdown/hpr_confirm_hostname.c | 45 | ||||
-rw-r--r-- | src/shutdown/s6-linux-init-hpr.c | 8 | ||||
-rw-r--r-- | src/shutdown/s6-linux-init-shutdown.c | 7 |
8 files changed, 71 insertions, 8 deletions
diff --git a/doc/s6-linux-init-hpr.html b/doc/s6-linux-init-hpr.html index 4d164e0..d2a03fb 100644 --- a/doc/s6-linux-init-hpr.html +++ b/doc/s6-linux-init-hpr.html @@ -29,7 +29,7 @@ It is normally invoked through <tt>halt</tt>, <tt>poweroff</tt> or <h2> Interface </h2> <pre> - s6-linux-init-hpr [ -f ] [ -h | -p | -r ] [ -d | -w ] [ -W ] + s6-linux-init-hpr [ -f ] [ -h | -p | -r ] [ -d | -w ] [ -W ] [ -i ] </pre> <ul> @@ -61,6 +61,10 @@ the system. </li> <li> <tt>-W</tt> : Do not send a <tt>wall</tt> message to users before shutting down the system. Some other implementations of the <tt>halt</tt>, <tt>poweroff</tt> and <tt>reboot</tt> commands use the <tt>--no-wall</tt> long option to achieve this. </li> + <li> <tt>-i</tt> : interactive confirmation request. The command needs to be +launched in a terminal, and will prompt the user to type the (short) hostname of +the machine to be shut down. On mismatch, the command will abort. The point is to +avoid inadvertently rebooting a remote machine in an ssh session. </li> </ul> <h2> Notes </h2> diff --git a/doc/s6-linux-init-shutdown.html b/doc/s6-linux-init-shutdown.html index cc3f9c1..fb7b671 100644 --- a/doc/s6-linux-init-shutdown.html +++ b/doc/s6-linux-init-shutdown.html @@ -26,7 +26,7 @@ It is normally invoked as <tt>/sbin/shutdown</tt>. <h2> Interface </h2> <pre> - s6-linux-init-shutdown [ -h [ -H | -P ] | -p | -r | -k ] [ -a ] [ -t <em>sec</em> ] [ -f | -F ] <em>time</em> [ <em>message</em> ] + s6-linux-init-shutdown [ -h [ -H | -P ] | -p | -r | -k ] [ -a ] [ -t <em>sec</em> ] [ -i ] [ -f | -F ] <em>time</em> [ <em>message</em> ] s6-linux-init-shutdown -c [ <em>message</em> ] </pre> @@ -87,6 +87,10 @@ Ensures the system is halted, not powered off, at the end of the shutdown sequen <li> <tt>-P</tt> : this option can only be used in conjunction with <tt>-h</tt>. Ensures the system is powered off at the end of the shutdown sequence. <tt>-Ph</tt> is equivalent to <tt>-p</tt>. </li> + <li> <tt>-i</tt> : interactive confirmation request. The command needs to be +launched in a terminal, and will prompt the user to type the (short) hostname of +the machine to be shut down. On mismatch, the command will abort. The point is to +avoid inadvertently rebooting a remote machine in an ssh session. </li> </ul> <h2> Notes </h2> diff --git a/package/deps.mak b/package/deps.mak index 2c32a6e..e5408fa 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -11,6 +11,7 @@ src/lib/s6_linux_init_logouthook.o src/lib/s6_linux_init_logouthook.lo: src/lib/ src/misc/s6-linux-init-echo.o src/misc/s6-linux-init-echo.lo: src/misc/s6-linux-init-echo.c src/misc/s6-linux-init-logouthookd.o src/misc/s6-linux-init-logouthookd.lo: src/misc/s6-linux-init-logouthookd.c src/misc/s6-linux-init-umountall.o src/misc/s6-linux-init-umountall.lo: src/misc/s6-linux-init-umountall.c src/include/s6-linux-init/config.h +src/shutdown/hpr_confirm_hostname.o src/shutdown/hpr_confirm_hostname.lo: src/shutdown/hpr_confirm_hostname.c src/shutdown/hpr.h src/shutdown/hpr_shutdown.o src/shutdown/hpr_shutdown.lo: src/shutdown/hpr_shutdown.c src/shutdown/hpr.h src/shutdown/hpr_wall.o src/shutdown/hpr_wall.lo: src/shutdown/hpr_wall.c src/shutdown/hpr.h src/shutdown/s6-linux-init-hpr.o src/shutdown/s6-linux-init-hpr.lo: src/shutdown/s6-linux-init-hpr.c src/include-local/defaults.h src/shutdown/hpr.h @@ -37,9 +38,9 @@ s6-linux-init-logouthookd: src/misc/s6-linux-init-logouthookd.o ${LIBUTMPS} s6-linux-init-umountall: EXTRA_LIBS := -lskarnet s6-linux-init-umountall: src/misc/s6-linux-init-umountall.o ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),) -libhpr.a.xyzzy: src/shutdown/hpr_shutdown.o src/shutdown/hpr_wall.o +libhpr.a.xyzzy: src/shutdown/hpr_shutdown.o src/shutdown/hpr_wall.o src/shutdown/hpr_confirm_hostname.o else -libhpr.a.xyzzy: src/shutdown/hpr_shutdown.lo src/shutdown/hpr_wall.lo +libhpr.a.xyzzy: src/shutdown/hpr_shutdown.lo src/shutdown/hpr_wall.lo src/shutdown/hpr_confirm_hostname.lo endif s6-linux-init-hpr: EXTRA_LIBS := -lskarnet ${SYSCLOCK_LIB} ${SOCKET_LIB} s6-linux-init-hpr: src/shutdown/s6-linux-init-hpr.o libhpr.a.xyzzy ${LIBUTMPS} diff --git a/src/shutdown/deps-lib/hpr b/src/shutdown/deps-lib/hpr index 9e1493d..95dff6a 100644 --- a/src/shutdown/deps-lib/hpr +++ b/src/shutdown/deps-lib/hpr @@ -1,2 +1,3 @@ hpr_shutdown.o hpr_wall.o +hpr_confirm_hostname.o diff --git a/src/shutdown/hpr.h b/src/shutdown/hpr.h index 993f5ab..3dd0375 100644 --- a/src/shutdown/hpr.h +++ b/src/shutdown/hpr.h @@ -16,5 +16,6 @@ #define hpr_cancel() hpr_send("c", 1) extern int hpr_shutdown (unsigned int, tain_t const *, unsigned int) ; extern void hpr_wall (char const *) ; +extern void hpr_confirm_hostname (void) ; #endif diff --git a/src/shutdown/hpr_confirm_hostname.c b/src/shutdown/hpr_confirm_hostname.c new file mode 100644 index 0000000..00b3de7 --- /dev/null +++ b/src/shutdown/hpr_confirm_hostname.c @@ -0,0 +1,45 @@ +/* ISC license. */ + +#include <string.h> +#include <strings.h> +#include <unistd.h> +#include <termios.h> +#include <errno.h> +#include <limits.h> + +#include <skalibs/allreadwrite.h> +#include <skalibs/bytestr.h> +#include <skalibs/strerr2.h> + +#include "hpr.h" + +#define PROMPT "Please enter the machine's hostname: " + +void hpr_confirm_hostname (void) +{ + char name[HOST_NAME_MAX + 1] ; + char buf[HOST_NAME_MAX + 1] ; + char *p ; + ssize_t r ; + if (!isatty(0) || !isatty(1)) + strerr_diefu1sys(100, "ask hostname confirmation") ; + if (gethostname(name, HOST_NAME_MAX) < 0) + strerr_diefu1sys(111, "get host name") ; + name[HOST_NAME_MAX] = 0 ; + p = strchr(name, '.') ; + if (p) *p = 0 ; + if (allwrite(1, PROMPT, sizeof(PROMPT)-1) < 0) + strerr_diefu1sys(111, "write to stdout") ; + if (tcdrain(1) < 0) + strerr_diefu1sys(111, "tcdrain stdout") ; + if (tcflush(0, TCIFLUSH) < 0) + strerr_diefu1sys(111, "empty stdin buffer") ; + r = fd_read(0, buf, HOST_NAME_MAX) ; + if (!r) errno = EPIPE ; + if (r <= 0) strerr_diefu1sys(111, "read from stdin") ; + buf[byte_chr(buf, r, '\n')] = 0 ; + p = strchr(buf, '.') ; + if (p) *p = 0 ; + if (strcasecmp(name, buf)) + strerr_dief2x(1, "hostname mismatch: expecting ", name) ; +} diff --git a/src/shutdown/s6-linux-init-hpr.c b/src/shutdown/s6-linux-init-hpr.c index d3cd74b..4ce4135 100644 --- a/src/shutdown/s6-linux-init-hpr.c +++ b/src/shutdown/s6-linux-init-hpr.c @@ -29,7 +29,7 @@ #define _PATH_WTMP "/dev/null/wtmp" #endif -#define USAGE "s6-linux-init-hpr [ -h | -p | -r ] [ -n ] [ -d | -w ] [ -W ] [ -f ]" +#define USAGE "s6-linux-init-hpr [ -h | -p | -r ] [ -n ] [ -d | -w ] [ -W ] [ -f ] [ -i ]" int main (int argc, char const *const *argv) { @@ -38,13 +38,14 @@ int main (int argc, char const *const *argv) int dowtmp = 1 ; int dowall = 1 ; int dosync = 1 ; + int doconfirm = 0 ; PROG = "s6-linux-init-hpr" ; { subgetopt_t l = SUBGETOPT_ZERO ; for (;;) { - int opt = subgetopt_r(argc, argv, "hprfdwWn", &l) ; + int opt = subgetopt_r(argc, argv, "hprfdwWni", &l) ; if (opt == -1) break ; switch (opt) { @@ -56,6 +57,7 @@ int main (int argc, char const *const *argv) case 'w' : dowtmp = 2 ; break ; case 'W' : dowall = 0 ; break ; case 'n' : dosync = 0 ; break ; + case 'i' : doconfirm = 0 ; break ; default : strerr_dieusage(100, USAGE) ; } } @@ -71,6 +73,8 @@ int main (int argc, char const *const *argv) strerr_dief1sys(100, "nice try, peon") ; } + if (doconfirm) hpr_confirm_hostname() ; + if (force) { if (dosync) sync() ; diff --git a/src/shutdown/s6-linux-init-shutdown.c b/src/shutdown/s6-linux-init-shutdown.c index 1492505..7966c5d 100644 --- a/src/shutdown/s6-linux-init-shutdown.c +++ b/src/shutdown/s6-linux-init-shutdown.c @@ -27,7 +27,7 @@ #define UT_NAMESIZE 32 #endif -#define USAGE "s6-linux-init-shutdown [ -h [ -H | -P ] | -p | -r | -k ] [ -f | -F ] [ -a ] [ -t sec ] time [ message ] or s6-linux-init-shutdown -c [ message ]" +#define USAGE "s6-linux-init-shutdown [ -h [ -H | -P ] | -p | -r | -k ] [ -f | -F ] [ -a ] [ -i ] [ -t sec ] time [ message ] or s6-linux-init-shutdown -c [ message ]" #define dieusage() strerr_dieusage(100, USAGE) #define AC_FILE "/etc/shutdown.allow" @@ -198,6 +198,7 @@ int main (int argc, char const *const *argv) int subwhat = 0 ; int doactl = 0 ; int docancel = 0 ; + int doconfirm = 0 ; tain_t when ; PROG = "s6-linux-init-shutdown" ; @@ -205,7 +206,7 @@ int main (int argc, char const *const *argv) subgetopt_t l = SUBGETOPT_ZERO ; for (;;) { - int opt = subgetopt_r(argc, argv, "HPhprkafFct:", &l) ; + int opt = subgetopt_r(argc, argv, "HPhprkafFcit:", &l) ; if (opt == -1) break ; switch (opt) { @@ -219,6 +220,7 @@ int main (int argc, char const *const *argv) case 'f' : /* talk to the hand */ break ; case 'F' : /* no, the other hand */ break ; case 'c' : docancel = 1 ; break ; + case 'i' : doconfirm = 1 ; break ; case 't' : if (!uint0_scan(l.arg, &gracetime)) dieusage() ; break ; default : strerr_dieusage(100, USAGE) ; } @@ -237,6 +239,7 @@ int main (int argc, char const *const *argv) strerr_diefu1sys(111, "shutdown") ; } if (doactl) access_control() ; + if (doconfirm) hpr_confirm_hostname() ; if (!tain_now_g()) strerr_warnw1sys("get current time") ; if (docancel) { |