runit

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

runsvchdir.c (2185B)


      1 #include <sys/types.h>
      2 #include <sys/stat.h>
      3 #include <unistd.h>
      4 #include <stdio.h>
      5 #include "strerr.h"
      6 #include "error.h"
      7 #include "buffer.h"
      8 
      9 #define USAGE " dir"
     10 #define SVDIR "/etc/runit/runsvdir"
     11 
     12 static char *progname;
     13 static char *new;
     14 
     15 static void usage( void ) { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
     16 
     17 static void fatal(char *m1, char *m2)
     18 {
     19   strerr_die5sys(111, progname, ": fatal: ", m1, m2, ": ");
     20 }
     21 static void fatalx(char *m1, char *m2)
     22 {
     23   strerr_die4x(111, progname, ": fatal: ", m1, m2);
     24 }
     25 static void warn(char *m1, char *m2)
     26 {
     27   strerr_warn5(progname, ": fatal: ", m1, m2, ": ", &strerr_sys);
     28 }
     29 
     30 int main (int argc, char **argv)
     31 {
     32   struct stat s;
     33   int dev;
     34   int ino;
     35 
     36   progname =*argv++;
     37   if (! argv || ! *argv) usage();
     38 
     39   new =*argv;
     40   if (new[0] == '.') fatalx(new, ": must not start with a dot.");
     41   if (chdir(SVDIR) == -1) fatal("unable to chdir: ", SVDIR);
     42 
     43   if (stat(new, &s) == -1) {
     44     if (errno == error_noent) fatal(new, 0);
     45     fatal("unable to stat: ", new);
     46   }
     47   if (! S_ISDIR(s.st_mode)) fatalx(new, "not a directory.");
     48   ino =s.st_ino;
     49   dev =s.st_dev;
     50   if (stat("current", &s) == -1) fatal("unable to stat: ", "current");
     51   if ((s.st_ino == ino) && (s.st_dev == dev)) {
     52     buffer_puts(buffer_1, "runsvchdir: ");
     53     buffer_puts(buffer_1, new);
     54     buffer_puts(buffer_1, ": current.\n");
     55     buffer_flush(buffer_1);
     56     _exit(0);
     57   }
     58 
     59   if (unlink("current.new") == -1)
     60     if (errno != error_noent) fatal("unable to unlink: ", "current.new");
     61   if (symlink(new, "current.new") == -1)
     62     fatal("unable to create: current.new -> ", new);
     63   if (unlink("previous") == -1)
     64     if (errno != error_noent) fatal("unable to unlink: ", "previous");
     65   if (rename("current", "previous") == -1)
     66     fatal("unable to copy: current to ", "previous");
     67   if (rename("current.new", "current") == -1) {
     68     warn("unable to move: current.new to ", "current");
     69     if (rename("previous", "current") == -1)
     70       fatal("unable to move previous back to ", "current");
     71     _exit(111);
     72   }
     73   buffer_puts(buffer_1, "runsvchdir: ");
     74   buffer_puts(buffer_1, new);
     75   buffer_puts(buffer_1, ": now current.\n");
     76   buffer_flush(buffer_1);
     77   _exit(0);
     78 }