s6

Mirror/fork of https://skarnet.org/software/s6/
git clone https://ccx.te2000.cz/git/s6
Log | Files | Refs | README | LICENSE

s6-fdholder-daemon.c (4700B)


      1 /* ISC license. */
      2 
      3 #include <sys/types.h>
      4 #include <limits.h>
      5 
      6 #include <skalibs/types.h>
      7 #include <skalibs/sgetopt.h>
      8 #include <skalibs/strerr.h>
      9 #include <skalibs/exec.h>
     10 
     11 #include <s6/config.h>
     12 
     13 #define USAGE "s6-fdholder-daemon [ -v verbosity ] [ -d | -D ] [ -1 ] [ -c maxconn ] [ -n maxfds ] [ -b backlog ] [ -G gid,gid,... ] [ -g gid ] [ -u uid ] [ -U ] [ -t timeout ] [ -T lameducktimeout ] [ -i rulesdir | -x rulesfile ] path"
     14 #define dieusage() strerr_dieusage(100, USAGE)
     15 
     16 int main (int argc, char const *const *argv)
     17 {
     18   unsigned int verbosity = 1 ;
     19   int flag1 = 0 ;
     20   int flagU = 0 ;
     21   int flagreuse = 1 ;
     22   unsigned int uid = 0, gid = 0 ;
     23   gid_t gids[NGROUPS_MAX] ;
     24   size_t gidn = (size_t)-1 ;
     25   unsigned int maxconn = 0 ;
     26   unsigned int maxfds = 0 ;
     27   unsigned int backlog = (unsigned int)-1 ;
     28   unsigned int timeout = 0 ;
     29   unsigned int ltimeout = 0 ;
     30   char const *rulesdir = 0 ;
     31   char const *rulesfile = 0 ;
     32   PROG = "s6-fdholder-daemon" ;
     33   {
     34     subgetopt l = SUBGETOPT_ZERO ;
     35     for (;;)
     36     {
     37       int opt = subgetopt_r(argc, argv, "Dd1Uv:c:n:b:u:g:G:t:T:i:x:", &l) ;
     38       if (opt == -1) break ;
     39       switch (opt)
     40       {
     41         case 'D' : flagreuse = 0 ; break ;
     42         case 'd' : flagreuse = 1 ; break ;
     43         case '1' : flag1 = 1 ; break ;
     44         case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ;
     45         case 'c' : if (!uint0_scan(l.arg, &maxconn)) dieusage() ; if (!maxconn) maxconn = 1 ; break ;
     46         case 'n' : if (!uint0_scan(l.arg, &maxfds)) dieusage() ; if (!maxfds) maxfds = 1 ; break ;
     47         case 'b' : if (!uint0_scan(l.arg, &backlog)) dieusage() ; break ;
     48         case 'u' : if (!uint0_scan(l.arg, &uid)) dieusage() ; break ;
     49         case 'g' : if (!uint0_scan(l.arg, &gid)) dieusage() ; break ;
     50         case 'G' : if (!gid_scanlist(gids, NGROUPS_MAX, l.arg, &gidn) && *l.arg) dieusage() ; break ;
     51         case 'U' : flagU = 1 ; uid = 0 ; gid = 0 ; gidn = (size_t)-1 ; break ;
     52         case 't' : if (!uint0_scan(l.arg, &timeout)) dieusage() ; break ;
     53         case 'T' : if (!uint0_scan(l.arg, &ltimeout)) dieusage() ; break ;
     54         case 'i' : rulesdir = l.arg ; rulesfile = 0 ; break ;
     55         case 'x' : rulesfile = l.arg ; rulesdir = 0 ; break ;
     56         default : dieusage() ;
     57       }
     58     }
     59     argc -= l.ind ; argv += l.ind ;
     60     if (!argc) dieusage() ;
     61   }
     62   if (!rulesdir && !rulesfile) strerr_dief1x(100, "no access rights specified!") ;
     63  
     64   {
     65     size_t pos = 0 ;
     66     unsigned int m = 0 ;
     67     char const *newargv[30] ;
     68     char fmt[UINT_FMT * 8 + GID_FMT * NGROUPS_MAX] ;
     69     newargv[m++] = S6_BINPREFIX "s6-ipcserver-socketbinder" ;
     70     if (!flagreuse) newargv[m++] = "-D" ;
     71     if (backlog != (unsigned int)-1)
     72     {
     73       newargv[m++] = "-b" ;
     74       newargv[m++] = fmt + pos ;
     75       pos += uint_fmt(fmt + pos, backlog) ;
     76       fmt[pos++] = 0 ;
     77     }
     78     newargv[m++] = "--" ;
     79     newargv[m++] = *argv++ ;
     80     if (flagU || uid || gid || gidn != (size_t)-1)
     81     {
     82       newargv[m++] = S6_BINPREFIX "s6-applyuidgid" ;
     83       if (flagU) newargv[m++] = "-Uz" ;
     84       if (uid)
     85       {
     86         newargv[m++] = "-u" ;
     87         newargv[m++] = fmt + pos ;
     88         pos += uint_fmt(fmt + pos, uid) ;
     89         fmt[pos++] = 0 ;
     90       }
     91       if (gid)
     92       {
     93         newargv[m++] = "-g" ;
     94         newargv[m++] = fmt + pos ;
     95         pos += uint_fmt(fmt + pos, gid) ;
     96         fmt[pos++] = 0 ;
     97       }
     98       if (gidn != (size_t)-1)
     99       {
    100         newargv[m++] = "-G" ;
    101         newargv[m++] = fmt + pos ;
    102         pos += gid_fmtlist(fmt + pos, gids, gidn) ;
    103         fmt[pos++] = 0 ;
    104       }
    105       newargv[m++] = "--" ;
    106     }
    107     newargv[m++] = S6_BINPREFIX "s6-fdholderd" ;
    108     if (verbosity != 1)
    109     {
    110       newargv[m++] = "-v" ;
    111       newargv[m++] = fmt + pos ;
    112       pos += uint_fmt(fmt + pos, verbosity) ;
    113       fmt[pos++] = 0 ;
    114     }
    115     if (flag1) newargv[m++] = "-1" ;
    116     if (maxconn)
    117     {
    118       newargv[m++] = "-c" ;
    119       newargv[m++] = fmt + pos ;
    120       pos += uint_fmt(fmt + pos, maxconn) ;
    121       fmt[pos++] = 0 ;
    122     }
    123     if (maxfds)
    124     {
    125      newargv[m++] = "-n" ;
    126      newargv[m++] = fmt + pos ;
    127      pos += uint_fmt(fmt + pos, maxfds) ;
    128      fmt[pos++] = 0 ;
    129     }
    130     if (timeout)
    131     {
    132       newargv[m++] = "-t" ;
    133       newargv[m++] = fmt + pos ;
    134       pos += uint_fmt(fmt + pos, timeout) ;
    135       fmt[pos++] = 0 ;
    136     }
    137     if (ltimeout)
    138     {
    139       newargv[m++] = "-T" ;
    140       newargv[m++] = fmt + pos ;
    141       pos += uint_fmt(fmt + pos, ltimeout) ;
    142       fmt[pos++] = 0 ;
    143     }
    144     if (rulesdir)
    145     {
    146       newargv[m++] = "-i" ;
    147       newargv[m++] = rulesdir ;
    148     }
    149     else if (rulesfile)
    150     {
    151       newargv[m++] = "-x" ;
    152       newargv[m++] = rulesfile ;
    153     }
    154     newargv[m++] = 0 ;
    155     xexec(newargv) ;
    156   }
    157 }