diff options
| author | Laurent Bercot <ska-skaware@skarnet.org> | 2025-11-26 10:15:55 +0000 |
|---|---|---|
| committer | Laurent Bercot <ska-skaware@skarnet.org> | 2025-11-26 10:15:55 +0000 |
| commit | c40145fca667f8b0243bbcf276b5aade18f7ae5b (patch) | |
| tree | d1de5084859c2d9fe0d599e1a3b1cfe6674492f9 | |
| parent | e31ad31e271e9e78f6755e047bb25230c6b542f1 (diff) | |
| download | s6-rc-c40145fca667f8b0243bbcf276b5aade18f7ae5b.tar.gz | |
s6-rc-set-list is now s6-rc-set-status and does everything
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | doc/repodefs.html | 2 | ||||
| -rw-r--r-- | doc/s6-rc-set-status.html (renamed from doc/s6-rc-set-list.html) | 33 | ||||
| -rw-r--r-- | package/deps.mak | 6 | ||||
| -rw-r--r-- | package/modes | 2 | ||||
| -rw-r--r-- | package/targets.mak | 2 | ||||
| -rw-r--r-- | src/repo/deps-exe/s6-rc-set-status (renamed from src/repo/deps-exe/s6-rc-set-list) | 0 | ||||
| -rw-r--r-- | src/repo/s6-rc-set-change.c | 9 | ||||
| -rw-r--r-- | src/repo/s6-rc-set-list.c | 86 | ||||
| -rw-r--r-- | src/repo/s6-rc-set-status.c | 118 |
10 files changed, 156 insertions, 104 deletions
@@ -17,7 +17,7 @@ /s6-rc-format-upgrade /s6-rc-repo-init /s6-rc-repo-sync -/s6-rc-set-list +/s6-rc-set-status /s6-rc-set-new /s6-rc-set-copy /s6-rc-set-delete diff --git a/doc/repodefs.html b/doc/repodefs.html index 6d0cd94..c234ba0 100644 --- a/doc/repodefs.html +++ b/doc/repodefs.html @@ -284,6 +284,8 @@ make a copy of an existing set with <a href="s6-rc-set-copy.html">s6-rc-set-copy or delete sets with <a href="s6-rc-set-delete.html">s6-rc-set-delete</a>. </li> <li> They mask, unmask, enable or disable services in their favorite set with <a href="s6-rc-set-change.html">s6-rc-set-change</a>. </li> + <li> They can check the list of services and their subs with +<a href="s6-rc-set-status.html">s6-rc-set-status</a>. </li> <li> They commit the set with <a href="s6-rc-set-commit.html">s6-rc-set-commit</a>. </li> <li> They install the set with <a href="s6-rc-set-install.html">s6-rc-set-install</a>. This action potentially modifies the current state of the machine! </li> diff --git a/doc/s6-rc-set-list.html b/doc/s6-rc-set-status.html index 18a04ee..8f058ba 100644 --- a/doc/s6-rc-set-list.html +++ b/doc/s6-rc-set-status.html @@ -3,9 +3,9 @@ <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Language" content="en" /> - <title>s6-rc: the s6-rc-set-list program</title> - <meta name="Description" content="s6-rc: the s6-rc-set-list program" /> - <meta name="Keywords" content="s6-rc s6-rc-set-list repo set sub list services" /> + <title>s6-rc: the s6-rc-set-status program</title> + <meta name="Description" content="s6-rc: the s6-rc-set-status program" /> + <meta name="Keywords" content="s6-rc s6-rc-set-status repo set sub list services status" /> <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> --> </head> <body> @@ -16,22 +16,24 @@ <a href="//skarnet.org/">skarnet.org</a> </p> -<h1> The s6-rc-set-list program </h1> +<h1> The s6-rc-set-status program </h1> <p> - s6-rc-set-list lists all the services of a <a href="repodefs.html#set">set</a>, + s6-rc-set-list lists some of, or all, the services of a <a href="repodefs.html#set">set</a>, along with the <a href="repodefs.html#sub">sub</a> each service is on. </p> <h2> Interface </h2> <pre> - s6-rc-set-list [ -v <em>verbosity</em> ] [ -r <em>repo</em> ] <em>set</em> + s6-rc-set-list [ -v <em>verbosity</em> ] [ -r <em>repo</em> ] [ -E | -e ] [ -L ] <em>set</em> [ <em>services...</em> ] </pre> <ul> - <li> s6-rc-set-list prints all the services in set <em>set</em> of repository -<em>repo</em>, one per line, to stdout. Each line contains: + <li> s6-rc-set-list prints the services in set <em>set</em> of repository +<em>repo</em>, one per line, to stdout. If some <em>services...</em> are specified, +it only prints the ones listed; if <em>services...</em> is empty, it prints all the +services in the set. Each line consists of: <ul> <li> The name of the service </li> <li> A slash (<tt>/</tt>) character </li> @@ -52,6 +54,16 @@ error messages will be written, and 2 or more adds informational messages. </dd> <dd> Use the repository in <em>repo</em>, which must exist. Default is <strong>/var/lib/s6-rc/repository</strong>. </dd> + + <dt> -E, --with-essentials </dt> + <dd> Do not ignore services in the <tt>always</tt> sub, i.e. services marked as +essential. This is the default. </dd> + + <dt> -e, --without-essentials </dt> + <dd> Ignore services in the <tt>always</tt> sub: do not print them. </dd> + + <dt> -L. --list </dt> + <dd> Do not print <tt>/<em>sub</em></tt> at the end of each line: only print the service names. </dd> </dl> <h2> Exit codes </h2> @@ -67,9 +79,8 @@ error messages will be written, and 2 or more adds informational messages. </dd> <h2> Notes </h2> <ul> - <li> s6-rc-set-list is meant to be used with automation such as -<a href="https://pubs.opengroup.org/onlinepubs/9799919799/utilities/cut.html">cut</a> -or util-linux's <a href="https://man7.org/linux/man-pages/man1/column.1.html">column</a> + <li> s6-rc-set-status is meant to be used with automation such as +util-linux's <a href="https://man7.org/linux/man-pages/man1/column.1.html">column</a> for formatting. A slash is used to separate the service name for the sub because slashes cannot appear in service names. </li> </ul> diff --git a/package/deps.mak b/package/deps.mak index 9543a02..f738d27 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -34,8 +34,8 @@ src/repo/s6-rc-set-commit.o src/repo/s6-rc-set-commit.lo: src/repo/s6-rc-set-com src/repo/s6-rc-set-copy.o src/repo/s6-rc-set-copy.lo: src/repo/s6-rc-set-copy.c src/include/s6-rc/config.h src/include/s6-rc/s6rc.h src/repo/s6-rc-set-delete.o src/repo/s6-rc-set-delete.lo: src/repo/s6-rc-set-delete.c src/include/s6-rc/config.h src/include/s6-rc/s6rc.h src/repo/s6-rc-set-install.o src/repo/s6-rc-set-install.lo: src/repo/s6-rc-set-install.c src/include/s6-rc/config.h src/include/s6-rc/s6rc.h -src/repo/s6-rc-set-list.o src/repo/s6-rc-set-list.lo: src/repo/s6-rc-set-list.c src/include/s6-rc/config.h src/include/s6-rc/repo.h src/repo/s6-rc-set-new.o src/repo/s6-rc-set-new.lo: src/repo/s6-rc-set-new.c src/include/s6-rc/config.h src/include/s6-rc/s6rc.h +src/repo/s6-rc-set-status.o src/repo/s6-rc-set-status.lo: src/repo/s6-rc-set-status.c src/include/s6-rc/config.h src/include/s6-rc/repo.h src/repo/s6rc_repo_badsub.o src/repo/s6rc_repo_badsub.lo: src/repo/s6rc_repo_badsub.c src/include/s6-rc/repo.h src/repo/s6rc_repo_checkset.o src/repo/s6rc_repo_checkset.lo: src/repo/s6rc_repo_checkset.c src/include/s6-rc/repo.h src/repo/s6rc_repo_cleanup.o src/repo/s6rc_repo_cleanup.lo: src/repo/s6rc_repo_cleanup.c src/include/s6-rc/repo.h @@ -115,10 +115,10 @@ s6-rc-set-delete: EXTRA_LIBS := ${SPAWN_LIB} s6-rc-set-delete: src/repo/s6-rc-set-delete.o ${LIBS6RCREPO} -lskarnet s6-rc-set-install: EXTRA_LIBS := ${SPAWN_LIB} s6-rc-set-install: src/repo/s6-rc-set-install.o ${LIBS6RCREPO} -lskarnet -s6-rc-set-list: EXTRA_LIBS := ${SPAWN_LIB} -s6-rc-set-list: src/repo/s6-rc-set-list.o ${LIBS6RCREPO} -lskarnet s6-rc-set-new: EXTRA_LIBS := ${SPAWN_LIB} s6-rc-set-new: src/repo/s6-rc-set-new.o ${LIBS6RCREPO} -lskarnet +s6-rc-set-status: EXTRA_LIBS := ${SPAWN_LIB} +s6-rc-set-status: src/repo/s6-rc-set-status.o ${LIBS6RCREPO} -lskarnet s6-rc: EXTRA_LIBS := ${SYSCLOCK_LIB} ${SPAWN_LIB} s6-rc: src/s6-rc/s6-rc.o ${LIBS6RC} -ls6 -lskarnet s6-rc-bundle: EXTRA_LIBS := diff --git a/package/modes b/package/modes index 95ee646..6ef7f93 100644 --- a/package/modes +++ b/package/modes @@ -10,7 +10,7 @@ s6-rc-oneshot-run 0755 s6-rc-format-upgrade 0755 s6-rc-repo-init 0755 s6-rc-repo-sync 0755 -s6-rc-set-list 0755 +s6-rc-set-status 0755 s6-rc-set-new 0755 s6-rc-set-copy 0755 s6-rc-set-delete 0755 diff --git a/package/targets.mak b/package/targets.mak index 9a83f37..f22dcaa 100644 --- a/package/targets.mak +++ b/package/targets.mak @@ -9,7 +9,7 @@ s6-rc-update \ s6-rc-format-upgrade \ s6-rc-repo-init \ s6-rc-repo-sync \ -s6-rc-set-list \ +s6-rc-set-status \ s6-rc-set-new \ s6-rc-set-copy \ s6-rc-set-delete \ diff --git a/src/repo/deps-exe/s6-rc-set-list b/src/repo/deps-exe/s6-rc-set-status index 9fe69bb..9fe69bb 100644 --- a/src/repo/deps-exe/s6-rc-set-list +++ b/src/repo/deps-exe/s6-rc-set-status diff --git a/src/repo/s6-rc-set-change.c b/src/repo/s6-rc-set-change.c index 1ab92f6..c678357 100644 --- a/src/repo/s6-rc-set-change.c +++ b/src/repo/s6-rc-set-change.c @@ -129,9 +129,16 @@ int main (int argc, char const *const *argv) if (newsub->sub == 3 && !(wgolb & GOLB_FORCE_ESSENTIAL)) strerr_diefu1x(10, " artificially mark a service as essential without --force-essential") ; + for (unsigned int i = 2 ; i < argc ; i++) + { + if (argv[i][0] == '.') + strerr_dief2x(100, "service names cannot ", "start with a dot") ; + if (strchr(argv[i], '/') || strchr(argv[i], '\n')) + strerr_dief2x(100, "service names cannot ", "contain / or newlines") ; + } + fdlock = s6rc_repo_lock(wgola[GOLA_REPODIR], 1) ; if (fdlock == -1) strerr_diefu2sys(111, "lock ", wgola[GOLA_REPODIR]) ; - if (!s6rc_repo_makesvlist_byname(wgola[GOLA_REPODIR], argv[0], &storage, &svlist)) _exit(111) ; list = genalloc_s(s6rc_repo_sv, &svlist) ; listn = genalloc_len(s6rc_repo_sv, &svlist) ; diff --git a/src/repo/s6-rc-set-list.c b/src/repo/s6-rc-set-list.c deleted file mode 100644 index 84ef3bb..0000000 --- a/src/repo/s6-rc-set-list.c +++ /dev/null @@ -1,86 +0,0 @@ -/* ISC license. */ - -#include <skalibs/nonposix.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include <skalibs/envexec.h> -#include <skalibs/direntry.h> -#include <skalibs/buffer.h> - -#include <s6-rc/config.h> -#include <s6-rc/repo.h> - -#define USAGE "s6-rc-set-list [ -v verbosity ] [ -r repo ] set" -#define dieusage() strerr_dieusage(100, USAGE) - -enum gola_e -{ - GOLA_VERBOSITY, - GOLA_REPODIR, - GOLA_N -} ; - -int main (int argc, char const *const *argv) -{ - static gol_arg const rgola[] = - { - { .so = 'v', .lo = "verbosity", .i = GOLA_VERBOSITY }, - { .so = 'r', .lo = "repodir", .i = GOLA_REPODIR } - } ; - int fdlock ; - unsigned int verbosity = 1 ; - char const *wgola[GOLA_N] = { 0 } ; - unsigned int golc ; - int e ; - uint8_t sub = 4 ; - - PROG = "s6-rc-set-list" ; - wgola[GOLA_REPODIR] = S6RC_REPODIR ; - - golc = gol_main(argc, argv, 0, 0, rgola, GOLA_N, 0, wgola) ; - argc -= golc ; argv += golc ; - if (wgola[GOLA_VERBOSITY] && !uint0_scan(wgola[GOLA_VERBOSITY], &verbosity)) - strerr_dief1x(100, "verbosity needs to be an unsigned integer") ; - if (!argc) dieusage() ; - if (strchr(argv[0], '/') || strchr(argv[0], '\n')) - strerr_dief1x(100, "set names cannot contain / or newlines") ; - - fdlock = s6rc_repo_lock(wgola[GOLA_REPODIR], 1) ; - if (fdlock == -1) strerr_diefu2sys(111, "lock ", wgola[GOLA_REPODIR]) ; - - e = s6rc_repo_checkset(wgola[GOLA_REPODIR], argv[0]) ; - if (e) _exit(e) ; - - size_t repolen = strlen(wgola[GOLA_REPODIR]) ; - size_t setlen = strlen(argv[0]) ; - char fn[repolen + setlen + 17] ; - memcpy(fn, wgola[GOLA_REPODIR], repolen) ; - memcpy(fn + repolen, "/sources/", 9) ; - memcpy(fn + repolen + 9, argv[0], setlen) ; - fn[repolen + 9 + setlen] = '/' ; - while (sub--) - { - memcpy(fn + repolen + 10 + setlen, s6rc_repo_subnames[sub], 7) ; - DIR *dir = opendir(fn) ; - if (!dir) strerr_diefu2sys(111, "opendir ", fn) ; - for (;;) - { - direntry *d ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - if (buffer_puts(buffer_1, d->d_name) < 0 - || buffer_put(buffer_1, "/", 1) < 0 - || buffer_put(buffer_1, s6rc_repo_subnames[sub], 6) < 0 - || buffer_put(buffer_1, "\n", 1) < 0) - strerr_diefu1sys(111, "write to stdout") ; - } - if (errno) strerr_diefu2sys(111, "readdir ", fn) ; - dir_close(dir) ; - } - if (!buffer_flush(buffer_1)) strerr_diefu1sys(111, "write to stdout") ; - _exit(0) ; -} diff --git a/src/repo/s6-rc-set-status.c b/src/repo/s6-rc-set-status.c new file mode 100644 index 0000000..b58811b --- /dev/null +++ b/src/repo/s6-rc-set-status.c @@ -0,0 +1,118 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> + +#include <skalibs/uint64.h> +#include <skalibs/envexec.h> +#include <skalibs/bytestr.h> +#include <skalibs/direntry.h> +#include <skalibs/buffer.h> + +#include <s6-rc/config.h> +#include <s6-rc/repo.h> + +#define USAGE "s6-rc-set-status [ -v verbosity ] [ -r repo ] [ -E | -e ] set services..." +#define dieusage() strerr_dieusage(100, USAGE) +#define dieout() strerr_diefu1sys(111, "write to stdout") + +enum golb_e +{ + GOLB_IGNORE_ESSENTIALS = 0x01, + GOLB_NOSUB = 0x02, +} ; + +enum gola_e +{ + GOLA_VERBOSITY, + GOLA_REPODIR, + GOLA_N +} ; + +int main (int argc, char const **argv) +{ + static gol_bool const rgolb[] = + { + { .so = 'E', .lo = "with-essentials", .clear = GOLB_IGNORE_ESSENTIALS, .set = 0 }, + { .so = 'e', .lo = "without-essentials", .clear = 0, .set = GOLB_IGNORE_ESSENTIALS }, + { .so = 'L', .lo = "list", .clear = 0, .set = GOLB_NOSUB }, + } ; + static gol_arg const rgola[] = + { + { .so = 'v', .lo = "verbosity", .i = GOLA_VERBOSITY }, + { .so = 'r', .lo = "repodir", .i = GOLA_REPODIR } + } ; + int fdlock ; + unsigned int verbosity = 1 ; + uint64_t wgolb = 0 ; + char const *setname ; + char const *wgola[GOLA_N] = { 0 } ; + unsigned int golc ; + uint8_t sub ; + + PROG = "s6-rc-set-status" ; + wgola[GOLA_REPODIR] = S6RC_REPODIR ; + + golc = GOL_main(argc, argv, rgolb, rgola, &wgolb, wgola) ; + argc -= golc ; argv += golc ; + if (argc < 2) dieusage() ; + setname = *argv++ ; argc-- ; + if (wgola[GOLA_VERBOSITY] && !uint0_scan(wgola[GOLA_VERBOSITY], &verbosity)) + strerr_dief1x(100, "verbosity needs to be an unsigned integer") ; + if (strchr(setname, '/') || strchr(setname, '\n')) + strerr_dief2x(100, "set", " names cannot contain / or newlines") ; + for (unsigned int i = 0 ; i < argc ; i++) + { + if (argv[i][0] == '.') + strerr_dief2x(100, "service", " names cannot start with a dot") ; + if (strchr(argv[i], '/') || strchr(argv[i], '\n')) + strerr_dief2x(100, "service", " names cannot contain / or newlines") ; + } + + fdlock = s6rc_repo_lock(wgola[GOLA_REPODIR], 1) ; + if (fdlock == -1) strerr_diefu2sys(111, "lock ", wgola[GOLA_REPODIR]) ; + + { + int e = s6rc_repo_checkset(wgola[GOLA_REPODIR], setname) ; + if (e) _exit(e) ; + } + + qsort(argv, argc, sizeof(char const *), &str_cmp) ; + + size_t repolen = strlen(wgola[GOLA_REPODIR]) ; + size_t setlen = strlen(setname) ; + char fn[repolen + setlen + 17] ; + memcpy(fn, wgola[GOLA_REPODIR], repolen) ; + memcpy(fn + repolen, "/sources/", 9) ; + memcpy(fn + repolen + 9, setname, setlen) ; + fn[repolen + 9 + setlen] = '/' ; + + sub = wgolb & GOLB_IGNORE_ESSENTIALS ? 3 : 4 ; + while (sub--) + { + memcpy(fn + repolen + 10 + setlen, s6rc_repo_subnames[sub], 7) ; + DIR *dir = opendir(fn) ; + if (!dir) strerr_diefu2sys(111, "opendir ", fn) ; + for (;;) + { + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + if (argc && !bsearch(d->d_name, argv, argc, sizeof(char const *), &str_bcmp)) continue ; + if (buffer_puts(buffer_1, d->d_name) < 0) dieout() ; + if (!(wgolb & GOLB_NOSUB)) + if (buffer_put(buffer_1, "/", 1) < 0 + || buffer_put(buffer_1, s6rc_repo_subnames[sub], 6) < 0) dieout() ; + if (buffer_put(buffer_1, "\n", 1) < 0) dieout() ; + } + if (errno) strerr_diefu2sys(111, "readdir ", fn) ; + dir_close(dir) ; + } + if (!buffer_flush(buffer_1)) strerr_diefu1sys(111, "write to stdout") ; + _exit(0) ; +} |
