about summary refs log tree commit diff
path: root/src/usertree
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2022-12-23 22:53:07 +0000
committerLaurent Bercot <ska@appnovation.com>2022-12-23 22:53:07 +0000
commit2c61fb1d1ce85fe400a8668e85fc0da42813a45a (patch)
tree68e0e63c747a08c3f3c38c7088a0e16c343afdb3 /src/usertree
parent977d6ca915355954ae6215b0aa577c24fc257efe (diff)
downloads6-2c61fb1d1ce85fe400a8668e85fc0da42813a45a.tar.gz
s6-2c61fb1d1ce85fe400a8668e85fc0da42813a45a.tar.xz
s6-2c61fb1d1ce85fe400a8668e85fc0da42813a45a.zip
Refactor libs6auto, add s6-instance-maker (untested)
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/usertree')
-rw-r--r--src/usertree/s6-usertree-maker.c219
1 files changed, 83 insertions, 136 deletions
diff --git a/src/usertree/s6-usertree-maker.c b/src/usertree/s6-usertree-maker.c
index 3edbd8b..f8740aa 100644
--- a/src/usertree/s6-usertree-maker.c
+++ b/src/usertree/s6-usertree-maker.c
@@ -22,186 +22,139 @@
 #include <s6/config.h>
 #include <s6/auto.h>
 
-#define USAGE "s6-usertree-maker [ -d userscandir ] [ -p path ] [ -E envdir [ -e var ... ] ] [ -r service/logger[/pipeline] ] [ -l loguser ] [ -t stamptype ] [ -n nfiles ] [ -s filesize ] [ -S maxsize ] user logdir dir"
+#define USAGE "s6-usertree-maker [ -d userscandir ] [ -p path ] [ -E envdir [ -e var ... ] ] [ -r service/logger[/pipeline] ] [ -l loguser ] [ -t stamptype ] [ -n nfiles ] [ -s filesize ] [ -S maxsize ] [ -P prefix ] user logdir dir"
 #define dieusage() strerr_dieusage(100, USAGE)
 
 #define VARS_MAX 64
 
-static mode_t mask ;
 static stralloc sa = STRALLOC_ZERO ;
 
-static inline void write_run (char const *runfile, char const *user, char const *sc, char const *path, char const *userenvdir, char const *const *vars, size_t varlen)
+typedef struct svinfo_s svinfo, *svinfo_ref ;
+struct svinfo_s
 {
-  buffer b ;
-  char buf[2048] ;
-  int fd = open_trunc(runfile) ;
-  if (fd < 0) strerr_diefu3sys(111, "open ", runfile, " for writing") ;
-  buffer_init(&b, &buffer_write, fd, buf, 2048) ;
-  if (!string_quote(&sa, user, strlen(user))) goto errq ;
-  if (buffer_puts(&b, "#!" EXECLINE_SHEBANGPREFIX "execlineb -P\n"
+  char const *user ;
+  char const *sc ;
+  char const *logger ;
+  char const *path ;
+  char const *userenvdir ;
+  char const **vars ;
+  size_t varlen ;
+} ;
+
+static int write_run (buffer *b, void *data)
+{
+  svinfo *t = data ;
+  if (!string_quote(&sa, t->user, strlen(t->user))) return 0 ;
+  if (buffer_puts(b, "#!" EXECLINE_SHEBANGPREFIX "execlineb -P\n"
     EXECLINE_EXTBINPREFIX "fdmove -c 2 1\n"
     EXECLINE_EXTBINPREFIX "emptyenv -p\n"
     EXECLINE_EXTBINPREFIX "export USER ") < 0
-   || buffer_put(&b, sa.s, sa.len) < 0
-   || buffer_puts(&b, "\n"
+   || buffer_put(b, sa.s, sa.len) < 0
+   || buffer_puts(b, "\n"
     S6_EXTBINPREFIX "s6-envuidgid -i -- ") < 0
-   || buffer_put(&b, sa.s, sa.len) < 0
-   || buffer_puts(&b, "\n"
+   || buffer_put(b, sa.s, sa.len) < 0
+   || buffer_puts(b, "\n"
     S6_EXTBINPREFIX "s6-applyuidgid -U --\n"
     EXECLINE_EXTBINPREFIX "backtick -in HOME { "
     EXECLINE_EXTBINPREFIX "homeof ") < 0
-   || buffer_put(&b, sa.s, sa.len) < 0
-   || buffer_put(&b, " }\n", 3) < 0) goto err ;
+   || buffer_put(b, sa.s, sa.len) < 0
+   || buffer_put(b, " }\n", 3) < 0) goto err ;
   sa.len = 0 ;
-  if (userenvdir)
+  if (t->userenvdir)
   {
-    if (!string_quote(&sa, userenvdir, strlen(userenvdir))) goto errq ;
-    if (buffer_puts(&b, S6_EXTBINPREFIX "s6-envdir -i -- ") < 0
-     || buffer_put(&b, sa.s, sa.len) < 0
-     || buffer_put(&b, "\n", 1) < 0) goto err ;
+    if (!string_quote(&sa, t->userenvdir, strlen(t->userenvdir))) return 0 ;
+    if (buffer_puts(b, S6_EXTBINPREFIX "s6-envdir -i -- ") < 0
+     || buffer_put(b, sa.s, sa.len) < 0
+     || buffer_put(b, "\n", 1) < 0) goto err ;
     sa.len = 0 ;
-    if (varlen)
+    if (t->varlen)
     {
-      if (buffer_puts(&b, EXECLINE_EXTBINPREFIX "multisubstitute\n{\n") < 0) goto err ;
-      for (size_t i = 0 ; i < varlen ; i++)
+      if (buffer_puts(b, EXECLINE_EXTBINPREFIX "multisubstitute\n{\n") < 0) return 0 ;
+      for (size_t i = 0 ; i < t->varlen ; i++)
       {
-        if (!string_quote(&sa, vars[i], strlen(vars[i]))) goto errq ;
-        if (buffer_puts(&b, "  importas -D \"\" -- ") < 0
-         || buffer_put(&b, sa.s, sa.len) < 0
-         || buffer_put(&b, " ", 1) < 0
-         || buffer_put(&b, sa.s, sa.len) < 0
-         || buffer_put(&b, "\n", 1) < 0) goto err ;
+        if (!string_quote(&sa, t->vars[i], strlen(t->vars[i]))) return 0 ;
+        if (buffer_puts(b, "  importas -D \"\" -- ") < 0
+         || buffer_put(b, sa.s, sa.len) < 0
+         || buffer_put(b, " ", 1) < 0
+         || buffer_put(b, sa.s, sa.len) < 0
+         || buffer_put(b, "\n", 1) < 0) goto err ;
         sa.len = 0 ;
       }
-      if (buffer_put(&b, "}\n", 2) < 0) goto err ;
+      if (buffer_put(b, "}\n", 2) < 0) return 0 ;
     }
   }
-  if (buffer_puts(&b, EXECLINE_EXTBINPREFIX "multisubstitute\n{\n"
+  if (buffer_puts(b, EXECLINE_EXTBINPREFIX "multisubstitute\n{\n"
    "  importas -i USER USER\n"
    "  importas -i HOME HOME\n"
    "  importas -i UID UID\n"
    "  importas -i GID GID\n"
-   "  importas -i GIDLIST GIDLIST\n}\n") < 0) goto err ;
-  if (userenvdir && varlen)
+   "  importas -i GIDLIST GIDLIST\n}\n") < 0) return 0 ;
+  if (t->userenvdir && t->varlen)
   {
-    for (size_t i = 0 ; i < varlen ; i++)
+    for (size_t i = 0 ; i < t->varlen ; i++)
     {
-      if (!string_quote(&sa, vars[i], strlen(vars[i]))) goto errq ;
-      if (buffer_puts(&b, EXECLINE_EXTBINPREFIX "export ") < 0
-       || buffer_put(&b, sa.s, sa.len) < 0
-       || buffer_put(&b, " ${", 3) < 0
-       || buffer_put(&b, sa.s, sa.len) < 0
-       || buffer_put(&b, "}\n", 2) < 0) goto err ;
+      if (!string_quote(&sa, t->vars[i], strlen(t->vars[i]))) return 0 ;
+      if (buffer_puts(b, EXECLINE_EXTBINPREFIX "export ") < 0
+       || buffer_put(b, sa.s, sa.len) < 0
+       || buffer_put(b, " ${", 3) < 0
+       || buffer_put(b, sa.s, sa.len) < 0
+       || buffer_put(b, "}\n", 2) < 0) goto err ;
       sa.len = 0 ;
     }
   }
-  if (!string_quote(&sa, path, strlen(path))) goto errq ;
-  if (buffer_puts(&b, EXECLINE_EXTBINPREFIX "export PATH ") < 0
-   || buffer_put(&b, sa.s, sa.len) < 0) goto err ;
+  if (!string_quote(&sa, t->path, strlen(t->path))) return 0 ;
+  if (buffer_puts(b, EXECLINE_EXTBINPREFIX "export PATH ") < 0
+   || buffer_put(b, sa.s, sa.len) < 0) goto err ;
   sa.len = 0 ;
-  if (!string_quote(&sa, sc, strlen(sc))) goto errq ;
-  if (buffer_puts(&b, "\n"
+  if (!string_quote(&sa, t->sc, strlen(t->sc))) return 0 ;
+  if (buffer_puts(b, "\n"
     S6_EXTBINPREFIX "s6-svscan -d3 -- ") < 0
-   || buffer_put(&b, sa.s, sa.len) < 0) goto err ;
+   || buffer_put(b, sa.s, sa.len) < 0) goto err ;
   sa.len = 0 ;
-  if (!buffer_putflush(&b, "\n", 1)) goto err ;
-  fd_close(fd) ;
-  return ;
- err:
-  strerr_diefu2sys(111, "write to ", runfile) ;
- errq:
-  strerr_diefu1sys(111, "quote string") ;
-}
+  if (!buffer_putflush(b, "\n", 1)) return 0 ;
+  return 1 ;
 
-static void write_service (char const *dir, char const *user, char const *sc, char const *logger, char const *path, char const *userenvdir, char const *const *vars, size_t varlen)
-{
-  size_t dirlen = strlen(dir) ;
-  char fn[dirlen + 17] ;
-  memcpy(fn, dir, dirlen) ;
-  memcpy(fn + dirlen, "/notification-fd", 17) ;
-  if (!openwritenclose_unsafe(fn, "3\n", 2)) strerr_diefu2sys(111, "write to ", fn) ;
-  memcpy(fn + dirlen + 1, "run", 4) ;
-  write_run(fn, user, sc, path, userenvdir, vars, varlen) ;
-  if (logger)
-  {
-    struct iovec v[2] = { { .iov_base = (char *)logger, .iov_len = strlen(logger) }, { .iov_base = "\n", .iov_len = 1 } } ;
-    memcpy(fn + dirlen + 1, "type", 5) ;
-    if (!openwritenclose_unsafe(fn, "longrun\n", 8)) strerr_diefu2sys(111, "write to ", fn) ;
-    memcpy(fn + dirlen + 1, "producer-for", 13) ;
-    if (!openwritevnclose_unsafe(fn, v, 2)) strerr_diefu2sys(111, "write to ", fn) ;
-  }
-  else
-  {
-    if (chmod(fn, mask | ((mask >> 2) & 0111)) < 0)
-      strerr_diefu2sys(111, "chmod ", fn) ;
-  }
-}
-
-static void write_logger (char const *dir, char const *user, char const *logdir, unsigned int stamptype, unsigned int nfiles, uint64_t filesize, uint64_t maxsize, char const *service, char const *pipelinename)
-{
-  size_t dirlen = strlen(dir) ;
-  char fn[dirlen + 17] ;
-  memcpy(fn, dir, dirlen) ;
-  memcpy(fn + dirlen, "/notification-fd", 17) ;
-  if (!openwritenclose_unsafe(fn, "3\n", 2)) goto err ;
-  memcpy(fn + dirlen + 1, "run", 4) ;
-  if (!s6_auto_write_logrun(fn, user, logdir, stamptype, nfiles, filesize, maxsize, &sa)) goto err ;
-  if (service)
-  {
-    struct iovec v[2] = { { .iov_base = (char *)service, .iov_len = strlen(service) }, { .iov_base = "\n", .iov_len = 1 } } ;
-    memcpy(fn + dirlen + 1, "type", 5) ;
-    if (!openwritenclose_unsafe(fn, "longrun\n", 8)) goto err ;
-    memcpy(fn + dirlen + 1, "consumer-for", 13) ;
-    if (!openwritevnclose_unsafe(fn, v, 2)) goto err ;
-    if (pipelinename)
-    {
-      v[0].iov_base = (char *)pipelinename ;
-      v[0].iov_len = strlen(pipelinename) ;
-      memcpy(fn + dirlen + 1, "pipeline-name", 14) ;
-      if (!openwritevnclose_unsafe(fn, v, 2)) goto err ;
-    }
-  }
-  else
-  {
-    if (chmod(fn, mask | ((mask >> 2) & 0111)) < 0)
-      strerr_diefu2sys(111, "chmod ", fn) ;
-  }
-  return ;
  err:
-  strerr_diefu2sys(111, "write to ", fn) ;
+  sa.len = 0 ;
+  return 0 ;
 }
 
 int main (int argc, char *const *argv)
 {
-  char const *userscandir = "${HOME}/service" ;
-  char const *path = SKALIBS_DEFAULTPATH ;
-  char const *userenvdir = 0 ;
+  char const *vars[VARS_MAX] ;
+  svinfo t =
+  {
+    .sc = "${HOME}/service",
+    .logger = 0,
+    .path = SKALIBS_DEFAULTPATH,
+    .userenvdir = 0,
+    .vars = vars,
+    .varlen = 0
+  } ;
   char *rcinfo[3] = { 0, 0, 0 } ;
   char const *loguser = 0 ;
   unsigned int stamptype = 1 ;
   unsigned int nfiles = 10 ;
   uint64_t filesize = 1000000 ;
   uint64_t maxsize = 0 ;
+  char const *prefix = 0 ;
   size_t dirlen ;
-  size_t varlen = 0 ;
-  mode_t m ;
-  char const *vars[VARS_MAX] ;
   PROG = "s6-usertree-maker" ;
   {
     subgetopt l = SUBGETOPT_ZERO ;
     for (;;)
     {
-      int opt = subgetopt_r(argc, (char const *const *)argv, "d:p:E:e:r:l:t:n:s:S:", &l) ;
+      int opt = subgetopt_r(argc, (char const *const *)argv, "d:p:E:e:r:l:t:n:s:S:P:", &l) ;
       if (opt == -1) break ;
       switch (opt)
       {
-        case 'd' : userscandir = l.arg ; break ;
-        case 'p' : path = l.arg ; break ;
-        case 'E' : userenvdir = l.arg ; break ;
+        case 'd' : t.sc = l.arg ; break ;
+        case 'p' : t.path = l.arg ; break ;
+        case 'E' : t.userenvdir = l.arg ; break ;
         case 'e' :
-          if (varlen >= VARS_MAX) strerr_dief1x(100, "too many -v variables") ;
+          if (t.varlen >= VARS_MAX) strerr_dief1x(100, "too many -v variables") ;
           if (strchr(l.arg, '=')) strerr_dief2x(100, "invalid variable name: ", l.arg) ;
-          vars[varlen++] = l.arg ;
+          t.vars[t.varlen++] = l.arg ;
           break ;
         case 'r' : rcinfo[0] = (char *)l.arg ; break ;
         case 'l' : loguser = l.arg ; break ;
@@ -209,6 +162,7 @@ int main (int argc, char *const *argv)
         case 'n' : if (!uint0_scan(l.arg, &nfiles)) dieusage() ; break ;
         case 's' : if (!uint640_scan(l.arg, &filesize)) dieusage() ; break ;
         case 'S' : if (!uint640_scan(l.arg, &maxsize)) dieusage() ; break ;
+        case 'P' : prefix = l.arg ; break ;
         default : dieusage() ;
       }
     }
@@ -216,7 +170,7 @@ int main (int argc, char *const *argv)
   }
   if (argc < 3) dieusage() ;
   if (argv[1][0] != '/') strerr_dief1x(100, "logdir must be absolute") ;
-  if (userscandir[0] != '/' && !str_start(userscandir, "${HOME}/"))
+  if (t.sc[0] != '/' && !str_start(t.sc, "${HOME}/"))
     strerr_dief1x(100, "userscandir must be absolute or start with ${HOME}/") ;
   if (stamptype > 3) strerr_dief1x(100, "stamptype must be 0, 1, 2 or 3") ;
   if (rcinfo[0])
@@ -239,8 +193,7 @@ int main (int argc, char *const *argv)
       if (strchr(rcinfo[2], '/')) strerr_dief2x(100, "slashes", " are forbidden in s6-rc names") ;
     }
   }
-  m = umask(0) ;
-  mask = ~m & 0666 ;
+  t.user = argv[0] ;
   dirlen = strlen(argv[2]) ;
 
   if (rcinfo[0])
@@ -252,25 +205,19 @@ int main (int argc, char *const *argv)
     dir[dirlen] = '/' ;
     if (mkdir(argv[2], 0755) < 0 && errno != EEXIST)
       strerr_diefu2sys(111, "mkdir ", argv[2]) ;
+    t.logger = rcinfo[1] ;
     memcpy(dir + dirlen + 1, rcinfo[0], svclen + 1) ;
-    if (mkdir(dir, 0755) < 0) strerr_diefu2sys(111, "mkdir ", dir) ;
+    s6_auto_write_service(dir, 3, &write_run, &t, rcinfo[1]) ;
     memcpy(dir + dirlen + 1, rcinfo[1], loglen + 1) ;
-    if (mkdir(dir, 0755) < 0) strerr_diefu2sys(111, "mkdir ", dir) ;
-    umask(m) ;
-    write_logger(dir, loguser, argv[1], stamptype, nfiles, filesize, maxsize, rcinfo[0], rcinfo[2]) ;
-    memcpy(dir + dirlen + 1, rcinfo[0], svclen + 1) ;
-    write_service(dir, argv[0], userscandir, rcinfo[1], path, userenvdir, vars, varlen) ;
+    s6_auto_write_logger_tmp(dir, loguser, argv[1], stamptype, nfiles, filesize, maxsize, prefix, rcinfo[0], rcinfo[2], &sa) ;
   }
   else
   {
     char dir[dirlen + 5] ;
     memcpy(dir, argv[2], dirlen) ;
     memcpy(dir + dirlen, "/log", 5) ;
-    if (mkdir(argv[2], 0755) < 0) strerr_diefu2sys(111, "mkdir ", argv[2]) ;
-    if (mkdir(dir, 0755) < 0) strerr_diefu2sys(111, "mkdir ", argv[2]) ;
-    umask(m) ;
-    write_service(argv[2], argv[0], userscandir, 0, path, userenvdir, vars, varlen) ;
-    write_logger(dir, loguser, argv[1], stamptype, nfiles, filesize, maxsize, 0, 0) ;
+    s6_auto_write_service(argv[2], 3, &write_run, &t, 0) ;
+    s6_auto_write_logger_tmp(dir, loguser, argv[1], stamptype, nfiles, filesize, maxsize, prefix, 0, 0, &sa) ;
   }
   return 0 ;
 }