From f94e976efbdfdd885ecc81745542bedf315768fd Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Fri, 12 Feb 2021 18:17:50 +0000 Subject: bugfix: wall message on non-immediate shutdown(8) --- package/deps.mak | 5 +-- src/shutdown/deps-lib/hpr | 1 + src/shutdown/hpr.h | 6 +++- src/shutdown/hpr_wall.c | 35 ++------------------ src/shutdown/hpr_wallv.c | 38 ++++++++++++++++++++++ src/shutdown/s6-linux-init-shutdown.c | 61 +++++++++++++++++++++++++++++------ 6 files changed, 102 insertions(+), 44 deletions(-) create mode 100644 src/shutdown/hpr_wallv.c diff --git a/package/deps.mak b/package/deps.mak index 4c0aa04..1f0bd20 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -15,6 +15,7 @@ src/misc/s6-linux-init-umountall.o src/misc/s6-linux-init-umountall.lo: src/misc 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/hpr_wallv.o src/shutdown/hpr_wallv.lo: src/shutdown/hpr_wallv.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 src/shutdown/s6-linux-init-shutdown.o src/shutdown/s6-linux-init-shutdown.lo: src/shutdown/s6-linux-init-shutdown.c src/include-local/defaults.h src/shutdown/hpr.h src/include-local/initctl.h src/shutdown/s6-linux-init-shutdownd.o src/shutdown/s6-linux-init-shutdownd.lo: src/shutdown/s6-linux-init-shutdownd.c src/include-local/defaults.h src/shutdown/hpr.h src/include-local/initctl.h src/include/s6-linux-init/config.h @@ -41,9 +42,9 @@ s6-linux-init-nuke: src/misc/s6-linux-init-nuke.o 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 src/shutdown/hpr_confirm_hostname.o +libhpr.a.xyzzy: src/shutdown/hpr_shutdown.o src/shutdown/hpr_wall.o src/shutdown/hpr_wallv.o src/shutdown/hpr_confirm_hostname.o else -libhpr.a.xyzzy: src/shutdown/hpr_shutdown.lo src/shutdown/hpr_wall.lo src/shutdown/hpr_confirm_hostname.lo +libhpr.a.xyzzy: src/shutdown/hpr_shutdown.lo src/shutdown/hpr_wall.lo src/shutdown/hpr_wallv.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 95dff6a..4642c75 100644 --- a/src/shutdown/deps-lib/hpr +++ b/src/shutdown/deps-lib/hpr @@ -1,3 +1,4 @@ hpr_shutdown.o hpr_wall.o +hpr_wallv.o hpr_confirm_hostname.o diff --git a/src/shutdown/hpr.h b/src/shutdown/hpr.h index 3dd0375..2c545a5 100644 --- a/src/shutdown/hpr.h +++ b/src/shutdown/hpr.h @@ -4,18 +4,22 @@ #define HPR_H #include +#include #include #include #include "initctl.h" -#define HPR_WALL_BANNER "\n\n*** WARNING ***\nThe system is going down NOW!\n" +#define HPR_WALL_PRE "\n\n*** WARNING ***\nThe system is going down " +#define HPR_WALL_POST "!\n" +#define HPR_WALL_BANNER HPR_WALL_PRE "NOW" HPR_WALL_POST #define hpr_send(s, n) openwritenclose_unsafe(INITCTL, (s), n) #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_wallv (struct iovec const *, unsigned int) ; extern void hpr_confirm_hostname (void) ; #endif diff --git a/src/shutdown/hpr_wall.c b/src/shutdown/hpr_wall.c index 2ce3dce..9810a94 100644 --- a/src/shutdown/hpr_wall.c +++ b/src/shutdown/hpr_wall.c @@ -1,41 +1,12 @@ /* ISC license. */ #include -#include - -#include -#include -#include -#include +#include #include "hpr.h" -#ifndef UT_LINESIZE -#define UT_LINESIZE 32 -#endif - void hpr_wall (char const *s) { - size_t n = strlen(s) ; - char tty[10 + UT_LINESIZE] = "/dev/" ; - char msg[n+1] ; - memcpy(msg, s, n) ; - msg[n++] = '\n' ; - setutxent() ; - for (;;) - { - size_t linelen ; - int fd ; - struct utmpx *utx = getutxent() ; - if (!utx) break ; - if (utx->ut_type != USER_PROCESS) continue ; - linelen = strnlen(utx->ut_line, UT_LINESIZE) ; - memcpy(tty + 5, utx->ut_line, linelen) ; - tty[5 + linelen] = 0 ; - fd = open_append(tty) ; - if (fd == -1) continue ; - allwrite(fd, msg, n) ; - fd_close(fd) ; - } - endutxent() ; + struct iovec v[2] = { { .iov_base = (char *)s, .iov_len = strlen(s) }, { .iov_base = "\n", .iov_len = 1 } } ; + hpr_wallv(v, 2) ; } diff --git a/src/shutdown/hpr_wallv.c b/src/shutdown/hpr_wallv.c new file mode 100644 index 0000000..50523c5 --- /dev/null +++ b/src/shutdown/hpr_wallv.c @@ -0,0 +1,38 @@ +/* ISC license. */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "hpr.h" + +#ifndef UT_LINESIZE +#define UT_LINESIZE 32 +#endif + +void hpr_wallv (struct iovec const *v, unsigned int n) +{ + char tty[10 + UT_LINESIZE] = "/dev/" ; + setutxent() ; + for (;;) + { + size_t linelen ; + int fd ; + struct utmpx *utx = getutxent() ; + if (!utx) break ; + if (utx->ut_type != USER_PROCESS) continue ; + linelen = strnlen(utx->ut_line, UT_LINESIZE) ; + memcpy(tty + 5, utx->ut_line, linelen) ; + tty[5 + linelen] = 0 ; + fd = open_append(tty) ; + if (fd == -1) continue ; + allwritev(fd, v, n) ; + fd_close(fd) ; + } + endutxent() ; +} diff --git a/src/shutdown/s6-linux-init-shutdown.c b/src/shutdown/s6-linux-init-shutdown.c index 7966c5d..85c3ae3 100644 --- a/src/shutdown/s6-linux-init-shutdown.c +++ b/src/shutdown/s6-linux-init-shutdown.c @@ -4,12 +4,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -188,6 +190,55 @@ static inline void access_control (void) strerr_dief1x(1, "no authorized users logged in") ; } +static void wallit (uint64_t t, char const *msg) +{ + struct iovec v[11] ; + unsigned int m = 11 ; + char fmtd[UINT64_FMT] ; + char fmth[UINT64_FMT] ; + char fmtm[UINT64_FMT] ; + char fmts[UINT64_FMT] ; + v[--m].iov_base = "\n" ; v[m].iov_len = 1 ; + v[--m].iov_base = HPR_WALL_POST ; v[m].iov_len = sizeof(HPR_WALL_POST) - 1 ; + if (!t) + { + v[--m].iov_base = "NOW" ; v[m].iov_len = 3 ; + } + else + { + if (t % 60) + { + v[--m].iov_base = " seconds" ; v[m].iov_len = 8 ; + v[--m].iov_base = fmts ; v[m].iov_len = uint64_fmt(fmts, t % 60) ; + } + t /= 60 ; + if (t) + { + if (t % 60) + { + v[--m].iov_base = " minutes " ; v[m].iov_len = 9 ; + v[--m].iov_base = fmtm ; v[m].iov_len = uint64_fmt(fmtm, t % 60) ; + } + t /= 60 ; + if (t) + { + if (t % 24) + { + v[--m].iov_base = " hours " ; v[m].iov_len = 7 ; + v[--m].iov_base = fmth ; v[m].iov_len = uint64_fmt(fmth, t % 24) ; + } + t /= 24 ; + if (t) + { + v[--m].iov_base = " days " ; v[m].iov_len = 6 ; + v[--m].iov_base = fmtd ; v[m].iov_len = uint64_fmt(fmtd, t) ; + } + } + } + } + v[--m].iov_base = HPR_WALL_PRE ; v[m].iov_len = sizeof(HPR_WALL_PRE) - 1 ; + hpr_wallv(v + m, 9 - m) ; +} /* main */ @@ -250,15 +301,7 @@ int main (int argc, char const *const *argv) if (!argc) dieusage() ; parse_time(&when, argv[0]) ; tain_sub(&when, &when, &STAMP) ; - if (argv[1]) - { - size_t len = strlen(argv[1]) ; - char msg[sizeof(HPR_WALL_BANNER) + 1 + len] ; - memcpy(msg, HPR_WALL_BANNER, sizeof(HPR_WALL_BANNER) - 1) ; - msg[sizeof(HPR_WALL_BANNER) - 1] = '\n' ; - memcpy(msg + sizeof(HPR_WALL_BANNER), argv[1], len + 1) ; - hpr_wall(msg) ; - } + if (argv[1]) wallit(tai_sec(tain_secp(&when)), argv[1]) ; if (what < 4) { if (gracetime > 300) -- cgit v1.2.3