static int check(char *a) { unsigned pid; if ((r = svstatus_get()) == -1) return -1; if (r == 0) { if (*a == 'x') return 1; return -1; } pid = (unsigned char)svstatus[15]; pid <<= 8; pid += (unsigned char)svstatus[14]; pid <<= 8; pid += (unsigned char)svstatus[13]; pid <<= 8; pid += (unsigned char)svstatus[12]; switch (*a) { case 'x': return 0; case 'u': if (!pid || svstatus[19] != 1) return 0; if (!checkscript()) return 0; break; case 'd': if (pid) return 0; break; case 'c': if (pid) if (!checkscript()) return 0; break; case 't': if (!pid && svstatus[17] == 'd') break; tai_unpack(svstatus, &tstatus); if ((tstart.sec.x > tstatus.x) || !pid || svstatus[18] || !checkscript()) return 0; break; case 'o': tai_unpack(svstatus, &tstatus); if ((!pid && tstart.sec.x > tstatus.x) || (pid && svstatus[17] != 'd')) return 0; } printf(OK); svstatus_print(*service); puts(""); /* will also flush the output */ return 1; }
Datum tai_lte_pg(PG_FUNCTION_ARGS) { void *p1 = PG_GETARG_POINTER(0); void *p2 = PG_GETARG_POINTER(1); tai_t t1; tai_t t2; tai_unpack(&t1, p1); tai_unpack(&t2, p2); PG_RETURN_BOOL(tai_cmp(&t1, &t2) <= 0); }
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); } }
int leapsecs_read(void) { char fbuf[1024]; struct sstring sstr; struct stat sb; struct tai tai; struct tai *mem = 0; unsigned long size; unsigned long ind; int fd = -1; /* build path to leapsecs.dat */ sstring_init(&sstr, fbuf, sizeof (fbuf)); sstring_cats(&sstr, leapsecs_dir); if (sstr.len + sizeof("/leapsecs.dat") >= 1024) { errno = error_nametoolong; return -1; } sstring_cats(&sstr, "/leapsecs.dat"); sstring_0(&sstr); /* open leapsecs.dat */ fd = open_ro(sstr.s); if (fd == -1) { if (errno != error_noent) return -1; leapsecs_free(); return 0; } if (fstat(fd, &sb) == -1) goto FAIL; /* map and unpack packed tai structures */ mem = alloc(sb.st_size); if (!mem) goto FAIL; size = read(fd, mem, sb.st_size); if (size != (unsigned long) sb.st_size) { dealloc(mem); goto FAIL; } size = sb.st_size / sizeof(struct tai); for (ind = 0; ind < size; ++ind) { tai_unpack((unsigned char *) &mem[ind], &tai); mem[ind] = tai; } leapsecs_free(); leapsecs_list = (struct tai *) mem; leapsecs_size = size; if (fd != -1) close(fd); return 0; FAIL: if (fd != -1) close(fd); return -1; }
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); }
int check(char *a) { unsigned int pid; if ((r =svstatus_get()) == -1) return(-1); while (*a) { if (r == 0) { if (*a == 'x') return(1); return(-1); } pid =(unsigned char)svstatus[15]; pid <<=8; pid +=(unsigned char)svstatus[14]; pid <<=8; pid +=(unsigned char)svstatus[13]; pid <<=8; pid +=(unsigned char)svstatus[12]; switch (*a) { case 'x': return(0); case 'u': if (!pid || svstatus[19] != 1) return(0); if (!checkscript()) return(0); break; case 'd': if (pid || svstatus[19] != 0) return(0); break; case 'C': if (pid) if (!checkscript()) return(0); break; case 't': case 'k': if (!pid && svstatus[17] == 'd') break; tai_unpack(svstatus, &tstatus); if ((tstart.sec.x > tstatus.x) || !pid || svstatus[18] || !checkscript()) return(0); break; case 'o': tai_unpack(svstatus, &tstatus); if ((!pid && tstart.sec.x > tstatus.x) || (pid && svstatus[17] != 'd')) return(0); break; case 'p': if (pid && !svstatus[16]) return(0); break; case 'c': if (pid && svstatus[16]) return(0); break; } ++a; } outs(OK); svstatus_print(*service); flush("\n"); return(1); }
int main() { tai_t t = TAI_INIT; uint64_t x; char buf[TAI_PACK_SIZE]; tai_now(&t); x = t.sec; tai_pack(&buf[0], &t); tai_unpack(&t, &buf[0]); if (t.sec == x) return 0; return 1; }
void taia_unpack(struct taia *ta, const char *s) { unsigned long x; tai_unpack(&ta->sec, s); s += 8; x = (unsigned char)s[4]; x <<= 8; x += (unsigned char)s[5]; x <<= 8; x += (unsigned char)s[6]; x <<= 8; x += (unsigned char)s[7]; ta->atto = x; x = (unsigned char)s[0]; x <<= 8; x += (unsigned char)s[1]; x <<= 8; x += (unsigned char)s[2]; x <<= 8; x += (unsigned char)s[3]; ta->nano = x; }
void taia_unpack(const char * s, struct taia * t) { unsigned long x; tai_unpack(s, &t->sec); s += 8; x = (unsigned char)s[0]; x <<= 8; x += (unsigned char)s[1]; x <<= 8; x += (unsigned char)s[2]; x <<= 8; x += (unsigned char)s[3]; t->nano = x; }
void taia_unpack(const char *s, struct taia *t) { uint32_t x; tai_unpack(s, &t->sec); s += 8; x = (unsigned char) s[4]; x <<= 8; x += (unsigned char) s[5]; x <<= 8; x += (unsigned char) s[6]; x <<= 8; x += (unsigned char) s[7]; t->atto = x; x = (unsigned char) s[0]; x <<= 8; x += (unsigned char) s[1]; x <<= 8; x += (unsigned char) s[2]; x <<= 8; x += (unsigned char) s[3]; t->nano = x; }
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; } }
unsigned int svstatus_print(char *m) { int pid; int normallyup =0; struct stat s; if (stat("down", &s) == -1) { if (errno != error_noent) { outs2(WARN); outs2("unable to stat "); outs2(*service); outs2("/down: "); outs2(error_str(errno)); flush2("\n"); return(0); } normallyup =1; } pid =(unsigned char) svstatus[15]; pid <<=8; pid +=(unsigned char)svstatus[14]; pid <<=8; pid +=(unsigned char)svstatus[13]; pid <<=8; pid +=(unsigned char)svstatus[12]; tai_unpack(svstatus, &tstatus); switch (svstatus[19]) { case 0: outs(DOWN); break; case 1: outs(RUN); break; case 2: outs(FINISH); break; } outs(m); outs(": "); if (svstatus[19]) { outs("(pid "); sulong[fmt_ulong(sulong, pid)] =0; outs(sulong); outs(") "); } buffer_put(buffer_1, sulong, fmt_ulong(sulong, tnow.sec.x < tstatus.x ? 0 : tnow.sec.x -tstatus.x)); outs("s"); if (pid && !normallyup) outs(", normally down"); if (!pid && normallyup) outs(", normally up"); if (pid && svstatus[16]) outs(", paused"); if (!pid && (svstatus[17] == 'u')) outs(", want up"); if (pid && (svstatus[17] == 'd')) outs(", want down"); if (pid && svstatus[18]) outs(", got TERM"); return(pid ? 1 : 2); }
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); }
static unsigned svstatus_print(char *m) { int pid; int normallyup = 0; struct stat s; if (stat("down", &s) == -1) { if (errno != ENOENT) { bb_perror_msg(WARN"cannot stat %s/down", *service); return 0; } normallyup = 1; } pid = (unsigned char) svstatus[15]; pid <<= 8; pid += (unsigned char)svstatus[14]; pid <<= 8; pid += (unsigned char)svstatus[13]; pid <<= 8; pid += (unsigned char)svstatus[12]; tai_unpack(svstatus, &tstatus); if (pid) { switch (svstatus[19]) { case 1: printf(RUN); break; case 2: printf(FINISH); break; } printf("%s: (pid %d) ", m, pid); } else { printf(DOWN"%s: ", m); } printf("%lus", (unsigned long)(tnow.sec.x < tstatus.x ? 0 : tnow.sec.x-tstatus.x)); if (pid && !normallyup) printf(", normally down"); if (!pid && normallyup) printf(", normally up"); if (pid && svstatus[16]) printf(", paused"); if (!pid && (svstatus[17] == 'u')) printf(", want up"); if (pid && (svstatus[17] == 'd')) printf(", want down"); if (pid && svstatus[18]) printf(", got TERM"); return pid ? 1 : 2; }
int build (stralloc *sa, char *q, int flagsoa, char id[2]) { char ttl[4]; char ttd[8]; char type[2]; char misc[20]; char recordloc[2]; struct tai cutoff; unsigned int rdatapos = 0; dpos = 0; copy (type, 2); if (flagsoa) if (byte_diff (type, 2, DNS_T_SOA)) return 0; if (!flagsoa) if (byte_equal (type, 2, DNS_T_SOA)) return 0; if (!stralloc_copyb (sa, id, 2)) err (-1, "could not allocate enough memory"); if (!stralloc_catb (sa, "\204\000\0\0\0\1\0\0\0\0", 10)) err (-1, "could not allocate enough memory"); copy (misc, 1); if ((misc[0] == '=' + 1) || (misc[0] == '*' + 1)) { --misc[0]; copy (recordloc, 2); if (byte_diff (recordloc, 2, clientloc)) return 0; } if (misc[0] == '*') { if (flagsoa) return 0; if (!stralloc_catb (sa, "\1*", 2)) err (-1, "could not allocate enough memory"); } if (!stralloc_catb (sa, q, dns_domain_length (q))) err (-1, "could not allocate enough memory"); if (!stralloc_catb (sa, type, 2)) err (-1, "could not allocate enough memory"); copy (ttl, 4); copy (ttd, 8); if (byte_diff (ttd, 8, "\0\0\0\0\0\0\0\0")) { tai_unpack (ttd, &cutoff); if (byte_equal (ttl, 4, "\0\0\0\0")) { if (tai_less (&cutoff, &now)) return 0; uint32_pack_big (ttl, 2); } else if (!tai_less (&cutoff, &now)) return 0; } if (!stralloc_catb (sa, DNS_C_IN, 2)) err (-1, "could not allocate enough memory"); if (!stralloc_catb (sa, ttl, 4)) err (-1, "could not allocate enough memory"); if (!stralloc_catb(sa,"\0\0",2)) err (-1, "could not allocate enough memory"); rdatapos = sa->len; if (byte_equal (type, 2, DNS_T_SOA)) { doname (sa); doname (sa); copy (misc, 20); if (!stralloc_catb (sa, misc, 20)) err (-1, "could not allocate enough memory"); } else if (byte_equal (type, 2, DNS_T_NS) || byte_equal (type, 2, DNS_T_PTR) || byte_equal (type, 2, DNS_T_CNAME)) { doname (sa); } else if (byte_equal (type, 2, DNS_T_MX)) { copy (misc, 2); if (!stralloc_catb (sa, misc, 2)) err (-1, "could not allocate enough memory"); doname (sa); } else { if (!stralloc_catb (sa, data + dpos, dlen - dpos)) err (-1, "could not allocate enough memory"); } if (sa->len > 65535) errx (-1, "could not read from file `data.cdb': format error"); uint16_pack_big (sa->s + rdatapos - 2, sa->len - rdatapos); return 1; }
void tain_unpack (char const *s, tain_t *t) { tai_unpack(s, &t->sec) ; uint32_unpack_big(s+8, &t->nano) ; }
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"); }
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); }