diff options
Diffstat (limited to 'src/state')
-rw-r--r-- | src/state/deps-exe/s6-linux-init-halt | 5 | ||||
-rw-r--r-- | src/state/deps-exe/s6-linux-init-poweroff | 5 | ||||
-rw-r--r-- | src/state/deps-exe/s6-linux-init-reboot | 5 | ||||
-rw-r--r-- | src/state/deps-exe/s6-linux-init-shutdown | 5 | ||||
-rw-r--r-- | src/state/deps-exe/s6-linux-init-shutdownd | 4 | ||||
-rw-r--r-- | src/state/deps-exe/s6-linux-init-single | 1 | ||||
-rw-r--r-- | src/state/deps-exe/s6-linux-init-telinit | 2 | ||||
-rw-r--r-- | src/state/deps-lib/hpr | 4 | ||||
-rw-r--r-- | src/state/hpr.c | 102 | ||||
-rw-r--r-- | src/state/hpr.h | 22 | ||||
-rw-r--r-- | src/state/hpr_fmttime.c | 52 | ||||
-rw-r--r-- | src/state/hpr_shutdown.c | 16 | ||||
-rw-r--r-- | src/state/hpr_wall.c | 47 | ||||
-rw-r--r-- | src/state/hpr_wall_seconds.c | 12 | ||||
-rw-r--r-- | src/state/s6-linux-init-halt.c | 7 | ||||
-rw-r--r-- | src/state/s6-linux-init-poweroff.c | 7 | ||||
-rw-r--r-- | src/state/s6-linux-init-reboot.c | 7 | ||||
-rw-r--r-- | src/state/s6-linux-init-shutdown.c | 268 | ||||
-rw-r--r-- | src/state/s6-linux-init-shutdownd.c | 241 | ||||
-rw-r--r-- | src/state/s6-linux-init-single.c | 54 | ||||
-rw-r--r-- | src/state/s6-linux-init-telinit.c | 42 |
21 files changed, 0 insertions, 908 deletions
diff --git a/src/state/deps-exe/s6-linux-init-halt b/src/state/deps-exe/s6-linux-init-halt deleted file mode 100644 index 0c4376c..0000000 --- a/src/state/deps-exe/s6-linux-init-halt +++ /dev/null @@ -1,5 +0,0 @@ -libhpr.a.xyzzy -${LIBUTMPS} --lskarnet -${TAINNOW_LIB} -${SOCKET_LIB} diff --git a/src/state/deps-exe/s6-linux-init-poweroff b/src/state/deps-exe/s6-linux-init-poweroff deleted file mode 100644 index 0c4376c..0000000 --- a/src/state/deps-exe/s6-linux-init-poweroff +++ /dev/null @@ -1,5 +0,0 @@ -libhpr.a.xyzzy -${LIBUTMPS} --lskarnet -${TAINNOW_LIB} -${SOCKET_LIB} diff --git a/src/state/deps-exe/s6-linux-init-reboot b/src/state/deps-exe/s6-linux-init-reboot deleted file mode 100644 index 0c4376c..0000000 --- a/src/state/deps-exe/s6-linux-init-reboot +++ /dev/null @@ -1,5 +0,0 @@ -libhpr.a.xyzzy -${LIBUTMPS} --lskarnet -${TAINNOW_LIB} -${SOCKET_LIB} diff --git a/src/state/deps-exe/s6-linux-init-shutdown b/src/state/deps-exe/s6-linux-init-shutdown deleted file mode 100644 index 0c4376c..0000000 --- a/src/state/deps-exe/s6-linux-init-shutdown +++ /dev/null @@ -1,5 +0,0 @@ -libhpr.a.xyzzy -${LIBUTMPS} --lskarnet -${TAINNOW_LIB} -${SOCKET_LIB} diff --git a/src/state/deps-exe/s6-linux-init-shutdownd b/src/state/deps-exe/s6-linux-init-shutdownd deleted file mode 100644 index 5a7d2fd..0000000 --- a/src/state/deps-exe/s6-linux-init-shutdownd +++ /dev/null @@ -1,4 +0,0 @@ -${LIBUTMPS} --lskarnet -${TAINNOW_LIB} -${SOCKET_LIB} diff --git a/src/state/deps-exe/s6-linux-init-single b/src/state/deps-exe/s6-linux-init-single deleted file mode 100644 index e7187fe..0000000 --- a/src/state/deps-exe/s6-linux-init-single +++ /dev/null @@ -1 +0,0 @@ --lskarnet diff --git a/src/state/deps-exe/s6-linux-init-telinit b/src/state/deps-exe/s6-linux-init-telinit deleted file mode 100644 index aeb24a6..0000000 --- a/src/state/deps-exe/s6-linux-init-telinit +++ /dev/null @@ -1,2 +0,0 @@ -libhpr.a.xyzzy --lskarnet diff --git a/src/state/deps-lib/hpr b/src/state/deps-lib/hpr deleted file mode 100644 index 066efd2..0000000 --- a/src/state/deps-lib/hpr +++ /dev/null @@ -1,4 +0,0 @@ -hpr_fmttime.o -hpr_shutdown.o -hpr_wall.o -hpr_wall_seconds.o diff --git a/src/state/hpr.c b/src/state/hpr.c deleted file mode 100644 index 401cc97..0000000 --- a/src/state/hpr.c +++ /dev/null @@ -1,102 +0,0 @@ -/* ISC license. */ - -#include <unistd.h> -#include <signal.h> -#include <errno.h> -#include <utmpx.h> -#include <sys/reboot.h> - -#include <skalibs/strerr2.h> -#include <skalibs/sgetopt.h> -#include <skalibs/sig.h> -#include <skalibs/tai.h> -#include <skalibs/djbunix.h> - -#include "defaults.h" -#include "hpr.h" - -#ifndef UT_NAMESIZE -#define UT_NAMESIZE 32 -#endif - -#ifndef UT_HOSTSIZE -#define UT_HOSTSIZE 256 -#endif - -#ifndef _PATH_WTMP -#define _PATH_WTMP "/dev/null/wtmp" -#endif - -#define USAGE PROGNAME " [ -h | -p | -r ] [ -d | -w ] [ -W ] [ -f ]" - -int main (int argc, char const *const *argv) -{ - int what = WHATDEFAULT ; - int force = 0 ; - int dowtmp = 1 ; - int dowall = 1 ; - PROG = PROGNAME ; - - { - subgetopt_t l = SUBGETOPT_ZERO ; - for (;;) - { - int opt = subgetopt_r(argc, argv, "hprfdwW", &l) ; - if (opt == -1) break ; - switch (opt) - { - case 'h' : what = 1 ; break ; - case 'p' : what = 2 ; break ; - case 'r' : what = 3 ; break ; - case 'f' : force = 1 ; break ; - case 'd' : dowtmp = 0 ; break ; - case 'w' : dowtmp = 2 ; break ; - case 'W' : dowall = 0 ; break ; - default : strerr_dieusage(100, USAGE) ; - } - } - argc -= l.ind ; argv += l.ind ; - } - - if (geteuid()) - { - errno = EPERM ; - strerr_dief1sys(100, "nice try, peon") ; - } - - if (force) - { - reboot(what == 3 ? RB_AUTOBOOT : what == 2 ? RB_POWER_OFF : RB_HALT_SYSTEM) ; - strerr_diefu1sys(111, "reboot()") ; - } - - if (!tain_now_g()) strerr_warnw1sys("get current time") ; - if (dowtmp) - { - struct utmpx utx = - { - .ut_type = RUN_LVL, - .ut_pid = getpid(), - .ut_line = "~", - .ut_id = "", - .ut_session = getsid(0) - } ; - strncpy(utx.ut_user, what == 3 ? "reboot" : "shutdown", UT_NAMESIZE) ; - if (gethostname(utx.ut_host, UT_HOSTSIZE) < 0) - { - utx.ut_host[0] = 0 ; - strerr_warnwu1sys("gethostname") ; - } - else utx.ut_host[UT_HOSTSIZE - 1] = 0 ; - if (!timeval_from_tain(&utx.ut_tv, &STAMP)) - strerr_warnwu1sys("timeval_from_tain") ; - updwtmpx(_PATH_WTMP, &utx) ; - } - if (dowall) hpr_wall_seconds(0) ; - if (dowtmp < 2) - { - if (!hpr_shutdown(what, &STAMP, 0)) - strerr_diefu1sys(111, "notify s6-linux-init-shutdownd") ; - } - return 0 ; -} diff --git a/src/state/hpr.h b/src/state/hpr.h deleted file mode 100644 index 9deb6c4..0000000 --- a/src/state/hpr.h +++ /dev/null @@ -1,22 +0,0 @@ -/* ISC license. */ - -#ifndef HPR_H -#define HPR_H - -#include <stddef.h> - -#include <skalibs/tai.h> -#include <skalibs/djbunix.h> - -#include "initctl.h" - -#define HPR_WALL_BANNER "\n\n*** WARNING ***\nThe system is going down in " - -#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 size_t hpr_fmttime (char *, size_t, unsigned int) ; -extern void hpr_wall (char const *) ; -extern void hpr_wall_seconds (unsigned int) ; - -#endif diff --git a/src/state/hpr_fmttime.c b/src/state/hpr_fmttime.c deleted file mode 100644 index 8038cfe..0000000 --- a/src/state/hpr_fmttime.c +++ /dev/null @@ -1,52 +0,0 @@ -/* ISC license. */ - -#include <string.h> - -#include <skalibs/types.h> - -#include "hpr.h" - -size_t hpr_fmttime (char *buf, size_t max, unsigned int seconds) -{ - size_t m = 0 ; - unsigned int minutes = 0 ; - unsigned int hours = 0 ; - if (seconds >= 60) - { - minutes = seconds / 60 ; - seconds %= 60 ; - if (minutes >= 60) - { - hours = minutes / 60 ; - minutes %= 60 ; - } - } - m = sizeof(HPR_WALL_BANNER) - 1 ; - if (m > max) return 0 ; - memcpy(buf, HPR_WALL_BANNER, m) ; - if (hours) - { - if (m + UINT_FMT + 6 > max) return 0 ; - m += uint_fmt(buf + m, hours) ; - memcpy(buf + m, " hour", 5) ; - m += 5 ; - if (hours > 1) buf[m++] = 's' ; - buf[m++] = ' ' ; - } - if (minutes) - { - if (m + UINT_FMT + 8 > max) return 0 ; - m += uint_fmt(buf + m, minutes) ; - memcpy(buf + m, " minute", 7) ; - m += 7 ; - if (minutes > 1) buf[m++] = 's' ; - buf[m++] = ' ' ; - } - if (m + UINT_FMT + 8 > max) return 0 ; - m += uint_fmt(buf + m, seconds) ; - memcpy(buf + m, " second", 7) ; - m += 7 ; - if (seconds != 1) buf[m++] = 's' ; - buf[m++] = ' ' ; - return m ; -} diff --git a/src/state/hpr_shutdown.c b/src/state/hpr_shutdown.c deleted file mode 100644 index 9c9ff51..0000000 --- a/src/state/hpr_shutdown.c +++ /dev/null @@ -1,16 +0,0 @@ -/* ISC license. */ - -#include <stdint.h> - -#include <skalibs/uint32.h> -#include <skalibs/tai.h> - -#include "hpr.h" - -int hpr_shutdown (unsigned int what, tain_t const *when, unsigned int grace) -{ - char pack[5 + TAIN_PACK] = { " hpr"[what] } ; - tain_pack(pack+1, when) ; - uint32_pack_big(pack + 1 + TAIN_PACK, (uint32_t)grace) ; - return hpr_send(pack, 5 + TAIN_PACK) ; -} diff --git a/src/state/hpr_wall.c b/src/state/hpr_wall.c deleted file mode 100644 index cc6da5e..0000000 --- a/src/state/hpr_wall.c +++ /dev/null @@ -1,47 +0,0 @@ -/* ISC license. */ - -#include <string.h> -#include <errno.h> -#include <utmpx.h> - -#include <skalibs/posixishard.h> -#include <skalibs/allreadwrite.h> -#include <skalibs/strerr2.h> -#include <skalibs/djbunix.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, idlen ; - struct utmpx *utx ; - int fd ; - errno = 0 ; - utx = getutxent() ; - if (!utx) break ; - if (utx->ut_type != USER_PROCESS) continue ; - linelen = strnlen(utx->ut_line, UT_LINESIZE) ; - idlen = strnlen(utx->ut_id, 4) ; - memcpy(tty + 5, utx->ut_line, linelen) ; - memcpy(tty + 5 + linelen, utx->ut_id, idlen) ; - tty[5 + linelen + idlen] = 0 ; - fd = open_append(tty) ; - if (fd == -1) continue ; - allwrite(fd, msg, n) ; - fd_close(fd) ; - } - if (errno) strerr_warnwu1sys("getutxent") ; - endutxent() ; -} diff --git a/src/state/hpr_wall_seconds.c b/src/state/hpr_wall_seconds.c deleted file mode 100644 index 6c0363b..0000000 --- a/src/state/hpr_wall_seconds.c +++ /dev/null @@ -1,12 +0,0 @@ -/* ISC license. */ - -#include "hpr.h" - -void hpr_wall_seconds (unsigned int secs) -{ - char buf[300] = HPR_WALL_BANNER ; - size_t n = sizeof(HPR_WALL_BANNER) - 1 ; - n += hpr_fmttime(buf + n, 300 - n, secs) ; - buf[n++] = 0 ; - hpr_wall(buf) ; -} diff --git a/src/state/s6-linux-init-halt.c b/src/state/s6-linux-init-halt.c deleted file mode 100644 index 4ccca1d..0000000 --- a/src/state/s6-linux-init-halt.c +++ /dev/null @@ -1,7 +0,0 @@ -/* ISC license. */ - -#undef PROGNAME -#define PROGNAME "s6-linux-init-halt" -#undef WHATDEFAULT -#define WHATDEFAULT 1 -#include "hpr.c" diff --git a/src/state/s6-linux-init-poweroff.c b/src/state/s6-linux-init-poweroff.c deleted file mode 100644 index d25dbb6..0000000 --- a/src/state/s6-linux-init-poweroff.c +++ /dev/null @@ -1,7 +0,0 @@ -/* ISC license. */ - -#undef PROGNAME -#define PROGNAME "s6-linux-init-poweroff" -#undef WHATDEFAULT -#define WHATDEFAULT 2 -#include "hpr.c" diff --git a/src/state/s6-linux-init-reboot.c b/src/state/s6-linux-init-reboot.c deleted file mode 100644 index 3612684..0000000 --- a/src/state/s6-linux-init-reboot.c +++ /dev/null @@ -1,7 +0,0 @@ -/* ISC license. */ - -#undef PROGNAME -#define PROGNAME "s6-linux-init-reboot" -#undef WHATDEFAULT -#define WHATDEFAULT 3 -#include "hpr.c" diff --git a/src/state/s6-linux-init-shutdown.c b/src/state/s6-linux-init-shutdown.c deleted file mode 100644 index bb0391d..0000000 --- a/src/state/s6-linux-init-shutdown.c +++ /dev/null @@ -1,268 +0,0 @@ -/* ISC license. */ - -#include <stdint.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> -#include <sys/stat.h> -#include <errno.h> -#include <time.h> -#include <utmpx.h> - -#include <skalibs/uint32.h> -#include <skalibs/types.h> -#include <skalibs/allreadwrite.h> -#include <skalibs/strerr2.h> -#include <skalibs/sgetopt.h> -#include <skalibs/sig.h> -#include <skalibs/tai.h> -#include <skalibs/djbunix.h> -#include <skalibs/djbtime.h> - -#include "defaults.h" -#include "initctl.h" -#include "hpr.h" - -#ifndef UT_NAMESIZE -#define UT_NAMESIZE 32 -#endif - -#define USAGE "s6-linux-init-shutdown [ -h | -p | -r | -k ] [ -f | -F ] [ -a ] [ -t sec ] time [ message ] or s6-linux-init-shutdown -c [ message ]" -#define dieusage() strerr_dieusage(100, USAGE) - -#define AC_FILE "/etc/shutdown.allow" -#define AC_BUFSIZE 4096 -#define AC_MAX 64 -#define AC_SHORT_MESSAGE "no authorized users logged in\n" -#define AC_MESSAGE "s6-linux-init-shutdown: " AC_SHORT_MESSAGE - - - /* shutdown 01:23: date/time format parsing */ - -static inline void add_one_day (struct tm *tm) -{ - tm->tm_isdst = -1 ; - if (tm->tm_mday++ < 31) return ; - tm->tm_mday = 1 ; - if (tm->tm_mon++ < 11) return ; - tm->tm_mon = 0 ; - tm->tm_year++ ; -} - -static inline void parse_hourmin (tain_t *when, char const *s) -{ - tai_t taithen ; - struct tm tmnow, tmthen ; - unsigned int hour, minute ; - size_t len = uint_scan(s, &hour) ; - if (!len || len > 2 || s[len] != ':' || hour > 23) - strerr_dief1x(100, "invalid time format") ; - s += len+1 ; - len = uint0_scan(s, &minute) ; - if (!len || len != 2 || minute > 59) - strerr_dief1x(100, "invalid time format") ; - if (!localtm_from_tai(&tmnow, tain_secp(&STAMP), 1)) - strerr_diefu1sys(111, "break down current time into struct tm") ; - tmthen = tmnow ; - tmthen.tm_hour = hour ; - tmthen.tm_min = minute ; - if (!tai_from_localtm(&taithen, &tmthen)) - strerr_diefu1sys(111, "assemble broken-down time into tain_t") ; - if (tai_less(&taithen, tain_secp(&STAMP))) - { - add_one_day(&tmthen) ; - if (!tai_from_localtm(&taithen, &tmthen)) - strerr_diefu1sys(111, "assemble broken-down time into tain_t") ; - } - tai_sub(tain_secp(when), &taithen, tain_secp(&STAMP)) ; - when->nano = 0 ; -} - -static inline void parse_time (tain_t *when, char const *s) -{ - if (!strcmp(s, "now")) tain_copynow(when) ; - else if (s[0] == '+') - { - unsigned int mins ; - if (!uint0_scan(s+1, &mins)) dieusage() ; - tain_addsec_g(when, mins * 60) ; - } - else if (strchr(s, ':')) parse_hourmin(when, s) ; - else - { - unsigned int mins ; - if (!uint0_scan(s, &mins)) dieusage() ; - tain_addsec_g(when, mins * 60) ; - } -} - - - /* shutdown -a: access control */ - -static inline unsigned char cclass (unsigned char c) -{ - switch (c) - { - case 0 : return 0 ; - case '\n' : return 1 ; - case '#' : return 2 ; - default : return 3 ; - } -} - -static inline unsigned int parse_authorized_users (char *buf, char const **users, unsigned int max) -{ - static unsigned char const table[3][4] = - { - { 0x03, 0x00, 0x01, 0x12 }, - { 0x03, 0x00, 0x01, 0x01 }, - { 0x23, 0x20, 0x02, 0x02 } - } ; - size_t pos = 0 ; - size_t mark = 0 ; - unsigned int n = 0 ; - unsigned int state = 0 ; - for (; state < 3 ; pos++) - { - unsigned char what = table[state][cclass(buf[pos])] ; - state = what & 3 ; - if (what & 0x10) mark = pos ; - if (what & 0x20) - { - if (n >= max) - { - char fmt[UINT32_MAX] ; - fmt[uint32_fmt(fmt, AC_MAX)] = 0 ; - strerr_warnw4x(AC_FILE, " lists more than ", fmt, " authorized users - ignoring the extra ones") ; - break ; - } - buf[pos] = 0 ; - users[n++] = buf + mark ; - } - } - return n ; -} - -static inline int match_users_with_utmp (char const *const *users, unsigned int n) -{ - setutxent() ; - for (;;) - { - struct utmpx *utx ; - errno = 0 ; - utx = getutxent() ; - if (!utx) break ; - if (utx->ut_type != USER_PROCESS) continue ; - for (unsigned int i = 0 ; i < n ; i++) - if (!strncmp(utx->ut_user, users[i], UT_NAMESIZE)) goto yes ; - } - if (errno) strerr_warnwu1sys("getutxent") ; - endutxent() ; - return 0 ; - - yes: - endutxent() ; - return 1 ; -} - -static inline void access_control (void) -{ - char buf[AC_BUFSIZE] ; - char const *users[AC_MAX] ; - unsigned int n ; - struct stat st ; - int fd = open_readb(AC_FILE) ; - if (fd == -1) - { - if (errno == ENOENT) return ; - strerr_diefu2sys(111, "open ", AC_FILE) ; - } - if (fstat(fd, &st) == -1) - strerr_diefu2sys(111, "stat ", AC_FILE) ; - if (st.st_size >= AC_BUFSIZE) - { - char fmt[UINT32_FMT] ; - fmt[uint32_fmt(fmt, AC_BUFSIZE - 1)] = 0 ; - strerr_dief4x(1, AC_FILE, " is too big: it needs to be ", fmt, " bytes or less") ; - } - if (allread(fd, buf, st.st_size) < st.st_size) - strerr_diefu2sys(111, "read ", AC_FILE) ; - fd_close(fd) ; - buf[st.st_size] = 0 ; - n = parse_authorized_users(buf, users, AC_MAX) ; - if (!n || !match_users_with_utmp(users, n)) - { - fd = open_append("/dev/console") ; - if (fd == -1) - strerr_diefu1sys(111, "open /dev/console") ; - if (allwrite(fd, AC_MESSAGE, sizeof(AC_MESSAGE) - 1) < sizeof(AC_MESSAGE) - 1) - strerr_diefu1sys(111, "write to /dev/console") ; - strerr_dief1x(1, AC_SHORT_MESSAGE) ; - } -} - - - /* main */ - -int main (int argc, char const *const *argv) -{ - unsigned int gracetime = 0 ; - int what = 0 ; - int doactl = 0 ; - int docancel = 0 ; - tain_t when ; - PROG = "shutdown" ; - - { - subgetopt_t l = SUBGETOPT_ZERO ; - for (;;) - { - int opt = subgetopt_r(argc, argv, "hprkafFct:", &l) ; - if (opt == -1) break ; - switch (opt) - { - case 'h' : what = 1 ; break ; - case 'p' : what = 2 ; break ; - case 'r' : what = 3 ; break ; - case 'k' : what = 4 ; break ; - case 'a' : doactl = 1 ; break ; - case 'f' : /* talk to the hand */ break ; - case 'F' : /* no, the other hand */ break ; - case 'c' : docancel = 1 ; break ; - case 't' : if (!uint0_scan(l.arg, &gracetime)) dieusage() ; break ; - default : strerr_dieusage(100, USAGE) ; - } - } - argc -= l.ind ; argv += l.ind ; - } - - if (geteuid()) - { - errno = EPERM ; - strerr_diefu1sys(111, "shutdown") ; - } - if (doactl) access_control() ; - if (!tain_now_g()) strerr_warnw1sys("get current time") ; - if (docancel) - { - if (argv[0]) hpr_wall(argv[0]) ; - if (!hpr_cancel()) goto err ; - return 0 ; - } - if (!argc) dieusage() ; - parse_time(&when, argv[0]) ; - if (argv[1]) hpr_wall(argv[1]) ; - if (what < 4) - { - if (gracetime > 300) - { - gracetime = 300 ; - strerr_warnw1x("delay between SIGTERM and SIGKILL is capped to 300 seconds") ; - } - if (!hpr_shutdown(what, &when, gracetime * 1000)) goto err ; - } - return 0 ; - - err: - strerr_diefu2sys(111, "write to ", INITCTL) ; -} diff --git a/src/state/s6-linux-init-shutdownd.c b/src/state/s6-linux-init-shutdownd.c deleted file mode 100644 index e330ac6..0000000 --- a/src/state/s6-linux-init-shutdownd.c +++ /dev/null @@ -1,241 +0,0 @@ -/* ISC license. */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <string.h> -#include <errno.h> -#include <signal.h> -#include <unistd.h> -#include <stdio.h> -#include <sys/wait.h> - -#include <skalibs/posixplz.h> -#include <skalibs/uint32.h> -#include <skalibs/types.h> -#include <skalibs/allreadwrite.h> -#include <skalibs/bytestr.h> -#include <skalibs/buffer.h> -#include <skalibs/strerr2.h> -#include <skalibs/sgetopt.h> -#include <skalibs/stralloc.h> -#include <skalibs/sig.h> -#include <skalibs/tai.h> -#include <skalibs/djbunix.h> -#include <skalibs/iopause.h> -#include <skalibs/skamisc.h> - -#include "defaults.h" -#include "initctl.h" -#include "hpr.h" - -#define STAGE4_FILE "stage 4" - -#define USAGE "s6-linux-init-shutdownd [ -b bindir ] [ -c basedir ] [ -g gracetime ]" -#define dieusage() strerr_dieusage(100, USAGE) - -static char const *basedir = BASEDIR ; - -static inline void prepare_shutdown (char c, unsigned int *what, tain_t *deadline, unsigned int *grace_time) -{ - uint32_t u ; - char pack[TAIN_PACK] ; - ssize_t r = sanitize_read(buffer_get(buffer_0small, pack, TAIN_PACK)) ; - if (r == -1) strerr_diefu1sys(111, "read from pipe") ; - if (r < TAIN_PACK + 4) strerr_dief1x(101, "bad shutdown protocol") ; - tain_unpack(pack, deadline) ; - uint32_unpack_big(pack + TAIN_PACK, &u) ; - if (u && u <= 300000) *grace_time = u ; - *what = 1 + byte_chr("hpr", c, 3) ; -} - -static inline void handle_stdin (unsigned int *what, tain_t *deadline, unsigned int *grace_time) -{ - for (;;) - { - char c ; - ssize_t r = sanitize_read(buffer_get(buffer_0small, &c, 1)) ; - if (r == -1) strerr_diefu1sys(111, "read from pipe") ; - else if (!r) break ; - switch (c) - { - case 'h' : - case 'p' : - case 'r' : - prepare_shutdown(c, what, deadline, grace_time) ; - break ; - case 'c' : - *what = 0 ; - tain_add_g(deadline, &tain_infinite_relative) ; - break ; - default : - { - char s[2] = { c, 0 } ; - strerr_warnw2x("unknown command: ", s) ; - } - break ; - } - } -} - -static inline void prepare_stage4 (char const *bindir, char const *basedir, unsigned int what) -{ - static char const *table[3] = { "halt", "poweroff", "reboot" } ; - stralloc sa = STRALLOC_ZERO ; - buffer b ; - char buf[512] ; - int fd ; - unlink_void(STAGE4_FILE ".new") ; - fd = open_excl(STAGE4_FILE ".new") ; - if (fd == -1) strerr_diefu3sys(111, "open ", STAGE4_FILE ".new", " for writing") ; - buffer_init(&b, &buffer_write, fd, buf, 512) ; - - if (buffer_puts(&b, "#!") == -1 - || buffer_puts(&b, bindir) == -1 - || buffer_puts(&b, "/execlineb -P\n\n") == -1) - strerr_diefu2sys(111, "write to ", STAGE4_FILE ".new") ; - if (!string_quote(&sa, basedir, strlen(basedir))) - strerr_diefu1sys(111, "string_quote") ; - if (buffer_put(&b, sa.s, sa.len) == -1 - || buffer_puts(&b, "/bin/" STAGE4 " ") == -1 - || buffer_puts(&b, table[what-1]) == -1 - || buffer_putsflush(&b, "\n") == -1) - strerr_diefu2sys(111, "write to ", STAGE4_FILE ".new") ; - stralloc_free(&sa) ; - if (fchmod(fd, S_IRWXU) == -1) - strerr_diefu2sys(111, "fchmod ", STAGE4_FILE ".new") ; - if (fsync(fd) == -1) - strerr_diefu2sys(111, "fsync ", STAGE4_FILE ".new") ; - fd_close(fd) ; - if (rename(STAGE4_FILE ".new", STAGE4_FILE) == -1) - strerr_diefu4sys(111, "rename ", STAGE4_FILE ".new", " to ", STAGE4_FILE) ; -} - -int main (int argc, char const *const *argv) -{ - char const *bindir = BINDIR ; - pid_t pid ; - tain_t deadline ; - unsigned int what = 0 ; - unsigned int grace_time = 3000 ; - int notif = 0 ; - PROG = "s6-linux-init-shutdownd" ; - - { - subgetopt_t l = SUBGETOPT_ZERO ; - for (;;) - { - int opt = subgetopt_r(argc, argv, "b:c:g:", &l) ; - if (opt == -1) break ; - switch (opt) - { - case 'b' : bindir = l.arg ; break ; - case 'c' : basedir = l.arg ; break ; - case 'g' : if (!uint0_scan(l.arg, &grace_time)) dieusage() ; break ; - default : dieusage() ; - } - } - argc -= l.ind ; argv += l.ind ; - } - if (bindir[0] != '/') - strerr_dief2x(100, "bindir", " must be an absolute path") ; - if (basedir[0] != '/') - strerr_dief2x(100, "basedir", " must be an absolute path") ; - if (grace_time > 300000) grace_time = 300000 ; - - /* if we're in stage 4, exec it immediately */ - { - char const *stage4_argv[2] = { STAGE4_FILE, 0 } ; - pathexec_run(stage4_argv[0], stage4_argv, (char const *const *)environ) ; - if (errno != ENOENT) - strerr_warnwu2sys("exec ", stage4_argv[0]) ; - } - - fd_close(1) ; - fd_close(0) ; - - if (open_read(SHUTDOWND_FIFO)) - strerr_diefu3sys(111, "open ", SHUTDOWND_FIFO, " for reading") ; - if (open_write(SHUTDOWND_FIFO) != 1) - strerr_diefu3sys(111, "open ", SHUTDOWND_FIFO, " for writing") ; - if (sig_ignore(SIGPIPE) == -1) - strerr_diefu1sys(111, "sig_ignore SIGPIPE") ; - tain_now_g() ; - tain_add_g(&deadline, &tain_infinite_relative) ; - - for (;;) - { - iopause_fd x = { .fd = 0, .events = IOPAUSE_READ } ; - int r = iopause_g(&x, 1, &deadline) ; - if (r == -1) strerr_diefu1sys(111, "iopause") ; - if (!r) - { - if (what) break ; - tain_add_g(&deadline, &tain_infinite_relative) ; - continue ; - } - if (x.revents & IOPAUSE_READ) - handle_stdin(&what, &deadline, &grace_time) ; - } - - - /* Stage 3 */ - - fd_close(1) ; - fd_close(0) ; - if (open_readb("/dev/null")) - strerr_diefu1sys(111, "open /dev/null for reading") ; - if (open_write("/dev/console") != 1 || ndelay_off(1) == -1) - strerr_diefu1sys(111, "open /dev/console for writing") ; - { - size_t basedirlen = strlen(basedir) ; - char stage3[basedirlen + sizeof("/" STAGE3)] ; - char const *stage3_argv[2] = { stage3, 0 } ; - memcpy(stage3, basedir, basedirlen) ; - memcpy(stage3 + basedirlen, "/" STAGE3, sizeof("/" STAGE3)) ; - sig_block(SIGCHLD) ; - pid = child_spawn0(stage3_argv[0], stage3_argv, (char const *const *)environ) ; - if (!pid) strerr_warnwu2sys("spawn ", stage3) ; - sig_unblock(SIGCHLD) ; - if (pid) - { - int wstat ; - if (wait_pid(pid, &wstat) == -1) strerr_diefu1sys(111, "waitpid") ; - if (WIFSIGNALED(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; - strerr_warnw3x(stage3, " was killed by signal ", fmt) ; - } - else if (WEXITSTATUS(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; - strerr_warnw3x(stage3, " was killed by signal ", fmt) ; - } - else if (WEXITSTATUS(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WEXITSTATUS(wstat))] = 0 ; - strerr_warnw3x(stage3, " exited ", fmt) ; - } - } - } - - - /* The end is coming! */ - - prepare_stage4(bindir, basedir, what) ; - if (fd_move(2, 1) == -1) strerr_warnwu1sys("fd_move") ; - sync() ; - if (sig_ignore(SIGTERM) == -1) strerr_warnwu1sys("sig_ignore SIGTERM") ; - strerr_warni1x("sending all processes the TERM signal...") ; - kill(-1, SIGTERM) ; - kill(-1, SIGCONT) ; - tain_from_millisecs(&deadline, grace_time) ; - tain_add_g(&deadline, &deadline) ; - deepsleepuntil_g(&deadline) ; - sync() ; - strerr_warni1x("sending all processes the KILL signal...") ; - kill(-1, SIGKILL) ; - return 0 ; -} diff --git a/src/state/s6-linux-init-single.c b/src/state/s6-linux-init-single.c deleted file mode 100644 index 4f23340..0000000 --- a/src/state/s6-linux-init-single.c +++ /dev/null @@ -1,54 +0,0 @@ -/* ISC license. */ - -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> - -#include <skalibs/allreadwrite.h> -#include <skalibs/strerr2.h> -#include <skalibs/djbunix.h> - -#include "initctl.h" - -#define USAGE "s6-linux-init-single" -#define dieusage() strerr_dieusage(100, USAGE) - -#define BANNER "Executing interactive root shell.\n" - -int main (void) -{ - int fd ; - PROG = "s6-linux-init-single" ; - fd = open(EARLYGETTY, O_RDONLY) ; - if (fd == -1) - { - if (errno != ENOENT) - strerr_diefu2sys(111, "opendir ", EARLYGETTY) ; - goto shell ; - } - if (faccessat(fd, "down", F_OK, 0) == 0) - { - fd_close(fd) ; - goto shell ; - } - if (errno != ENOENT) - strerr_diefu3sys(111, "access ", EARLYGETTY, "/down") ; - return 0 ; - - shell: - - fd = open("/dev/console", O_RDONLY) ; - if (fd == -1) strerr_diefu2sys(111, "open /dev/console for ", "reading") ; - if (fd_move(0, fd) == -1) strerr_diefu1sys(111, "move /dev/console fd to 0") ; - fd = open("/dev/console", O_WRONLY) ; - if (fd == -1) strerr_diefu2sys(111, "open /dev/console for ", "writing") ; - if (fd_move(1, fd) == -1) strerr_diefu1sys(111, "move /dev/console fd to 1") ; - if (fd_copy(2, 1) == -1) strerr_diefu1sys(111, "dup2 1 to 2") ; - if (allwrite(1, BANNER, sizeof(BANNER) - 1) < sizeof(BANNER) - 1) - strerr_diefu1sys(111, "write banner") ; - { - char *argv[3] = { "/bin/sh", "-i", 0 } ; - execv(argv[0], argv) ; - strerr_dieexec(111, argv[0]) ; - } -} diff --git a/src/state/s6-linux-init-telinit.c b/src/state/s6-linux-init-telinit.c deleted file mode 100644 index 856e78b..0000000 --- a/src/state/s6-linux-init-telinit.c +++ /dev/null @@ -1,42 +0,0 @@ -/* ISC license. */ - -#include <skalibs/sgetopt.h> -#include <skalibs/types.h> -#include <skalibs/strerr2.h> - -#include "defaults.h" -#include "initctl.h" -#include "hpr.h" - -#define USAGE "s6-linux-init-telinit runlevel" -#define dieusage() strerr_dieusage(100, USAGE) - -int main (int argc, char const *const *argv, char const *const *envp) -{ - PROG = "s6-linux-init-telinit" ; - { - subgetopt_t l = SUBGETOPT_ZERO ; - for (;;) - { - int opt = subgetopt_r(argc, argv, "rc:p:s:m:d:", &l) ; - if (opt == -1) break ; - switch (opt) - { - case 'r' : - case 'c' : - case 'p' : - case 's' : - case 'm' : - case 'd' : break ; - default : dieusage() ; - } - } - argc -= l.ind ; argv += l.ind ; - } - - if (!argc) dieusage() ; - if (!argv[0][0] || argv[0][1]) dieusage() ; - if (argv[0][0] != 'S' && (argv[0][0] < '0' || argv[0][0] > '6')) dieusage() ; - if (!hpr_send(argv[0], 1)) strerr_diefu2sys(111, "write to ", INITCTL) ; - return 0 ; -} |