diff options
Diffstat (limited to 'src/libs6rc/s6rc_servicedir_manage.c')
-rw-r--r-- | src/libs6rc/s6rc_servicedir_manage.c | 219 |
1 files changed, 79 insertions, 140 deletions
diff --git a/src/libs6rc/s6rc_servicedir_manage.c b/src/libs6rc/s6rc_servicedir_manage.c index 3c883be..bad4f4b 100644 --- a/src/libs6rc/s6rc_servicedir_manage.c +++ b/src/libs6rc/s6rc_servicedir_manage.c @@ -1,152 +1,91 @@ /* ISC license. */ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> #include <skalibs/tai.h> +#include <skalibs/direntry.h> +#include <skalibs/djbunix.h> +#include <skalibs/genalloc.h> +#include <s6/s6-supervise.h> +#include <s6/ftrigr.h> +#include <s6/ftrigw.h> #include <s6-rc/s6rc-servicedir.h> - -static int s6rc_servicedir_manage (char const *live, unsigned char const *state, unsigned int nlong, tain_t const *deadline) +int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *stamp) { -#if 0 + ftrigr_t a = FTRIGR_ZERO ; + genalloc ids = GENALLOC_ZERO ; /* uint16 */ + gid_t gid = getgid() ; unsigned int livelen = str_len(live) ; - char - byte_copy(lfn + llen + 1, 12, "servicedirs") ; - byte_copy(cfn, llen + 1, lfn) ; - byte_copy(cfn + llen + 1, 21, "compiled/servicedirs") ; - if (!hiercopy(cfn, lfn)) - { - cleanup() ; - strerr_diefu4sys(111, "recursively copy ", cfn, " to ", lfn) ; - } - - tain_now_g() ; - tain_add_g(&deadline, &tto) ; - dir = opendir(lfn) ; - if (!dir) + int ok = 1 ; + int e ; + DIR *dir ; + char dirfn[livelen + 13] ; + if (!ftrigr_startf(&a, deadline, stamp)) return 0 ; + byte_copy(dirfn, livelen, live) ; + byte_copy(dirfn + livelen, 13, "/servicedirs") ; + dir = opendir(dirfn) ; + if (!dir) goto closederr ; + for (;;) + { + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; { - cleanup() ; - strerr_diefu2sys(111, "opendir ", lfn) ; + unsigned int len = str_len(d->d_name) ; + uint16 id ; + char srcfn[livelen + 20 + len] ; + char dstfn[livelen + 10 + len] ; + register int r ; + byte_copy(srcfn, livelen + 12, dirfn) ; + srcfn[livelen + 12] = '/' ; + byte_copy(srcfn + livelen + 13, len + 1, d->d_name) ; + r = s6_svc_ok(srcfn) ; + if (r < 0) { e = errno ; goto err ; } + if (r) continue ; + byte_copy(srcfn + livelen + 13 + len, 6, "/down") ; + if (!touch(srcfn)) { e = errno ; goto err ; } + byte_copy(srcfn + livelen + 14 + len, 6, "event") ; + if (!ftrigw_fifodir_make(srcfn, gid, 0)) { e = errno ; goto err ; } + id = ftrigr_subscribe(&a, srcfn, "s", 0, deadline, stamp) ; + if (!id) { e = errno ; goto err ; } + if (!genalloc_append(uint16, &ids, &id)) { e = errno ; goto err ; } + srcfn[livelen + 13 + len] = 0 ; + byte_copy(dstfn, livelen, live) ; + byte_copy(dstfn + livelen, 9, "/scandir/") ; + byte_copy(dstfn + livelen + 9, len + 1, d->d_name) ; + if (symlink(srcfn, dstfn) < 0) { e = errno ; goto err ; } } - for (;;) - { - unsigned int thislen ; - direntry *d ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - thislen = str_len(d->d_name) ; - if (thislen > maxlen) maxlen = thislen ; - ndirs++ ; - } - if (errno) - { - int e = errno ; - dir_close(dir) ; - errno = e ; - cleanup() ; - strerr_diefu2sys(111, "readdir ", lfn) ; - } - if (ndirs) - { - ftrigr_t a = FTRIGR_ZERO ; - gid_t gid = getgid() ; - unsigned int i = 0 ; - int r ; - uint16 ids[ndirs] ; - char srcfn[llen + 23 + maxlen] ; /* XXX: unsafe if dir is writable by non-root */ - char dstfn[llen + 9 + sizeof(S6_SVSCAN_CTLDIR "/control") + maxlen] ; - rewinddir(dir) ; - byte_copy(srcfn, llen + 12, lfn) ; - srcfn[llen + 12] = '/' ; - byte_copy(dstfn, llen, satmp.s) ; - byte_copy(dstfn + llen, 8, "/scandir") ; - dstfn[llen + 8] = '/' ; - if (!ftrigr_startf_g(&a, &deadline)) - { - int e = errno ; - dir_close(dir) ; - errno = e ; - cleanup() ; - strerr_diefu1sys(111, "start event listener process") ; - } - for (;;) - { - unsigned int thislen ; - direntry *d ; - errno = 0 ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') continue ; - thislen = str_len(d->d_name) ; - byte_copy(srcfn + llen + 13, thislen, d->d_name) ; - byte_copy(srcfn + llen + 13 + thislen, 6, "/down") ; - if (!touch(srcfn)) - { - cleanup() ; - strerr_diefu2sys(111, "touch ", srcfn) ; - } - byte_copy(srcfn + llen + 14 + thislen, 9, "log/down") ; - if (!touch(srcfn)) - { - cleanup() ; - strerr_diefu2sys(111, "touch ", srcfn) ; - } - byte_copy(srcfn + llen + 14 + thislen, 6, "event") ; - if (!ftrigw_fifodir_make(srcfn, gid, 0)) - { - cleanup() ; - strerr_diefu2sys(111, "make fifodir ", srcfn) ; - } - ids[i] = ftrigr_subscribe_g(&a, srcfn, "s", 0, &deadline) ; - if (!ids[i]) - { - int e = errno ; - dir_close(dir) ; - errno = e ; - cleanup() ; - strerr_diefu2sys(111, "subscribe to ", srcfn) ; - } - srcfn[llen + 13 + thislen] = 0 ; - byte_copy(dstfn + llen + 9, thislen + 1, d->d_name) ; - if (symlink(srcfn, dstfn) < 0) - { - int e = errno ; - dir_close(dir) ; - errno = e ; - cleanup() ; - strerr_diefu4sys(111, "symlink ", srcfn, " to ", dstfn) ; - } - i++ ; - } - if (errno) - { - int e = errno ; - dir_close(dir) ; - errno = e ; - cleanup() ; - strerr_diefu2sys(111, "readdir ", lfn) ; - } - dir_close(dir) ; - byte_copy(dstfn + llen + 9, sizeof(S6_SVSCAN_CTLDIR "/control"), S6_SVSCAN_CTLDIR "/control") ; - r = s6_svc_write(dstfn, "a", 1) ; - if (r < 0) - { - cleanup() ; - strerr_diefu2sys(111, "write to ", dstfn) ; - } - if (!r) strerr_warnw2x("s6-svscan not running on ", argv[0]) ; - else - { - if (ftrigr_wait_and_g(&a, ids, ndirs, &deadline) < 0) - { - cleanup() ; - strerr_diefu1sys(111, "wait for s6-supervise processes to come up") ; - } - } - ftrigr_end(&a) ; - } - else dir_close(dir) ; } -#endif + if (errno) { e = errno ; goto err ; } + dir_close(dir) ; + { + char scanfn[livelen + 9] ; + register int r ; + byte_copy(scanfn, livelen, live) ; + byte_copy(scanfn + livelen, 9, "/scandir") ; + r = s6_svc_writectl(scanfn, S6_SVSCAN_CTLDIR, "a", 1) ; + if (r < 0) { e = errno ; goto closederr ; } + if (!r) ok = 3 ; + else if (ftrigr_wait_and(&a, genalloc_s(uint16, &ids), genalloc_len(uint16, &ids), deadline, stamp) < 0) + { e = errno ; goto closederr ; } + } + + genalloc_free(uint16, &ids) ; + ftrigr_end(&a) ; + return ok ; + + err: + dir_close(dir) ; + closederr: + genalloc_free(uint16, &ids) ; + ftrigr_end(&a) ; + errno = e ; return 0 ; } |