static void showstatus(const char status[19], int r) { const char *x; struct tai when; struct tai now; pid = (unsigned char) status[15]; pid <<= 8; pid += (unsigned char) status[14]; pid <<= 8; pid += (unsigned char) status[13]; pid <<= 8; pid += (unsigned char) status[12]; paused = status[16]; want = status[17]; statusflag = status[18]; tai_unpack(status,&when); tai_now(&now); if (tai_less(&now,&when)) when = now; tai_sub(&when,&now,&when); if (pid) { buffer_puts(&b,"up (pid "); buffer_put(&b,strnum,fmt_ulong(strnum,pid)); buffer_puts(&b,") "); } else buffer_puts(&b,"down "); buffer_put(&b,strnum,fmt_ulong(strnum,tai_approx(&when))); buffer_puts(&b," seconds"); if (pid && !normallyup) buffer_puts(&b,", normally down"); if (!pid && normallyup) buffer_puts(&b,", normally up"); if (pid && paused) buffer_puts(&b,", paused"); if (!pid && (want == 'u')) buffer_puts(&b,", want up"); if (pid && (want == 'd')) buffer_puts(&b,", want down"); if (r > 18) { switch (statusflag) { case svstatus_stopped: x = ", stopped"; break; case svstatus_starting: x = ", starting"; break; case svstatus_started: x = ", started"; break; case svstatus_running: x = ", running"; break; case svstatus_stopping: x = ", stopping"; break; case svstatus_failed: x=", failed"; break; default: x = ", status unknown"; } if (x) buffer_puts(&b,x); } }
int32_t leapsecs_sub(struct tai *lt) { #ifndef DISABLE_LEAPS char out[101],x[TAI_PACK]; double packerr; int32_t weekday,yearday,i,j,s; uint64_t u; struct tai t,t2; struct taitime ct2; if ( leaptais[0].x == 0 ) { for (i=0; i<sizeof(leapseconds)/sizeof(*leapseconds); i++) { t = taidate_scan(leapseconds[i],i); if ( t.x == 0 ) printf("unable to parse.(%s)\n",leapseconds[i]); else { //t = taitime2tai(ct); leaptais[i] = t; ct2 = tai2time(t,&weekday,&yearday); tai_pack(x,&t); tai_unpack(x,&t2); tai_sub(&t2,&t2,&t); packerr = tai_approx(&t2); for (j=0; j<TAI_PACK; j++) printf("%2.2x",(uint32_t)(uint8_t)x[j]); if ( packerr != 0 ) printf(" packerr=%f",packerr); taitime_str(out,ct2); printf(" %03d %s %s",yearday,dayname[weekday],out); printf("\n"); } } } u = lt->x; if ( u > leaptais[sizeof(leaptais)/sizeof(*leaptais)-1].x ) lt->x -= (sizeof(leaptais)/sizeof(*leaptais) - 1); else { s = 0; for (i=0; i<sizeof(leaptais)/sizeof(*leaptais); i++) { if ( u < leaptais[i].x ) break; ++s; if ( u == leaptais[i].x ) { lt->x = u - s; return(1); } } lt->x = u - s; } #endif return(0); }
static int find(char *d,int flagwild) { int r; char ch; struct tai cutoff; char ttd[8]; char ttlstr[4]; char recordloc[2]; double newttl; for (;;) { r = cdb_findnext(&c,d,dns_domain_length(d)); if (r <= 0) return r; dlen = cdb_datalen(&c); if (dlen > sizeof data) return -1; if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return -1; dpos = dns_packet_copy(data,dlen,0,type,2); if (!dpos) return -1; dpos = dns_packet_copy(data,dlen,dpos,&ch,1); if (!dpos) return -1; if ((ch == '=' + 1) || (ch == '*' + 1)) { --ch; dpos = dns_packet_copy(data,dlen,dpos,recordloc,2); if (!dpos) return -1; if (byte_diff(recordloc,2,clientloc)) continue; } if (flagwild != (ch == '*')) continue; dpos = dns_packet_copy(data,dlen,dpos,ttlstr,4); if (!dpos) return -1; uint32_unpack_big(ttlstr,&ttl); dpos = dns_packet_copy(data,dlen,dpos,ttd,8); if (!dpos) return -1; if (byte_diff(ttd,8,"\0\0\0\0\0\0\0\0")) { tai_unpack(ttd,&cutoff); if (ttl == 0) { if (tai_less(&cutoff,&now)) continue; tai_sub(&cutoff,&cutoff,&now); newttl = tai_approx(&cutoff); if (newttl <= 2.0) newttl = 2.0; if (newttl >= 3600.0) newttl = 3600.0; ttl = newttl; } else if (!tai_less(&cutoff,&now)) continue; } return 1; } }
main() { struct tai t; struct tai t2; struct caltime ct; struct caltime ct2; int weekday; int yearday; int i; double packerr; if (leapsecs_init() == -1) printf("unable to init leapsecs\n"); while (fgets(line,sizeof line,stdin)) if (!caltime_scan(line,&ct)) printf("unable to parse\n"); else { caltime_tai(&ct,&t); caltime_utc(&ct2,&t,&weekday,&yearday); tai_pack(x,&t); tai_unpack(x,&t2); tai_sub(&t2,&t2,&t); packerr = tai_approx(&t2); for (i = 0;i < TAI_PACK;++i) printf("%2.2x",(unsigned long) (unsigned char) x[i]); if (packerr) printf(" packerr=%f",packerr); printf(" %03d %s",yearday,dayname[weekday]); if (caltime_fmt((char *) 0,&ct2) + 1 < sizeof out) { out[caltime_fmt(out,&ct2)] = 0; printf(" %s",out); } printf("\n"); } return(0); }
void handle(char *path) { struct taia now; char pid_str[FMT_ULONG_MAX + 1]; int r; struct sv_stat svst; char timestamp_str[FMT_ULONG_MAX + 1]; bio_put_str(bio_1, path); bio_put_str(bio_1, ": "); r = sv_stat(&svst, path); if (r == -1) { switch (errno) { case ESVSTATDOWN: bio_put_str(bio_1, "unable to stat down: "); bio_put_str(bio_1, strerr_sys.x); break; case ESVNOTRUN: bio_put_str(bio_1, "supervise not running"); break; case ESVOPENOK: bio_put_str(bio_1, "unable to open " SUPERVISE_OK_PATH ": "); bio_put_str(bio_1, strerr_sys.x); break; case ESVOPENSTAT: bio_put_str(bio_1, "unable to open " SUPERVISE_STATUS_PATH ": "); bio_put_str(bio_1, strerr_sys.x); break; case ESVREADSTAT: bio_put_str(bio_1, "unable to read " SUPERVISE_STATUS_PATH ": "); bio_put_str(bio_1, strerr_sys.x); break; case ESVINVALSTAT: bio_put_str(bio_1, "unable to read " SUPERVISE_STATUS_PATH ": bad format"); break; default: bio_put_str(bio_1, "unknown error"); break; } return; } /* Print out the services status information. */ if (svst.pid) { pid_str[fmt_ulong(pid_str, svst.pid)] = 0; bio_put_str(bio_1, "up (pid "); bio_put_str(bio_1, pid_str); bio_put_str(bio_1, ") "); } else bio_put_str(bio_1, "down "); taia_now(&now); taia_sub(&now, &now, &svst.timestamp); timestamp_str[fmt_ulong(timestamp_str, tai_approx(&now))] = 0; bio_put_str(bio_1, timestamp_str); bio_put_str(bio_1, " seconds"); if (svst.pid && !svst.autostart) bio_put_str(bio_1, ", normally down"); if (!svst.pid && svst.autostart) bio_put_str(bio_1, ", normally up"); if (svst.pid && svst.paused) bio_put_str(bio_1, ", paused"); if (!svst.pid && (svst.mode == 'u')) bio_put_str(bio_1, ", want up"); if (svst.pid && (svst.mode == 'd')) bio_put_str(bio_1, ", want down"); }
double taia_approx(const struct taia *t) { return tai_approx(&t->sec) + taia_frac(t); }
int main(int argc, const char * const *argv) { int opt; unsigned long sec =600; int verbose =0; int doexit =0; int dokill =0; int wdir; int fd; char status[20]; int r; unsigned long pid; struct tai start; struct tai now; progname =*argv; while ((opt =getopt(argc, argv, "t:xkvV")) != opteof) { switch(opt) { case 't': scan_ulong(optarg, &sec); if ((sec < 1) || (sec > 6000)) usage(); break; case 'x': doexit =1; break; case 'k': dokill =1; break; case 'v': verbose =1; break; case 'V': strerr_warn1(VERSION, 0); case '?': usage(); } } argv +=optind; if (! argv || ! *argv) usage(); if ((wdir =open_read(".")) == -1) fatal("unable to open current working directory"); for (dir =argv; *dir; ++dir) { if (dir != argv) if (fchdir(wdir) == -1) fatal("unable to switch to starting directory"); if (chdir(*dir) == -1) continue; /* bummer */ if ((fd =open_write("supervise/control")) == -1) continue; /* bummer */ if (write(fd, "dx", 1 +doexit) != (1 +doexit)) { close(fd); continue; /* bummer */ } close(fd); } dir =argv; tai_now(&start); while (*dir) { if (fchdir(wdir) == -1) fatal("unable to switch to starting directory"); if (chdir(*dir) == -1) { warn(*dir, ": unable to change directory: ", &strerr_sys); continue; } if ((fd =open_write("supervise/ok")) == -1) { if (errno == error_nodevice) { if (verbose) strerr_warn3(INFO, *dir, ": runsv not running.", 0); dir++; } else warn(*dir, ": unable to open supervise/ok: ", &strerr_sys); continue; } close(fd); if ((fd =open_read("supervise/status")) == -1) { warn(*dir, "unable to open supervise/status: ", &strerr_sys); continue; } r =buffer_unixread(fd, status, 20); close(fd); if ((r < 18) || (r == 19)) { /* supervise compatibility */ if (r == -1) warn(*dir, "unable to read supervise/status: ", &strerr_sys); else warn(*dir, ": unable to read supervise/status: bad format.", 0); continue; } pid =(unsigned char)status[15]; pid <<=8; pid +=(unsigned char)status[14]; pid <<=8; pid +=(unsigned char)status[13]; pid <<=8; pid +=(unsigned char)status[12]; if (! doexit && ! pid) { /* ok, service is down */ if (verbose) strerr_warn3(INFO, *dir, ": down.", 0); dir++; continue; } if (status[17] != 'd') { /* catch previous failures */ if ((fd =open_write("supervise/control")) == -1) { warn(*dir, ": unable to open supervise/control: ", &strerr_sys); continue; } if (write(fd, "dx", 1 +doexit) != (1 +doexit)) { warn(*dir, ": unable to write to supervise/control: ", &strerr_sys); close(fd); continue; } close(fd); } tai_now(&now); tai_sub(&now, &now, &start); if (tai_approx(&now) >= sec) { /* timeout */ if (verbose) strerr_warn2(INFO, "timeout.", 0); if (dokill) { if (chdir(*dir) == -1) { warn(*dir, ": unable to change directory: ", &strerr_sys); continue; } if ((fd =open_write("supervise/control")) == -1) { if (errno == error_nodevice) { if (verbose) strerr_warn3(INFO, *dir, ": runsv not running.", 0); dir++; } else warn(*argv, ": unable to open supervise/control: ", &strerr_sys); continue; } if (write(fd, "k", 1) != 1) warn(*argv, ": unable to write to supervise/control: ", &strerr_sys); else strerr_warn3(INFO, *dir, ": killed.", 0); close(fd); dir++; if (! *dir) _exit(111); continue; } _exit(111); } sleep(1); } if (fchdir(wdir) == -1) strerr_warn2(WARN, "unable to switch to starting directory: ", &strerr_sys); close(wdir); if (rc > 100) rc =100; _exit(rc); }
int main(int argc, const char * const *argv) { int opt; int verbose =0; char status[18]; int fd; int is; int r; int wdir; unsigned long pid; struct tai when; struct tai now; char sulong[FMT_ULONG]; progname =*argv; while ((opt =getopt(argc, argv, "s:vV")) != opteof) { switch(opt) { case 's': scan_ulong(optarg, &sec); if ((sec < 1) || (sec > 600)) usage(); break; case 'v': verbose =1; break; case 'V': strerr_warn1("$Id: e2d6c574c5e56f9931323fbc0e539c7f9b829b73 $", 0); case '?': usage(); } } argv +=optind; if (! argv || ! *argv) usage(); if ((wdir =open_read(".")) == -1) fatal("unable to open current working directory"); dir =argv; while (*dir) { if (dir != argv) if (fchdir(wdir) == -1) fatal("unable to switch to starting directory"); if (chdir(*dir) == -1) { warn(*dir, ": unable to change directory: ", &strerr_sys); continue; } if ((fd =open_write("supervise/ok")) == -1) { if (errno == error_nodevice) warn(*dir, ": runsv not running.", 0); else warn(*dir, ": unable to open supervise/ok: ", &strerr_sys); continue; } close(fd); if ((fd =open_read("supervise/status")) == -1) { warn(*dir, "unable to open supervise/status: ", &strerr_sys); continue; } r =buffer_unixread(fd, status, sizeof status); close(fd); if (r < sizeof status) { if (r == -1) warn(*dir, "unable to read supervise/status: ", &strerr_sys); else warn(*dir, ": unable to read supervise/status: bad format.", 0); continue; } pid =(unsigned char)status[15]; pid <<=8; pid +=(unsigned char)status[14]; pid <<=8; pid +=(unsigned char)status[13]; pid <<=8; pid +=(unsigned char)status[12]; if (! pid) { warn(*dir, ": is down.", 0); continue; } tai_unpack(status, &when); tai_now(&now); if (tai_less(&now, &when)) when =now; tai_sub(&when, &now, &when); is =tai_approx(&when); if (is >= sec) { /* ok */ if (verbose) { sulong[fmt_ulong(sulong, is)] =0; strerr_warn5(INFO, *dir, ": is up (", sulong, " seconds)", 0); } dir++; continue; } sleep(sec -is); } if (fchdir(wdir) == -1) strerr_warn2(WARN, "unable to switch to starting directory: ", &strerr_sys); close(wdir); if (rc > 100) rc =100; _exit(rc); }
void doit(char *dir) { struct stat st; int r; int fd; const char *x; struct tai when; struct tai now; buffer_puts(&b,dir); buffer_puts(&b,": "); if (chdir(dir) == -1) { x = error_str(errno); buffer_puts(&b,"unable to chdir: "); buffer_puts(&b,x); return; } normallyup = 0; if (stat("down",&st) == -1) { if (errno != error_noent) { x = error_str(errno); buffer_puts(&b,"unable to stat down: "); buffer_puts(&b,x); return; } normallyup = 1; } fd = open_write("supervise/ok"); if (fd == -1) { if (errno == error_nodevice) { buffer_puts(&b,"supervise not running"); return; } x = error_str(errno); buffer_puts(&b,"unable to open supervise/ok: "); buffer_puts(&b,x); return; } close(fd); fd = open_read("supervise/status"); if (fd == -1) { x = error_str(errno); buffer_puts(&b,"unable to open supervise/status: "); buffer_puts(&b,x); return; } r = buffer_unixread(fd,status,sizeof status); close(fd); if (r < sizeof status) { if (r == -1) x = error_str(errno); else x = "bad format"; buffer_puts(&b,"unable to read supervise/status: "); buffer_puts(&b,x); return; } pid = (unsigned char) status[15]; pid <<= 8; pid += (unsigned char) status[14]; pid <<= 8; pid += (unsigned char) status[13]; pid <<= 8; pid += (unsigned char) status[12]; paused = status[16]; want = status[17]; tai_unpack(status,&when); tai_now(&now); if (tai_less(&now,&when)) when = now; tai_sub(&when,&now,&when); if (pid) { buffer_puts(&b,"up (pid "); buffer_put(&b,strnum,fmt_ulong(strnum,pid)); buffer_puts(&b,") "); } else buffer_puts(&b,"down "); buffer_put(&b,strnum,fmt_ulong(strnum,tai_approx(&when))); buffer_puts(&b," seconds"); if (pid && !normallyup) buffer_puts(&b,", normally down"); if (!pid && normallyup) buffer_puts(&b,", normally up"); if (pid && paused) buffer_puts(&b,", paused"); if (!pid && (want == 'u')) buffer_puts(&b,", want up"); if (pid && (want == 'd')) buffer_puts(&b,", want down"); }
double tain_approx (tain_t const *t) { return tai_approx(&t->sec) + tain_frac(t) ; }