1 #include <unistd.h>
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include "strerr.h"
5 #include "error.h"
6 #include "open.h"
7 #include "fmt.h"
8 #include "tai.h"
9 #include "buffer.h"
10 
11 #define FATAL "svstat: fatal: "
12 #define WARNING "svstat: warning: "
13 
14 char bspace[1024];
15 buffer b = BUFFER_INIT(buffer_unixwrite,1,bspace,sizeof bspace);
16 
17 char status[18];
18 char strnum[FMT_ULONG];
19 
20 unsigned long pid;
21 unsigned char normallyup;
22 unsigned char want;
23 unsigned char paused;
24 
doit(char * dir)25 void doit(char *dir)
26 {
27   struct stat st;
28   int r;
29   int fd;
30   const char *x;
31   struct tai when;
32   struct tai now;
33 
34   buffer_puts(&b,dir);
35   buffer_puts(&b,": ");
36 
37   if (chdir(dir) == -1) {
38     x = error_str(errno);
39     buffer_puts(&b,"unable to chdir: ");
40     buffer_puts(&b,x);
41     return;
42   }
43 
44   normallyup = 0;
45   if (stat("down",&st) == -1) {
46     if (errno != error_noent) {
47       x = error_str(errno);
48       buffer_puts(&b,"unable to stat down: ");
49       buffer_puts(&b,x);
50       return;
51     }
52     normallyup = 1;
53   }
54 
55   fd = open_write("supervise/ok");
56   if (fd == -1) {
57     if (errno == error_nodevice) {
58       buffer_puts(&b,"supervise not running");
59       return;
60     }
61     x = error_str(errno);
62     buffer_puts(&b,"unable to open supervise/ok: ");
63     buffer_puts(&b,x);
64     return;
65   }
66   close(fd);
67 
68   fd = open_read("supervise/status");
69   if (fd == -1) {
70     x = error_str(errno);
71     buffer_puts(&b,"unable to open supervise/status: ");
72     buffer_puts(&b,x);
73     return;
74   }
75   r = buffer_unixread(fd,status,sizeof status);
76   close(fd);
77   if (r < sizeof status) {
78     if (r == -1)
79       x = error_str(errno);
80     else
81       x = "bad format";
82     buffer_puts(&b,"unable to read supervise/status: ");
83     buffer_puts(&b,x);
84     return;
85   }
86 
87   pid = (unsigned char) status[15];
88   pid <<= 8; pid += (unsigned char) status[14];
89   pid <<= 8; pid += (unsigned char) status[13];
90   pid <<= 8; pid += (unsigned char) status[12];
91 
92   paused = status[16];
93   want = status[17];
94 
95   tai_unpack(status,&when);
96   tai_now(&now);
97   if (tai_less(&now,&when)) when = now;
98   tai_sub(&when,&now,&when);
99 
100   if (pid) {
101     buffer_puts(&b,"up (pid ");
102     buffer_put(&b,strnum,fmt_ulong(strnum,pid));
103     buffer_puts(&b,") ");
104   }
105   else
106     buffer_puts(&b,"down ");
107 
108   buffer_put(&b,strnum,fmt_ulong(strnum,tai_approx(&when)));
109   buffer_puts(&b," seconds");
110 
111   if (pid && !normallyup)
112     buffer_puts(&b,", normally down");
113   if (!pid && normallyup)
114     buffer_puts(&b,", normally up");
115   if (pid && paused)
116     buffer_puts(&b,", paused");
117   if (!pid && (want == 'u'))
118     buffer_puts(&b,", want up");
119   if (pid && (want == 'd'))
120     buffer_puts(&b,", want down");
121 }
122 
main(int argc,char ** argv)123 int main(int argc,char **argv)
124 {
125   int fdorigdir;
126   char *dir;
127 
128   ++argv;
129 
130   fdorigdir = open_read(".");
131   if (fdorigdir == -1)
132     strerr_die2sys(111,FATAL,"unable to open current directory: ");
133 
134   while (dir = *argv++) {
135     doit(dir);
136     buffer_puts(&b,"\n");
137     if (fchdir(fdorigdir) == -1)
138       strerr_die2sys(111,FATAL,"unable to set directory: ");
139   }
140 
141   buffer_flush(&b);
142 
143   _exit(0);
144 }
145