diff options
| author | Laurent Bercot <ska-skaware@skarnet.org> | 2025-12-21 16:27:04 +0000 |
|---|---|---|
| committer | Laurent Bercot <ska-skaware@skarnet.org> | 2025-12-21 16:27:04 +0000 |
| commit | aff2e0c6435433a6f73b9d29c93a3109bfe146ca (patch) | |
| tree | cc17ac2c7228646c035d233412340ad885008cb9 | |
| parent | b24a07fca1f2a410b3d97d1e3dc5de7720ad1d76 (diff) | |
| download | s6-rc-aff2e0c6435433a6f73b9d29c93a3109bfe146ca.tar.gz | |
s6-rc-set-install fixes
| -rw-r--r-- | src/repo/s6-rc-set-change.c | 93 | ||||
| -rw-r--r-- | src/repo/s6-rc-set-install.c | 53 | ||||
| -rw-r--r-- | src/repo/s6rc_repo_lock.c | 2 |
3 files changed, 77 insertions, 71 deletions
diff --git a/src/repo/s6-rc-set-change.c b/src/repo/s6-rc-set-change.c index d413eb1..e763d25 100644 --- a/src/repo/s6-rc-set-change.c +++ b/src/repo/s6-rc-set-change.c @@ -42,53 +42,6 @@ struct subname_s uint8_t sub ; } ; -static gol_bool const rgolb[] = -{ - { .so = 'E', .lo = "no-force-essential", .clear = GOLB_FORCE_ESSENTIAL, .set = 0 }, - { .so = 'e', .lo = "force-essential", .clear = 0, .set = GOLB_FORCE_ESSENTIAL }, - { .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 = 'v', .lo = "verbosity", .i = GOLA_VERBOSITY }, - { .so = 'r', .lo = "repodir", .i = GOLA_REPODIR }, - { .so = 'I', .lo = "if-dependencies-found", .i = GOLA_FORCELEVEL } -} ; - -static struct subname_s const accepted_forcelevels[] = -{ - { .name = "fail", .sub = 0 }, - { .name = "pull", .sub = 2 }, - { .name = "warn", .sub = 1 } -} ; - -static uint64_t wgolb = 0 ; - -static struct subname_s const accepted_subs[] = -{ - { .name = "activate", .sub = 2 }, - { .name = "active", .sub = 2 }, - { .name = "always", .sub = 3 }, - { .name = "deactivate", .sub = 1 }, - { .name = "disable", .sub = 1 }, - { .name = "disabled", .sub = 1 }, - { .name = "enable", .sub = 2 }, - { .name = "enabled", .sub = 2 }, - { .name = "essential", .sub = 3 }, - { .name = "inactive", .sub = 1 }, - { .name = "latent", .sub = 1 }, - { .name = "make-essential", .sub = 3 }, - { .name = "mask", .sub = 0 }, - { .name = "masked", .sub = 0 }, - { .name = "onboot", .sub = 2 }, - { .name = "suppress", .sub = 0 }, - { .name = "unmask", .sub = 1 }, - { .name = "unmasked", .sub = 1 }, - { .name = "usable", .sub = 1 } -} ; - static int subname_cmp (void const *a, void const *b) { return strcmp((char const *)a, ((struct subname_s const *)b)->name) ; @@ -96,14 +49,56 @@ static int subname_cmp (void const *a, void const *b) int main (int argc, char const *const *argv) { + static gol_bool const rgolb[] = + { + { .so = 'E', .lo = "no-force-essential", .clear = GOLB_FORCE_ESSENTIAL, .set = 0 }, + { .so = 'e', .lo = "force-essential", .clear = 0, .set = GOLB_FORCE_ESSENTIAL }, + { .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 = 'v', .lo = "verbosity", .i = GOLA_VERBOSITY }, + { .so = 'r', .lo = "repodir", .i = GOLA_REPODIR }, + { .so = 'I', .lo = "if-dependencies-found", .i = GOLA_FORCELEVEL } + } ; + static struct subname_s const accepted_forcelevels[] = + { + { .name = "fail", .sub = 0 }, + { .name = "pull", .sub = 2 }, + { .name = "warn", .sub = 1 } + } ; + static struct subname_s const accepted_subs[] = + { + { .name = "activate", .sub = 2 }, + { .name = "active", .sub = 2 }, + { .name = "always", .sub = 3 }, + { .name = "deactivate", .sub = 1 }, + { .name = "disable", .sub = 1 }, + { .name = "disabled", .sub = 1 }, + { .name = "enable", .sub = 2 }, + { .name = "enabled", .sub = 2 }, + { .name = "essential", .sub = 3 }, + { .name = "inactive", .sub = 1 }, + { .name = "latent", .sub = 1 }, + { .name = "make-essential", .sub = 3 }, + { .name = "mask", .sub = 0 }, + { .name = "masked", .sub = 0 }, + { .name = "onboot", .sub = 2 }, + { .name = "suppress", .sub = 0 }, + { .name = "unmask", .sub = 1 }, + { .name = "unmasked", .sub = 1 }, + { .name = "usable", .sub = 1 } + } ; stralloc storage = STRALLOC_ZERO ; genalloc svlist = GENALLOC_ZERO ; /* s6rc_repo_sv */ genalloc indices = GENALLOC_ZERO ; /* size_t then uint32_t */ - genalloc gatmp = GENALLOC_ZERO ; /* size_t */ + genalloc gatmp = GENALLOC_ZERO ; /* size_t whatever */ int fdlock ; unsigned int verbosity = 1 ; unsigned int forcelevel = 1 ; char const *wgola[GOLA_N] = { 0 } ; + uint64_t wgolb = 0 ; unsigned int golc ; struct subname_s *newsub ; size_t max = 0, sabase ; @@ -126,7 +121,7 @@ int main (int argc, char const *const *argv) if (argc < 3) dieusage() ; s6rc_repo_sanitize_setname(argv[0]) ; newsub = bsearch(argv[1], accepted_subs, sizeof(accepted_subs)/sizeof(struct subname_s), sizeof(struct subname_s), &subname_cmp) ; - if (!newsub) strerr_dief2x(100, "unrecognized state change directive:", argv[1]) ; + if (!newsub) strerr_dief2x(100, "unrecognized state change directive: ", argv[1]) ; if (newsub->sub == 3 && !(wgolb & GOLB_FORCE_ESSENTIAL)) strerr_diefu1x(100, "artificially mark a service as essential without --force-essential") ; for (unsigned int i = 2 ; i < argc ; i++) s6rc_repo_sanitize_svname(argv[i]) ; diff --git a/src/repo/s6-rc-set-install.c b/src/repo/s6-rc-set-install.c index a3a82df..27c58cf 100644 --- a/src/repo/s6-rc-set-install.c +++ b/src/repo/s6-rc-set-install.c @@ -1,7 +1,10 @@ /* ISC license. */ #include <skalibs/bsdsnowflake.h> +#include <skalibs/nonposix.h> +#include <skalibs/stat.h> +#include <time.h> #include <string.h> #include <unistd.h> #include <stdlib.h> @@ -9,7 +12,6 @@ #include <errno.h> #include <skalibs/uint64.h> -#include <skalibs/stat.h> #include <skalibs/types.h> #include <skalibs/posixplz.h> #include <skalibs/prog.h> @@ -44,23 +46,22 @@ enum gola_e GOLA_N } ; -static gol_bool const rgolb[] = -{ - { .so = 'b', .lo = "block", .clear = 0, .set = GOLB_BLOCK }, - { .so = 'K', .lo = "keep-old", .clear = 0, .set = GOLB_KEEPOLD } -} ; - -static gol_arg const rgola[] = -{ - { .so = 'v', .lo = "verbosity", .i = GOLA_VERBOSITY }, - { .so = 'c', .lo = "bootdb", .i = GOLA_BOOTDB }, - { .so = 'l', .lo = "livedir", .i = GOLA_LIVEDIR }, - { .so = 'r', .lo = "repodir", .i = GOLA_REPODIR }, - { .so = 'f', .lo = "conversion-file", .i = GOLA_CONVFILE } -} ; - int main (int argc, char const *const *argv) { + static gol_bool const rgolb[] = + { + { .so = 'b', .lo = "block", .clear = 0, .set = GOLB_BLOCK }, + { .so = 'K', .lo = "keep-old", .clear = 0, .set = GOLB_KEEPOLD } + } ; + static gol_arg const rgola[] = + { + { .so = 'v', .lo = "verbosity", .i = GOLA_VERBOSITY }, + { .so = 'c', .lo = "bootdb", .i = GOLA_BOOTDB }, + { .so = 'l', .lo = "livedir", .i = GOLA_LIVEDIR }, + { .so = 'r', .lo = "repodir", .i = GOLA_REPODIR }, + { .so = 'f', .lo = "conversion-file", .i = GOLA_CONVFILE } + } ; + int fdlock ; unsigned int verbosity = 1 ; char const *wgola[GOLA_N] = { 0 } ; @@ -78,6 +79,10 @@ int main (int argc, char const *const *argv) 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 (wgola[GOLA_BOOTDB][0] != '/') + strerr_dief2x(100, "bootdb", " needs to be an absolute path") ; + if (wgola[GOLA_LIVEDIR][0] != '/') + strerr_dief2x(100, "livedir", " needs to be an absolute path") ; if (!argc) dieusage() ; s6rc_repo_sanitize_setname(argv[0]) ; @@ -122,13 +127,19 @@ int main (int argc, char const *const *argv) memcpy(dstfn + sa.len + 1, cfull + repolen + 10, l+1) ; l = 0 ; { - struct stat st ; - if (stat(dstfn, &st) == -1) + struct stat stsource, stdest ; + if (stat(cfull, &stsource) == -1) strerr_diefu2sys(111, "stat ", cfull) ; + if (stat(dstfn, &stdest) == -1) { if (errno != ENOENT) strerr_diefu2sys(111, "stat ", dstfn) ; } - else strerr_dief2x(102, dstfn, " already exists") ; + else if (stdest.st_mtim.tv_sec > stsource.st_mtim.tv_sec || (stdest.st_mtim.tv_sec == stsource.st_mtim.tv_sec && stdest.st_mtim.tv_nsec >= stsource.st_mtim.tv_nsec)) + { + strerr_warni(0, "set ", argv[0], " is already installed as ", dstfn) ; + _exit(0) ; + } + else strerr_dief(102, "huh? ", dstfn, " already exists") ; } { size_t llen = strlen(wgola[GOLA_LIVEDIR]) ; @@ -206,8 +217,8 @@ int main (int argc, char const *const *argv) fmt[int_fmt(fmt, r)] = 0 ; strerr_dief4x(r, uargv[0], " exited with code ", fmt, " (live database switch was performed") ; } - if (!atomic_symlink4(dstfn + sa.len + 1, argv[1], 0, 0)) - strerr_diefu6sys(111, "symlink ", dstfn + sa.len + 1, " to ", argv[1], " (live database switch was performed)", " (update that link manually or next boot might fail)") ; + if (!atomic_symlink4(dstfn + sa.len + 1, wgola[GOLA_BOOTDB], 0, 0)) + strerr_diefu6sys(111, "symlink ", dstfn + sa.len + 1, " to ", wgola[GOLA_BOOTDB], " (live database switch was performed)", " (update that link manually or next boot might fail)") ; } // stralloc_free(&sa) ; _exit(0) ; diff --git a/src/repo/s6rc_repo_lock.c b/src/repo/s6rc_repo_lock.c index 472ff15..ba13fc7 100644 --- a/src/repo/s6rc_repo_lock.c +++ b/src/repo/s6rc_repo_lock.c @@ -13,7 +13,7 @@ int s6rc_repo_lock (char const *repo, int w) char fn[repolen + 13] ; memcpy(fn, repo, repolen) ; memcpy(fn + repolen, "/lock", 6) ; - fd = openc_write(fn) ; + fd = w ? openc_write(fn) : openc_read(fn) ; if (fd == -1) return -1 ; if (fd_lock(fd, w, 0) < 1) return -1 ; return fd ; |
