chiark / gitweb /
client: Clean up variable declarations.
[tripe] / client / tripectl.c
index 133170475f5a9dd5095fc8767a7f21e54f8eed25..e2411afb304cf6b8776c2fbd0c96ef9f865dab20 100644 (file)
@@ -74,6 +74,7 @@
 
 /*----- Static variables --------------------------------------------------*/
 
+static sel_state sel;
 static const char *pidfile = 0;
 static const char *logname = 0;
 static FILE *logfp = 0;
@@ -318,6 +319,8 @@ Options in full:\n\
 \n\
 -D, --daemon           Become a background task after connecting.\n\
 -d, --directory=DIR    Select current directory [default " CONFIGDIR "].\n\
+-U, --setuid=USER      Set uid to USER after initialization.\n\
+-G, --setgid=GROUP     Set gid to GROUP after initialization.\n\
 -a, --admin-socket=FILE        Select socket to connect to\n\
                          [default " SOCKETDIR "/tripesock].\n\
 -P, --pidfile=FILE     Write process-id to FILE.\n\
@@ -340,6 +343,18 @@ int main(int argc, char *argv[])
   string_v spawnopts = DA_INIT;
   char *p;
   FILE *pidfp = 0;
+  int i;
+  size_t sz;
+  uid_t u = -1;
+  gid_t g = -1;
+  int pfd[2];
+  pid_t kid;
+  struct sigaction sa;
+  sigset_t newmask, oldmask;
+  struct sockaddr_un sun;
+  selbuf bu, bs;
+  dstr d = DSTR_INIT;
+  sig hup;
 
   ego(argv[0]);
 
@@ -356,6 +371,10 @@ int main(int argc, char *argv[])
       { "version",     0,              0,      'v' },
       { "usage",       0,              0,      'u' },
       { "daemon",      0,              0,      'D' },
+      { "uid",         OPTF_ARGREQ,    0,      'U' },
+      { "setuid",      OPTF_ARGREQ,    0,      'U' },
+      { "gid",         OPTF_ARGREQ,    0,      'G' },
+      { "setgid",      OPTF_ARGREQ,    0,      'G' },
       { "directory",   OPTF_ARGREQ,    0,      'd' },
       { "admin-socket",        OPTF_ARGREQ,    0,      'a' },
       { "spawn",       0,              0,      's' },
@@ -368,7 +387,7 @@ int main(int argc, char *argv[])
       { 0,             0,              0,      0 }
     };
 
-    int i = mdwopt(argc, argv, "+hvuDd:a:sp:S:lwf:nP:", opts, 0, 0, 0);
+    i = mdwopt(argc, argv, "+hvuDU:G:d:a:sp:S:lwf:nP:", opts, 0, 0, 0);
     if (i < 0)
       break;
     switch (i) {
@@ -384,6 +403,12 @@ int main(int argc, char *argv[])
       case 'D':
        f |= f_daemon | f_noinput;
        break;
+      case 'U':
+       u = u_getuser(optarg, &g);
+       break;
+      case 'G':
+       g = u_getgroup(optarg);
+       break;
       case 'd':
        dir = optarg;
        break;
@@ -439,6 +464,8 @@ int main(int argc, char *argv[])
     die(EXIT_FAILURE, "couldn't open `%s' for writing: %s",
        pidfile, strerror(errno));
   }
+  sel_init(&sel);
+  sig_init(&sel);
   signal(SIGINT, sigdie);
   signal(SIGQUIT, sigdie);
   signal(SIGTERM, sigdie);
@@ -447,11 +474,6 @@ int main(int argc, char *argv[])
   /* --- Connect to the server --- */
 
   if (f & f_spawn) {
-    int pfd[2];
-    pid_t kid;
-    struct sigaction sa;
-    sigset_t newmask, oldmask;
-
     sa.sa_handler = reap;
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = SA_NOCLDSTOP;
@@ -461,6 +483,8 @@ int main(int argc, char *argv[])
     sigaction(SIGCHLD, &sa, 0);
 
     DA_PUSH(&spawnopts, 0);
+    if (g != (gid_t)-1) putarg(&spawnopts, "-G%lu", (unsigned long)g);
+    if (u != (uid_t)-1) putarg(&spawnopts, "-U%lu", (unsigned long)u);
     putarg(&spawnopts, "-a%s", sock);
     putarg(&spawnopts, "-d.");
     putarg(&spawnopts, "-F");
@@ -488,8 +512,7 @@ int main(int argc, char *argv[])
     fd = pfd[0];
     close(pfd[1]);
   } else {
-    struct sockaddr_un sun;
-    size_t sz = strlen(sock) + 1;
+    sz = strlen(sock) + 1;
     if (sz > sizeof(sun.sun_path))
       die(EXIT_FAILURE, "socket name `%s' too long", sock);
     memset(&sun, 0, sizeof(sun));
@@ -504,6 +527,7 @@ int main(int argc, char *argv[])
     }
   }
 
+  u_setugid(u, g);
   if (f & f_daemon) {
     if (daemonize())
       die(EXIT_FAILURE, "error becoming daemon: %s", strerror(errno));
@@ -519,10 +543,6 @@ int main(int argc, char *argv[])
   if (optind == argc)
     setup("WATCH -A+tw");
   if (!(f & f_noinput) && optind == argc) {
-    sel_state sel;
-    selbuf bu, bs;
-
-    sel_init(&sel);
     selbuf_init(&bu, &sel, STDIN_FILENO, uline, &bu);
     selbuf_init(&bs, &sel, fd, sline, &bs);
     for (;;) {
@@ -534,7 +554,6 @@ int main(int argc, char *argv[])
   /* --- If there's a command, submit it --- */
 
   if (optind < argc) {
-    dstr d = DSTR_INIT;
     setup((f & f_warn) ? "WATCH -A+w" : "WATCH -A");
     while (optind < argc)
       u_quotify(&d, argv[optind++]);
@@ -548,24 +567,15 @@ int main(int argc, char *argv[])
 
   /* --- Pull everything else out of the box --- */
 
-  {
-    sel_state sel;
-    selbuf b;
-    sig hup;
+  selbuf_init(&bs, &sel, fd, cline, 0);
 
-    sel_init(&sel);
-    selbuf_init(&b, &sel, fd, cline, 0);
-
-    if (f & f_syslog)
-      openlog(QUIS, 0, LOG_DAEMON);
-    if (logfp) {
-      sig_init(&sel);
-      sig_add(&hup, SIGHUP, sighup, 0);
-    }
-    for (;;) {
-      if (sel_select(&sel) && errno != EINTR && errno != EAGAIN)
-       die(EXIT_FAILURE, "select failed: %s", strerror(errno));
-    }
+  if (f & f_syslog)
+    openlog(QUIS, 0, LOG_DAEMON);
+  if (logfp)
+    sig_add(&hup, SIGHUP, sighup, 0);
+  for (;;) {
+    if (sel_select(&sel) && errno != EINTR && errno != EAGAIN)
+      die(EXIT_FAILURE, "select failed: %s", strerror(errno));
   }
 
   return (0);