aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2025-11-11 01:25:23 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2025-11-11 01:25:23 +0000
commitc00521078b8277964be155e44da84e9db72b0929 (patch)
tree6c256c842453eb7acc7869c078253e9318a34890
parentcfacd5d6205ab664a0de185e6361c1702d16f622 (diff)
downloads6-frontend-c00521078b8277964be155e44da84e9db72b0929.tar.gz
Add a lot of subcommands, see a nice framework emerge
-rw-r--r--package/deps.mak16
-rw-r--r--src/s6-frontend/deps-exe/s6-frontend13
-rw-r--r--src/s6-frontend/live.c13
-rw-r--r--src/s6-frontend/live_boot.c143
-rw-r--r--src/s6-frontend/live_hpr.c62
-rw-r--r--src/s6-frontend/live_status.c2
-rw-r--r--src/s6-frontend/live_stop_everything.c66
-rw-r--r--src/s6-frontend/process.c8
-rw-r--r--src/s6-frontend/repository.c26
-rw-r--r--src/s6-frontend/repository_help.c18
-rw-r--r--src/s6-frontend/repository_init.c82
-rw-r--r--src/s6-frontend/s6-frontend-internal.h33
-rw-r--r--src/s6-frontend/s6-frontend.c17
-rw-r--r--src/s6-frontend/service.c30
-rw-r--r--src/s6-frontend/set.c60
-rw-r--r--src/s6-frontend/set_change.c80
-rw-r--r--src/s6-frontend/set_help.c (renamed from src/s6-frontend/service_help.c)6
-rw-r--r--src/s6-frontend/set_init.c83
18 files changed, 692 insertions, 66 deletions
diff --git a/package/deps.mak b/package/deps.mak
index 9f4f977..9d75108 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -11,19 +11,27 @@ src/libs6f/s6f_report_state_change.o src/libs6f/s6f_report_state_change.lo: src/
src/libs6f/s6f_user_get_confdirs.o src/libs6f/s6f_user_get_confdirs.lo: src/libs6f/s6f_user_get_confdirs.c src/include-local/s6f.h
src/s6-frontend/help.o src/s6-frontend/help.lo: src/s6-frontend/help.c src/s6-frontend/s6-frontend-internal.h src/include/s6-frontend/config.h
src/s6-frontend/live.o src/s6-frontend/live.lo: src/s6-frontend/live.c src/s6-frontend/s6-frontend-internal.h
+src/s6-frontend/live_boot.o src/s6-frontend/live_boot.lo: src/s6-frontend/live_boot.c src/s6-frontend/s6-frontend-internal.h src/include/s6-frontend/config.h
src/s6-frontend/live_help.o src/s6-frontend/live_help.lo: src/s6-frontend/live_help.c src/s6-frontend/s6-frontend-internal.h
+src/s6-frontend/live_hpr.o src/s6-frontend/live_hpr.lo: src/s6-frontend/live_hpr.c src/s6-frontend/s6-frontend-internal.h src/include/s6-frontend/config.h
src/s6-frontend/live_startstop.o src/s6-frontend/live_startstop.lo: src/s6-frontend/live_startstop.c src/s6-frontend/s6-frontend-internal.h
-src/s6-frontend/live_status.o src/s6-frontend/live_status.lo: src/s6-frontend/live_status.c src/s6-frontend/s6-frontend-internal.h
+src/s6-frontend/live_status.o src/s6-frontend/live_status.lo: src/s6-frontend/live_status.c src/s6-frontend/s6-frontend-internal.h src/include/s6-frontend/config.h
+src/s6-frontend/live_stop_everything.o src/s6-frontend/live_stop_everything.lo: src/s6-frontend/live_stop_everything.c src/s6-frontend/s6-frontend-internal.h
src/s6-frontend/process.o src/s6-frontend/process.lo: src/s6-frontend/process.c src/s6-frontend/s6-frontend-internal.h
src/s6-frontend/process_help.o src/s6-frontend/process_help.lo: src/s6-frontend/process_help.c src/s6-frontend/s6-frontend-internal.h
src/s6-frontend/process_kill.o src/s6-frontend/process_kill.lo: src/s6-frontend/process_kill.c src/s6-frontend/s6-frontend-internal.h src/include-local/s6f.h
src/s6-frontend/process_restart.o src/s6-frontend/process_restart.lo: src/s6-frontend/process_restart.c src/s6-frontend/s6-frontend-internal.h
src/s6-frontend/process_startstop.o src/s6-frontend/process_startstop.lo: src/s6-frontend/process_startstop.c src/s6-frontend/s6-frontend-internal.h
src/s6-frontend/process_status.o src/s6-frontend/process_status.lo: src/s6-frontend/process_status.c src/s6-frontend/s6-frontend-internal.h
+src/s6-frontend/repository.o src/s6-frontend/repository.lo: src/s6-frontend/repository.c src/s6-frontend/s6-frontend-internal.h
+src/s6-frontend/repository_help.o src/s6-frontend/repository_help.lo: src/s6-frontend/repository_help.c src/s6-frontend/s6-frontend-internal.h
+src/s6-frontend/repository_init.o src/s6-frontend/repository_init.lo: src/s6-frontend/repository_init.c src/s6-frontend/s6-frontend-internal.h src/include/s6-frontend/config.h
src/s6-frontend/s6-frontend.o src/s6-frontend/s6-frontend.lo: src/s6-frontend/s6-frontend.c src/s6-frontend/s6-frontend-internal.h
src/s6-frontend/s6.o src/s6-frontend/s6.lo: src/s6-frontend/s6.c src/include/s6-frontend/config.h
-src/s6-frontend/service.o src/s6-frontend/service.lo: src/s6-frontend/service.c src/s6-frontend/s6-frontend-internal.h
-src/s6-frontend/service_help.o src/s6-frontend/service_help.lo: src/s6-frontend/service_help.c src/s6-frontend/s6-frontend-internal.h
+src/s6-frontend/set.o src/s6-frontend/set.lo: src/s6-frontend/set.c src/s6-frontend/s6-frontend-internal.h
+src/s6-frontend/set_change.o src/s6-frontend/set_change.lo: src/s6-frontend/set_change.c src/s6-frontend/s6-frontend-internal.h
+src/s6-frontend/set_help.o src/s6-frontend/set_help.lo: src/s6-frontend/set_help.c src/s6-frontend/s6-frontend-internal.h
+src/s6-frontend/set_init.o src/s6-frontend/set_init.lo: src/s6-frontend/set_init.c src/s6-frontend/s6-frontend-internal.h src/include/s6-frontend/config.h
s6-frontend-helper-kill: EXTRA_LIBS :=
s6-frontend-helper-kill: src/helpers/s6-frontend-helper-kill.o -lskarnet
@@ -35,5 +43,5 @@ endif
s6: EXTRA_LIBS :=
s6: src/s6-frontend/s6.o -lskarnet
s6-frontend: EXTRA_LIBS := ${MAYBEPTHREAD_LIB}
-s6-frontend: src/s6-frontend/s6-frontend.o src/s6-frontend/help.o src/s6-frontend/live.o src/s6-frontend/live_help.o src/s6-frontend/live_startstop.o src/s6-frontend/live_status.o src/s6-frontend/process.o src/s6-frontend/process_help.o src/s6-frontend/process_kill.o src/s6-frontend/process_restart.o src/s6-frontend/process_startstop.o src/s6-frontend/process_status.o src/s6-frontend/s6-frontend.o src/s6-frontend/service.o src/s6-frontend/service_help.o libs6f.a.xyzzy ${LIBNSSS} -ls6rc -ls6 -lskarnet
+s6-frontend: src/s6-frontend/s6-frontend.o src/s6-frontend/help.o src/s6-frontend/live.o src/s6-frontend/live_boot.o src/s6-frontend/live_help.o src/s6-frontend/live_hpr.o src/s6-frontend/live_startstop.o src/s6-frontend/live_status.o src/s6-frontend/live_stop_everything.o src/s6-frontend/process.o src/s6-frontend/process_help.o src/s6-frontend/process_kill.o src/s6-frontend/process_restart.o src/s6-frontend/process_startstop.o src/s6-frontend/process_status.o src/s6-frontend/repository.o src/s6-frontend/repository_help.o src/s6-frontend/repository_init.o src/s6-frontend/set.o src/s6-frontend/set_change.o src/s6-frontend/set_help.o src/s6-frontend/set_init.o libs6f.a.xyzzy ${LIBNSSS} -ls6rc -ls6 -lskarnet
INTERNAL_LIBS := libs6f.a.xyzzy
diff --git a/src/s6-frontend/deps-exe/s6-frontend b/src/s6-frontend/deps-exe/s6-frontend
index 62ca26a..3c28943 100644
--- a/src/s6-frontend/deps-exe/s6-frontend
+++ b/src/s6-frontend/deps-exe/s6-frontend
@@ -1,17 +1,24 @@
help.o
live.o
+live_boot.o
live_help.o
+live_hpr.o
live_startstop.o
live_status.o
+live_stop_everything.o
process.o
process_help.o
process_kill.o
process_restart.o
process_startstop.o
process_status.o
-s6-frontend.o
-service.o
-service_help.o
+repository.o
+repository_help.o
+repository_init.o
+set.o
+set_change.o
+set_help.o
+set_init.o
libs6f.a.xyzzy
${LIBNSSS}
-ls6rc
diff --git a/src/s6-frontend/live.c b/src/s6-frontend/live.c
index 22e7516..e401552 100644
--- a/src/s6-frontend/live.c
+++ b/src/s6-frontend/live.c
@@ -1,15 +1,8 @@
/* ISC license. */
-#include <string.h>
-#include <errno.h>
#include <unistd.h>
-#include <skalibs/uint64.h>
-#include <skalibs/stat.h>
-#include <skalibs/types.h>
-#include <skalibs/posixplz.h>
#include <skalibs/envexec.h>
-#include <skalibs/djbunix.h>
#include <s6/config.h>
@@ -22,11 +15,17 @@ void live (char const *const *argv)
{
static struct command_s const commands[] =
{
+ { .s = "boot", .f = &live_boot },
+ { .s = "halt", .f = &live_halt },
{ .s = "help", .f = &live_help },
+ { .s = "poweroff", .f = &live_poweroff },
+ { .s = "reboot", .f = &live_reboot },
{ .s = "restart", .f = &live_restart },
{ .s = "start", .f = &live_start },
+ { .s = "start-everything", .f = &live_start_everything },
{ .s = "status", .f = &live_status },
{ .s = "stop", .f = &live_stop },
+ { .s = "stop-everything", .f = &live_stop_everything },
} ;
struct command_s *cmd ;
diff --git a/src/s6-frontend/live_boot.c b/src/s6-frontend/live_boot.c
new file mode 100644
index 0000000..00c90a3
--- /dev/null
+++ b/src/s6-frontend/live_boot.c
@@ -0,0 +1,143 @@
+/* ISC license. */
+
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include <skalibs/uint64.h>
+#include <skalibs/types.h>
+#include <skalibs/envexec.h>
+#include <skalibs/cspawn.h>
+#include <skalibs/djbunix.h>
+
+#include <s6-frontend/config.h>
+#include "s6-frontend-internal.h"
+
+enum golb_e
+{
+ GOLB_DRYRUN = 0x01,
+} ;
+
+enum gola_e
+{
+ GOLA_PREFIX,
+ GOLA_TIMEOUT,
+ GOLA_DEFBUNDLE,
+ GOLA_N
+} ;
+
+static gol_bool const rgolb[] =
+{
+ { .so = 'n', .lo = "dry-run", .clear = 0, .set = GOLB_DRYRUN },
+} ;
+static gol_arg const rgola[] =
+{
+ { .so = 'p', .lo = "prefix", .i = GOLA_PREFIX },
+ { .so = 't', .lo = "timeout", .i = GOLA_TIMEOUT },
+ { .so = 'D', .lo = "default-bundle", .i = GOLA_DEFBUNDLE },
+} ;
+
+static void live_init_fill (char const **argv, char const *prefix)
+{
+ unsigned int m = 0 ;
+ argv[m++] = S6RC_EXTBINPREFIX "s6-rc-init" ;
+ if (prefix)
+ {
+ argv[m++] = "-p" ;
+ argv[m++] = prefix ;
+ }
+ argv[m++] = "-l" ;
+ argv[m++] = g->dirs.live ;
+ argv[m++] = "-c" ;
+ argv[m++] = g->dirs.boot ;
+ argv[m++] = "-b" ;
+ argv[m++] = "--" ;
+ argv[m++] = g->dirs.scan ;
+ argv[m++] = 0 ;
+}
+
+void live_init (char const *const *argv)
+{
+ char const *wgola[GOLA_N] = { 0 } ;
+ char const *newargv[13] ;
+ argv += gol_argv(argv, 0, 0, rgola, 1, 0, wgola) ;
+ live_init_fill(newargv, wgola[GOLA_PREFIX]) ;
+ xmexec_n(newargv, cleanup_modif.s, cleanup_modif.len, cleanup_modif.n) ;
+}
+
+static void live_init_spawn (char const *prefix)
+{
+ pid_t pid ;
+ int wstat ;
+ char const *newargv[13] ;
+ live_init_fill(newargv, prefix) ;
+ pid = xmspawn_n(newargv, cleanup_modif.s, cleanup_modif.len, cleanup_modif.n, 0, 0, 0) ;
+ if (wait_pid(pid, &wstat) == -1)
+ strerr_diefu2sys(111, "wait for ", newargv[0]) ;
+ if (wait_estatus(wstat))
+ strerr_dief2x(wait_estatus(wstat), newargv[0], " failed") ;
+}
+
+static void exec_live_start_everything (unsigned int timeout, int dryrun, char const *defbundle) gccattr_noreturn ;
+static void exec_live_start_everything (unsigned int timeout, int dryrun, char const *defbundle)
+{
+ unsigned int m = 0 ;
+ char const *argv[13] ;
+ char fmtv[UINT_FMT] ;
+ char fmtt[UINT_FMT] ;
+
+ argv[m++] = S6RC_EXTBINPREFIX "s6-rc" ;
+ if (g->verbosity != 1)
+ {
+ fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ;
+ argv[m++] = "-v" ;
+ argv[m++] = fmtv ;
+ }
+ if (timeout)
+ {
+ fmtt[uint_fmt(fmtt, timeout)] = 0 ;
+ argv[m++] = "-t" ;
+ argv[m++] = fmtt ;
+ }
+ if (dryrun) argv[m++] = "-n1" ;
+ argv[m++] = "-l" ;
+ argv[m++] = g->dirs.live ;
+ argv[m++] = "-b" ;
+ argv[m++] = "--" ;
+ argv[m++] = "start" ;
+ argv[m++] = defbundle ;
+ argv[m++] = 0 ;
+ xmexec_n(argv, cleanup_modif.s, cleanup_modif.len, cleanup_modif.n) ;
+}
+
+void live_start_everything (char const *const *argv)
+{
+ uint64_t wgolb = 0 ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ unsigned int timeout = 0 ;
+
+ wgola[GOLA_DEFBUNDLE] = S6_FRONTEND_DEFBUNDLE ;
+ argv += gol_argv(argv, rgolb, 1, rgola + 1, 2, &wgolb, wgola) ;
+ if (wgola[GOLA_TIMEOUT])
+ {
+ if (!uint0_scan(wgola[GOLA_TIMEOUT], &timeout))
+ strerr_dief1x(100, "timeout must be an integer (milliseconds)") ;
+ }
+ exec_live_start_everything(timeout, !!(wgolb & GOLB_DRYRUN), wgola[GOLA_DEFBUNDLE]) ;
+}
+
+void live_boot (char const *const *argv)
+{
+ uint64_t wgolb = 0 ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ unsigned int timeout = 0 ;
+
+ wgola[GOLA_DEFBUNDLE] = S6_FRONTEND_DEFBUNDLE ;
+ argv += GOL_argv(argv, rgolb, rgola, &wgolb, wgola) ;
+ if (wgola[GOLA_TIMEOUT])
+ {
+ if (!uint0_scan(wgola[GOLA_TIMEOUT], &timeout))
+ strerr_dief1x(100, "--timeout= argument must be an unsigned integer (in milliseconds)") ;
+ }
+ live_init_spawn(wgola[GOLA_PREFIX]) ;
+ exec_live_start_everything(timeout, !!(wgolb & GOLB_DRYRUN), wgola[GOLA_DEFBUNDLE]) ;
+}
diff --git a/src/s6-frontend/live_hpr.c b/src/s6-frontend/live_hpr.c
new file mode 100644
index 0000000..54f50fc
--- /dev/null
+++ b/src/s6-frontend/live_hpr.c
@@ -0,0 +1,62 @@
+/* ISC license. */
+
+#include <s6-frontend/config.h>
+#include "s6-frontend-internal.h"
+
+#ifdef S6_FRONTEND_USE_S6LI
+
+#include <skalibs/exec.h>
+
+static void live_hpr (char const *arg) gccattr_noreturn ;
+static void live_hpr (char const *arg)
+{
+ unsigned int m = 0 ;
+ char const *argv[4] ;
+ argv[m++] = S6_LINUX_INIT_EXTBINPREFIX "s6-linux-init-hpr" ;
+ argv[m++] = arg ;
+ argv[m++] = "--" ;
+ argv[m++] = 0 ;
+ xmexec_n(argv, cleanup_modif.s, cleanup_modif.len, cleanup_modif.n) ;
+}
+
+void live_halt (char const *const *argv)
+{
+ live_hpr("-h") ;
+}
+
+void live_poweroff (char const *const *argv)
+{
+ live_hpr("-p") ;
+}
+
+void live_reboot (char const *const *argv)
+{
+ live_hpr("-r") ;
+}
+
+#else
+
+#include <skalibs/strerr.h>
+
+static void live_hpr (char const *arg) gccattr_noreturn ;
+static void live_hpr (char const *const *arg)
+{
+ strerr_dief3x(100, "s6 live ", arg, " needs s6-frontend to be built with s6-linux-init support") ;
+}
+
+void live_halt (char const *const *argv)
+{
+ live_hpr("halt") ;
+}
+
+void live_poweroff (char const *const *argv)
+{
+ live_hpr("poweroff") ;
+}
+
+void live_reboot (char const *const *argv)
+{
+ live_hpr("reboot") ;
+}
+
+#endif
diff --git a/src/s6-frontend/live_status.c b/src/s6-frontend/live_status.c
index 1d43166..df42aed 100644
--- a/src/s6-frontend/live_status.c
+++ b/src/s6-frontend/live_status.c
@@ -130,7 +130,7 @@ static void live_status_some (char const *const *services)
unsigned int m = 0 ;
size_t uplistpos ;
int e ;
- char const * argv[59] ;
+ char const *argv[59] ;
if (!stralloc_catb(&sa, " ", 1)) dienomem() ;
e = get_atomics(services, env_len(services), &sa) ;
if (e) _exit(e) ;
diff --git a/src/s6-frontend/live_stop_everything.c b/src/s6-frontend/live_stop_everything.c
new file mode 100644
index 0000000..8dc2ae3
--- /dev/null
+++ b/src/s6-frontend/live_stop_everything.c
@@ -0,0 +1,66 @@
+/* ISC license. */
+
+#include <skalibs/uint64.h>
+#include <skalibs/types.h>
+#include <skalibs/envexec.h>
+
+#include "s6-frontend-internal.h"
+
+enum golb_e
+{
+ GOLB_DRYRUN = 0x01,
+} ;
+
+enum gola_e
+{
+ GOLA_TIMEOUT,
+ GOLA_DEFBUNDLE,
+ GOLA_N
+} ;
+
+void live_stop_everything (char const *const *argv)
+{
+ static gol_bool const rgolb[] =
+ {
+ { .so = 'n', .lo = "dry-run", .clear = 0, .set = GOLB_DRYRUN },
+ } ;
+ static gol_arg const rgola[] =
+ {
+ { .so = 't', .lo = "timeout", .i = GOLA_TIMEOUT },
+ } ;
+ uint64_t wgolb = 0 ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ unsigned int timeout = 0 ;
+ unsigned int m = 0 ;
+ char const *newargv[12] ;
+ char fmtv[UINT_FMT] ;
+
+ argv += GOL_argv(argv, rgolb, rgola, &wgolb, wgola) ;
+ if (wgola[GOLA_TIMEOUT])
+ {
+ if (!uint0_scan(wgola[GOLA_TIMEOUT], &timeout))
+ strerr_dief1x(100, "timeout must be an integer (milliseconds)") ;
+ }
+
+ newargv[m++] = S6RC_EXTBINPREFIX "s6-rc" ;
+ if (g->verbosity != 1)
+ {
+ fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ;
+ newargv[m++] = "-v" ;
+ newargv[m++] = fmtv ;
+ }
+ if (timeout)
+ {
+ newargv[m++] = "-t" ;
+ newargv[m++] = wgola[GOLA_TIMEOUT] ;
+ }
+ if (wgolb & GOLB_DRYRUN) newargv[m++] = "-n1" ;
+ newargv[m++] = "-l" ;
+ newargv[m++] = g->dirs.live ;
+ newargv[m++] = "-bda" ;
+ newargv[m++] = "--" ;
+ newargv[m++] = "change" ;
+ newargv[m++] = 0 ;
+
+ xmexec_n(newargv, cleanup_modif.s, cleanup_modif.len, cleanup_modif.n) ;
+}
diff --git a/src/s6-frontend/process.c b/src/s6-frontend/process.c
index 5e96d13..7cea951 100644
--- a/src/s6-frontend/process.c
+++ b/src/s6-frontend/process.c
@@ -30,10 +30,10 @@ static inline int check_service (char const *name, size_t scandirlen)
return stat(path, &st) == -1 ? errno == ENOENT ? 0 : -1 : !!S_ISDIR(st.st_mode) ;
}
-void process_check_services (char const *const *argv, size_t argc)
+void process_check_services (char const *const *argv, unsigned int argc)
{
size_t const scandirlen = strlen(g->dirs.scan) ;
- for (size_t i = 0 ; i < argc ; i++)
+ for (unsigned int i = 0 ; i < argc ; i++)
{
int r = check_service(argv[i], scandirlen) ;
if (r == -1)
@@ -48,7 +48,7 @@ void process_send_svc (char const *svcopt, char const *const *argv, unsigned int
size_t const scandirlen = strlen(g->dirs.scan) ;
size_t len = 0 ;
unsigned int m = 0 ;
- for (size_t i = 0 ; i < argc ; i++) len += scandirlen + 2 + strlen(argv[i]) ;
+ for (unsigned int i = 0 ; i < argc ; i++) len += scandirlen + 2 + strlen(argv[i]) ;
char const *newargv[4 + (timeout ? 2 : 0) + argc] ;
char s[len] ;
char fmtt[timeout ? UINT_FMT : 1] ;
@@ -64,7 +64,7 @@ void process_send_svc (char const *svcopt, char const *const *argv, unsigned int
newargv[m++] = "--" ;
len = 0 ;
- for (size_t i = 0 ; i < argc ; i++)
+ for (unsigned int i = 0 ; i < argc ; i++)
{
size_t l = strlen(argv[i]) ;
newargv[m++] = s + len ;
diff --git a/src/s6-frontend/repository.c b/src/s6-frontend/repository.c
new file mode 100644
index 0000000..1f78811
--- /dev/null
+++ b/src/s6-frontend/repository.c
@@ -0,0 +1,26 @@
+/* ISC license. */
+
+#include <unistd.h>
+
+#include <skalibs/envexec.h>
+
+#include "s6-frontend-internal.h"
+
+#define USAGE "s6 repository subcommand [ subcommand options ] [ services... ] Type \"s6 repository help\" for details."
+#define dieusage() strerr_dieusage(100, USAGE)
+
+void repository (char const *const *argv)
+{
+ static struct command_s const commands[] =
+ {
+ { .s = "help", .f = &repository_help },
+ { .s = "init", .f = &repository_init },
+ } ;
+ struct command_s *cmd ;
+ argv += gol_argv(argv, 0, 0, 0, 0, 0, 0) ;
+ if (!*argv) dieusage() ;
+ cmd = BSEARCH(struct command_s, *argv, commands) ;
+ if (!cmd) dieusage() ;
+ (*cmd->f)(++argv) ;
+ _exit(101) ;
+}
diff --git a/src/s6-frontend/repository_help.c b/src/s6-frontend/repository_help.c
new file mode 100644
index 0000000..683e064
--- /dev/null
+++ b/src/s6-frontend/repository_help.c
@@ -0,0 +1,18 @@
+/* ISC license. */
+
+#include <unistd.h>
+
+#include <skalibs/buffer.h>
+#include <skalibs/strerr.h>
+
+#include "s6-frontend-internal.h"
+
+#define REPOSITORY_HELP_MESSAGE "This is the live help message.\n"
+
+void repository_help (char const *const *argv)
+{
+ (void)argv ;
+ if (!buffer_putsflush(buffer_1, REPOSITORY_HELP_MESSAGE))
+ strerr_diefu1sys(111, "write to stdout") ;
+ _exit(0) ;
+}
diff --git a/src/s6-frontend/repository_init.c b/src/s6-frontend/repository_init.c
new file mode 100644
index 0000000..ad2e639
--- /dev/null
+++ b/src/s6-frontend/repository_init.c
@@ -0,0 +1,82 @@
+/* ISC license. */
+
+#include <string.h>
+
+#include <skalibs/uint64.h>
+#include <skalibs/types.h>
+#include <skalibs/envexec.h>
+
+#include <s6-rc/config.h>
+
+#include <s6-frontend/config.h>
+#include "s6-frontend-internal.h"
+
+enum golb_e
+{
+ GOLB_FORCE = 0x01,
+} ;
+
+enum gola_e
+{
+ GOLA_FDHUSER,
+ GOLA_STOREPATH,
+ GOLA_N
+} ;
+
+void repository_init (char const *const *argv)
+{
+ static gol_bool const rgolb[] =
+ {
+ { .so = 'f', .lo = "force", .clear = 0, .set = GOLB_FORCE },
+ } ;
+ static gol_arg const rgola[] =
+ {
+ { .so = 'h', .lo = "fdholder-user", .i = GOLA_FDHUSER },
+ { .so = 'p', .lo = "store-path", .i = GOLA_STOREPATH },
+ } ;
+ uint64_t wgolb = 0 ;
+ unsigned int m = 0 ;
+ unsigned int n = 0 ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ size_t len ;
+ char fmtv[UINT_FMT] ;
+
+ wgola[GOLA_STOREPATH] = S6_FRONTEND_STOREPATH ;
+ argv += GOL_argv(argv, rgolb, rgola, &wgolb, wgola) ;
+
+ len = strlen(wgola[GOLA_STOREPATH]) ;
+ char storage[len+1] ;
+ for (size_t i = 0 ; i < len ; i++)
+ {
+ if (wgola[GOLA_STOREPATH][i] == ':') { n++ ; storage[i] = 0 ; }
+ else storage[i] = wgola[GOLA_STOREPATH][i] ;
+ }
+ if (storage[len-1]) { n++ ; storage[len] = 0 ; }
+
+ char const *newargv[10 + n] ;
+ newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-repo-init" ;
+ if (g->verbosity != 1)
+ {
+ fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ;
+ newargv[m++] = "-v" ;
+ newargv[m++] = fmtv ;
+ }
+ newargv[m++] = "-r" ;
+ newargv[m++] = g->dirs.repo ;
+ if (wgolb & GOLB_FORCE)
+ newargv[m++] = "-f" ;
+ if (wgola[GOLA_FDHUSER])
+ {
+ newargv[m++] = "-h" ;
+ newargv[m++] = wgola[GOLA_FDHUSER] ;
+ }
+ newargv[m++] = "--" ;
+ len = 0 ;
+ for (unsigned int i = 0 ; i < n ; i++)
+ {
+ newargv[m++] = storage + len ;
+ len += strlen(storage + len) + 1 ;
+ }
+ newargv[m++] = 0 ;
+ xmexec_n(newargv, cleanup_modif.s, cleanup_modif.len, cleanup_modif.n) ;
+}
diff --git a/src/s6-frontend/s6-frontend-internal.h b/src/s6-frontend/s6-frontend-internal.h
index 0f47003..93e8b19 100644
--- a/src/s6-frontend/s6-frontend-internal.h
+++ b/src/s6-frontend/s6-frontend-internal.h
@@ -1,7 +1,7 @@
/* ISC license. */
-#ifndef S6_INTERNAL_H
-#define S6_INTERNAL_H
+#ifndef S6_FRONTEND_INTERNAL_H
+#define S6_FRONTEND_INTERNAL_H
#include <stddef.h>
#include <stdint.h>
@@ -29,19 +29,30 @@ extern void version (char const *const *) gccattr_noreturn ;
extern void live (char const *const *) gccattr_noreturn ;
extern void live_help (char const *const *) gccattr_noreturn ;
+
+extern void live_boot (char const *const *) gccattr_noreturn ;
+extern void live_init (char const *const *) gccattr_noreturn ;
+extern void live_start_everything (char const *const *) gccattr_noreturn ;
+
+extern void live_halt (char const *const *) gccattr_noreturn ;
+extern void live_poweroff (char const *const *) gccattr_noreturn ;
+extern void live_reboot (char const *const *) gccattr_noreturn ;
+
extern void live_restart (char const *const *) gccattr_noreturn ;
extern void live_start (char const *const *) gccattr_noreturn ;
extern void live_status (char const *const *) gccattr_noreturn ;
extern void live_stop (char const *const *) gccattr_noreturn ;
+extern void live_stop_everything (char const *const *) gccattr_noreturn ;
/* process */
-extern void process_check_services (char const *const *, size_t) ;
+extern void process_check_services (char const *const *, unsigned int) ;
extern void process_send_svc (char const *, char const *const *, unsigned int, unsigned int) gccattr_noreturn ;
extern void process (char const *const *) gccattr_noreturn ;
extern void process_help (char const *const *) gccattr_noreturn ;
+
extern void process_kill (char const *const *) gccattr_noreturn ;
extern void process_restart (char const *const *) gccattr_noreturn ;
extern void process_start (char const *const *) gccattr_noreturn ;
@@ -49,10 +60,20 @@ extern void process_stop (char const *const *) gccattr_noreturn ;
extern void process_status (char const *const *) gccattr_noreturn ;
- /* service */
+ /* repository */
+
+extern void repository (char const *const *) gccattr_noreturn ;
+extern void repository_help (char const *const *) gccattr_noreturn ;
+
+extern void repository_init (char const *const *) gccattr_noreturn ;
+
+
+ /* set */
+
+extern void set_change (char const *const *argv, char const *, char const *) gccattr_noreturn ;
-extern void service (char const *const *) gccattr_noreturn ;
-extern void service_help (char const *const *) gccattr_noreturn ;
+extern void set (char const *const *) gccattr_noreturn ;
+extern void set_help (char const *const *) gccattr_noreturn ;
/* main */
diff --git a/src/s6-frontend/s6-frontend.c b/src/s6-frontend/s6-frontend.c
index ddc4eb2..9f550f5 100644
--- a/src/s6-frontend/s6-frontend.c
+++ b/src/s6-frontend/s6-frontend.c
@@ -49,20 +49,12 @@ struct global_s *g ;
int main (int argc, char const *const *argv)
{
- static struct command_s const commands[] =
- {
- { .s = "help", .f = &help },
- { .s = "process", .f = &process },
- { .s = "service", .f = &service },
- { .s = "version", .f = &version },
- } ;
static gol_bool const rgolb[] =
{
{ .so = 'h', .lo = "help", .clear = 0, .set = GOLB_HELP },
{ .so = 'V', .lo = "version", .clear = 0, .set = GOLB_VERSION },
{ .so = 0, .lo = "user", .clear = 0, .set = GOLB_USER },
} ;
-
static gol_arg const rgola[] =
{
{ .so = 's', .lo = "scandir", .i = GOLA_SCANDIR },
@@ -73,6 +65,15 @@ int main (int argc, char const *const *argv)
{ .so = 'v', .lo = "verbosity", .i = GOLA_VERBOSITY },
{ .so = 0, .lo = "color", .i = GOLA_COLOR },
} ;
+ static struct command_s const commands[] =
+ {
+ { .s = "help", .f = &help },
+ { .s = "live", .f = &live },
+ { .s = "process", .f = &process },
+ { .s = "repository", .f = &repository },
+ { .s = "set", .f = &set },
+ { .s = "version", .f = &version },
+ } ;
struct global_s globals_in_the_stack = GLOBAL_ZERO ;
uint64_t wgolb = 0 ;
diff --git a/src/s6-frontend/service.c b/src/s6-frontend/service.c
deleted file mode 100644
index 028aee0..0000000
--- a/src/s6-frontend/service.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* ISC license. */
-
-#include <unistd.h>
-
-#include <skalibs/strerr.h>
-#include <skalibs/gol.h>
-
-#include "s6-frontend-internal.h"
-
-#define USAGE "s6 service [ service options ] subcommand [ subcommand options ] services... Type \"s6 service help\" for details."
-#define dieusage() strerr_dieusage(100, USAGE)
-
-void service (char const *const *argv)
-{
- static struct command_s const commands[] =
- {
- { .s = "help", .f = &service_help },
-// { .s = "start", .f = &service_start },
-// { .s = "status", .f = &service_status },
-// { .s = "stop", .f = &service_stop },
- } ;
- struct command_s *cmd ;
-
- argv += gol_argv(argv, 0, 0, 0, 0, 0, 0) ;
- if (!*argv) dieusage() ;
- cmd = BSEARCH(struct command_s, *argv, commands) ;
- if (!cmd) dieusage() ;
- (*cmd->f)(++argv) ;
- _exit(101) ;
-}
diff --git a/src/s6-frontend/set.c b/src/s6-frontend/set.c
new file mode 100644
index 0000000..d31c50c
--- /dev/null
+++ b/src/s6-frontend/set.c
@@ -0,0 +1,60 @@
+/* ISC license. */
+
+#include <unistd.h>
+
+#include <skalibs/envexec.h>
+
+#include <s6/config.h>
+
+#include "s6-frontend-internal.h"
+
+#define USAGE "s6 set subcommand [ subcommand options ] [ services... ] Type \"s6 set help\" for details."
+#define dieusage() strerr_dieusage(100, USAGE)
+
+static void set_disable (char const *const *argv) gccattr_noreturn ;
+static void set_disable (char const *const *argv)
+{
+ set_change(argv, "latent", "disable") ;
+}
+
+static void set_enable (char const *const *argv) gccattr_noreturn ;
+static void set_enable (char const *const *argv)
+{
+ set_change(argv, "active", "enable") ;
+}
+
+static void set_mask (char const *const *argv) gccattr_noreturn ;
+static void set_mask (char const *const *argv)
+{
+ set_change(argv, "masked", "mask") ;
+}
+
+static void set_unmask (char const *const *argv) gccattr_noreturn ;
+static void set_unmask (char const *const *argv)
+{
+ set_change(argv, "latent", "unmask") ;
+}
+
+void set (char const *const *argv)
+{
+ static struct command_s const commands[] =
+ {
+ { .s = "disable", .f = &set_disable },
+ { .s = "enable", .f = &set_enable },
+ { .s = "help", .f = &set_help },
+// { .s = "list", .f = &set_list },
+// { .s = "load", .f = &set_load },
+ { .s = "mask", .f = &set_mask },
+// { .s = "save", .f = &set_save },
+// { .s = "status", .f = &set_status },
+// { .s = "sync", .f = &set_sync },
+ { .s = "unmask", .f = &set_unmask },
+ } ;
+ struct command_s *cmd ;
+ argv += gol_argv(argv, 0, 0, 0, 0, 0, 0) ;
+ if (!*argv) dieusage() ;
+ cmd = BSEARCH(struct command_s, *argv, commands) ;
+ if (!cmd) dieusage() ;
+ (*cmd->f)(++argv) ;
+ _exit(101) ;
+}
diff --git a/src/s6-frontend/set_change.c b/src/s6-frontend/set_change.c
new file mode 100644
index 0000000..b5fa2d2
--- /dev/null
+++ b/src/s6-frontend/set_change.c
@@ -0,0 +1,80 @@
+/* ISC license. */
+
+#include <string.h>
+#include <unistd.h>
+
+#include <skalibs/gccattributes.h>
+#include <skalibs/uint64.h>
+#include <skalibs/types.h>
+#include <skalibs/envexec.h>
+
+#include <s6-rc/config.h>
+
+#include "s6-frontend-internal.h"
+
+enum golb_e
+{
+ GOLB_IGNORE_DEPENDENCIES = 0x02,
+ GOLB_DRYRUN = 0x04,
+} ;
+
+enum gola_e
+{
+ GOLA_FORCELEVEL,
+ GOLA_N
+} ;
+
+void set_change (char const *const *argv, char const *newsub, char const *cmd)
+{
+ static gol_bool const rgolb[] =
+ {
+ { .so = 'f', .lo = "ignore-dependencies", .clear = 0, .set = GOLB_IGNORE_DEPENDENCIES },
+ { .so = 'n', .lo = "dry-run", .clear = 0, .set = GOLB_DRYRUN }
+ } ;
+ static gol_arg const rgola[] =
+ {
+ { .so = 'I', .lo = "if-dependencies-found", .i = GOLA_FORCELEVEL }
+ } ;
+ uint64_t wgolb = 0 ;
+ unsigned int m = 0 ;
+ unsigned int argc ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ argv += GOL_argv(argv, rgolb, rgola, &wgolb, wgola) ;
+ if (!*argv) strerr_die(100, "usage: ", "s6 set ", cmd, " [ --ignore-dependencies ] [ --dry-run ] [ --if-dependencies-found=fail|warn|pull ] services...") ;
+ argc = env_len(argv) ;
+ if (wgola[GOLA_FORCELEVEL])
+ {
+ if (strcmp(wgola[GOLA_FORCELEVEL], "fail")
+ && strcmp(wgola[GOLA_FORCELEVEL], "pull")
+ && strcmp(wgola[GOLA_FORCELEVEL], "warn"))
+ strerr_dief1x(100, "--if-dependencies-found= argument must be fail, warn or pull") ;
+ }
+
+ char fmtv[UINT_FMT] ;
+ char const *newargv[13 + argc] ;
+ newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-set-change" ;
+ if (g->verbosity != 1)
+ {
+ fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ;
+ newargv[m++] = "-v" ;
+ newargv[m++] = fmtv ;
+ }
+ newargv[m++] = "-r" ;
+ newargv[m++] = g->dirs.repo ;
+ if (wgolb & GOLB_IGNORE_DEPENDENCIES)
+ newargv[m++] = "-f" ;
+ if (wgolb & GOLB_DRYRUN)
+ newargv[m++] = "-n" ;
+ if (wgola[GOLA_FORCELEVEL])
+ {
+ newargv[m++] = "-I" ;
+ newargv[m++] = wgola[GOLA_FORCELEVEL] ;
+ }
+ newargv[m++] = "--" ;
+ newargv[m++] = "current" ;
+ newargv[m++] = newsub ;
+ for (unsigned int i = 0 ; i < argc ; i++)
+ newargv[m++] = argv[i] ;
+ newargv[m++] = 0 ;
+ xmexec_n(newargv, cleanup_modif.s, cleanup_modif.len, cleanup_modif.n) ;
+}
diff --git a/src/s6-frontend/service_help.c b/src/s6-frontend/set_help.c
index d0d0d0a..27715a1 100644
--- a/src/s6-frontend/service_help.c
+++ b/src/s6-frontend/set_help.c
@@ -7,12 +7,12 @@
#include "s6-frontend-internal.h"
-#define SERVICE_HELP_MESSAGE "This is the service help message.\n"
+#define SET_HELP_MESSAGE "This is the set help message.\n"
-void service_help (char const *const *argv)
+void set_help (char const *const *argv)
{
(void)argv ;
- if (!buffer_putsflush(buffer_1, SERVICE_HELP_MESSAGE))
+ if (!buffer_putsflush(buffer_1, SET_HELP_MESSAGE))
strerr_diefu1sys(111, "write to stdout") ;
_exit(0) ;
}
diff --git a/src/s6-frontend/set_init.c b/src/s6-frontend/set_init.c
new file mode 100644
index 0000000..3a5225b
--- /dev/null
+++ b/src/s6-frontend/set_init.c
@@ -0,0 +1,83 @@
+/* ISC license. */
+
+#include <string.h>
+
+#include <skalibs/gccattributes.h>
+#include <skalibs/uint64.h>
+#include <skalibs/types.h>
+#include <skalibs/envexec.h>
+
+#include <s6-rc/config.h>
+
+#include <s6-frontend/config.h>
+#include "s6-frontend-internal.h"
+
+enum golb_e
+{
+ GOLB_FORCE = 0x01,
+} ;
+
+enum gola_e
+{
+ GOLA_FDHUSER,
+ GOLA_STOREPATH,
+ GOLA_N
+} ;
+
+void set_init (char const *const *argv)
+{
+ static gol_bool const rgolb[] =
+ {
+ { .so = 'f', .lo = "force", .clear = 0, .set = GOLB_FORCE },
+ } ;
+ static gol_arg const rgola[] =
+ {
+ { .so = 'h', .lo = "fdholder-user", .i = GOLA_FDHUSER },
+ { .so = 'p', .lo = "store-path", .i = GOLA_STOREPATH },
+ } ;
+ uint64_t wgolb = 0 ;
+ unsigned int m = 0 ;
+ unsigned int n = 0 ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ size_t len ;
+ char fmtv[UINT_FMT] ;
+
+ wgola[GOLA_STOREPATH] = S6_FRONTEND_STOREPATH ;
+ argv += GOL_argv(argv, rgolb, rgola, &wgolb, wgola) ;
+
+ len = strlen(wgola[GOLA_STOREPATH]) ;
+ char storage[len+1] ;
+ for (size_t i = 0 ; i < len ; i++)
+ {
+ if (wgola[GOLA_STOREPATH][i] == ':') { n++ ; storage[i] = 0 ; }
+ else storage[i] = wgola[GOLA_STOREPATH][i] ;
+ }
+ if (storage[len-1]) { n++ ; storage[len] = 0 ; }
+
+ char const *newargv[10 + n] ;
+ newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-repo-init" ;
+ if (g->verbosity != 1)
+ {
+ fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ;
+ newargv[m++] = "-v" ;
+ newargv[m++] = fmtv ;
+ }
+ newargv[m++] = "-r" ;
+ newargv[m++] = g->dirs.repo ;
+ if (wgolb & GOLB_FORCE)
+ newargv[m++] = "-f" ;
+ if (wgola[GOLA_FDHUSER])
+ {
+ newargv[m++] = "-h" ;
+ newargv[m++] = wgola[GOLA_FDHUSER] ;
+ }
+ newargv[m++] = "--" ;
+ len = 0 ;
+ for (unsigned int i = 0 ; i < n ; i++)
+ {
+ newargv[m++] = storage + len ;
+ len += strlen(storage + len) + 1 ;
+ }
+ newargv[m++] = 0 ;
+ xmexec_n(newargv, cleanup_modif.s, cleanup_modif.len, cleanup_modif.n) ;
+}