summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/s6-linux-init-hpr.html6
-rw-r--r--doc/s6-linux-init-shutdown.html6
-rw-r--r--package/deps.mak5
-rw-r--r--src/shutdown/deps-lib/hpr1
-rw-r--r--src/shutdown/hpr.h1
-rw-r--r--src/shutdown/hpr_confirm_hostname.c45
-rw-r--r--src/shutdown/s6-linux-init-hpr.c8
-rw-r--r--src/shutdown/s6-linux-init-shutdown.c7
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>&nbsp;: 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>&nbsp;: 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>&nbsp;: 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>&nbsp;: 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)
{