summaryrefslogtreecommitdiff
path: root/src/shutdown
diff options
context:
space:
mode:
Diffstat (limited to 'src/shutdown')
-rw-r--r--src/shutdown/deps-lib/hpr1
-rw-r--r--src/shutdown/hpr.h6
-rw-r--r--src/shutdown/hpr_wall.c35
-rw-r--r--src/shutdown/hpr_wallv.c38
-rw-r--r--src/shutdown/s6-linux-init-shutdown.c61
5 files changed, 99 insertions, 42 deletions
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 <stddef.h>
+#include <sys/uio.h>
#include <skalibs/tai.h>
#include <skalibs/djbunix.h>
#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 <string.h>
-#include <utmpx.h>
-
-#include <skalibs/allreadwrite.h>
-#include <skalibs/strerr2.h>
-#include <skalibs/djbunix.h>
-#include <skalibs/posixishard.h>
+#include <sys/uio.h>
#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 <string.h>
+#include <sys/uio.h>
+#include <utmpx.h>
+
+#include <skalibs/allreadwrite.h>
+#include <skalibs/strerr2.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/posixishard.h>
+
+#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 <string.h>
#include <unistd.h>
#include <signal.h>
+#include <sys/uio.h>
#include <sys/stat.h>
#include <errno.h>
#include <time.h>
#include <utmpx.h>
#include <skalibs/uint32.h>
+#include <skalibs/uint64.h>
#include <skalibs/types.h>
#include <skalibs/allreadwrite.h>
#include <skalibs/strerr2.h>
@@ -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)