From e0bcc0ef3466b7b5fc776d2e78d7e7ec027810c0 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 22 Oct 2025 22:05:56 +0000 Subject: Separate libs6rcrepo --- src/include/s6-rc/repo.h | 4 + src/include/s6-rc/s6rc-utils.h | 6 - src/libs6rc/deps-lib/s6rc | 34 ----- src/libs6rc/s6rc_ls.c | 46 ------ src/libs6rc/s6rc_nlto0.c | 33 ----- src/libs6rc/s6rc_repo_badsub.c | 69 --------- src/libs6rc/s6rc_repo_checkset.c | 40 ------ src/libs6rc/s6rc_repo_cleanup.c | 117 --------------- src/libs6rc/s6rc_repo_compile.c | 106 -------------- src/libs6rc/s6rc_repo_fillset.c | 73 ---------- src/libs6rc/s6rc_repo_fix.c | 51 ------- src/libs6rc/s6rc_repo_fixset.c | 96 ------------- src/libs6rc/s6rc_repo_flattenservices.c | 73 ---------- src/libs6rc/s6rc_repo_getserviceflags.c | 70 --------- src/libs6rc/s6rc_repo_list_sets.c | 15 -- src/libs6rc/s6rc_repo_listalldeps.c | 8 -- src/libs6rc/s6rc_repo_listcontents.c | 68 --------- src/libs6rc/s6rc_repo_listdeps.c | 8 -- src/libs6rc/s6rc_repo_listdeps_internal.c | 74 ---------- src/libs6rc/s6rc_repo_listsub.c | 20 --- src/libs6rc/s6rc_repo_lock.c | 20 --- src/libs6rc/s6rc_repo_makedefbundle.c | 121 ---------------- src/libs6rc/s6rc_repo_makesetbundles.c | 137 ------------------ src/libs6rc/s6rc_repo_makestores.c | 65 --------- src/libs6rc/s6rc_repo_makesvlist.c | 66 --------- src/libs6rc/s6rc_repo_makesvlist_byname.c | 14 -- src/libs6rc/s6rc_repo_moveservices.c | 60 -------- src/libs6rc/s6rc_repo_setcompile.c | 33 ----- src/libs6rc/s6rc_repo_setuptodate.c | 45 ------ src/libs6rc/s6rc_repo_subnames.c | 5 - src/libs6rc/s6rc_repo_sv_bcmpr.c | 13 -- src/libs6rc/s6rc_repo_sv_cmpr.c | 11 -- src/libs6rc/s6rc_repo_sync.c | 231 ------------------------------ src/libs6rc/s6rc_repo_syncset.c | 16 --- src/libs6rc/s6rc_repo_syncset_tmp.c | 102 ------------- src/libs6rc/s6rc_repo_touch.c | 45 ------ src/libs6rc/s6rc_repo_touchset.c | 25 ---- src/libs6rc/s6rc_type_check.c | 33 ----- src/repo/deps-exe/s6-rc-repo-init | 4 +- src/repo/deps-exe/s6-rc-repo-sync | 4 +- src/repo/deps-exe/s6-rc-set-change | 4 +- src/repo/deps-exe/s6-rc-set-commit | 4 +- src/repo/deps-exe/s6-rc-set-copy | 4 +- src/repo/deps-exe/s6-rc-set-delete | 4 +- src/repo/deps-exe/s6-rc-set-install | 4 +- src/repo/deps-exe/s6-rc-set-new | 4 +- src/repo/deps-lib/s6rcrepo | 36 +++++ src/repo/s6rc_repo_badsub.c | 69 +++++++++ src/repo/s6rc_repo_checkset.c | 39 +++++ src/repo/s6rc_repo_cleanup.c | 117 +++++++++++++++ src/repo/s6rc_repo_compile.c | 106 ++++++++++++++ src/repo/s6rc_repo_fillset.c | 73 ++++++++++ src/repo/s6rc_repo_fix.c | 51 +++++++ src/repo/s6rc_repo_fixset.c | 96 +++++++++++++ src/repo/s6rc_repo_flattenservices.c | 72 ++++++++++ src/repo/s6rc_repo_getserviceflags.c | 70 +++++++++ src/repo/s6rc_repo_list_sets.c | 14 ++ src/repo/s6rc_repo_listalldeps.c | 8 ++ src/repo/s6rc_repo_listcontents.c | 67 +++++++++ src/repo/s6rc_repo_listdeps.c | 8 ++ src/repo/s6rc_repo_listdeps_internal.c | 73 ++++++++++ src/repo/s6rc_repo_listsub.c | 19 +++ src/repo/s6rc_repo_lock.c | 20 +++ src/repo/s6rc_repo_ls.c | 46 ++++++ src/repo/s6rc_repo_makedefbundle.c | 121 ++++++++++++++++ src/repo/s6rc_repo_makesetbundles.c | 137 ++++++++++++++++++ src/repo/s6rc_repo_makestores.c | 65 +++++++++ src/repo/s6rc_repo_makesvlist.c | 66 +++++++++ src/repo/s6rc_repo_makesvlist_byname.c | 14 ++ src/repo/s6rc_repo_moveservices.c | 60 ++++++++ src/repo/s6rc_repo_nlto0.c | 33 +++++ src/repo/s6rc_repo_setcompile.c | 33 +++++ src/repo/s6rc_repo_setuptodate.c | 44 ++++++ src/repo/s6rc_repo_subnames.c | 5 + src/repo/s6rc_repo_sv_bcmpr.c | 13 ++ src/repo/s6rc_repo_sv_cmpr.c | 11 ++ src/repo/s6rc_repo_sync.c | 230 +++++++++++++++++++++++++++++ src/repo/s6rc_repo_syncset.c | 16 +++ src/repo/s6rc_repo_syncset_tmp.c | 101 +++++++++++++ src/repo/s6rc_repo_touch.c | 45 ++++++ src/repo/s6rc_repo_touchset.c | 25 ++++ src/repo/s6rc_repo_type_check.c | 29 ++++ src/s6-rc/s6-rc-compile.c | 17 ++- 83 files changed, 2068 insertions(+), 2066 deletions(-) delete mode 100644 src/libs6rc/s6rc_ls.c delete mode 100644 src/libs6rc/s6rc_nlto0.c delete mode 100644 src/libs6rc/s6rc_repo_badsub.c delete mode 100644 src/libs6rc/s6rc_repo_checkset.c delete mode 100644 src/libs6rc/s6rc_repo_cleanup.c delete mode 100644 src/libs6rc/s6rc_repo_compile.c delete mode 100644 src/libs6rc/s6rc_repo_fillset.c delete mode 100644 src/libs6rc/s6rc_repo_fix.c delete mode 100644 src/libs6rc/s6rc_repo_fixset.c delete mode 100644 src/libs6rc/s6rc_repo_flattenservices.c delete mode 100644 src/libs6rc/s6rc_repo_getserviceflags.c delete mode 100644 src/libs6rc/s6rc_repo_list_sets.c delete mode 100644 src/libs6rc/s6rc_repo_listalldeps.c delete mode 100644 src/libs6rc/s6rc_repo_listcontents.c delete mode 100644 src/libs6rc/s6rc_repo_listdeps.c delete mode 100644 src/libs6rc/s6rc_repo_listdeps_internal.c delete mode 100644 src/libs6rc/s6rc_repo_listsub.c delete mode 100644 src/libs6rc/s6rc_repo_lock.c delete mode 100644 src/libs6rc/s6rc_repo_makedefbundle.c delete mode 100644 src/libs6rc/s6rc_repo_makesetbundles.c delete mode 100644 src/libs6rc/s6rc_repo_makestores.c delete mode 100644 src/libs6rc/s6rc_repo_makesvlist.c delete mode 100644 src/libs6rc/s6rc_repo_makesvlist_byname.c delete mode 100644 src/libs6rc/s6rc_repo_moveservices.c delete mode 100644 src/libs6rc/s6rc_repo_setcompile.c delete mode 100644 src/libs6rc/s6rc_repo_setuptodate.c delete mode 100644 src/libs6rc/s6rc_repo_subnames.c delete mode 100644 src/libs6rc/s6rc_repo_sv_bcmpr.c delete mode 100644 src/libs6rc/s6rc_repo_sv_cmpr.c delete mode 100644 src/libs6rc/s6rc_repo_sync.c delete mode 100644 src/libs6rc/s6rc_repo_syncset.c delete mode 100644 src/libs6rc/s6rc_repo_syncset_tmp.c delete mode 100644 src/libs6rc/s6rc_repo_touch.c delete mode 100644 src/libs6rc/s6rc_repo_touchset.c delete mode 100644 src/libs6rc/s6rc_type_check.c create mode 100644 src/repo/deps-lib/s6rcrepo create mode 100644 src/repo/s6rc_repo_badsub.c create mode 100644 src/repo/s6rc_repo_checkset.c create mode 100644 src/repo/s6rc_repo_cleanup.c create mode 100644 src/repo/s6rc_repo_compile.c create mode 100644 src/repo/s6rc_repo_fillset.c create mode 100644 src/repo/s6rc_repo_fix.c create mode 100644 src/repo/s6rc_repo_fixset.c create mode 100644 src/repo/s6rc_repo_flattenservices.c create mode 100644 src/repo/s6rc_repo_getserviceflags.c create mode 100644 src/repo/s6rc_repo_list_sets.c create mode 100644 src/repo/s6rc_repo_listalldeps.c create mode 100644 src/repo/s6rc_repo_listcontents.c create mode 100644 src/repo/s6rc_repo_listdeps.c create mode 100644 src/repo/s6rc_repo_listdeps_internal.c create mode 100644 src/repo/s6rc_repo_listsub.c create mode 100644 src/repo/s6rc_repo_lock.c create mode 100644 src/repo/s6rc_repo_ls.c create mode 100644 src/repo/s6rc_repo_makedefbundle.c create mode 100644 src/repo/s6rc_repo_makesetbundles.c create mode 100644 src/repo/s6rc_repo_makestores.c create mode 100644 src/repo/s6rc_repo_makesvlist.c create mode 100644 src/repo/s6rc_repo_makesvlist_byname.c create mode 100644 src/repo/s6rc_repo_moveservices.c create mode 100644 src/repo/s6rc_repo_nlto0.c create mode 100644 src/repo/s6rc_repo_setcompile.c create mode 100644 src/repo/s6rc_repo_setuptodate.c create mode 100644 src/repo/s6rc_repo_subnames.c create mode 100644 src/repo/s6rc_repo_sv_bcmpr.c create mode 100644 src/repo/s6rc_repo_sv_cmpr.c create mode 100644 src/repo/s6rc_repo_sync.c create mode 100644 src/repo/s6rc_repo_syncset.c create mode 100644 src/repo/s6rc_repo_syncset_tmp.c create mode 100644 src/repo/s6rc_repo_touch.c create mode 100644 src/repo/s6rc_repo_touchset.c create mode 100644 src/repo/s6rc_repo_type_check.c (limited to 'src') diff --git a/src/include/s6-rc/repo.h b/src/include/s6-rc/repo.h index ca17b4b..17b7047 100644 --- a/src/include/s6-rc/repo.h +++ b/src/include/s6-rc/repo.h @@ -19,6 +19,10 @@ struct s6rc_repo_sv_s extern int s6rc_repo_sv_cmpr (void const *, void const *, void *) ; extern int s6rc_repo_sv_bcmpr (void const *a, void const *b, void *aux) ; +extern int s6rc_repo_nlto0 (char *, size_t, size_t, genalloc *) ; +extern int s6rc_repo_type_check (char const *) ; +extern int s6rc_repo_ls (char const *, stralloc *, genalloc *) ; + extern char const s6rc_repo_subnames[4][7] ; extern int s6rc_repo_makestores (char const *, char const *const *, uint16_t, char *) ; diff --git a/src/include/s6-rc/s6rc-utils.h b/src/include/s6-rc/s6rc-utils.h index 7da49ee..84f035b 100644 --- a/src/include/s6-rc/s6rc-utils.h +++ b/src/include/s6-rc/s6rc-utils.h @@ -7,8 +7,6 @@ #include #include -#include -#include #include @@ -25,8 +23,4 @@ extern int s6rc_livedir_canon (char const **) ; extern int s6rc_live_state_size (char const *, uint32_t *, uint32_t *) ; extern int s6rc_live_state_read (char const *, unsigned char *, uint32_t) ; -extern int s6rc_ls (char const *, stralloc *, genalloc *) ; -extern int s6rc_type_check (int, char const *) ; -extern int s6rc_nlto0 (char *, size_t, size_t, genalloc *) ; - #endif diff --git a/src/libs6rc/deps-lib/s6rc b/src/libs6rc/deps-lib/s6rc index ec22808..9f677f7 100644 --- a/src/libs6rc/deps-lib/s6rc +++ b/src/libs6rc/deps-lib/s6rc @@ -12,40 +12,7 @@ s6rc_livedir_create.o s6rc_livedir_prefix.o s6rc_livedir_prefixsize.o s6rc_lock.o -s6rc_ls.o -s6rc_nlto0.o s6rc_read_uint.o -s6rc_repo_badsub.o -s6rc_repo_checkset.o -s6rc_repo_cleanup.o -s6rc_repo_compile.o -s6rc_repo_fillset.o -s6rc_repo_fixset.o -s6rc_repo_flattenservices.o -s6rc_repo_getserviceflags.o -s6rc_repo_list_sets.o -s6rc_repo_listalldeps.o -s6rc_repo_listcontents.o -s6rc_repo_listdeps.o -s6rc_repo_listdeps_internal.o -s6rc_repo_listsub.o -s6rc_repo_lock.o -s6rc_repo_makedefbundle.o -s6rc_repo_makesetbundles.o -s6rc_repo_makestores.o -s6rc_repo_makesvlist.o -s6rc_repo_makesvlist_byname.o -s6rc_repo_moveservices.o -s6rc_repo_setcompile.o -s6rc_repo_setuptodate.o -s6rc_repo_subnames.o -s6rc_repo_sv_bcmpr.o -s6rc_repo_sv_cmpr.o -s6rc_repo_sync.o -s6rc_repo_syncset.o -s6rc_repo_syncset_tmp.o -s6rc_repo_touch.o -s6rc_repo_touchset.o s6rc_sanitize_dir.o s6rc_servicedir_internal.o s6rc_servicedir_block.o @@ -54,7 +21,6 @@ s6rc_servicedir_copy_offline.o s6rc_servicedir_copy_online.o s6rc_servicedir_manage.o s6rc_servicedir_unsupervise.o -s6rc_type_check.o -ls6 -lskarnet ${SPAWN_LIB} diff --git a/src/libs6rc/s6rc_ls.c b/src/libs6rc/s6rc_ls.c deleted file mode 100644 index 75f90f2..0000000 --- a/src/libs6rc/s6rc_ls.c +++ /dev/null @@ -1,46 +0,0 @@ -/* ISC license. */ - -#include -#include - -#include -#include -#include - -#include - -int s6rc_ls (char const *fn, stralloc *sa, genalloc *ga) -{ - size_t sabase = sa->len ; - size_t gabase = genalloc_len(size_t, ga) ; - int sawasnull = !sa->s ; - int gawasnull = !genalloc_s(size_t, ga) ; - int n = 0 ; - - DIR *dir = opendir(fn) ; - if (!dir) return -1 ; - for (;;) - { - direntry *d ; - size_t len ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - len = strlen(d->d_name) ; - if (!genalloc_catb(size_t, ga, &sa->len, 1)) goto err ; - if (!stralloc_catb(sa, d->d_name, len+1)) goto err ; - n++ ; - } - if (errno) goto err ; - dir_close(dir) ; - return n ; - - err: - dir_close(dir) ; - if (gawasnull) genalloc_free(size_t, ga) ; - else genalloc_setlen(size_t, ga, gabase) ; - if (sawasnull) stralloc_free(sa) ; - else sa->len = sabase ; - return -1 ; -} diff --git a/src/libs6rc/s6rc_nlto0.c b/src/libs6rc/s6rc_nlto0.c deleted file mode 100644 index 6436cdb..0000000 --- a/src/libs6rc/s6rc_nlto0.c +++ /dev/null @@ -1,33 +0,0 @@ -/* ISC license. */ - -#include - -#include - -#include - -int s6rc_nlto0 (char *s, size_t start, size_t len, genalloc *indices) -{ - size_t origlen = genalloc_len(size_t, indices) ; - size_t pos = start ; - int wasnull = !indices->s ; - int inword = 0 ; - - for (size_t i = start ; i < len ; i++) - { - if (s[i] == '\n') - { - s[i] = 0 ; - if (!genalloc_append(size_t, indices, &pos)) goto err ; - inword = 0 ; - } - else if (!inword) { pos = i ; inword = 1 ; } - } - if (inword) goto err ; - return 1 ; - - err: - if (wasnull) genalloc_free(size_t, indices) ; - else genalloc_setlen(size_t, indices, origlen) ; - return 0 ; -} diff --git a/src/libs6rc/s6rc_repo_badsub.c b/src/libs6rc/s6rc_repo_badsub.c deleted file mode 100644 index 69697eb..0000000 --- a/src/libs6rc/s6rc_repo_badsub.c +++ /dev/null @@ -1,69 +0,0 @@ -/* ISC license. */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -static int strqcmp (void const *a, void const *b) -{ - return strcmp(*(char const *const *)a, *(char const *const *)b) ; -} - -int s6rc_repo_badsub (char const *repo, char const *set, char const **services, uint32_t n, uint8_t newsub, uint8_t what, s6rc_repo_sv const *svlist, uint32_t ntot, stralloc *sa, genalloc *badga) -{ - int sawasnull = !!sa->s ; - int gawasnull = !!genalloc_s(uint32_t, badga) ; - size_t sabase = sa->len ; - size_t gabase = genalloc_len(uint32_t, badga) ; - genalloc fulldeps = GENALLOC_ZERO ; - size_t fulln ; - size_t const *ind ; - uint32_t mid ; - - if (newsub < 3 && (what & 1) && s6rc_repo_listalldeps(repo, services, n, sa, &fulldeps, 0)) return 0 ; - mid = genalloc_len(size_t, &fulldeps) ; - if (newsub > 0 && (what & 2) && s6rc_repo_listalldeps(repo, services, n, sa, &fulldeps, 1)) goto err ; - - qsort(services, n, sizeof(char const *), &strqcmp) ; - fulln = genalloc_len(size_t, &fulldeps) ; - ind = genalloc_s(size_t, &fulldeps) ; - - for (uint32_t i = 0 ; i < fulln ; i++) - { - s6rc_repo_sv *p ; - char const *cur = sa->s + ind[i] ; - if (bsearch(&cur, services, n, sizeof(char const *), &strqcmp)) continue ; - p = bsearchr(cur, svlist, ntot, sizeof(s6rc_repo_sv), &s6rc_repo_sv_bcmpr, sa->s) ; - if (!p) - { - strerr_warnfu6x("find service ", cur, " in set ", set, " of repository ", repo) ; - goto err ; - } - if (i >= mid ? p->sub < newsub : p->sub > newsub) - { - uint32_t k = p - svlist ; - if (!genalloc_append(uint32_t, badga, &k)) - { - strerr_warnfu1sys("make bad sub list") ; - goto err ; - } - } - } - genalloc_free(size_t, &fulldeps) ; - return 1 ; - - err: - genalloc_free(size_t, &fulldeps) ; - if (sawasnull) stralloc_free(sa) ; else sa->len = sabase ; - if (gawasnull) genalloc_free(uint32_t, badga) ; else genalloc_setlen(uint32_t, badga, gabase) ; - return 0 ; -} diff --git a/src/libs6rc/s6rc_repo_checkset.c b/src/libs6rc/s6rc_repo_checkset.c deleted file mode 100644 index adf8674..0000000 --- a/src/libs6rc/s6rc_repo_checkset.c +++ /dev/null @@ -1,40 +0,0 @@ -/* ISC license. */ - -#include -#include - -#include -#include - -#include -#include - -int s6rc_repo_checkset (char const *repo, char const *set) -{ - struct stat st ; - size_t repolen = strlen(repo) ; - size_t setlen = strlen(set) ; - char fn[repolen + 10 + setlen] ; - memcpy(fn, repo, repolen) ; - memcpy(fn + repolen, "/sources/", 9) ; - memcpy(fn + repolen + 9, set, setlen + 1) ; - if (stat(fn, &st) == -1) - { - if (errno == ENOENT) - { - strerr_warnf4x("set ", set, " does not exist in repository ", repo) ; - return 3 ; - } - else - { - strerr_warnfu2sys("stat ", fn) ; - return 111 ; - } - } - if (!S_ISDIR(st.st_mode)) - { - strerr_warnf3x("file ", fn, " is not a directory") ; - return 102 ; - } - return 0 ; -} diff --git a/src/libs6rc/s6rc_repo_cleanup.c b/src/libs6rc/s6rc_repo_cleanup.c deleted file mode 100644 index 05881cd..0000000 --- a/src/libs6rc/s6rc_repo_cleanup.c +++ /dev/null @@ -1,117 +0,0 @@ -/* ISC license. */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -static inline int sub_cleanup (char const *sub) -{ - size_t sublen = strlen(sub) ; - DIR *dir = opendir(sub) ; - if (!dir) return 0 ; - for (;;) - { - size_t len ; - direntry *d ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - len = strlen(d->d_name) ; - { - char fn[sublen + len + 2] ; - memcpy(fn, sub, sublen) ; - fn[sublen] = '/' ; - memcpy(fn + sublen + 1, d->d_name, len + 1) ; - if (access(fn, F_OK) == 0) - { - struct stat st ; - if (lstat(fn, &st) == -1) break ; - if (!S_ISLNK(st.st_mode)) rm_rf(fn) ; - } - else if (errno != ENOENT) - { - strerr_warnfu2sys("access ", fn) ; - break ; - } - else unlink_void(fn) ; - } - } - dir_close(dir) ; - return !errno ; -} - -static inline int set_cleanup (char const *set) -{ - size_t setlen = strlen(set) ; - DIR *dir ; - { - char bundle[setlen + 8] ; - memcpy(bundle, set, setlen) ; - memcpy(bundle + setlen, "/bundle", 8) ; - rm_rf(bundle) ; - } - dir = opendir(set) ; - if (!dir) return 0 ; - for (;;) - { - size_t len ; - direntry *d ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - len = strlen(d->d_name) ; - { - char fn[setlen + len + 2] ; - memcpy(fn, set, setlen) ; - fn[setlen] = '/' ; - memcpy(fn + setlen + 1, d->d_name, len + 1) ; - if (!sub_cleanup(fn)) break ; - } - } - dir_close(dir) ; - return !errno ; -} - -int s6rc_repo_sources_cleanup (char const *repo) -{ - DIR *dir ; - size_t repolen = strlen(repo) ; - unsigned int nsets = 0 ; - char sets[repolen + 9] ; - memcpy(sets, repo, repolen) ; - memcpy(sets + repolen, "/sources", 9) ; - dir = opendir(sets) ; - if (!dir) return 0 ; - for (;;) - { - size_t len ; - direntry *d ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - len = strlen(d->d_name) ; - { - char fn[repolen + len + 10] ; - memcpy(fn, sets, repolen + 8) ; - fn[repolen + 8] = '/' ; - memcpy(fn + repolen + 9, d->d_name, len + 1) ; - if (!set_cleanup(fn)) break ; - nsets++ ; - } - } - dir_close(dir) ; - return errno ? -1 : nsets ; -} diff --git a/src/libs6rc/s6rc_repo_compile.c b/src/libs6rc/s6rc_repo_compile.c deleted file mode 100644 index ac4207d..0000000 --- a/src/libs6rc/s6rc_repo_compile.c +++ /dev/null @@ -1,106 +0,0 @@ -/* ISC license. */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -int s6rc_repo_compile (char const *repo, char const *set, char const *const *subs, uint8_t nsubs, char *oldc, unsigned int verbosity, char const *fdhuser) -{ - size_t repolen = strlen(repo) ; - size_t setlen = strlen(set) ; - size_t totsublen = 0 ; - int needprefix = strcmp(set, ".ref") ; - char newc[repolen + setlen + 45] ; - memcpy(newc, repo, repolen) ; - memcpy(newc + repolen, "/compiled/.", 11) ; - memcpy(newc + repolen + 11, set, setlen) ; - newc[repolen + 11 + setlen] = ':' ; - timestamp_g(newc + repolen + 12 + setlen) ; - memcpy(newc + repolen + 37 + setlen, ":XXXXXX", 8) ; - memcpy(oldc, newc, repolen + 10) ; - if (mkntemp(newc) == -1) { strerr_warnfu2sys("mkntemp ", newc) ; return -1 ; } - for (uint8_t i = 0 ; i < nsubs ; i++) totsublen += strlen(subs[i]) + 1 ; - - { - pid_t pid ; - size_t m = 0 ; - int wstat ; - char const *argv[9 + nsubs] ; - char fmtv[UINT_FMT] ; - char src[nsubs * (repolen + 10 + (needprefix ? setlen + 1 : 0)) + totsublen] ; - char *w = src ; - fmtv[uint_fmt(fmtv, verbosity)] = 0 ; - argv[m++] = S6RC_BINPREFIX "s6-rc-compile" ; - argv[m++] = "-v"; - argv[m++] = fmtv ; - argv[m++] = "-b" ; - if (fdhuser) - { - argv[m++] = "-h" ; - argv[m++] = fdhuser ; - } - argv[m++] = "--" ; - argv[m++] = newc ; - for (uint8_t i = 0 ; i < nsubs ; i++) - { - size_t sublen = strlen(subs[i]) ; - argv[m++] = w ; - memcpy(w, repo, repolen) ; w += repolen ; - memcpy(w, "/sources/", 9) ; w += 9 ; - if (needprefix) - { - memcpy(w, set, setlen) ; w += setlen ; - *w++ = '/' ; - } - memcpy(w, subs[i], sublen+1) ; w += sublen + 1 ; - } - argv[m++] = 0 ; - pid = cspawn(argv[0], argv, (char const *const *)environ, 0, 0, 0) ; - if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return -1 ; } - if (wait_pid(pid, &wstat) == -1) - { - strerr_warnfu2sys("wait for ", argv[0]) ; - return -1 ; - } - if (WIFSIGNALED(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; - strerr_warnf3x(argv[0], " crashed with signal ", fmt) ; - return -1 ; - } - if (WEXITSTATUS(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WEXITSTATUS(wstat))] = 0 ; - strerr_warnf3x(argv[0], " exited with code ", fmt) ; - return (WEXITSTATUS(wstat) == 1) - 1 ; - } - } - { - char fn[repolen + setlen + 11] ; - memcpy(fn, newc, repolen + 10) ; - memcpy(fn + repolen + 10, set, setlen + 1) ; - if (!atomic_symlink4(newc + repolen + 10, fn, oldc + repolen + 10, setlen + 35)) - { - int e = errno ; - rm_rf(newc) ; - errno = e ; - strerr_warnfu4sys("atomically make a ", fn, " symlink pointing to ", newc + repolen + 10) ; - return -1 ; - } - } - return 1 + !!oldc[repolen + 10] ; -} diff --git a/src/libs6rc/s6rc_repo_fillset.c b/src/libs6rc/s6rc_repo_fillset.c deleted file mode 100644 index 15832c3..0000000 --- a/src/libs6rc/s6rc_repo_fillset.c +++ /dev/null @@ -1,73 +0,0 @@ -/* ISC license. */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -int s6rc_repo_fillset (char const *repo, char const *set, char const *const *existing, uint32_t n) -{ - size_t repolen = strlen(repo) ; - size_t setlen = strlen(set) ; - DIR *dir ; - char atomics[repolen + 18] ; - char setfn[repolen + 10 + setlen] ; - memcpy(atomics, repo, repolen) ; - memcpy(atomics + repolen, "/sources/.atomics", 18) ; - memcpy(setfn, repo, repolen) ; - memcpy(setfn + repolen, "/sources/", 9) ; - memcpy(setfn + repolen + 9, set, setlen+1) ; - - dir = opendir(atomics) ; - if (!dir) - { - strerr_warnfu2sys("opendir ", atomics) ; - return 0 ; - } - for (;;) - { - size_t len ; - uint32_t flags ; - direntry *d ; - uint8_t subi ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - - len = strlen(d->d_name) ; - char src[len + 13] ; - char dst[repolen + 18 + setlen + len] ; - memcpy(src, "../.atomics/", 12) ; - memcpy(src + 12, d->d_name, len+1) ; - if (n && bsearch(d->d_name, existing, n, sizeof(char const *), &str_bcmp)) continue ; - if (s6rc_repo_getserviceflags(repo, d->d_name, &flags) <= 0) return 0 ; - if (flags & 1) subi = 3 ; - else if (flags & 2) subi = 2 ; - else subi = 1 ; - memcpy(dst, setfn, repolen + 10 + setlen) ; - memcpy(dst + repolen + 10 + setlen, s6rc_repo_subnames[subi], 6) ; - dst[repolen + setlen + 16] = '/' ; - memcpy(dst + repolen + setlen + 17, d->d_name, len+1) ; - if (symlink(src, dst) == -1) - { - strerr_warnfu4sys("make a symlink named ", dst, " pointing to ", src) ; - return 0 ; - } - } - dir_close(dir) ; - if (errno) - { - strerr_warnfu2sys("readdir ", atomics) ; - return 0 ; - } - - return 1 ; -} diff --git a/src/libs6rc/s6rc_repo_fix.c b/src/libs6rc/s6rc_repo_fix.c deleted file mode 100644 index b379d30..0000000 --- a/src/libs6rc/s6rc_repo_fix.c +++ /dev/null @@ -1,51 +0,0 @@ -/* ISC license. */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -int s6rc_repo_fix (char const *repo, uint32_t options, unsigned int verbosity) -{ - stralloc sa = STRALLOC_ZERO ; - genalloc svlist = GENALLOC_ZERO ; /* s6rc_repo_sv */ - genalloc badga = GENALLOC_ZERO ; /* uint32_t */ - genalloc setind = GENALLOC_ZERO ; /* size_t */ - int n ; - - if (verbosity >= 3) - strerr_warni2x("checking set consistency in repository ", repo) ; - - n = s6rc_repo_list_sets(repo, &sa, &setind) ; - if (n < 0) - { - strerr_warnfu1sys("list sets") ; - return 0 ; - } - for (uint32_t i = 0 ; i < nsets ; i++) - { - if (verbosity >= 3) - strerr_warni2x("checking set ", sa.s + genalloc_s(size_t, &setind)[i]) ; - if (!s6rc_repo_fixset(repo, sa.s + genalloc_s(size_t, &setind)[i], options, verbosity, &sa, &svlist, &badga)) goto err ; - } - - genalloc_free(s6rc_repo_sv, &svlist) ; - genalloc_free(uint32_t, &badga) ; - genalloc_free(size_t, &setind) ; - stralloc_free(&sa) ; - return 1 ; - - err: - genalloc_free(s6rc_repo_sv, &svlist) ; - genalloc_free(uint32_t, &badga) ; - genalloc_free(size_t, &setind) ; - stralloc_free(&sa) ; - return 0 ; -} diff --git a/src/libs6rc/s6rc_repo_fixset.c b/src/libs6rc/s6rc_repo_fixset.c deleted file mode 100644 index 8ad64bc..0000000 --- a/src/libs6rc/s6rc_repo_fixset.c +++ /dev/null @@ -1,96 +0,0 @@ -/* ISC license. */ - -#include -#include -#include - -#include -#include -#include -#include - -#include - -static inline int s6rc_repo_fixsub (char const *repo, char const *set, uint8_t sub, s6rc_repo_sv *byname, char const **bysub, uint32_t ntot, uint32_t options, uint32_t const *subind, uint32_t const *subn, unsigned int verbosity, stralloc *sa, genalloc *badga) -{ - size_t sabase = sa->len ; - uint32_t gabase = genalloc_len(uint32_t, badga) ; - uint32_t const *bads ; - uint32_t badn ; - if (!s6rc_repo_badsub(repo, set, bysub + subind[sub], subn[sub], sub, options & 1 ? 2 : 1, byname, ntot, sa, badga)) return 0 ; - bads = genalloc_s(uint32_t, badga) ; - badn = genalloc_len(uint32_t, badga) ; - if (!badn) return 1 ; - - s6rc_repo_sv tomove[badn] ; - for (uint32_t j = 0 ; j < badn ; j++) - { - tomove[j] = byname[bads[j]] ; - if (verbosity >= 2) - strerr_warni("in set ", set, " of repository ", repo, ": ", options & 1 ? "up" : "down", "fixing service ", sa->s + tomove[j].pos, " from ", s6rc_repo_subnames[tomove[j].sub], " to ", s6rc_repo_subnames[sub]) ; - if (tomove[j].sub == 0 && verbosity) - strerr_warnw("service ", sa->s + tomove[j].pos, " is being automatically unmasked by an upfix to ", s6rc_repo_subnames[sub]) ; - if (tomove[j].sub == 3) - { - if (!(options & 2)) - { - strerr_warnf("in set ", set, " of repository ", repo, ": service ", sa->s + tomove[j].pos, " is marked as essential and cannot be downfixed. If you are sure of yourself, try --force-essential") ; - goto err ; - } - if (verbosity) - strerr_warnw("service ", sa->s + tomove[j].pos, " is being automatically marked non-essential by a downfix to ", s6rc_repo_subnames[sub]) ; - } - } - if (!s6rc_repo_moveservices(repo, set, tomove, badn, sub, sa->s, verbosity)) goto err ; - for (uint32_t j = 0 ; j < badn ; j++) byname[bads[j]].sub = sub ; - genalloc_setlen(uint32_t, badga, gabase) ; - sa->len = sabase ; - return 1 ; - - err: - genalloc_setlen(uint32_t, badga, gabase) ; - sa->len = sabase ; - return 0 ; -} - -int s6rc_repo_fixset (char const *repo, char const *set, uint32_t options, unsigned int verbosity, stralloc *sa, genalloc *svlist, genalloc *badga) -{ - int sawasnull = !sa->s ; - int svwasnull = !genalloc_s(s6rc_repo_sv, svlist) ; - int gawasnull = !genalloc_s(uint32_t, badga) ; - size_t sabase = sa->len ; - uint32_t svbase = genalloc_len(s6rc_repo_sv, svlist) ; - uint32_t gabase = genalloc_len(uint32_t, badga) ; - uint32_t ntot ; - uint32_t subind[4] ; - uint32_t sublen[4] ; - s6rc_repo_sv *byname ; - if (!s6rc_repo_makesvlist(repo, set, sa, svlist, subind)) return 0 ; - byname = genalloc_s(s6rc_repo_sv, svlist) ; - ntot = genalloc_len(s6rc_repo_sv, svlist) ; - if (!ntot) return 1 ; - for (uint8_t i = 0 ; i < 4 ; i++) sublen[i] = (i == 3 ? ntot : subind[i+1]) - subind[i] ; - - char const *bysub[ntot] ; - char bysub_storage[sa->len - sabase] ; - memcpy(bysub_storage, sa->s + sabase, sa->len - sabase) ; - for (uint32_t i = 0 ; i < ntot ; i++) bysub[i] = bysub_storage + byname[i].pos - sabase ; - qsortr(byname, ntot, sizeof(s6rc_repo_sv), &s6rc_repo_sv_cmpr, sa->s) ; - - for (uint8_t i = 0 ; i < 4 ; i++) if (sublen[i]) - { - if (!s6rc_repo_fixsub(repo, set, i, byname, bysub, ntot, options, subind, sublen, verbosity, sa, badga)) - goto err ; - } - - genalloc_setlen(uint32_t, badga, gabase) ; - genalloc_setlen(s6rc_repo_sv, svlist, svbase) ; - sa->len = sabase ; - return 1 ; - - err: - if (gawasnull) genalloc_free(uint32_t, badga) ; else genalloc_setlen(uint32_t, badga, gabase) ; - if (svwasnull) genalloc_free(s6rc_repo_sv, svlist) ; else genalloc_setlen(s6rc_repo_sv, svlist, svbase) ; - if (sawasnull) stralloc_free(sa) ; else sa->len = sabase ; - return 0 ; -} diff --git a/src/libs6rc/s6rc_repo_flattenservices.c b/src/libs6rc/s6rc_repo_flattenservices.c deleted file mode 100644 index 15363ac..0000000 --- a/src/libs6rc/s6rc_repo_flattenservices.c +++ /dev/null @@ -1,73 +0,0 @@ -/* ISC license. */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -int s6rc_repo_flattenservices (char const *repo, char const *const *services, uint32_t n, stralloc *storage, genalloc *indices) -{ - int swasnull = !storage->s ; - int gwasnull = !indices->s ; - size_t sabase = storage->len ; - size_t gabase = genalloc_len(size_t, indices) ; - - { - size_t m = 0 ; - size_t repolen = strlen(repo) ; - pid_t pid ; - int fd ; - int wstat ; - char const *argv[7 + n] ; - char refdb[repolen + 15] ; - memcpy(refdb, repo, repolen) ; - memcpy(refdb + repolen, "/compiled/.ref", 15) ; - argv[m++] = S6RC_BINPREFIX "s6-rc-db" ; - argv[m++] = "-c"; - argv[m++] = refdb ; - argv[m++] = "-b" ; - argv[m++] = "--" ; - argv[m++] = "atomics" ; - for (size_t i = 0 ; i < n ; i++) argv[m++] = services[i] ; - argv[m++] = 0 ; - pid = child_spawn1_pipe(argv[0], argv, (char const *const *)environ, &fd, 1) ; - if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return 111 ; } - if (!slurpn(fd, storage, 0)) { strerr_warnfu2sys("read output from ", argv[0]) ; return 111 ; } - fd_close(fd) ; - if (wait_pid(pid, &wstat) == -1) - { - strerr_warnfu2sys("wait for ", argv[0]) ; - goto err ; - } - if (WIFSIGNALED(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; - strerr_warnf3x(argv[0], " crashed with signal ", fmt) ; - goto err ; - } - if (WEXITSTATUS(wstat)) return WEXITSTATUS(wstat) ; - } - - if (!s6rc_nlto0(storage->s + sabase, sabase, storage->len, indices)) goto err ; - return 0 ; - - err: - if (gwasnull) genalloc_free(size_t, indices) ; - else genalloc_setlen(size_t, indices, gabase) ; - if (swasnull) stralloc_free(storage) ; - else storage->len = sabase ; - return 111 ; -} diff --git a/src/libs6rc/s6rc_repo_getserviceflags.c b/src/libs6rc/s6rc_repo_getserviceflags.c deleted file mode 100644 index 0ad68e7..0000000 --- a/src/libs6rc/s6rc_repo_getserviceflags.c +++ /dev/null @@ -1,70 +0,0 @@ -/* ISC license. */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -int s6rc_repo_getserviceflags (char const *repo, char const *name, uint32_t *flags) -{ - size_t repolen = strlen(repo) ; - ssize_t r ; - pid_t pid ; - int fd ; - int wstat ; - char flagstr[10] ; - char refdb[repolen + 15] ; - char const *argv[8] = { S6RC_BINPREFIX "s6-rc-db", "-c", refdb, "-b", "--", "flags", name, 0 } ; - - memcpy(refdb, repo, repolen) ; - memcpy(refdb + repolen, "/compiled/.ref", 15) ; - pid = child_spawn1_pipe(argv[0], argv, (char const *const *)environ, &fd, 1) ; - if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return -1 ; } - r = readnclose(fd, flagstr, 10) ; - if (r != 9) - { - if (r == 10) goto err ; - else if (r >= 0) errno = EPIPE ; - strerr_warnfu2sys("read output from ", argv[0]) ; - return -1 ; - } - if (wait_pid(pid, &wstat) == -1) - { - strerr_warnfu2sys("wait for ", argv[0]) ; - return -1 ; - } - if (WIFSIGNALED(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; - strerr_warnf3x(argv[0], " crashed with signal ", fmt) ; - return -1 ; - } - if (WEXITSTATUS(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WEXITSTATUS(wstat))] = 0 ; - strerr_warnf3x(argv[0], " exited with code ", fmt) ; - return (WEXITSTATUS(wstat) < 99) - 1 ; - } - flagstr[8] = 0 ; - if (!uint320_xscan(flagstr, flags)) goto err ; - return 1 ; - - err: - strerr_warnf2x("invalid output from ", S6RC_BINPREFIX "s6-rc-db") ; - errno = EPROTO ; - return -1 ; -} diff --git a/src/libs6rc/s6rc_repo_list_sets.c b/src/libs6rc/s6rc_repo_list_sets.c deleted file mode 100644 index 99f2162..0000000 --- a/src/libs6rc/s6rc_repo_list_sets.c +++ /dev/null @@ -1,15 +0,0 @@ -/* ISC license. */ - -#include - -#include -#include - -int s6rc_repo_list_sets (char const *repo, stralloc *sa, genalloc *ga) -{ - size_t repolen = strlen(repo) ; - char fn[repolen + 9] ; - memcpy(fn, repo, repolen) ; - memcpy(fn + repolen, "/sources", 9) ; - return s6rc_ls(fn, sa, ga) ; -} diff --git a/src/libs6rc/s6rc_repo_listalldeps.c b/src/libs6rc/s6rc_repo_listalldeps.c deleted file mode 100644 index 7e9aca6..0000000 --- a/src/libs6rc/s6rc_repo_listalldeps.c +++ /dev/null @@ -1,8 +0,0 @@ -/* ISC license. */ - -#include - -int s6rc_repo_listalldeps (char const *repo, char const *const *services, uint32_t n, stralloc *storage, genalloc *indices, int up) -{ - return s6rc_repo_listdeps_internal(repo, services, n, storage, indices, 2 | !!up) ; -} diff --git a/src/libs6rc/s6rc_repo_listcontents.c b/src/libs6rc/s6rc_repo_listcontents.c deleted file mode 100644 index 0e493c6..0000000 --- a/src/libs6rc/s6rc_repo_listcontents.c +++ /dev/null @@ -1,68 +0,0 @@ -/* ISC license. */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -int s6rc_repo_listcontents (char const *repo, char const *bundle, stralloc *storage, genalloc *indices) -{ - int swasnull = !storage->s ; - int gwasnull = !indices->s ; - size_t sabase = storage->len ; - size_t gabase = genalloc_len(size_t, indices) ; - size_t repolen = strlen(repo) ; - pid_t pid ; - int fd ; - int wstat ; - char refdb[repolen + 15] ; - char const *argv[8] = { S6RC_BINPREFIX "s6-rc-db", "-c", refdb, "-b", "--", "contents", bundle, 0 } ; - - memcpy(refdb, repo, repolen) ; - memcpy(refdb + repolen, "/compiled/.ref", 15) ; - pid = child_spawn1_pipe(argv[0], argv, (char const *const *)environ, &fd, 1) ; - if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return -1 ; } - if (!slurpn(fd, storage, 0)) { strerr_warnfu2sys("read output from ", argv[0]) ; return -1 ; } - fd_close(fd) ; - if (wait_pid(pid, &wstat) == -1) - { - strerr_warnfu2sys("wait for ", argv[0]) ; - return -1 ; - } - if (WIFSIGNALED(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; - strerr_warnf3x(argv[0], " crashed with signal ", fmt) ; - return -1 ; - } - if (WEXITSTATUS(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WEXITSTATUS(wstat))] = 0 ; - strerr_warnf3x(argv[0], " exited with code ", fmt) ; - return (WEXITSTATUS(wstat) < 99) - 1 ; - } - - if (!s6rc_nlto0(storage->s + sabase, sabase, storage->len, indices)) goto err ; - return 1 ; - - err: - if (gwasnull) genalloc_free(size_t, indices) ; - else genalloc_setlen(size_t, indices, gabase) ; - if (swasnull) stralloc_free(storage) ; - else storage->len = sabase ; - return -1 ; -} diff --git a/src/libs6rc/s6rc_repo_listdeps.c b/src/libs6rc/s6rc_repo_listdeps.c deleted file mode 100644 index 4dfb495..0000000 --- a/src/libs6rc/s6rc_repo_listdeps.c +++ /dev/null @@ -1,8 +0,0 @@ -/* ISC license. */ - -#include - -int s6rc_repo_listdeps (char const *repo, char const *service, stralloc *storage, genalloc *indices, int up) -{ - return s6rc_repo_listdeps_internal(repo, &service, 1, storage, indices, !!up) ; -} diff --git a/src/libs6rc/s6rc_repo_listdeps_internal.c b/src/libs6rc/s6rc_repo_listdeps_internal.c deleted file mode 100644 index 30ecf26..0000000 --- a/src/libs6rc/s6rc_repo_listdeps_internal.c +++ /dev/null @@ -1,74 +0,0 @@ -/* ISC license. */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -int s6rc_repo_listdeps_internal (char const *repo, char const *const *services, uint32_t n, stralloc *storage, genalloc *indices, uint32_t options) -{ - int swasnull = !storage->s ; - int gwasnull = !indices->s ; - size_t sabase = storage->len ; - size_t gabase = genalloc_len(size_t, indices) ; - - { - size_t m = 0 ; - size_t repolen = strlen(repo) ; - pid_t pid ; - int fd ; - int wstat ; - char const *argv[8 + n] ; - char refdb[repolen + 15] ; - memcpy(refdb, repo, repolen) ; - memcpy(refdb + repolen, "/compiled/.ref", 15) ; - argv[m++] = S6RC_BINPREFIX "s6-rc-db" ; - argv[m++] = "-c"; - argv[m++] = refdb ; - argv[m++] = "-b" ; - argv[m++] = options & 1 ? "-u" : "-d" ; - argv[m++] = "--" ; - argv[m++] = options & 2 ? "all-dependencies" : "dependencies" ; - for (uint32_t i = 0 ; i < n ; i++) argv[m++] = services[i] ; - argv[m++] = 0 ; - pid = child_spawn1_pipe(argv[0], argv, (char const *const *)environ, &fd, 1) ; - if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return 111 ; } - if (!slurpn(fd, storage, 0)) { strerr_warnfu2sys("read output from ", argv[0]) ; return 111 ; } - fd_close(fd) ; - if (wait_pid(pid, &wstat) == -1) - { - strerr_warnfu2sys("wait for ", argv[0]) ; - goto err ; - } - if (WIFSIGNALED(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; - strerr_warnf3x(argv[0], " crashed with signal ", fmt) ; - goto err ; - } - if (WEXITSTATUS(wstat)) return wait_estatus(wstat) ; - } - - if (!s6rc_nlto0(storage->s + sabase, sabase, storage->len, indices)) goto err ; - return 0 ; - - err: - if (gwasnull) genalloc_free(size_t, indices) ; - else genalloc_setlen(size_t, indices, gabase) ; - if (swasnull) stralloc_free(storage) ; - else storage->len = sabase ; - return 111 ; -} diff --git a/src/libs6rc/s6rc_repo_listsub.c b/src/libs6rc/s6rc_repo_listsub.c deleted file mode 100644 index eed5cb4..0000000 --- a/src/libs6rc/s6rc_repo_listsub.c +++ /dev/null @@ -1,20 +0,0 @@ -/* ISC license. */ - -#include - -#include -#include - -int s6rc_repo_listsub (char const *repo, char const *set, char const *sub, stralloc *sa, genalloc *ga) -{ - size_t repolen = strlen(repo) ; - size_t setlen = strlen(set) ; - size_t sublen = strlen(sub) ; - char fn[repolen + setlen + 10 + sublen] ; - memcpy(fn, repo, repolen) ; - memcpy(fn + repolen, "/sources/", 9) ; - memcpy(fn + repolen + 9, set, setlen) ; - memcpy(fn + repolen + 9 + setlen, sub, sublen + 1) ; - - return s6rc_ls(fn, sa, ga) ; -} diff --git a/src/libs6rc/s6rc_repo_lock.c b/src/libs6rc/s6rc_repo_lock.c deleted file mode 100644 index 472ff15..0000000 --- a/src/libs6rc/s6rc_repo_lock.c +++ /dev/null @@ -1,20 +0,0 @@ -/* ISC license. */ - -#include - -#include - -#include - -int s6rc_repo_lock (char const *repo, int w) -{ - int fd ; - size_t repolen = strlen(repo) ; - char fn[repolen + 13] ; - memcpy(fn, repo, repolen) ; - memcpy(fn + repolen, "/lock", 6) ; - fd = openc_write(fn) ; - if (fd == -1) return -1 ; - if (fd_lock(fd, w, 0) < 1) return -1 ; - return fd ; -} diff --git a/src/libs6rc/s6rc_repo_makedefbundle.c b/src/libs6rc/s6rc_repo_makedefbundle.c deleted file mode 100644 index 5c67917..0000000 --- a/src/libs6rc/s6rc_repo_makedefbundle.c +++ /dev/null @@ -1,121 +0,0 @@ -/* ISC license. */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -int s6rc_repo_makedefbundle (char const *repo, char const *set, char const *bundle) -{ - size_t repolen = strlen(repo) ; - size_t setlen = strlen(set) ; - size_t bundlelen = strlen(bundle) ; - size_t bfnlen = repolen + setlen + bundlelen + 28 ; - DIR *dir ; - char bfn[bfnlen + 1] ; - char subfn[repolen + setlen + 17] ; - - memcpy(bfn, repo, repolen) ; - memcpy(bfn + repolen, "/sources/.atomics/", 18) ; - memcpy(bfn + repolen + 18, bundle, bundlelen + 1) ; - - if (access(bfn, F_OK) == 0) goto errexists ; - if (errno != ENOENT) - { - strerr_warnfu2sys("check existence of ", bfn) ; - return 0 ; - } - memcpy(bfn + repolen + 10, "bundle", 6) ; - if (access(bfn, F_OK) == 0) goto errexists ; - if (errno != ENOENT) - { - strerr_warnfu2sys("check existence of ", bfn) ; - return 0 ; - } - - memcpy(bfn + repolen + 9, set, setlen) ; - memcpy(bfn + repolen + 9 + setlen, "/bundle/", 8) ; - memcpy(bfn + repolen + 17 + setlen, bundle, bundlelen + 1) ; - if (mkdir(bfn, 02755) == -1) - { - if (errno != EEXIST) strerr_warnfu2sys("mkdir ", bfn) ; - else strerr_warnf6x("bundle ", bundle, " is already defined in set ", set, " of repository ", repo) ; - return 0 ; - } - memcpy(bfn + repolen + setlen + 17 + bundlelen, "/type", 6) ; - if (!openwritenclose_unsafe(bfn, "bundle\n", 7)) - { - strerr_warnfu2sys("write to ", bfn) ; - return 0 ; - } - memcpy(bfn + repolen + setlen + 18 + bundlelen, "contents.d", 11) ; - if (mkdir(bfn, 02755) == -1) - { - strerr_warnfu2sys("mkdir ", bfn) ; - return 0 ; - } - bfn[bfnlen] = '/' ; - - memcpy(subfn, bfn, repolen + 10 + setlen) ; - memcpy(subfn + repolen + 10 + setlen, "onboot", 7) ; - dir = opendir(subfn) ; - if (!dir) - { - strerr_warnfu2sys("opendir ", subfn) ; - return 0 ; - } - - for (;;) - { - size_t len ; - direntry *d ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - len = strlen(d->d_name) ; - char fn[bfnlen + len + 2] ; - memcpy(fn, bfn, bfnlen + 1) ; - memcpy(fn + bfnlen + 1, d->d_name, len + 1) ; - if (!openwritenclose_unsafe(fn, "", 0)) - { - strerr_warnfu2sys("write to ", fn) ; - dir_close(dir) ; - return 0 ; - } - } - dir_close(dir) ; - if (errno) - { - strerr_warnfu2sys("readdir ", subfn) ; - return 0 ; - } - - return 1 ; - - errexists: - if (sareadlink(&satmp, bfn) == -1) - { - strerr_warnfu2sys("readlink ", bfn) ; - return 0 ; - } - if (!stralloc_0(&satmp)) - { - strerr_warnfu1sys("stralloc_catb ") ; - satmp.len = 0 ; - return 0 ; - } - strerr_warnf4x("bundle ", bundle, " is already defined at ", satmp.s) ; - satmp.len = 0 ; - return (errno = EINVAL, 0) ; -} diff --git a/src/libs6rc/s6rc_repo_makesetbundles.c b/src/libs6rc/s6rc_repo_makesetbundles.c deleted file mode 100644 index 81267b9..0000000 --- a/src/libs6rc/s6rc_repo_makesetbundles.c +++ /dev/null @@ -1,137 +0,0 @@ -/* ISC license. */ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -int s6rc_repo_makesetbundles (char const *repo, char const *set, unsigned int verbosity) -{ - size_t repolen = strlen(repo) ; - size_t setlen = strlen(set) ; - stralloc sa = STRALLOC_ZERO ; - genalloc ga = GENALLOC_ZERO ; - int n ; - char src[repolen + 19] ; - char dst[repolen + 17 + setlen] ; - memcpy(dst, repo, repolen) ; - memcpy(dst + repolen, "/sources/", 9) ; - memcpy(dst + repolen + 9, set, setlen) ; - memcpy(dst + repolen + 9 + setlen, "/bundle", 8) ; - memcpy(src, dst, repolen + 10) ; - memcpy(src + repolen + 10, ".bundles", 9) ; - rm_rf_tmp(dst, &sa) ; - - n = s6rc_repo_listsub(repo, set, s6rc_repo_subnames[0], &sa, &ga) ; - if (n < 0) - { - strerr_warnfu6sys("list sub ", s6rc_repo_subnames[0], " of set ", set, " in repository ", repo) ; - goto err ; - } - if (n) - { - DIR *dir ; - char const *masked[n] ; - char maskedstorage[sa.len] ; - memcpy(maskedstorage, sa.s, sa.len) ; - for (size_t i = 0 ; i < n ; i++) masked[i] = maskedstorage + genalloc_s(size_t, &ga)[i] ; - sa.len = 0 ; - genalloc_setlen(size_t, &ga, 0) ; - qsort(masked, n, sizeof(char const *), &str_cmp) ; - - if (mkdir(dst, 02755) == -1) - { - strerr_warnfu2sys("mkdir ", dst) ; - goto errga ; - } - dir = opendir(src) ; - if (!dir) - { - strerr_warnfu2sys("opendir ", src) ; - goto err0 ; - } - for (;;) - { - int m, i = 0 ; - direntry *d ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - - sa.len = 0 ; - genalloc_setlen(size_t, &ga, 0) ; - m = s6rc_repo_listcontents(repo, d->d_name, &sa, &ga) ; - if (m < 0) - { - dir_close(dir) ; - goto err0 ; - } - - for (; i < m ; i++) - { - char const *x = sa.s + genalloc_s(size_t, &ga)[i] ; - if (bsearch(x, masked, n, sizeof(char const *), &str_bcmp)) - { - if (verbosity >= 3) - strerr_warni4x("skipping bundle ", d->d_name, " containing e.g. masked service ", x) ; - break ; - } - } - if (i < m) continue ; - - size_t len = strlen(d->d_name) ; - char target[16 + len] ; - char fn[repolen + setlen + 18 + len] ; - memcpy(target, "../../.bundles/", 15) ; - memcpy(target + 15, d->d_name, len+1) ; - memcpy(fn, dst, repolen + setlen + 16) ; - fn[repolen + setlen + 16] = '/' ; - memcpy(fn + repolen + setlen + 17, d->d_name, len+1) ; - if (symlink(target, fn) == -1) - { - strerr_warnfu4sys("make a symlink named ", fn, " pointing to ", target) ; - dir_close(dir) ; - goto err0 ; - } - } - dir_close(dir) ; - if (errno) - { - strerr_warnfu2sys("readdir ", src) ; - goto err0 ; - } - } - else if (!hiercopy_tmp(src, dst, &sa)) - { - strerr_warnfu4sys("recursively copy ", src, " to ", dst) ; - goto err0 ; - } - - stralloc_free(&sa) ; - return 1 ; - - err0: - { - int e = errno ; - rm_rf_tmp(dst, &sa) ; - errno = e ; - } - errga: - genalloc_free(size_t, &ga) ; - err: - stralloc_free(&sa) ; - return 0 ; -} diff --git a/src/libs6rc/s6rc_repo_makestores.c b/src/libs6rc/s6rc_repo_makestores.c deleted file mode 100644 index f61f94c..0000000 --- a/src/libs6rc/s6rc_repo_makestores.c +++ /dev/null @@ -1,65 +0,0 @@ -/* ISC license. */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -int s6rc_repo_makestores (char const *repo, char const *const *stores, uint16_t n, char *sold) -{ - size_t repolen = strlen(repo) ; - mode_t m = umask(0) ; - char slink[repolen + 8] ; - char sdir[repolen + 21] ; - - memcpy(slink, repo, repolen) ; - memcpy(slink + repolen, "/stores", 8) ; - memcpy(sdir, slink, repolen + 1) ; - memcpy(sdir + repolen + 1, ".stores:XXXXXX", 15) ; - - if (!mkdtemp(sdir)) - { - umask(m) ; - strerr_warnfu2sys("mkdtemp ", sdir) ; - return 0 ; - } - umask(m) ; - sdir[repolen + 15] = '/' ; - sdir[repolen + 20] = 0 ; - for (uint16_t i = 0 ; i < n ; i++) - { - uint160_xfmt(sdir + repolen + 16, i, 4) ; - if (symlink(stores[i], sdir) == -1) - { - strerr_warnfu4sys("symlink ", stores[i], " to ", sdir) ; - sdir[repolen + 15] = 0 ; - goto err ; - } - } - sdir[repolen + 15] = 0 ; - if (chmod(sdir, 02755) == -1) - { - strerr_warnfu2sys("chmod ", sdir) ; - goto err ; - } - if (!atomic_symlink4(sdir + repolen + 1, slink, sold, 15)) - { - strerr_warnfu4sys("atomically symlink ", sdir + repolen + 1, " to ", slink) ; - goto err ; - } - return 1 ; - - err: - rm_rf(sdir) ; - return 0 ; -} diff --git a/src/libs6rc/s6rc_repo_makesvlist.c b/src/libs6rc/s6rc_repo_makesvlist.c deleted file mode 100644 index 99a174e..0000000 --- a/src/libs6rc/s6rc_repo_makesvlist.c +++ /dev/null @@ -1,66 +0,0 @@ -/* ISC license. */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -static inline int s6rc_repo_addsub (char const *sub, uint8_t i, stralloc *sa, genalloc *ga) -{ - DIR *dir = opendir(sub) ; - if (!dir) { strerr_warnfu2sys("opendir ", sub) ; return 0 ; } - for (;;) - { - s6rc_repo_sv sv = { .pos = sa->len, .sub = i } ; - direntry *d ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - - if (!stralloc_cats(sa, d->d_name) || !stralloc_0(sa) - || !genalloc_append(s6rc_repo_sv, ga, &sv)) goto nomem ; - } - dir_close(dir) ; - if (errno) { strerr_warnfu2sys("readdir ", sub) ; return 0 ; } - return 1 ; - - nomem: - strerr_warnfu1sys("stralloc_catb") ; - return 0 ; -} - -int s6rc_repo_makesvlist (char const *repo, char const *set, stralloc *sa, genalloc *ga, uint32_t *tab) -{ - size_t repolen = strlen(repo) ; - size_t setlen = strlen(set) ; - size_t sabase = sa->len ; - size_t gabase = genalloc_len(s6rc_repo_sv, ga) ; - int sawasnull = !sa->s ; - int gawasnull = !genalloc_s(s6rc_repo_sv, ga) ; - char subfn[repolen + setlen + 17] ; - - memcpy(subfn, repo, repolen) ; - memcpy(subfn + repolen, "/sources/", 9) ; - memcpy(subfn + repolen + 9, set, setlen) ; - subfn[repolen + 9 + setlen] = '/' ; - for (uint8_t i = 0 ; i < 4 ; i++) - { - if (tab) tab[i] = genalloc_len(s6rc_repo_sv, ga) ; - memcpy(subfn + repolen + setlen + 10, s6rc_repo_subnames[i], 7) ; - if (!s6rc_repo_addsub(subfn, i, sa, ga)) goto err ; - } - return 1 ; - - err: - if (sawasnull) stralloc_free(sa) ; else sa->len = sabase ; - if (gawasnull) genalloc_free(s6rc_repo_sv, ga) ; else genalloc_setlen(s6rc_repo_sv, ga, gabase) ; - return 0 ; -} diff --git a/src/libs6rc/s6rc_repo_makesvlist_byname.c b/src/libs6rc/s6rc_repo_makesvlist_byname.c deleted file mode 100644 index c017be6..0000000 --- a/src/libs6rc/s6rc_repo_makesvlist_byname.c +++ /dev/null @@ -1,14 +0,0 @@ -/* ISC license. */ - -#include -#include -#include - -#include - -int s6rc_repo_makesvlist_byname (char const *repo, char const *set, stralloc *sa, genalloc *ga) -{ - if (!s6rc_repo_makesvlist(repo, set, sa, ga, 0)) return 0 ; - qsortr(genalloc_s(s6rc_repo_sv, ga), genalloc_len(s6rc_repo_sv, ga), sizeof(s6rc_repo_sv), &s6rc_repo_sv_cmpr, sa->s) ; - return 1 ; -} diff --git a/src/libs6rc/s6rc_repo_moveservices.c b/src/libs6rc/s6rc_repo_moveservices.c deleted file mode 100644 index 3cc3b92..0000000 --- a/src/libs6rc/s6rc_repo_moveservices.c +++ /dev/null @@ -1,60 +0,0 @@ -/* ISC license. */ - -#include -#include -#include -#include - -#include - -#include - -int s6rc_repo_moveservices (char const *repo, char const *set, s6rc_repo_sv const *services, uint32_t n, uint8_t newsub, char const *storage, unsigned int verbosity) -{ - size_t repolen = strlen(repo) ; - size_t setlen = strlen(set) ; - size_t maxserviceslen = 0 ; - for (uint32_t i = 0 ; i < n ; i++) - { - size_t len = strlen(storage + services[i].pos) ; - if (len > maxserviceslen) maxserviceslen = len ; - } - char oldfn[repolen + setlen + maxserviceslen + 18] ; - char newfn[repolen + setlen + maxserviceslen + 18] ; - memcpy(oldfn, repo, repolen) ; - memcpy(oldfn + repolen, "/sources/", 9) ; - memcpy(oldfn + repolen + 9, set, setlen) ; - oldfn[repolen + 9 + setlen] = '/' ; - oldfn[repolen + 16 + setlen] = '/' ; - memcpy(newfn, oldfn, repolen + 10 + setlen) ; - memcpy(newfn + repolen + 10 + setlen, s6rc_repo_subnames[newsub], 6) ; - newfn[repolen + 16 + setlen] = '/' ; - - for (uint32_t i = 0 ; i < n ; i++) - { - size_t len = strlen(storage + services[i].pos) ; - memcpy(oldfn + repolen + 10, s6rc_repo_subnames[services[i].sub], 6) ; - memcpy(oldfn + repolen + setlen + 17, storage + services[i].pos, len + 1) ; - memcpy(newfn + repolen + setlen + 17, storage + services[i].pos, len + 1) ; - if (access(newfn, F_OK) == 0) - { - if (verbosity >= 2) - strerr_warni8x("service ", storage + services[i].pos, " already existed in subset ", s6rc_repo_subnames[newsub], " of set ", set, " in repository ", repo) ; - } - else if (errno != ENOENT) - { - strerr_warnfu2sys("access ", newfn) ; - return 0 ; - } - if (rename(oldfn, newfn) == -1) - { - strerr_warnfu4sys("rename ", oldfn, " to ", newfn) ; - return 0 ; - } - if (verbosity >= 4) - { - strerr_warnt10x("repository ", repo, ", set ", set, ", from subset ", s6rc_repo_subnames[services[i].sub], " to subset ", s6rc_repo_subnames[newsub], ": successfully moved service ", storage + services[i].pos) ; - } - } - return 1 ; -} diff --git a/src/libs6rc/s6rc_repo_setcompile.c b/src/libs6rc/s6rc_repo_setcompile.c deleted file mode 100644 index 5da136a..0000000 --- a/src/libs6rc/s6rc_repo_setcompile.c +++ /dev/null @@ -1,33 +0,0 @@ -/* ISC license. */ - -#include -#include - -#include - -#include - -int s6rc_repo_setcompile (char const *repo, char const *set, char const *defbundle, char *oldc, unsigned int verbosity, char const *fdhuser) -{ - static char const *const subs[4] = { "bundle", s6rc_repo_subnames[1], s6rc_repo_subnames[2], s6rc_repo_subnames[3] } ; - int r ; - if (!s6rc_repo_makesetbundles(repo, set, verbosity)) return -1 ; - if (!s6rc_repo_makedefbundle(repo, set, defbundle)) return -1 ; - r = s6rc_repo_compile(repo, set, subs, 4, oldc, verbosity, fdhuser) ; - - { - int e = errno ; - size_t repolen = strlen(repo) ; - size_t setlen = strlen(set) ; - size_t sublen = strlen(subs[0]) ; - char fn[repolen + setlen + 11 + sublen] ; - memcpy(fn, repo, repolen) ; - memcpy(fn + repolen, "/sources/", 9) ; - memcpy(fn + repolen + 9, set, setlen) ; - fn[repolen + 9 + setlen] = '/' ; - memcpy(fn + repolen + setlen + 10, subs[0], sublen + 1) ; - rm_rf(fn) ; - errno = e ; - } - return r ; -} diff --git a/src/libs6rc/s6rc_repo_setuptodate.c b/src/libs6rc/s6rc_repo_setuptodate.c deleted file mode 100644 index 9e9fe58..0000000 --- a/src/libs6rc/s6rc_repo_setuptodate.c +++ /dev/null @@ -1,45 +0,0 @@ -/* ISC license. */ - -#include - -#include -#include - -#include -#include - -#include -#include - -int s6rc_repo_setuptodate (char const *repo, char const *set) -{ - struct stat stsource ; - struct stat stcompiled ; - size_t repolen = strlen(repo) ; - size_t setlen = strlen(set) ; - char srcfn[repolen + 17 + setlen] ; - char dstfn[repolen + 11 + setlen] ; - memcpy(srcfn, repo, repolen) ; - memcpy(srcfn + repolen, "/sources/", 9) ; - memcpy(srcfn + repolen + 9, set, setlen) ; - memcpy(srcfn + repolen + 9 + setlen, "/.stamp", 8) ; - memcpy(dstfn, repo, repolen) ; - memcpy(dstfn + repolen, "/compiled/", 10) ; - memcpy(dstfn + repolen + 10, set, setlen + 1) ; - if (stat(srcfn, &stsource) == -1) - { - strerr_warnfu2sys("stat ", srcfn) ; - return -1 ; - } - if (stat(dstfn, &stcompiled) == -1) - { - if (errno == ENOENT) return 0 ; - strerr_warnfu2sys("stat ", dstfn) ; - return -1 ; - } - return - stsource.st_atim.tv_sec < stcompiled.st_atim.tv_sec ? 1 : - stsource.st_atim.tv_sec > stcompiled.st_atim.tv_sec ? 0 : - stsource.st_atim.tv_nsec < stcompiled.st_atim.tv_nsec ; -} - diff --git a/src/libs6rc/s6rc_repo_subnames.c b/src/libs6rc/s6rc_repo_subnames.c deleted file mode 100644 index 2653f01..0000000 --- a/src/libs6rc/s6rc_repo_subnames.c +++ /dev/null @@ -1,5 +0,0 @@ -/* ISC license. */ - -#include - -char const s6rc_repo_subnames[4][7] = { "masked", "usable", "active", "always" } ; diff --git a/src/libs6rc/s6rc_repo_sv_bcmpr.c b/src/libs6rc/s6rc_repo_sv_bcmpr.c deleted file mode 100644 index bcc4d80..0000000 --- a/src/libs6rc/s6rc_repo_sv_bcmpr.c +++ /dev/null @@ -1,13 +0,0 @@ -/* ISC license. */ - -#include - -#include - -int s6rc_repo_sv_bcmpr (void const *a, void const *b, void *aux) -{ - char const *key = a ; - s6rc_repo_sv const *elem = b ; - char const *s = aux ; - return strcmp(key, s + elem->pos) ; -} diff --git a/src/libs6rc/s6rc_repo_sv_cmpr.c b/src/libs6rc/s6rc_repo_sv_cmpr.c deleted file mode 100644 index 80b07c9..0000000 --- a/src/libs6rc/s6rc_repo_sv_cmpr.c +++ /dev/null @@ -1,11 +0,0 @@ -/* ISC license. */ - -#include - -int s6rc_repo_sv_cmpr (void const *a, void const *b, void *aux) -{ - s6rc_repo_sv const *aa = a ; - s6rc_repo_sv const *bb = b ; - char const *s = aux ; - return strcmp(s + aa->pos, s + bb->pos) ; -} diff --git a/src/libs6rc/s6rc_repo_sync.c b/src/libs6rc/s6rc_repo_sync.c deleted file mode 100644 index 9458dcb..0000000 --- a/src/libs6rc/s6rc_repo_sync.c +++ /dev/null @@ -1,231 +0,0 @@ -/* ISC license. */ - -#include /* mkdtemp */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static inline void cleanup (char const *ato, char const *bun) -{ - int e = errno ; - rm_rf(ato) ; - rm_rf(bun) ; - errno = e ; -} - -int s6rc_repo_sync (char const *repo, unsigned int verbosity, char const *fdhuser) -{ - size_t repolen = strlen(repo) ; - mode_t m ; - char store[repolen + 13] ; - char ato[repolen + 26] ; - char bun[repolen + 26] ; - - memcpy(store, repo, repolen) ; - memcpy(store + repolen, "/stores/", 8) ; - store[repolen + 12] = 0 ; - - - /* Fill new .atomics/ and .bundles/ with symlinks to real stores */ - - memcpy(ato, repo, repolen) ; - memcpy(ato + repolen, "/sources/..atomics:XXXXXX", 26) ; - memcpy(bun, ato, repolen + 26) ; - memcpy(bun + repolen + 11, "bundle", 6) ; - m = umask(0) ; - if (!mkdtemp(ato)) - { - strerr_warnfu2sys("mkdtemp ", ato) ; - umask(m) ; - return -1 ; - } - if (chmod(ato, 02755) == -1) - { - strerr_warnfu2sys("chmod ", ato) ; - umask(m) ; - return -1 ; - } - - if (!mkdtemp(bun)) - { - strerr_warnfu2sys("mkdtemp ", bun) ; - rmdir(ato) ; - umask(m) ; - return -1 ; - } - umask(m) ; - if (chmod(bun, 02755) == -1) - { - strerr_warnfu2sys("chmod ", bun) ; - return -1 ; - } - - for (uint16_t istore = 0 ;; istore++) - { - DIR *dir ; - uint160_xfmt(store + repolen + 8, istore, 4) ; - dir = opendir(store) ; - if (!dir) - { - if (errno == ENOENT) break ; - strerr_warnfu2sys("opendir ", store) ; - goto err ; - } - for (;;) - { - size_t len ; - direntry *d ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - len = strlen(d->d_name) ; - { - char const *x ; - char dst[repolen + 28 + len] ; - char src[22 + len] ; - memcpy(src, "../../../stores/", 16) ; - memcpy(src + 16, store + repolen + 8, 4) ; - src[20] = '/' ; - memcpy(src + 21, d->d_name, len+1) ; - switch (s6rc_type_check(-1, src)) - { - case 1 : - case 2 : x = ato ; break ; - case 3 : x = bun ; break ; - case 0 : - strerr_warnf2x("invalid service type for ", src) ; - dir_close(dir) ; - goto err ; - default : - strerr_warnfu2sys("check service type of ", src) ; - dir_close(dir) ; - goto err ; - } - memcpy(dst, x, repolen + 26) ; - dst[repolen + 26] = '/' ; - memcpy(dst + repolen + 27, d->d_name, len+1) ; - if (symlink(src, dst) == -1) - { - if (errno != EEXIST) - { - strerr_warnfu4sys("symlink ", src, " to ", dst) ; - dir_close(dir) ; - goto err ; - } - if (verbosity) - { - if (!sareadlink(&satmp, dst) || !stralloc_0(&satmp)) - { - strerr_warnwu2sys("readlink ", dst) ; - errno = EEXIST ; - strerr_warnwu4sys("symlink ", src, " to ", dst) ; - } - else - strerr_warnwu6x("symlink ", src, " to ", dst, ": already provided by ", satmp.s) ; - satmp.len = 0 ; - } - } - } - } - dir_close(dir) ; - if (errno) - { - strerr_warnfu2sys("readdir ", store) ; - goto err ; - } - } - - - /* Compile the reference db - also checks consistency of new stores */ - - { - char const *subs[2] = { ato + repolen + 9, bun + repolen + 9 } ; - char oldc[repolen + 49] ; - int r = s6rc_repo_compile(repo, ".ref", subs, 2, oldc, verbosity, fdhuser) ; - if (r < 0) goto err ; - if (!r) { cleanup(ato, bun) ; return 0 ; } - if (r == 2) rm_rf(oldc) ; - } - - - /* Switch, delete links to old stores */ - - { - char fn[repolen + 18] ; - char oldato[17] ; - char oldbun[17] ; - memcpy(fn, repo, repolen) ; - memcpy(fn + repolen, "/sources/.atomics", 18) ; - if (!atomic_symlink4(ato + repolen + 9, fn, oldato, 17)) goto err ; - memcpy(fn + repolen + 10, "bundle", 6) ; - if (!atomic_symlink4(bun + repolen + 9, fn, oldbun, 17)) - { - strerr_warnfu4sys("symlink ", bun + repolen + 9, " to ", fn) ; - memcpy(fn + repolen + 10, "atomic", 6) ; - if (!atomic_symlink4(oldato, fn, 0, 0)) - { - strerr_warnfu6sys("symlink ", oldato, " back to ", fn, " - weird race, manually check ", repo) ; - goto err ; - } - goto err ; - } - memcpy(ato + repolen + 9, oldato, 16) ; - memcpy(bun + repolen + 9, oldbun, 16) ; - cleanup(ato, bun) ; - } - - - /* Update the existing sets */ - - ato[repolen + 8] = 0 ; - { - stralloc sa = STRALLOC_ZERO ; - genalloc ga = GENALLOC_ZERO ; /* size_t */ - DIR *dir = opendir(ato) ; - if (!dir) - { - strerr_warnfu2sys("opendir ", ato) ; - return -1 ; - } - for (;;) - { - direntry *d ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - if (!s6rc_repo_syncset_tmp(repo, d->d_name, &sa, &ga, verbosity)) break ; - } - dir_close(dir) ; - genalloc_free(size_t, &ga) ; - stralloc_free(&sa) ; - if (errno) - { - strerr_warnfu2sys("readdir ", ato) ; - return -1 ; - } - } - - return 1 ; - - err: - cleanup(ato, bun) ; - return -1 ; -} diff --git a/src/libs6rc/s6rc_repo_syncset.c b/src/libs6rc/s6rc_repo_syncset.c deleted file mode 100644 index 929d9c4..0000000 --- a/src/libs6rc/s6rc_repo_syncset.c +++ /dev/null @@ -1,16 +0,0 @@ -/* ISC license. */ - -#include -#include - -#include - -int s6rc_repo_syncset (char const *repo, char const *set, unsigned int verbosity) -{ - stralloc sa = STRALLOC_ZERO ; - genalloc ga = GENALLOC_ZERO ; /* size_t */ - int r = s6rc_repo_syncset_tmp(repo, set, &sa, &ga, verbosity) ; - genalloc_free(&size_t, &ga) ; - stralloc_free(&sa) ; - return r ; -} diff --git a/src/libs6rc/s6rc_repo_syncset_tmp.c b/src/libs6rc/s6rc_repo_syncset_tmp.c deleted file mode 100644 index b555bc2..0000000 --- a/src/libs6rc/s6rc_repo_syncset_tmp.c +++ /dev/null @@ -1,102 +0,0 @@ -/* ISC license. */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -static int unlink_stales_in_sub (char const *repo, size_t repolen, char const *set, char const *sub, uint32_t where, stralloc *sa, genalloc *ga, unsigned int verbosity) -{ - size_t setlen = strlen(set) ; - size_t sublen = strlen(sub) ; - size_t subfnlen = repolen + setlen + sublen + 10 ; - char subfn[subfnlen + 1] ; - memcpy(subfn, repo, repolen) ; - memcpy(subfn + repolen, "/sources/", 9) ; - memcpy(subfn + repolen + 9, set, setlen) ; - subfn[repolen + 9 + setlen] = '/' ; - memcpy(subfn + repolen + 10 + setlen, sub, sublen + 1) ; - DIR *dir = opendir(subfn) ; - if (!dir) - { - strerr_warnfu2sys("opendir ", subfn) ; - return 0 ; - } - for (;;) - { - size_t len ; - direntry *d ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - len = strlen(d->d_name) ; - char fn[subfnlen + len + 2] ; - memcpy(fn, subfn, sublen) ; - fn[sublen] = '/' ; - memcpy(fn + sublen + 1, d->d_name, len+1) ; - if (access(fn, F_OK) == -1) - { - if (errno != ENOENT) - { - strerr_warnfu2sys("access ", fn) ; - goto err ; - } - unlink_void(fn) ; - if (verbosity >= 3) - strerr_warni6x("service ", d->d_name, " does not exist anymore, removed from sub ", sub, " of set ", set) ; - } - else - { - if (!genalloc_append(size_t, ga, &sa->len)) goto err ; - if (!stralloc_catb(sa, d->d_name, len+1)) goto err ; - } - } - if (errno) - { - strerr_warnfu2sys("readdir ", subfn) ; - goto err ; - } - - dir_close(dir) ; - return 1 ; - - err: - dir_close(dir) ; - return 0 ; -} - -int s6rc_repo_syncset_tmp (char const *repo, char const *set, stralloc *sa, genalloc *ga, unsigned int verbosity) -{ - size_t repolen = strlen(repo) ; - size_t sabase = sa->len ; - size_t gabase = genalloc_len(size_t, ga) ; - - for (unsigned int i = 0 ; i < 4 ; i++) - if (unlink_stales_in_sub(repo, repolen, set, s6rc_repo_subnames[i], i, sa, ga, verbosity)) goto err ; - - { - uint32_t n = genalloc_len(size_t, ga) ; - char const *stillhere[n + !n] ; - for (uint32_t i = 0 ; i < n ; i++) stillhere[i] = sa->s + genalloc_s(size_t, ga)[i] ; - if (!s6rc_repo_fillset(repo, set, stillhere, n)) goto err ; - } - - sa->len = sabase ; - genalloc_setlen(size_t, ga, gabase) ; - return 1 ; - - err: - sa->len = sabase ; - genalloc_setlen(size_t, ga, gabase) ; - return 0 ; -} diff --git a/src/libs6rc/s6rc_repo_touch.c b/src/libs6rc/s6rc_repo_touch.c deleted file mode 100644 index 069ed78..0000000 --- a/src/libs6rc/s6rc_repo_touch.c +++ /dev/null @@ -1,45 +0,0 @@ -/* ISC license. */ - -#include -#include - -#include -#include - -#include - -int s6rc_repo_touch (char const *repo) -{ - DIR *dir ; - size_t repolen = strlen(repo) ; - char sources[repolen + 9] ; - memcpy(sources, repo, repolen) ; - memcpy(sources + repolen, "/sources", 9) ; - - dir = opendir(sources) ; - if (!dir) - { - strerr_warnfu2sys("opendir ", sources) ; - return 0 ; - } - for (;;) - { - direntry *d ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - if (!s6rc_repo_touchset(repo, d->d_name)) - { - dir_close(dir) ; - return 0 ; - } - } - dir_close(dir) ; - if (errno) - { - strerr_warnfu2sys("readdir ", sources) ; - return 0 ; - } - return 1 ; -} diff --git a/src/libs6rc/s6rc_repo_touchset.c b/src/libs6rc/s6rc_repo_touchset.c deleted file mode 100644 index 684bfc4..0000000 --- a/src/libs6rc/s6rc_repo_touchset.c +++ /dev/null @@ -1,25 +0,0 @@ -/* ISC license. */ - -#include - -#include -#include - -#include - -int s6rc_repo_touchset (char const *repo, char const *set) -{ - size_t repolen = strlen(repo) ; - size_t setlen = strlen(set) ; - char fn[repolen + 17 + setlen] ; - memcpy(fn, repo, repolen) ; - memcpy(fn + repolen, "/sources/", 9) ; - memcpy(fn + repolen + 9, set, setlen) ; - memcpy(fn + repolen + 9 + setlen, "/.stamp", 8) ; - if (!touch(fn)) - { - strerr_warnfu2sys("touch ", fn) ; - return 0 ; - } - return 1 ; -} diff --git a/src/libs6rc/s6rc_type_check.c b/src/libs6rc/s6rc_type_check.c deleted file mode 100644 index 9ce84b9..0000000 --- a/src/libs6rc/s6rc_type_check.c +++ /dev/null @@ -1,33 +0,0 @@ -/* ISC license. */ - -#include -#include - -#include -#include - -#include - -int s6rc_type_check (int dfd, char const *src) -{ - char type[8] ; - ssize_t r ; - if (dfd >= 0) r = openreadnclose_at(dfd, "type", type, 8) ; - else - { - size_t srclen = strlen(src) ; - char fn[srclen + 6] ; - memcpy(fn, src, srclen) ; - memcpy(fn + srclen, "/type", 6) ; - r = openreadnclose(fn, type, 8) ; - } - if (r == -1) return -1 ; - if (r < 6) return 0 ; - if (type[r-1] == '\n') r-- ; - if (r == 8) return 0 ; - type[r++] = 0 ; - return - !strcmp(type, "longrun") ? 1 : - !strcmp(type, "oneshot") ? 2 : - !strcmp(type, "bundle") ? 3 : 0 ; -} diff --git a/src/repo/deps-exe/s6-rc-repo-init b/src/repo/deps-exe/s6-rc-repo-init index 6dd7af7..9fe69bb 100644 --- a/src/repo/deps-exe/s6-rc-repo-init +++ b/src/repo/deps-exe/s6-rc-repo-init @@ -1,3 +1,3 @@ -${LIBS6RC} +${LIBS6RCREPO} -lskarnet -${SYSCLOCK_LIB} +${SPAWN_LIB} diff --git a/src/repo/deps-exe/s6-rc-repo-sync b/src/repo/deps-exe/s6-rc-repo-sync index 6dd7af7..9fe69bb 100644 --- a/src/repo/deps-exe/s6-rc-repo-sync +++ b/src/repo/deps-exe/s6-rc-repo-sync @@ -1,3 +1,3 @@ -${LIBS6RC} +${LIBS6RCREPO} -lskarnet -${SYSCLOCK_LIB} +${SPAWN_LIB} diff --git a/src/repo/deps-exe/s6-rc-set-change b/src/repo/deps-exe/s6-rc-set-change index 6dd7af7..9fe69bb 100644 --- a/src/repo/deps-exe/s6-rc-set-change +++ b/src/repo/deps-exe/s6-rc-set-change @@ -1,3 +1,3 @@ -${LIBS6RC} +${LIBS6RCREPO} -lskarnet -${SYSCLOCK_LIB} +${SPAWN_LIB} diff --git a/src/repo/deps-exe/s6-rc-set-commit b/src/repo/deps-exe/s6-rc-set-commit index 6dd7af7..9fe69bb 100644 --- a/src/repo/deps-exe/s6-rc-set-commit +++ b/src/repo/deps-exe/s6-rc-set-commit @@ -1,3 +1,3 @@ -${LIBS6RC} +${LIBS6RCREPO} -lskarnet -${SYSCLOCK_LIB} +${SPAWN_LIB} diff --git a/src/repo/deps-exe/s6-rc-set-copy b/src/repo/deps-exe/s6-rc-set-copy index 6dd7af7..9fe69bb 100644 --- a/src/repo/deps-exe/s6-rc-set-copy +++ b/src/repo/deps-exe/s6-rc-set-copy @@ -1,3 +1,3 @@ -${LIBS6RC} +${LIBS6RCREPO} -lskarnet -${SYSCLOCK_LIB} +${SPAWN_LIB} diff --git a/src/repo/deps-exe/s6-rc-set-delete b/src/repo/deps-exe/s6-rc-set-delete index 6dd7af7..9fe69bb 100644 --- a/src/repo/deps-exe/s6-rc-set-delete +++ b/src/repo/deps-exe/s6-rc-set-delete @@ -1,3 +1,3 @@ -${LIBS6RC} +${LIBS6RCREPO} -lskarnet -${SYSCLOCK_LIB} +${SPAWN_LIB} diff --git a/src/repo/deps-exe/s6-rc-set-install b/src/repo/deps-exe/s6-rc-set-install index 6dd7af7..9fe69bb 100644 --- a/src/repo/deps-exe/s6-rc-set-install +++ b/src/repo/deps-exe/s6-rc-set-install @@ -1,3 +1,3 @@ -${LIBS6RC} +${LIBS6RCREPO} -lskarnet -${SYSCLOCK_LIB} +${SPAWN_LIB} diff --git a/src/repo/deps-exe/s6-rc-set-new b/src/repo/deps-exe/s6-rc-set-new index 6dd7af7..9fe69bb 100644 --- a/src/repo/deps-exe/s6-rc-set-new +++ b/src/repo/deps-exe/s6-rc-set-new @@ -1,3 +1,3 @@ -${LIBS6RC} +${LIBS6RCREPO} -lskarnet -${SYSCLOCK_LIB} +${SPAWN_LIB} diff --git a/src/repo/deps-lib/s6rcrepo b/src/repo/deps-lib/s6rcrepo new file mode 100644 index 0000000..a3afeb5 --- /dev/null +++ b/src/repo/deps-lib/s6rcrepo @@ -0,0 +1,36 @@ +s6rc_repo_badsub.o +s6rc_repo_checkset.o +s6rc_repo_cleanup.o +s6rc_repo_compile.o +s6rc_repo_fillset.o +s6rc_repo_fixset.o +s6rc_repo_flattenservices.o +s6rc_repo_getserviceflags.o +s6rc_repo_list_sets.o +s6rc_repo_listalldeps.o +s6rc_repo_listcontents.o +s6rc_repo_listdeps.o +s6rc_repo_listdeps_internal.o +s6rc_repo_listsub.o +s6rc_repo_lock.o +s6rc_repo_ls.o +s6rc_repo_makedefbundle.o +s6rc_repo_makesetbundles.o +s6rc_repo_makestores.o +s6rc_repo_makesvlist.o +s6rc_repo_makesvlist_byname.o +s6rc_repo_moveservices.o +s6rc_repo_nlto0.o +s6rc_repo_setcompile.o +s6rc_repo_setuptodate.o +s6rc_repo_subnames.o +s6rc_repo_sv_bcmpr.o +s6rc_repo_sv_cmpr.o +s6rc_repo_sync.o +s6rc_repo_syncset.o +s6rc_repo_syncset_tmp.o +s6rc_repo_touch.o +s6rc_repo_touchset.o +s6rc_repo_type_check.o +-lskarnet +${SPAWN_LIB} diff --git a/src/repo/s6rc_repo_badsub.c b/src/repo/s6rc_repo_badsub.c new file mode 100644 index 0000000..69697eb --- /dev/null +++ b/src/repo/s6rc_repo_badsub.c @@ -0,0 +1,69 @@ +/* ISC license. */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +static int strqcmp (void const *a, void const *b) +{ + return strcmp(*(char const *const *)a, *(char const *const *)b) ; +} + +int s6rc_repo_badsub (char const *repo, char const *set, char const **services, uint32_t n, uint8_t newsub, uint8_t what, s6rc_repo_sv const *svlist, uint32_t ntot, stralloc *sa, genalloc *badga) +{ + int sawasnull = !!sa->s ; + int gawasnull = !!genalloc_s(uint32_t, badga) ; + size_t sabase = sa->len ; + size_t gabase = genalloc_len(uint32_t, badga) ; + genalloc fulldeps = GENALLOC_ZERO ; + size_t fulln ; + size_t const *ind ; + uint32_t mid ; + + if (newsub < 3 && (what & 1) && s6rc_repo_listalldeps(repo, services, n, sa, &fulldeps, 0)) return 0 ; + mid = genalloc_len(size_t, &fulldeps) ; + if (newsub > 0 && (what & 2) && s6rc_repo_listalldeps(repo, services, n, sa, &fulldeps, 1)) goto err ; + + qsort(services, n, sizeof(char const *), &strqcmp) ; + fulln = genalloc_len(size_t, &fulldeps) ; + ind = genalloc_s(size_t, &fulldeps) ; + + for (uint32_t i = 0 ; i < fulln ; i++) + { + s6rc_repo_sv *p ; + char const *cur = sa->s + ind[i] ; + if (bsearch(&cur, services, n, sizeof(char const *), &strqcmp)) continue ; + p = bsearchr(cur, svlist, ntot, sizeof(s6rc_repo_sv), &s6rc_repo_sv_bcmpr, sa->s) ; + if (!p) + { + strerr_warnfu6x("find service ", cur, " in set ", set, " of repository ", repo) ; + goto err ; + } + if (i >= mid ? p->sub < newsub : p->sub > newsub) + { + uint32_t k = p - svlist ; + if (!genalloc_append(uint32_t, badga, &k)) + { + strerr_warnfu1sys("make bad sub list") ; + goto err ; + } + } + } + genalloc_free(size_t, &fulldeps) ; + return 1 ; + + err: + genalloc_free(size_t, &fulldeps) ; + if (sawasnull) stralloc_free(sa) ; else sa->len = sabase ; + if (gawasnull) genalloc_free(uint32_t, badga) ; else genalloc_setlen(uint32_t, badga, gabase) ; + return 0 ; +} diff --git a/src/repo/s6rc_repo_checkset.c b/src/repo/s6rc_repo_checkset.c new file mode 100644 index 0000000..a5b994e --- /dev/null +++ b/src/repo/s6rc_repo_checkset.c @@ -0,0 +1,39 @@ +/* ISC license. */ + +#include +#include + +#include +#include + +#include + +int s6rc_repo_checkset (char const *repo, char const *set) +{ + struct stat st ; + size_t repolen = strlen(repo) ; + size_t setlen = strlen(set) ; + char fn[repolen + 10 + setlen] ; + memcpy(fn, repo, repolen) ; + memcpy(fn + repolen, "/sources/", 9) ; + memcpy(fn + repolen + 9, set, setlen + 1) ; + if (stat(fn, &st) == -1) + { + if (errno == ENOENT) + { + strerr_warnf4x("set ", set, " does not exist in repository ", repo) ; + return 3 ; + } + else + { + strerr_warnfu2sys("stat ", fn) ; + return 111 ; + } + } + if (!S_ISDIR(st.st_mode)) + { + strerr_warnf3x("file ", fn, " is not a directory") ; + return 102 ; + } + return 0 ; +} diff --git a/src/repo/s6rc_repo_cleanup.c b/src/repo/s6rc_repo_cleanup.c new file mode 100644 index 0000000..05881cd --- /dev/null +++ b/src/repo/s6rc_repo_cleanup.c @@ -0,0 +1,117 @@ +/* ISC license. */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +static inline int sub_cleanup (char const *sub) +{ + size_t sublen = strlen(sub) ; + DIR *dir = opendir(sub) ; + if (!dir) return 0 ; + for (;;) + { + size_t len ; + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + len = strlen(d->d_name) ; + { + char fn[sublen + len + 2] ; + memcpy(fn, sub, sublen) ; + fn[sublen] = '/' ; + memcpy(fn + sublen + 1, d->d_name, len + 1) ; + if (access(fn, F_OK) == 0) + { + struct stat st ; + if (lstat(fn, &st) == -1) break ; + if (!S_ISLNK(st.st_mode)) rm_rf(fn) ; + } + else if (errno != ENOENT) + { + strerr_warnfu2sys("access ", fn) ; + break ; + } + else unlink_void(fn) ; + } + } + dir_close(dir) ; + return !errno ; +} + +static inline int set_cleanup (char const *set) +{ + size_t setlen = strlen(set) ; + DIR *dir ; + { + char bundle[setlen + 8] ; + memcpy(bundle, set, setlen) ; + memcpy(bundle + setlen, "/bundle", 8) ; + rm_rf(bundle) ; + } + dir = opendir(set) ; + if (!dir) return 0 ; + for (;;) + { + size_t len ; + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + len = strlen(d->d_name) ; + { + char fn[setlen + len + 2] ; + memcpy(fn, set, setlen) ; + fn[setlen] = '/' ; + memcpy(fn + setlen + 1, d->d_name, len + 1) ; + if (!sub_cleanup(fn)) break ; + } + } + dir_close(dir) ; + return !errno ; +} + +int s6rc_repo_sources_cleanup (char const *repo) +{ + DIR *dir ; + size_t repolen = strlen(repo) ; + unsigned int nsets = 0 ; + char sets[repolen + 9] ; + memcpy(sets, repo, repolen) ; + memcpy(sets + repolen, "/sources", 9) ; + dir = opendir(sets) ; + if (!dir) return 0 ; + for (;;) + { + size_t len ; + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + len = strlen(d->d_name) ; + { + char fn[repolen + len + 10] ; + memcpy(fn, sets, repolen + 8) ; + fn[repolen + 8] = '/' ; + memcpy(fn + repolen + 9, d->d_name, len + 1) ; + if (!set_cleanup(fn)) break ; + nsets++ ; + } + } + dir_close(dir) ; + return errno ? -1 : nsets ; +} diff --git a/src/repo/s6rc_repo_compile.c b/src/repo/s6rc_repo_compile.c new file mode 100644 index 0000000..ac4207d --- /dev/null +++ b/src/repo/s6rc_repo_compile.c @@ -0,0 +1,106 @@ +/* ISC license. */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +int s6rc_repo_compile (char const *repo, char const *set, char const *const *subs, uint8_t nsubs, char *oldc, unsigned int verbosity, char const *fdhuser) +{ + size_t repolen = strlen(repo) ; + size_t setlen = strlen(set) ; + size_t totsublen = 0 ; + int needprefix = strcmp(set, ".ref") ; + char newc[repolen + setlen + 45] ; + memcpy(newc, repo, repolen) ; + memcpy(newc + repolen, "/compiled/.", 11) ; + memcpy(newc + repolen + 11, set, setlen) ; + newc[repolen + 11 + setlen] = ':' ; + timestamp_g(newc + repolen + 12 + setlen) ; + memcpy(newc + repolen + 37 + setlen, ":XXXXXX", 8) ; + memcpy(oldc, newc, repolen + 10) ; + if (mkntemp(newc) == -1) { strerr_warnfu2sys("mkntemp ", newc) ; return -1 ; } + for (uint8_t i = 0 ; i < nsubs ; i++) totsublen += strlen(subs[i]) + 1 ; + + { + pid_t pid ; + size_t m = 0 ; + int wstat ; + char const *argv[9 + nsubs] ; + char fmtv[UINT_FMT] ; + char src[nsubs * (repolen + 10 + (needprefix ? setlen + 1 : 0)) + totsublen] ; + char *w = src ; + fmtv[uint_fmt(fmtv, verbosity)] = 0 ; + argv[m++] = S6RC_BINPREFIX "s6-rc-compile" ; + argv[m++] = "-v"; + argv[m++] = fmtv ; + argv[m++] = "-b" ; + if (fdhuser) + { + argv[m++] = "-h" ; + argv[m++] = fdhuser ; + } + argv[m++] = "--" ; + argv[m++] = newc ; + for (uint8_t i = 0 ; i < nsubs ; i++) + { + size_t sublen = strlen(subs[i]) ; + argv[m++] = w ; + memcpy(w, repo, repolen) ; w += repolen ; + memcpy(w, "/sources/", 9) ; w += 9 ; + if (needprefix) + { + memcpy(w, set, setlen) ; w += setlen ; + *w++ = '/' ; + } + memcpy(w, subs[i], sublen+1) ; w += sublen + 1 ; + } + argv[m++] = 0 ; + pid = cspawn(argv[0], argv, (char const *const *)environ, 0, 0, 0) ; + if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return -1 ; } + if (wait_pid(pid, &wstat) == -1) + { + strerr_warnfu2sys("wait for ", argv[0]) ; + return -1 ; + } + if (WIFSIGNALED(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; + strerr_warnf3x(argv[0], " crashed with signal ", fmt) ; + return -1 ; + } + if (WEXITSTATUS(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WEXITSTATUS(wstat))] = 0 ; + strerr_warnf3x(argv[0], " exited with code ", fmt) ; + return (WEXITSTATUS(wstat) == 1) - 1 ; + } + } + { + char fn[repolen + setlen + 11] ; + memcpy(fn, newc, repolen + 10) ; + memcpy(fn + repolen + 10, set, setlen + 1) ; + if (!atomic_symlink4(newc + repolen + 10, fn, oldc + repolen + 10, setlen + 35)) + { + int e = errno ; + rm_rf(newc) ; + errno = e ; + strerr_warnfu4sys("atomically make a ", fn, " symlink pointing to ", newc + repolen + 10) ; + return -1 ; + } + } + return 1 + !!oldc[repolen + 10] ; +} diff --git a/src/repo/s6rc_repo_fillset.c b/src/repo/s6rc_repo_fillset.c new file mode 100644 index 0000000..15832c3 --- /dev/null +++ b/src/repo/s6rc_repo_fillset.c @@ -0,0 +1,73 @@ +/* ISC license. */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +int s6rc_repo_fillset (char const *repo, char const *set, char const *const *existing, uint32_t n) +{ + size_t repolen = strlen(repo) ; + size_t setlen = strlen(set) ; + DIR *dir ; + char atomics[repolen + 18] ; + char setfn[repolen + 10 + setlen] ; + memcpy(atomics, repo, repolen) ; + memcpy(atomics + repolen, "/sources/.atomics", 18) ; + memcpy(setfn, repo, repolen) ; + memcpy(setfn + repolen, "/sources/", 9) ; + memcpy(setfn + repolen + 9, set, setlen+1) ; + + dir = opendir(atomics) ; + if (!dir) + { + strerr_warnfu2sys("opendir ", atomics) ; + return 0 ; + } + for (;;) + { + size_t len ; + uint32_t flags ; + direntry *d ; + uint8_t subi ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + + len = strlen(d->d_name) ; + char src[len + 13] ; + char dst[repolen + 18 + setlen + len] ; + memcpy(src, "../.atomics/", 12) ; + memcpy(src + 12, d->d_name, len+1) ; + if (n && bsearch(d->d_name, existing, n, sizeof(char const *), &str_bcmp)) continue ; + if (s6rc_repo_getserviceflags(repo, d->d_name, &flags) <= 0) return 0 ; + if (flags & 1) subi = 3 ; + else if (flags & 2) subi = 2 ; + else subi = 1 ; + memcpy(dst, setfn, repolen + 10 + setlen) ; + memcpy(dst + repolen + 10 + setlen, s6rc_repo_subnames[subi], 6) ; + dst[repolen + setlen + 16] = '/' ; + memcpy(dst + repolen + setlen + 17, d->d_name, len+1) ; + if (symlink(src, dst) == -1) + { + strerr_warnfu4sys("make a symlink named ", dst, " pointing to ", src) ; + return 0 ; + } + } + dir_close(dir) ; + if (errno) + { + strerr_warnfu2sys("readdir ", atomics) ; + return 0 ; + } + + return 1 ; +} diff --git a/src/repo/s6rc_repo_fix.c b/src/repo/s6rc_repo_fix.c new file mode 100644 index 0000000..b379d30 --- /dev/null +++ b/src/repo/s6rc_repo_fix.c @@ -0,0 +1,51 @@ +/* ISC license. */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +int s6rc_repo_fix (char const *repo, uint32_t options, unsigned int verbosity) +{ + stralloc sa = STRALLOC_ZERO ; + genalloc svlist = GENALLOC_ZERO ; /* s6rc_repo_sv */ + genalloc badga = GENALLOC_ZERO ; /* uint32_t */ + genalloc setind = GENALLOC_ZERO ; /* size_t */ + int n ; + + if (verbosity >= 3) + strerr_warni2x("checking set consistency in repository ", repo) ; + + n = s6rc_repo_list_sets(repo, &sa, &setind) ; + if (n < 0) + { + strerr_warnfu1sys("list sets") ; + return 0 ; + } + for (uint32_t i = 0 ; i < nsets ; i++) + { + if (verbosity >= 3) + strerr_warni2x("checking set ", sa.s + genalloc_s(size_t, &setind)[i]) ; + if (!s6rc_repo_fixset(repo, sa.s + genalloc_s(size_t, &setind)[i], options, verbosity, &sa, &svlist, &badga)) goto err ; + } + + genalloc_free(s6rc_repo_sv, &svlist) ; + genalloc_free(uint32_t, &badga) ; + genalloc_free(size_t, &setind) ; + stralloc_free(&sa) ; + return 1 ; + + err: + genalloc_free(s6rc_repo_sv, &svlist) ; + genalloc_free(uint32_t, &badga) ; + genalloc_free(size_t, &setind) ; + stralloc_free(&sa) ; + return 0 ; +} diff --git a/src/repo/s6rc_repo_fixset.c b/src/repo/s6rc_repo_fixset.c new file mode 100644 index 0000000..8ad64bc --- /dev/null +++ b/src/repo/s6rc_repo_fixset.c @@ -0,0 +1,96 @@ +/* ISC license. */ + +#include +#include +#include + +#include +#include +#include +#include + +#include + +static inline int s6rc_repo_fixsub (char const *repo, char const *set, uint8_t sub, s6rc_repo_sv *byname, char const **bysub, uint32_t ntot, uint32_t options, uint32_t const *subind, uint32_t const *subn, unsigned int verbosity, stralloc *sa, genalloc *badga) +{ + size_t sabase = sa->len ; + uint32_t gabase = genalloc_len(uint32_t, badga) ; + uint32_t const *bads ; + uint32_t badn ; + if (!s6rc_repo_badsub(repo, set, bysub + subind[sub], subn[sub], sub, options & 1 ? 2 : 1, byname, ntot, sa, badga)) return 0 ; + bads = genalloc_s(uint32_t, badga) ; + badn = genalloc_len(uint32_t, badga) ; + if (!badn) return 1 ; + + s6rc_repo_sv tomove[badn] ; + for (uint32_t j = 0 ; j < badn ; j++) + { + tomove[j] = byname[bads[j]] ; + if (verbosity >= 2) + strerr_warni("in set ", set, " of repository ", repo, ": ", options & 1 ? "up" : "down", "fixing service ", sa->s + tomove[j].pos, " from ", s6rc_repo_subnames[tomove[j].sub], " to ", s6rc_repo_subnames[sub]) ; + if (tomove[j].sub == 0 && verbosity) + strerr_warnw("service ", sa->s + tomove[j].pos, " is being automatically unmasked by an upfix to ", s6rc_repo_subnames[sub]) ; + if (tomove[j].sub == 3) + { + if (!(options & 2)) + { + strerr_warnf("in set ", set, " of repository ", repo, ": service ", sa->s + tomove[j].pos, " is marked as essential and cannot be downfixed. If you are sure of yourself, try --force-essential") ; + goto err ; + } + if (verbosity) + strerr_warnw("service ", sa->s + tomove[j].pos, " is being automatically marked non-essential by a downfix to ", s6rc_repo_subnames[sub]) ; + } + } + if (!s6rc_repo_moveservices(repo, set, tomove, badn, sub, sa->s, verbosity)) goto err ; + for (uint32_t j = 0 ; j < badn ; j++) byname[bads[j]].sub = sub ; + genalloc_setlen(uint32_t, badga, gabase) ; + sa->len = sabase ; + return 1 ; + + err: + genalloc_setlen(uint32_t, badga, gabase) ; + sa->len = sabase ; + return 0 ; +} + +int s6rc_repo_fixset (char const *repo, char const *set, uint32_t options, unsigned int verbosity, stralloc *sa, genalloc *svlist, genalloc *badga) +{ + int sawasnull = !sa->s ; + int svwasnull = !genalloc_s(s6rc_repo_sv, svlist) ; + int gawasnull = !genalloc_s(uint32_t, badga) ; + size_t sabase = sa->len ; + uint32_t svbase = genalloc_len(s6rc_repo_sv, svlist) ; + uint32_t gabase = genalloc_len(uint32_t, badga) ; + uint32_t ntot ; + uint32_t subind[4] ; + uint32_t sublen[4] ; + s6rc_repo_sv *byname ; + if (!s6rc_repo_makesvlist(repo, set, sa, svlist, subind)) return 0 ; + byname = genalloc_s(s6rc_repo_sv, svlist) ; + ntot = genalloc_len(s6rc_repo_sv, svlist) ; + if (!ntot) return 1 ; + for (uint8_t i = 0 ; i < 4 ; i++) sublen[i] = (i == 3 ? ntot : subind[i+1]) - subind[i] ; + + char const *bysub[ntot] ; + char bysub_storage[sa->len - sabase] ; + memcpy(bysub_storage, sa->s + sabase, sa->len - sabase) ; + for (uint32_t i = 0 ; i < ntot ; i++) bysub[i] = bysub_storage + byname[i].pos - sabase ; + qsortr(byname, ntot, sizeof(s6rc_repo_sv), &s6rc_repo_sv_cmpr, sa->s) ; + + for (uint8_t i = 0 ; i < 4 ; i++) if (sublen[i]) + { + if (!s6rc_repo_fixsub(repo, set, i, byname, bysub, ntot, options, subind, sublen, verbosity, sa, badga)) + goto err ; + } + + genalloc_setlen(uint32_t, badga, gabase) ; + genalloc_setlen(s6rc_repo_sv, svlist, svbase) ; + sa->len = sabase ; + return 1 ; + + err: + if (gawasnull) genalloc_free(uint32_t, badga) ; else genalloc_setlen(uint32_t, badga, gabase) ; + if (svwasnull) genalloc_free(s6rc_repo_sv, svlist) ; else genalloc_setlen(s6rc_repo_sv, svlist, svbase) ; + if (sawasnull) stralloc_free(sa) ; else sa->len = sabase ; + return 0 ; +} diff --git a/src/repo/s6rc_repo_flattenservices.c b/src/repo/s6rc_repo_flattenservices.c new file mode 100644 index 0000000..5693129 --- /dev/null +++ b/src/repo/s6rc_repo_flattenservices.c @@ -0,0 +1,72 @@ +/* ISC license. */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +int s6rc_repo_flattenservices (char const *repo, char const *const *services, uint32_t n, stralloc *storage, genalloc *indices) +{ + int swasnull = !storage->s ; + int gwasnull = !indices->s ; + size_t sabase = storage->len ; + size_t gabase = genalloc_len(size_t, indices) ; + + { + size_t m = 0 ; + size_t repolen = strlen(repo) ; + pid_t pid ; + int fd ; + int wstat ; + char const *argv[7 + n] ; + char refdb[repolen + 15] ; + memcpy(refdb, repo, repolen) ; + memcpy(refdb + repolen, "/compiled/.ref", 15) ; + argv[m++] = S6RC_BINPREFIX "s6-rc-db" ; + argv[m++] = "-c"; + argv[m++] = refdb ; + argv[m++] = "-b" ; + argv[m++] = "--" ; + argv[m++] = "atomics" ; + for (size_t i = 0 ; i < n ; i++) argv[m++] = services[i] ; + argv[m++] = 0 ; + pid = child_spawn1_pipe(argv[0], argv, (char const *const *)environ, &fd, 1) ; + if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return 111 ; } + if (!slurpn(fd, storage, 0)) { strerr_warnfu2sys("read output from ", argv[0]) ; return 111 ; } + fd_close(fd) ; + if (wait_pid(pid, &wstat) == -1) + { + strerr_warnfu2sys("wait for ", argv[0]) ; + goto err ; + } + if (WIFSIGNALED(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; + strerr_warnf3x(argv[0], " crashed with signal ", fmt) ; + goto err ; + } + if (WEXITSTATUS(wstat)) return WEXITSTATUS(wstat) ; + } + + if (!s6rc_repo_nlto0(storage->s + sabase, sabase, storage->len, indices)) goto err ; + return 0 ; + + err: + if (gwasnull) genalloc_free(size_t, indices) ; + else genalloc_setlen(size_t, indices, gabase) ; + if (swasnull) stralloc_free(storage) ; + else storage->len = sabase ; + return 111 ; +} diff --git a/src/repo/s6rc_repo_getserviceflags.c b/src/repo/s6rc_repo_getserviceflags.c new file mode 100644 index 0000000..0ad68e7 --- /dev/null +++ b/src/repo/s6rc_repo_getserviceflags.c @@ -0,0 +1,70 @@ +/* ISC license. */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +int s6rc_repo_getserviceflags (char const *repo, char const *name, uint32_t *flags) +{ + size_t repolen = strlen(repo) ; + ssize_t r ; + pid_t pid ; + int fd ; + int wstat ; + char flagstr[10] ; + char refdb[repolen + 15] ; + char const *argv[8] = { S6RC_BINPREFIX "s6-rc-db", "-c", refdb, "-b", "--", "flags", name, 0 } ; + + memcpy(refdb, repo, repolen) ; + memcpy(refdb + repolen, "/compiled/.ref", 15) ; + pid = child_spawn1_pipe(argv[0], argv, (char const *const *)environ, &fd, 1) ; + if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return -1 ; } + r = readnclose(fd, flagstr, 10) ; + if (r != 9) + { + if (r == 10) goto err ; + else if (r >= 0) errno = EPIPE ; + strerr_warnfu2sys("read output from ", argv[0]) ; + return -1 ; + } + if (wait_pid(pid, &wstat) == -1) + { + strerr_warnfu2sys("wait for ", argv[0]) ; + return -1 ; + } + if (WIFSIGNALED(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; + strerr_warnf3x(argv[0], " crashed with signal ", fmt) ; + return -1 ; + } + if (WEXITSTATUS(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WEXITSTATUS(wstat))] = 0 ; + strerr_warnf3x(argv[0], " exited with code ", fmt) ; + return (WEXITSTATUS(wstat) < 99) - 1 ; + } + flagstr[8] = 0 ; + if (!uint320_xscan(flagstr, flags)) goto err ; + return 1 ; + + err: + strerr_warnf2x("invalid output from ", S6RC_BINPREFIX "s6-rc-db") ; + errno = EPROTO ; + return -1 ; +} diff --git a/src/repo/s6rc_repo_list_sets.c b/src/repo/s6rc_repo_list_sets.c new file mode 100644 index 0000000..1698460 --- /dev/null +++ b/src/repo/s6rc_repo_list_sets.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include + +#include + +int s6rc_repo_list_sets (char const *repo, stralloc *sa, genalloc *ga) +{ + size_t repolen = strlen(repo) ; + char fn[repolen + 9] ; + memcpy(fn, repo, repolen) ; + memcpy(fn + repolen, "/sources", 9) ; + return s6rc_repo_ls(fn, sa, ga) ; +} diff --git a/src/repo/s6rc_repo_listalldeps.c b/src/repo/s6rc_repo_listalldeps.c new file mode 100644 index 0000000..7e9aca6 --- /dev/null +++ b/src/repo/s6rc_repo_listalldeps.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include + +int s6rc_repo_listalldeps (char const *repo, char const *const *services, uint32_t n, stralloc *storage, genalloc *indices, int up) +{ + return s6rc_repo_listdeps_internal(repo, services, n, storage, indices, 2 | !!up) ; +} diff --git a/src/repo/s6rc_repo_listcontents.c b/src/repo/s6rc_repo_listcontents.c new file mode 100644 index 0000000..e3ffc84 --- /dev/null +++ b/src/repo/s6rc_repo_listcontents.c @@ -0,0 +1,67 @@ +/* ISC license. */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +int s6rc_repo_listcontents (char const *repo, char const *bundle, stralloc *storage, genalloc *indices) +{ + int swasnull = !storage->s ; + int gwasnull = !indices->s ; + size_t sabase = storage->len ; + size_t gabase = genalloc_len(size_t, indices) ; + size_t repolen = strlen(repo) ; + pid_t pid ; + int fd ; + int wstat ; + char refdb[repolen + 15] ; + char const *argv[8] = { S6RC_BINPREFIX "s6-rc-db", "-c", refdb, "-b", "--", "contents", bundle, 0 } ; + + memcpy(refdb, repo, repolen) ; + memcpy(refdb + repolen, "/compiled/.ref", 15) ; + pid = child_spawn1_pipe(argv[0], argv, (char const *const *)environ, &fd, 1) ; + if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return -1 ; } + if (!slurpn(fd, storage, 0)) { strerr_warnfu2sys("read output from ", argv[0]) ; return -1 ; } + fd_close(fd) ; + if (wait_pid(pid, &wstat) == -1) + { + strerr_warnfu2sys("wait for ", argv[0]) ; + return -1 ; + } + if (WIFSIGNALED(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; + strerr_warnf3x(argv[0], " crashed with signal ", fmt) ; + return -1 ; + } + if (WEXITSTATUS(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WEXITSTATUS(wstat))] = 0 ; + strerr_warnf3x(argv[0], " exited with code ", fmt) ; + return (WEXITSTATUS(wstat) < 99) - 1 ; + } + + if (!s6rc_repo_nlto0(storage->s + sabase, sabase, storage->len, indices)) goto err ; + return 1 ; + + err: + if (gwasnull) genalloc_free(size_t, indices) ; + else genalloc_setlen(size_t, indices, gabase) ; + if (swasnull) stralloc_free(storage) ; + else storage->len = sabase ; + return -1 ; +} diff --git a/src/repo/s6rc_repo_listdeps.c b/src/repo/s6rc_repo_listdeps.c new file mode 100644 index 0000000..4dfb495 --- /dev/null +++ b/src/repo/s6rc_repo_listdeps.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include + +int s6rc_repo_listdeps (char const *repo, char const *service, stralloc *storage, genalloc *indices, int up) +{ + return s6rc_repo_listdeps_internal(repo, &service, 1, storage, indices, !!up) ; +} diff --git a/src/repo/s6rc_repo_listdeps_internal.c b/src/repo/s6rc_repo_listdeps_internal.c new file mode 100644 index 0000000..6d66796 --- /dev/null +++ b/src/repo/s6rc_repo_listdeps_internal.c @@ -0,0 +1,73 @@ +/* ISC license. */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +int s6rc_repo_listdeps_internal (char const *repo, char const *const *services, uint32_t n, stralloc *storage, genalloc *indices, uint32_t options) +{ + int swasnull = !storage->s ; + int gwasnull = !indices->s ; + size_t sabase = storage->len ; + size_t gabase = genalloc_len(size_t, indices) ; + + { + size_t m = 0 ; + size_t repolen = strlen(repo) ; + pid_t pid ; + int fd ; + int wstat ; + char const *argv[8 + n] ; + char refdb[repolen + 15] ; + memcpy(refdb, repo, repolen) ; + memcpy(refdb + repolen, "/compiled/.ref", 15) ; + argv[m++] = S6RC_BINPREFIX "s6-rc-db" ; + argv[m++] = "-c"; + argv[m++] = refdb ; + argv[m++] = "-b" ; + argv[m++] = options & 1 ? "-u" : "-d" ; + argv[m++] = "--" ; + argv[m++] = options & 2 ? "all-dependencies" : "dependencies" ; + for (uint32_t i = 0 ; i < n ; i++) argv[m++] = services[i] ; + argv[m++] = 0 ; + pid = child_spawn1_pipe(argv[0], argv, (char const *const *)environ, &fd, 1) ; + if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return 111 ; } + if (!slurpn(fd, storage, 0)) { strerr_warnfu2sys("read output from ", argv[0]) ; return 111 ; } + fd_close(fd) ; + if (wait_pid(pid, &wstat) == -1) + { + strerr_warnfu2sys("wait for ", argv[0]) ; + goto err ; + } + if (WIFSIGNALED(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; + strerr_warnf3x(argv[0], " crashed with signal ", fmt) ; + goto err ; + } + if (WEXITSTATUS(wstat)) return wait_estatus(wstat) ; + } + + if (!s6rc_repo_nlto0(storage->s + sabase, sabase, storage->len, indices)) goto err ; + return 0 ; + + err: + if (gwasnull) genalloc_free(size_t, indices) ; + else genalloc_setlen(size_t, indices, gabase) ; + if (swasnull) stralloc_free(storage) ; + else storage->len = sabase ; + return 111 ; +} diff --git a/src/repo/s6rc_repo_listsub.c b/src/repo/s6rc_repo_listsub.c new file mode 100644 index 0000000..1ee23bf --- /dev/null +++ b/src/repo/s6rc_repo_listsub.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include + +#include + +int s6rc_repo_listsub (char const *repo, char const *set, char const *sub, stralloc *sa, genalloc *ga) +{ + size_t repolen = strlen(repo) ; + size_t setlen = strlen(set) ; + size_t sublen = strlen(sub) ; + char fn[repolen + setlen + 10 + sublen] ; + memcpy(fn, repo, repolen) ; + memcpy(fn + repolen, "/sources/", 9) ; + memcpy(fn + repolen + 9, set, setlen) ; + memcpy(fn + repolen + 9 + setlen, sub, sublen + 1) ; + + return s6rc_repo_ls(fn, sa, ga) ; +} diff --git a/src/repo/s6rc_repo_lock.c b/src/repo/s6rc_repo_lock.c new file mode 100644 index 0000000..472ff15 --- /dev/null +++ b/src/repo/s6rc_repo_lock.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include + +#include + +#include + +int s6rc_repo_lock (char const *repo, int w) +{ + int fd ; + size_t repolen = strlen(repo) ; + char fn[repolen + 13] ; + memcpy(fn, repo, repolen) ; + memcpy(fn + repolen, "/lock", 6) ; + fd = openc_write(fn) ; + if (fd == -1) return -1 ; + if (fd_lock(fd, w, 0) < 1) return -1 ; + return fd ; +} diff --git a/src/repo/s6rc_repo_ls.c b/src/repo/s6rc_repo_ls.c new file mode 100644 index 0000000..1294f48 --- /dev/null +++ b/src/repo/s6rc_repo_ls.c @@ -0,0 +1,46 @@ +/* ISC license. */ + +#include +#include + +#include +#include +#include + +#include + +int s6rc_repo_ls (char const *fn, stralloc *sa, genalloc *ga) +{ + size_t sabase = sa->len ; + size_t gabase = genalloc_len(size_t, ga) ; + int sawasnull = !sa->s ; + int gawasnull = !genalloc_s(size_t, ga) ; + int n = 0 ; + + DIR *dir = opendir(fn) ; + if (!dir) return -1 ; + for (;;) + { + direntry *d ; + size_t len ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + len = strlen(d->d_name) ; + if (!genalloc_catb(size_t, ga, &sa->len, 1)) goto err ; + if (!stralloc_catb(sa, d->d_name, len+1)) goto err ; + n++ ; + } + if (errno) goto err ; + dir_close(dir) ; + return n ; + + err: + dir_close(dir) ; + if (gawasnull) genalloc_free(size_t, ga) ; + else genalloc_setlen(size_t, ga, gabase) ; + if (sawasnull) stralloc_free(sa) ; + else sa->len = sabase ; + return -1 ; +} diff --git a/src/repo/s6rc_repo_makedefbundle.c b/src/repo/s6rc_repo_makedefbundle.c new file mode 100644 index 0000000..5c67917 --- /dev/null +++ b/src/repo/s6rc_repo_makedefbundle.c @@ -0,0 +1,121 @@ +/* ISC license. */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +int s6rc_repo_makedefbundle (char const *repo, char const *set, char const *bundle) +{ + size_t repolen = strlen(repo) ; + size_t setlen = strlen(set) ; + size_t bundlelen = strlen(bundle) ; + size_t bfnlen = repolen + setlen + bundlelen + 28 ; + DIR *dir ; + char bfn[bfnlen + 1] ; + char subfn[repolen + setlen + 17] ; + + memcpy(bfn, repo, repolen) ; + memcpy(bfn + repolen, "/sources/.atomics/", 18) ; + memcpy(bfn + repolen + 18, bundle, bundlelen + 1) ; + + if (access(bfn, F_OK) == 0) goto errexists ; + if (errno != ENOENT) + { + strerr_warnfu2sys("check existence of ", bfn) ; + return 0 ; + } + memcpy(bfn + repolen + 10, "bundle", 6) ; + if (access(bfn, F_OK) == 0) goto errexists ; + if (errno != ENOENT) + { + strerr_warnfu2sys("check existence of ", bfn) ; + return 0 ; + } + + memcpy(bfn + repolen + 9, set, setlen) ; + memcpy(bfn + repolen + 9 + setlen, "/bundle/", 8) ; + memcpy(bfn + repolen + 17 + setlen, bundle, bundlelen + 1) ; + if (mkdir(bfn, 02755) == -1) + { + if (errno != EEXIST) strerr_warnfu2sys("mkdir ", bfn) ; + else strerr_warnf6x("bundle ", bundle, " is already defined in set ", set, " of repository ", repo) ; + return 0 ; + } + memcpy(bfn + repolen + setlen + 17 + bundlelen, "/type", 6) ; + if (!openwritenclose_unsafe(bfn, "bundle\n", 7)) + { + strerr_warnfu2sys("write to ", bfn) ; + return 0 ; + } + memcpy(bfn + repolen + setlen + 18 + bundlelen, "contents.d", 11) ; + if (mkdir(bfn, 02755) == -1) + { + strerr_warnfu2sys("mkdir ", bfn) ; + return 0 ; + } + bfn[bfnlen] = '/' ; + + memcpy(subfn, bfn, repolen + 10 + setlen) ; + memcpy(subfn + repolen + 10 + setlen, "onboot", 7) ; + dir = opendir(subfn) ; + if (!dir) + { + strerr_warnfu2sys("opendir ", subfn) ; + return 0 ; + } + + for (;;) + { + size_t len ; + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + len = strlen(d->d_name) ; + char fn[bfnlen + len + 2] ; + memcpy(fn, bfn, bfnlen + 1) ; + memcpy(fn + bfnlen + 1, d->d_name, len + 1) ; + if (!openwritenclose_unsafe(fn, "", 0)) + { + strerr_warnfu2sys("write to ", fn) ; + dir_close(dir) ; + return 0 ; + } + } + dir_close(dir) ; + if (errno) + { + strerr_warnfu2sys("readdir ", subfn) ; + return 0 ; + } + + return 1 ; + + errexists: + if (sareadlink(&satmp, bfn) == -1) + { + strerr_warnfu2sys("readlink ", bfn) ; + return 0 ; + } + if (!stralloc_0(&satmp)) + { + strerr_warnfu1sys("stralloc_catb ") ; + satmp.len = 0 ; + return 0 ; + } + strerr_warnf4x("bundle ", bundle, " is already defined at ", satmp.s) ; + satmp.len = 0 ; + return (errno = EINVAL, 0) ; +} diff --git a/src/repo/s6rc_repo_makesetbundles.c b/src/repo/s6rc_repo_makesetbundles.c new file mode 100644 index 0000000..81267b9 --- /dev/null +++ b/src/repo/s6rc_repo_makesetbundles.c @@ -0,0 +1,137 @@ +/* ISC license. */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +int s6rc_repo_makesetbundles (char const *repo, char const *set, unsigned int verbosity) +{ + size_t repolen = strlen(repo) ; + size_t setlen = strlen(set) ; + stralloc sa = STRALLOC_ZERO ; + genalloc ga = GENALLOC_ZERO ; + int n ; + char src[repolen + 19] ; + char dst[repolen + 17 + setlen] ; + memcpy(dst, repo, repolen) ; + memcpy(dst + repolen, "/sources/", 9) ; + memcpy(dst + repolen + 9, set, setlen) ; + memcpy(dst + repolen + 9 + setlen, "/bundle", 8) ; + memcpy(src, dst, repolen + 10) ; + memcpy(src + repolen + 10, ".bundles", 9) ; + rm_rf_tmp(dst, &sa) ; + + n = s6rc_repo_listsub(repo, set, s6rc_repo_subnames[0], &sa, &ga) ; + if (n < 0) + { + strerr_warnfu6sys("list sub ", s6rc_repo_subnames[0], " of set ", set, " in repository ", repo) ; + goto err ; + } + if (n) + { + DIR *dir ; + char const *masked[n] ; + char maskedstorage[sa.len] ; + memcpy(maskedstorage, sa.s, sa.len) ; + for (size_t i = 0 ; i < n ; i++) masked[i] = maskedstorage + genalloc_s(size_t, &ga)[i] ; + sa.len = 0 ; + genalloc_setlen(size_t, &ga, 0) ; + qsort(masked, n, sizeof(char const *), &str_cmp) ; + + if (mkdir(dst, 02755) == -1) + { + strerr_warnfu2sys("mkdir ", dst) ; + goto errga ; + } + dir = opendir(src) ; + if (!dir) + { + strerr_warnfu2sys("opendir ", src) ; + goto err0 ; + } + for (;;) + { + int m, i = 0 ; + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + + sa.len = 0 ; + genalloc_setlen(size_t, &ga, 0) ; + m = s6rc_repo_listcontents(repo, d->d_name, &sa, &ga) ; + if (m < 0) + { + dir_close(dir) ; + goto err0 ; + } + + for (; i < m ; i++) + { + char const *x = sa.s + genalloc_s(size_t, &ga)[i] ; + if (bsearch(x, masked, n, sizeof(char const *), &str_bcmp)) + { + if (verbosity >= 3) + strerr_warni4x("skipping bundle ", d->d_name, " containing e.g. masked service ", x) ; + break ; + } + } + if (i < m) continue ; + + size_t len = strlen(d->d_name) ; + char target[16 + len] ; + char fn[repolen + setlen + 18 + len] ; + memcpy(target, "../../.bundles/", 15) ; + memcpy(target + 15, d->d_name, len+1) ; + memcpy(fn, dst, repolen + setlen + 16) ; + fn[repolen + setlen + 16] = '/' ; + memcpy(fn + repolen + setlen + 17, d->d_name, len+1) ; + if (symlink(target, fn) == -1) + { + strerr_warnfu4sys("make a symlink named ", fn, " pointing to ", target) ; + dir_close(dir) ; + goto err0 ; + } + } + dir_close(dir) ; + if (errno) + { + strerr_warnfu2sys("readdir ", src) ; + goto err0 ; + } + } + else if (!hiercopy_tmp(src, dst, &sa)) + { + strerr_warnfu4sys("recursively copy ", src, " to ", dst) ; + goto err0 ; + } + + stralloc_free(&sa) ; + return 1 ; + + err0: + { + int e = errno ; + rm_rf_tmp(dst, &sa) ; + errno = e ; + } + errga: + genalloc_free(size_t, &ga) ; + err: + stralloc_free(&sa) ; + return 0 ; +} diff --git a/src/repo/s6rc_repo_makestores.c b/src/repo/s6rc_repo_makestores.c new file mode 100644 index 0000000..f61f94c --- /dev/null +++ b/src/repo/s6rc_repo_makestores.c @@ -0,0 +1,65 @@ +/* ISC license. */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +int s6rc_repo_makestores (char const *repo, char const *const *stores, uint16_t n, char *sold) +{ + size_t repolen = strlen(repo) ; + mode_t m = umask(0) ; + char slink[repolen + 8] ; + char sdir[repolen + 21] ; + + memcpy(slink, repo, repolen) ; + memcpy(slink + repolen, "/stores", 8) ; + memcpy(sdir, slink, repolen + 1) ; + memcpy(sdir + repolen + 1, ".stores:XXXXXX", 15) ; + + if (!mkdtemp(sdir)) + { + umask(m) ; + strerr_warnfu2sys("mkdtemp ", sdir) ; + return 0 ; + } + umask(m) ; + sdir[repolen + 15] = '/' ; + sdir[repolen + 20] = 0 ; + for (uint16_t i = 0 ; i < n ; i++) + { + uint160_xfmt(sdir + repolen + 16, i, 4) ; + if (symlink(stores[i], sdir) == -1) + { + strerr_warnfu4sys("symlink ", stores[i], " to ", sdir) ; + sdir[repolen + 15] = 0 ; + goto err ; + } + } + sdir[repolen + 15] = 0 ; + if (chmod(sdir, 02755) == -1) + { + strerr_warnfu2sys("chmod ", sdir) ; + goto err ; + } + if (!atomic_symlink4(sdir + repolen + 1, slink, sold, 15)) + { + strerr_warnfu4sys("atomically symlink ", sdir + repolen + 1, " to ", slink) ; + goto err ; + } + return 1 ; + + err: + rm_rf(sdir) ; + return 0 ; +} diff --git a/src/repo/s6rc_repo_makesvlist.c b/src/repo/s6rc_repo_makesvlist.c new file mode 100644 index 0000000..99a174e --- /dev/null +++ b/src/repo/s6rc_repo_makesvlist.c @@ -0,0 +1,66 @@ +/* ISC license. */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +static inline int s6rc_repo_addsub (char const *sub, uint8_t i, stralloc *sa, genalloc *ga) +{ + DIR *dir = opendir(sub) ; + if (!dir) { strerr_warnfu2sys("opendir ", sub) ; return 0 ; } + for (;;) + { + s6rc_repo_sv sv = { .pos = sa->len, .sub = i } ; + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + + if (!stralloc_cats(sa, d->d_name) || !stralloc_0(sa) + || !genalloc_append(s6rc_repo_sv, ga, &sv)) goto nomem ; + } + dir_close(dir) ; + if (errno) { strerr_warnfu2sys("readdir ", sub) ; return 0 ; } + return 1 ; + + nomem: + strerr_warnfu1sys("stralloc_catb") ; + return 0 ; +} + +int s6rc_repo_makesvlist (char const *repo, char const *set, stralloc *sa, genalloc *ga, uint32_t *tab) +{ + size_t repolen = strlen(repo) ; + size_t setlen = strlen(set) ; + size_t sabase = sa->len ; + size_t gabase = genalloc_len(s6rc_repo_sv, ga) ; + int sawasnull = !sa->s ; + int gawasnull = !genalloc_s(s6rc_repo_sv, ga) ; + char subfn[repolen + setlen + 17] ; + + memcpy(subfn, repo, repolen) ; + memcpy(subfn + repolen, "/sources/", 9) ; + memcpy(subfn + repolen + 9, set, setlen) ; + subfn[repolen + 9 + setlen] = '/' ; + for (uint8_t i = 0 ; i < 4 ; i++) + { + if (tab) tab[i] = genalloc_len(s6rc_repo_sv, ga) ; + memcpy(subfn + repolen + setlen + 10, s6rc_repo_subnames[i], 7) ; + if (!s6rc_repo_addsub(subfn, i, sa, ga)) goto err ; + } + return 1 ; + + err: + if (sawasnull) stralloc_free(sa) ; else sa->len = sabase ; + if (gawasnull) genalloc_free(s6rc_repo_sv, ga) ; else genalloc_setlen(s6rc_repo_sv, ga, gabase) ; + return 0 ; +} diff --git a/src/repo/s6rc_repo_makesvlist_byname.c b/src/repo/s6rc_repo_makesvlist_byname.c new file mode 100644 index 0000000..c017be6 --- /dev/null +++ b/src/repo/s6rc_repo_makesvlist_byname.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include +#include +#include + +#include + +int s6rc_repo_makesvlist_byname (char const *repo, char const *set, stralloc *sa, genalloc *ga) +{ + if (!s6rc_repo_makesvlist(repo, set, sa, ga, 0)) return 0 ; + qsortr(genalloc_s(s6rc_repo_sv, ga), genalloc_len(s6rc_repo_sv, ga), sizeof(s6rc_repo_sv), &s6rc_repo_sv_cmpr, sa->s) ; + return 1 ; +} diff --git a/src/repo/s6rc_repo_moveservices.c b/src/repo/s6rc_repo_moveservices.c new file mode 100644 index 0000000..3cc3b92 --- /dev/null +++ b/src/repo/s6rc_repo_moveservices.c @@ -0,0 +1,60 @@ +/* ISC license. */ + +#include +#include +#include +#include + +#include + +#include + +int s6rc_repo_moveservices (char const *repo, char const *set, s6rc_repo_sv const *services, uint32_t n, uint8_t newsub, char const *storage, unsigned int verbosity) +{ + size_t repolen = strlen(repo) ; + size_t setlen = strlen(set) ; + size_t maxserviceslen = 0 ; + for (uint32_t i = 0 ; i < n ; i++) + { + size_t len = strlen(storage + services[i].pos) ; + if (len > maxserviceslen) maxserviceslen = len ; + } + char oldfn[repolen + setlen + maxserviceslen + 18] ; + char newfn[repolen + setlen + maxserviceslen + 18] ; + memcpy(oldfn, repo, repolen) ; + memcpy(oldfn + repolen, "/sources/", 9) ; + memcpy(oldfn + repolen + 9, set, setlen) ; + oldfn[repolen + 9 + setlen] = '/' ; + oldfn[repolen + 16 + setlen] = '/' ; + memcpy(newfn, oldfn, repolen + 10 + setlen) ; + memcpy(newfn + repolen + 10 + setlen, s6rc_repo_subnames[newsub], 6) ; + newfn[repolen + 16 + setlen] = '/' ; + + for (uint32_t i = 0 ; i < n ; i++) + { + size_t len = strlen(storage + services[i].pos) ; + memcpy(oldfn + repolen + 10, s6rc_repo_subnames[services[i].sub], 6) ; + memcpy(oldfn + repolen + setlen + 17, storage + services[i].pos, len + 1) ; + memcpy(newfn + repolen + setlen + 17, storage + services[i].pos, len + 1) ; + if (access(newfn, F_OK) == 0) + { + if (verbosity >= 2) + strerr_warni8x("service ", storage + services[i].pos, " already existed in subset ", s6rc_repo_subnames[newsub], " of set ", set, " in repository ", repo) ; + } + else if (errno != ENOENT) + { + strerr_warnfu2sys("access ", newfn) ; + return 0 ; + } + if (rename(oldfn, newfn) == -1) + { + strerr_warnfu4sys("rename ", oldfn, " to ", newfn) ; + return 0 ; + } + if (verbosity >= 4) + { + strerr_warnt10x("repository ", repo, ", set ", set, ", from subset ", s6rc_repo_subnames[services[i].sub], " to subset ", s6rc_repo_subnames[newsub], ": successfully moved service ", storage + services[i].pos) ; + } + } + return 1 ; +} diff --git a/src/repo/s6rc_repo_nlto0.c b/src/repo/s6rc_repo_nlto0.c new file mode 100644 index 0000000..9076bd3 --- /dev/null +++ b/src/repo/s6rc_repo_nlto0.c @@ -0,0 +1,33 @@ +/* ISC license. */ + +#include + +#include + +#include + +int s6rc_repo_nlto0 (char *s, size_t start, size_t len, genalloc *indices) +{ + size_t origlen = genalloc_len(size_t, indices) ; + size_t pos = start ; + int wasnull = !indices->s ; + int inword = 0 ; + + for (size_t i = start ; i < len ; i++) + { + if (s[i] == '\n') + { + s[i] = 0 ; + if (!genalloc_append(size_t, indices, &pos)) goto err ; + inword = 0 ; + } + else if (!inword) { pos = i ; inword = 1 ; } + } + if (inword) goto err ; + return 1 ; + + err: + if (wasnull) genalloc_free(size_t, indices) ; + else genalloc_setlen(size_t, indices, origlen) ; + return 0 ; +} diff --git a/src/repo/s6rc_repo_setcompile.c b/src/repo/s6rc_repo_setcompile.c new file mode 100644 index 0000000..5da136a --- /dev/null +++ b/src/repo/s6rc_repo_setcompile.c @@ -0,0 +1,33 @@ +/* ISC license. */ + +#include +#include + +#include + +#include + +int s6rc_repo_setcompile (char const *repo, char const *set, char const *defbundle, char *oldc, unsigned int verbosity, char const *fdhuser) +{ + static char const *const subs[4] = { "bundle", s6rc_repo_subnames[1], s6rc_repo_subnames[2], s6rc_repo_subnames[3] } ; + int r ; + if (!s6rc_repo_makesetbundles(repo, set, verbosity)) return -1 ; + if (!s6rc_repo_makedefbundle(repo, set, defbundle)) return -1 ; + r = s6rc_repo_compile(repo, set, subs, 4, oldc, verbosity, fdhuser) ; + + { + int e = errno ; + size_t repolen = strlen(repo) ; + size_t setlen = strlen(set) ; + size_t sublen = strlen(subs[0]) ; + char fn[repolen + setlen + 11 + sublen] ; + memcpy(fn, repo, repolen) ; + memcpy(fn + repolen, "/sources/", 9) ; + memcpy(fn + repolen + 9, set, setlen) ; + fn[repolen + 9 + setlen] = '/' ; + memcpy(fn + repolen + setlen + 10, subs[0], sublen + 1) ; + rm_rf(fn) ; + errno = e ; + } + return r ; +} diff --git a/src/repo/s6rc_repo_setuptodate.c b/src/repo/s6rc_repo_setuptodate.c new file mode 100644 index 0000000..3dded26 --- /dev/null +++ b/src/repo/s6rc_repo_setuptodate.c @@ -0,0 +1,44 @@ +/* ISC license. */ + +#include + +#include +#include + +#include +#include + +#include + +int s6rc_repo_setuptodate (char const *repo, char const *set) +{ + struct stat stsource ; + struct stat stcompiled ; + size_t repolen = strlen(repo) ; + size_t setlen = strlen(set) ; + char srcfn[repolen + 17 + setlen] ; + char dstfn[repolen + 11 + setlen] ; + memcpy(srcfn, repo, repolen) ; + memcpy(srcfn + repolen, "/sources/", 9) ; + memcpy(srcfn + repolen + 9, set, setlen) ; + memcpy(srcfn + repolen + 9 + setlen, "/.stamp", 8) ; + memcpy(dstfn, repo, repolen) ; + memcpy(dstfn + repolen, "/compiled/", 10) ; + memcpy(dstfn + repolen + 10, set, setlen + 1) ; + if (stat(srcfn, &stsource) == -1) + { + strerr_warnfu2sys("stat ", srcfn) ; + return -1 ; + } + if (stat(dstfn, &stcompiled) == -1) + { + if (errno == ENOENT) return 0 ; + strerr_warnfu2sys("stat ", dstfn) ; + return -1 ; + } + return + stsource.st_atim.tv_sec < stcompiled.st_atim.tv_sec ? 1 : + stsource.st_atim.tv_sec > stcompiled.st_atim.tv_sec ? 0 : + stsource.st_atim.tv_nsec < stcompiled.st_atim.tv_nsec ; +} + diff --git a/src/repo/s6rc_repo_subnames.c b/src/repo/s6rc_repo_subnames.c new file mode 100644 index 0000000..2653f01 --- /dev/null +++ b/src/repo/s6rc_repo_subnames.c @@ -0,0 +1,5 @@ +/* ISC license. */ + +#include + +char const s6rc_repo_subnames[4][7] = { "masked", "usable", "active", "always" } ; diff --git a/src/repo/s6rc_repo_sv_bcmpr.c b/src/repo/s6rc_repo_sv_bcmpr.c new file mode 100644 index 0000000..bcc4d80 --- /dev/null +++ b/src/repo/s6rc_repo_sv_bcmpr.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include + +#include + +int s6rc_repo_sv_bcmpr (void const *a, void const *b, void *aux) +{ + char const *key = a ; + s6rc_repo_sv const *elem = b ; + char const *s = aux ; + return strcmp(key, s + elem->pos) ; +} diff --git a/src/repo/s6rc_repo_sv_cmpr.c b/src/repo/s6rc_repo_sv_cmpr.c new file mode 100644 index 0000000..80b07c9 --- /dev/null +++ b/src/repo/s6rc_repo_sv_cmpr.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include + +int s6rc_repo_sv_cmpr (void const *a, void const *b, void *aux) +{ + s6rc_repo_sv const *aa = a ; + s6rc_repo_sv const *bb = b ; + char const *s = aux ; + return strcmp(s + aa->pos, s + bb->pos) ; +} diff --git a/src/repo/s6rc_repo_sync.c b/src/repo/s6rc_repo_sync.c new file mode 100644 index 0000000..6a17876 --- /dev/null +++ b/src/repo/s6rc_repo_sync.c @@ -0,0 +1,230 @@ +/* ISC license. */ + +#include /* mkdtemp */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static inline void cleanup (char const *ato, char const *bun) +{ + int e = errno ; + rm_rf(ato) ; + rm_rf(bun) ; + errno = e ; +} + +int s6rc_repo_sync (char const *repo, unsigned int verbosity, char const *fdhuser) +{ + size_t repolen = strlen(repo) ; + mode_t m ; + char store[repolen + 13] ; + char ato[repolen + 26] ; + char bun[repolen + 26] ; + + memcpy(store, repo, repolen) ; + memcpy(store + repolen, "/stores/", 8) ; + store[repolen + 12] = 0 ; + + + /* Fill new .atomics/ and .bundles/ with symlinks to real stores */ + + memcpy(ato, repo, repolen) ; + memcpy(ato + repolen, "/sources/..atomics:XXXXXX", 26) ; + memcpy(bun, ato, repolen + 26) ; + memcpy(bun + repolen + 11, "bundle", 6) ; + m = umask(0) ; + if (!mkdtemp(ato)) + { + strerr_warnfu2sys("mkdtemp ", ato) ; + umask(m) ; + return -1 ; + } + if (chmod(ato, 02755) == -1) + { + strerr_warnfu2sys("chmod ", ato) ; + umask(m) ; + return -1 ; + } + + if (!mkdtemp(bun)) + { + strerr_warnfu2sys("mkdtemp ", bun) ; + rmdir(ato) ; + umask(m) ; + return -1 ; + } + umask(m) ; + if (chmod(bun, 02755) == -1) + { + strerr_warnfu2sys("chmod ", bun) ; + return -1 ; + } + + for (uint16_t istore = 0 ;; istore++) + { + DIR *dir ; + uint160_xfmt(store + repolen + 8, istore, 4) ; + dir = opendir(store) ; + if (!dir) + { + if (errno == ENOENT) break ; + strerr_warnfu2sys("opendir ", store) ; + goto err ; + } + for (;;) + { + size_t len ; + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + len = strlen(d->d_name) ; + { + char const *x ; + char dst[repolen + 28 + len] ; + char src[22 + len] ; + memcpy(src, "../../../stores/", 16) ; + memcpy(src + 16, store + repolen + 8, 4) ; + src[20] = '/' ; + memcpy(src + 21, d->d_name, len+1) ; + switch (s6rc_repo_type_check(src)) + { + case 1 : + case 2 : x = ato ; break ; + case 3 : x = bun ; break ; + case 0 : + strerr_warnf2x("invalid service type for ", src) ; + dir_close(dir) ; + goto err ; + default : + strerr_warnfu2sys("check service type of ", src) ; + dir_close(dir) ; + goto err ; + } + memcpy(dst, x, repolen + 26) ; + dst[repolen + 26] = '/' ; + memcpy(dst + repolen + 27, d->d_name, len+1) ; + if (symlink(src, dst) == -1) + { + if (errno != EEXIST) + { + strerr_warnfu4sys("symlink ", src, " to ", dst) ; + dir_close(dir) ; + goto err ; + } + if (verbosity) + { + if (!sareadlink(&satmp, dst) || !stralloc_0(&satmp)) + { + strerr_warnwu2sys("readlink ", dst) ; + errno = EEXIST ; + strerr_warnwu4sys("symlink ", src, " to ", dst) ; + } + else + strerr_warnwu6x("symlink ", src, " to ", dst, ": already provided by ", satmp.s) ; + satmp.len = 0 ; + } + } + } + } + dir_close(dir) ; + if (errno) + { + strerr_warnfu2sys("readdir ", store) ; + goto err ; + } + } + + + /* Compile the reference db - also checks consistency of new stores */ + + { + char const *subs[2] = { ato + repolen + 9, bun + repolen + 9 } ; + char oldc[repolen + 49] ; + int r = s6rc_repo_compile(repo, ".ref", subs, 2, oldc, verbosity, fdhuser) ; + if (r < 0) goto err ; + if (!r) { cleanup(ato, bun) ; return 0 ; } + if (r == 2) rm_rf(oldc) ; + } + + + /* Switch, delete links to old stores */ + + { + char fn[repolen + 18] ; + char oldato[17] ; + char oldbun[17] ; + memcpy(fn, repo, repolen) ; + memcpy(fn + repolen, "/sources/.atomics", 18) ; + if (!atomic_symlink4(ato + repolen + 9, fn, oldato, 17)) goto err ; + memcpy(fn + repolen + 10, "bundle", 6) ; + if (!atomic_symlink4(bun + repolen + 9, fn, oldbun, 17)) + { + strerr_warnfu4sys("symlink ", bun + repolen + 9, " to ", fn) ; + memcpy(fn + repolen + 10, "atomic", 6) ; + if (!atomic_symlink4(oldato, fn, 0, 0)) + { + strerr_warnfu6sys("symlink ", oldato, " back to ", fn, " - weird race, manually check ", repo) ; + goto err ; + } + goto err ; + } + memcpy(ato + repolen + 9, oldato, 16) ; + memcpy(bun + repolen + 9, oldbun, 16) ; + cleanup(ato, bun) ; + } + + + /* Update the existing sets */ + + ato[repolen + 8] = 0 ; + { + stralloc sa = STRALLOC_ZERO ; + genalloc ga = GENALLOC_ZERO ; /* size_t */ + DIR *dir = opendir(ato) ; + if (!dir) + { + strerr_warnfu2sys("opendir ", ato) ; + return -1 ; + } + for (;;) + { + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + if (!s6rc_repo_syncset_tmp(repo, d->d_name, &sa, &ga, verbosity)) break ; + } + dir_close(dir) ; + genalloc_free(size_t, &ga) ; + stralloc_free(&sa) ; + if (errno) + { + strerr_warnfu2sys("readdir ", ato) ; + return -1 ; + } + } + + return 1 ; + + err: + cleanup(ato, bun) ; + return -1 ; +} diff --git a/src/repo/s6rc_repo_syncset.c b/src/repo/s6rc_repo_syncset.c new file mode 100644 index 0000000..929d9c4 --- /dev/null +++ b/src/repo/s6rc_repo_syncset.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include +#include + +#include + +int s6rc_repo_syncset (char const *repo, char const *set, unsigned int verbosity) +{ + stralloc sa = STRALLOC_ZERO ; + genalloc ga = GENALLOC_ZERO ; /* size_t */ + int r = s6rc_repo_syncset_tmp(repo, set, &sa, &ga, verbosity) ; + genalloc_free(&size_t, &ga) ; + stralloc_free(&sa) ; + return r ; +} diff --git a/src/repo/s6rc_repo_syncset_tmp.c b/src/repo/s6rc_repo_syncset_tmp.c new file mode 100644 index 0000000..44e5b52 --- /dev/null +++ b/src/repo/s6rc_repo_syncset_tmp.c @@ -0,0 +1,101 @@ +/* ISC license. */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +static int unlink_stales_in_sub (char const *repo, size_t repolen, char const *set, char const *sub, uint32_t where, stralloc *sa, genalloc *ga, unsigned int verbosity) +{ + size_t setlen = strlen(set) ; + size_t sublen = strlen(sub) ; + size_t subfnlen = repolen + setlen + sublen + 10 ; + char subfn[subfnlen + 1] ; + memcpy(subfn, repo, repolen) ; + memcpy(subfn + repolen, "/sources/", 9) ; + memcpy(subfn + repolen + 9, set, setlen) ; + subfn[repolen + 9 + setlen] = '/' ; + memcpy(subfn + repolen + 10 + setlen, sub, sublen + 1) ; + DIR *dir = opendir(subfn) ; + if (!dir) + { + strerr_warnfu2sys("opendir ", subfn) ; + return 0 ; + } + for (;;) + { + size_t len ; + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + len = strlen(d->d_name) ; + char fn[subfnlen + len + 2] ; + memcpy(fn, subfn, sublen) ; + fn[sublen] = '/' ; + memcpy(fn + sublen + 1, d->d_name, len+1) ; + if (access(fn, F_OK) == -1) + { + if (errno != ENOENT) + { + strerr_warnfu2sys("access ", fn) ; + goto err ; + } + unlink_void(fn) ; + if (verbosity >= 3) + strerr_warni6x("service ", d->d_name, " does not exist anymore, removed from sub ", sub, " of set ", set) ; + } + else + { + if (!genalloc_append(size_t, ga, &sa->len)) goto err ; + if (!stralloc_catb(sa, d->d_name, len+1)) goto err ; + } + } + if (errno) + { + strerr_warnfu2sys("readdir ", subfn) ; + goto err ; + } + + dir_close(dir) ; + return 1 ; + + err: + dir_close(dir) ; + return 0 ; +} + +int s6rc_repo_syncset_tmp (char const *repo, char const *set, stralloc *sa, genalloc *ga, unsigned int verbosity) +{ + size_t repolen = strlen(repo) ; + size_t sabase = sa->len ; + size_t gabase = genalloc_len(size_t, ga) ; + + for (unsigned int i = 0 ; i < 4 ; i++) + if (unlink_stales_in_sub(repo, repolen, set, s6rc_repo_subnames[i], i, sa, ga, verbosity)) goto err ; + + { + uint32_t n = genalloc_len(size_t, ga) ; + char const *stillhere[n + !n] ; + for (uint32_t i = 0 ; i < n ; i++) stillhere[i] = sa->s + genalloc_s(size_t, ga)[i] ; + if (!s6rc_repo_fillset(repo, set, stillhere, n)) goto err ; + } + + sa->len = sabase ; + genalloc_setlen(size_t, ga, gabase) ; + return 1 ; + + err: + sa->len = sabase ; + genalloc_setlen(size_t, ga, gabase) ; + return 0 ; +} diff --git a/src/repo/s6rc_repo_touch.c b/src/repo/s6rc_repo_touch.c new file mode 100644 index 0000000..069ed78 --- /dev/null +++ b/src/repo/s6rc_repo_touch.c @@ -0,0 +1,45 @@ +/* ISC license. */ + +#include +#include + +#include +#include + +#include + +int s6rc_repo_touch (char const *repo) +{ + DIR *dir ; + size_t repolen = strlen(repo) ; + char sources[repolen + 9] ; + memcpy(sources, repo, repolen) ; + memcpy(sources + repolen, "/sources", 9) ; + + dir = opendir(sources) ; + if (!dir) + { + strerr_warnfu2sys("opendir ", sources) ; + return 0 ; + } + for (;;) + { + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + if (!s6rc_repo_touchset(repo, d->d_name)) + { + dir_close(dir) ; + return 0 ; + } + } + dir_close(dir) ; + if (errno) + { + strerr_warnfu2sys("readdir ", sources) ; + return 0 ; + } + return 1 ; +} diff --git a/src/repo/s6rc_repo_touchset.c b/src/repo/s6rc_repo_touchset.c new file mode 100644 index 0000000..684bfc4 --- /dev/null +++ b/src/repo/s6rc_repo_touchset.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include + +#include +#include + +#include + +int s6rc_repo_touchset (char const *repo, char const *set) +{ + size_t repolen = strlen(repo) ; + size_t setlen = strlen(set) ; + char fn[repolen + 17 + setlen] ; + memcpy(fn, repo, repolen) ; + memcpy(fn + repolen, "/sources/", 9) ; + memcpy(fn + repolen + 9, set, setlen) ; + memcpy(fn + repolen + 9 + setlen, "/.stamp", 8) ; + if (!touch(fn)) + { + strerr_warnfu2sys("touch ", fn) ; + return 0 ; + } + return 1 ; +} diff --git a/src/repo/s6rc_repo_type_check.c b/src/repo/s6rc_repo_type_check.c new file mode 100644 index 0000000..8793819 --- /dev/null +++ b/src/repo/s6rc_repo_type_check.c @@ -0,0 +1,29 @@ +/* ISC license. */ + +#include +#include + +#include +#include + +#include + +int s6rc_repo_type_check (char const *src) +{ + ssize_t r ; + char type[8] ; + size_t srclen = strlen(src) ; + char fn[srclen + 6] ; + memcpy(fn, src, srclen) ; + memcpy(fn + srclen, "/type", 6) ; + r = openreadnclose(fn, type, 8) ; + if (r == -1) return -1 ; + if (r < 6) return 0 ; + if (type[r-1] == '\n') r-- ; + if (r == 8) return 0 ; + type[r++] = 0 ; + return + !strcmp(type, "longrun") ? 1 : + !strcmp(type, "oneshot") ? 2 : + !strcmp(type, "bundle") ? 3 : 0 ; +} diff --git a/src/s6-rc/s6-rc-compile.c b/src/s6-rc/s6-rc-compile.c index 4e390ac..5c29f84 100644 --- a/src/s6-rc/s6-rc-compile.c +++ b/src/s6-rc/s6-rc-compile.c @@ -145,6 +145,21 @@ static char const *typestr (servicetype_t type) "unknown" ; } +static inline int type_check (int dfd) +{ + char type[8] ; + ssize_t r = openreadnclose_at(dfd, "type", type, 8) ; + if (r == -1) return -1 ; + if (r < 6) return 0 ; + if (type[r-1] == '\n') r-- ; + if (r == 8) return 0 ; + type[r++] = 0 ; + return + !strcmp(type, "longrun") ? 1 : + !strcmp(type, "oneshot") ? 2 : + !strcmp(type, "bundle") ? 3 : 0 ; +} + static int add_name_nocheck (before_t *be, char const *srcdir, char const *name, servicetype_t type, unsigned int *pos, unsigned int *kpos) { uint32_t id ; @@ -529,7 +544,7 @@ static inline void add_bundle (before_t *be, int dfd, char const *srcdir, char c static inline void add_source (before_t *be, int dfd, char const *srcdir, char const *name) { if (verbosity >= 2) strerr_warni4x("parsing ", srcdir, "/", name) ; - switch (s6rc_type_check(dfd, 0)) + switch (type_check(dfd)) { case 0 : strerr_dief6x(1, "invalid ", srcdir, "/", name, "/type", ": must be oneshot, longrun, or bundle") ; case 1 : add_longrun(be, dfd, srcdir, name) ; break ; -- cgit v1.3.1