s6

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

s6-ipcserver.c (4310B)


      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-ipcserver [ -q | -Q | -v ] [ -d | -D ] [ -P | -p ] [ -1 ] [ -c maxconn ] [ -C localmaxconn ] [ -b backlog ] [ -a socketperms ] [ -G gid,gid,... ] [ -g gid ] [ -u uid ] [ -U ] path prog..."
     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 flaglookup = 1 ;
     22   int flagreuse = 1 ;
     23   uid_t uid = 0 ;
     24   gid_t gid = 0 ;
     25   gid_t gids[NGROUPS_MAX] ;
     26   size_t gidn = (size_t)-1 ;
     27   unsigned int maxconn = 0 ;
     28   unsigned int localmaxconn = 0 ;
     29   unsigned int backlog = (unsigned int)-1 ;
     30   unsigned int socketperms = 0777 ;
     31   PROG = "s6-ipcserver" ;
     32   {
     33     subgetopt l = SUBGETOPT_ZERO ;
     34     for (;;)
     35     {
     36       int opt = subgetopt_r(argc, argv, "qQvDd1UPpc:C:b:a:u:g:G:", &l) ;
     37       if (opt == -1) break ;
     38       switch (opt)
     39       {
     40         case 'q' : verbosity = 0 ; break ;
     41         case 'Q' : verbosity = 1 ; break ;
     42         case 'v' : verbosity = 2 ; break ;
     43         case 'D' : flagreuse = 0 ; break ;
     44         case 'd' : flagreuse = 1 ; break ;
     45         case 'P' : flaglookup = 0 ; break ;
     46         case 'p' : flaglookup = 1 ; break ;
     47         case 'c' : if (!uint0_scan(l.arg, &maxconn)) dieusage() ; if (!maxconn) maxconn = 1 ; break ;
     48         case 'C' : if (!uint0_scan(l.arg, &localmaxconn)) dieusage() ; if (!localmaxconn) localmaxconn = 1 ; break ;
     49         case 'b' : if (!uint0_scan(l.arg, &backlog)) dieusage() ; break ;
     50         case 'a' : if (!uint0_oscan(l.arg, &socketperms)) dieusage() ; break ;
     51         case 'u' : if (!uid0_scan(l.arg, &uid)) dieusage() ; break ;
     52         case 'g' : if (!gid0_scan(l.arg, &gid)) dieusage() ; break ;
     53         case 'G' : if (!gid_scanlist(gids, NGROUPS_MAX, l.arg, &gidn) && *l.arg) dieusage() ; break ;
     54         case '1' : flag1 = 1 ; break ;
     55         case 'U' : flagU = 1 ; uid = 0 ; gid = 0 ; gidn = (size_t)-1 ; break ;
     56         default : dieusage() ;
     57       }
     58     }
     59     argc -= l.ind ; argv += l.ind ;
     60     if (argc < 2) dieusage() ;
     61   }
     62 
     63   {
     64     size_t pos = 0 ;
     65     unsigned int m = 0 ;
     66     char fmt[UINT_FMT * 3 + 5 + UID_FMT + GID_FMT * (NGROUPS_MAX+1)] ;
     67     char const *newargv[26 + argc] ;
     68     newargv[m++] = S6_BINPREFIX "s6-ipcserver-socketbinder" ;
     69     if (!flagreuse) newargv[m++] = "-D" ;
     70     if (backlog != (unsigned int)-1)
     71     {
     72       if (!backlog) backlog = 1 ;
     73       newargv[m++] = "-b" ;
     74       newargv[m++] = fmt + pos ;
     75       pos += uint_fmt(fmt + pos, backlog) ;
     76       fmt[pos++] = 0 ;
     77     }
     78     if (socketperms != 0777)
     79     {
     80       newargv[m++] = "-a" ;
     81       newargv[m++] = fmt + pos ;
     82       fmt[pos++] = '0' ;
     83       pos += uint_ofmt(fmt + pos, socketperms & 0777) ;
     84       fmt[pos++] = 0 ;
     85     }
     86     newargv[m++] = "--" ;
     87     newargv[m++] = *argv++ ;
     88     if (flagU || uid || gid || gidn != (size_t)-1)
     89     {
     90       newargv[m++] = S6_BINPREFIX "s6-applyuidgid" ;
     91       if (flagU) newargv[m++] = "-Uz" ;
     92       if (uid)
     93       {
     94         newargv[m++] = "-u" ;
     95         newargv[m++] = fmt + pos ;
     96         pos += uid_fmt(fmt + pos, uid) ;
     97         fmt[pos++] = 0 ;
     98       }
     99       if (gid)
    100       {
    101         newargv[m++] = "-g" ;
    102         newargv[m++] = fmt + pos ;
    103         pos += gid_fmt(fmt + pos, gid) ;
    104         fmt[pos++] = 0 ;
    105       }
    106       if (gidn != (size_t)-1)
    107       {
    108         newargv[m++] = "-G" ;
    109         newargv[m++] = fmt + pos ;
    110         pos += gid_fmtlist(fmt + pos, gids, gidn) ;
    111         fmt[pos++] = 0 ;
    112       }
    113       newargv[m++] = "--" ;
    114     }
    115     newargv[m++] = S6_BINPREFIX "s6-ipcserverd" ;
    116     if (!verbosity) newargv[m++] = "-v0" ;
    117     else if (verbosity == 2) newargv[m++] = "-v2" ;
    118     if (flag1) newargv[m++] = "-1" ;
    119     if (!flaglookup) newargv[m++] = "-P" ;
    120     if (maxconn)
    121     {
    122       newargv[m++] = "-c" ;
    123       newargv[m++] = fmt + pos ;
    124       pos += uint_fmt(fmt + pos, maxconn) ;
    125       fmt[pos++] = 0 ;
    126     }
    127     if (localmaxconn)
    128     {
    129       newargv[m++] = "-C" ;
    130       newargv[m++] = fmt + pos ;
    131       pos += uint_fmt(fmt + pos, localmaxconn) ;
    132       fmt[pos++] = 0 ;
    133     }
    134     newargv[m++] = "--" ;
    135     while (*argv) newargv[m++] = *argv++ ;
    136     newargv[m++] = 0 ;
    137     xexec(newargv) ;
    138   }
    139 }