s6

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

s6-instance-status.c (2582B)


      1 /* ISC license. */
      2 
      3 #include <string.h>
      4 
      5 #include <skalibs/bytestr.h>
      6 #include <skalibs/strerr.h>
      7 #include <skalibs/sgetopt.h>
      8 #include <skalibs/exec.h>
      9 
     10 #include <s6/config.h>
     11 
     12 #define USAGE "s6-instance-status [ -uwNrpest | -o up,wantedup,normallyup,ready,paused,pid,exitcode,signal,signum,updownsince,readysince,updownfor,readyfor ] [ -n ] service name"
     13 #define dieusage() strerr_dieusage(100, USAGE)
     14 
     15 #define MAXFIELDS 16
     16 #define checkfields() if (n++ >= MAXFIELDS) strerr_dief1x(100, "too many option fields")
     17 
     18 static unsigned int check_options (char const *arg, unsigned int n)
     19 {
     20   static char const *table[] =
     21   {
     22     "up",
     23     "wantedup",
     24     "normallyup",
     25     "ready",
     26     "paused",
     27     "pid",
     28     "exitcode",
     29     "signal",
     30     "signum",
     31     "updownsince",
     32     "readysince",
     33     "updownfor",
     34     "readyfor",
     35     0
     36   } ;
     37   while (*arg)
     38   {
     39     size_t pos = str_chr(arg, ',') ;
     40     char const *const *p = table ;
     41     if (!pos) strerr_dief1x(100, "invalid null option field") ;
     42     for (; *p ; p++) if (!strncmp(arg, *p, pos)) break ;
     43     if (!p)
     44     {
     45       char blah[pos+1] ;
     46       memcpy(blah, arg, pos) ;
     47       blah[pos] = 0 ;
     48       strerr_dief2x(100, "invalid option field: ", blah) ;
     49     }
     50     checkfields() ;
     51     arg += pos ; if (*arg) arg++ ;
     52   }
     53   return n ;
     54 }
     55 
     56 int main (int argc, char const **argv)
     57 {
     58   char const **fullargv = argv ;
     59   size_t namelen ;
     60   unsigned int n = 0 ;
     61   PROG = "s6-instance-status" ;
     62   {
     63     subgetopt l = SUBGETOPT_ZERO ;
     64     for (;;)
     65     {
     66       int opt = subgetopt_r(argc, argv, "no:uwNrpest", &l) ;
     67       if (opt == -1) break ;
     68       switch (opt)
     69       {
     70         case 'n' : break ;
     71         case 'o' : n = check_options(l.arg, n) ; break ;
     72         case 'u' :
     73         case 'w' :
     74         case 'N' :
     75         case 'r' :
     76         case 'p' :
     77         case 'e' :
     78         case 's' :
     79         case 't' : if (n++ >= MAXFIELDS) strerr_dief1x(100, "too many option fields") ; break ;
     80         default : dieusage() ;
     81       }
     82     }
     83     argc -= l.ind ; argv += l.ind ;
     84   }
     85   if (argc < 2) dieusage() ;
     86   namelen = strlen(argv[1]) ;
     87   if (!argv[0][0]) strerr_dief1x(100, "invalid service name") ;
     88   if (!argv[1][0] || argv[1][0] == '.' || byte_in(argv[1], namelen, " \t\f\r\n", 5) < namelen)
     89     strerr_dief1x(100, "invalid instance name") ;
     90 
     91   {
     92     size_t svlen = strlen(argv[0]) ;
     93     char fn[svlen + 11 + namelen] ;
     94     memcpy(fn, argv[0], svlen) ;
     95     memcpy(fn + svlen, "/instance/", 10) ;
     96     memcpy(fn + svlen + 10, argv[1], namelen + 1) ;
     97     argv[0] = fn ;
     98     argv[1] = 0 ;
     99     fullargv[0] = S6_BINPREFIX "s6-svstat" ;
    100     xexec(fullargv) ;
    101   }
    102 }