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; } }
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); } }
/* Some versions of ls also fail to show the year for future dates. */ static long guess_year(unsigned long month,unsigned long day) { static long this_year; static struct tai yearstart; struct tai x; struct tai now; tai_now(&now); if (!this_year) { struct tai n; tai_now(&n); this_year=1970; while (1) { utcdate2tai(&yearstart,this_year+1,0,1,0,0,0); if (tai_less(&n,&yearstart)) break; this_year++; } } utcdate2tai(&x,this_year,month,day,0,0,0); if (tai_less(&now,&x)) return this_year-1; return this_year; }
int respond(char *q,char qtype[2],char ip[4]) { static struct tai cdb_valid = { 0 }; static int fd = -1; struct tai one_second; int r; char key[6]; tai_now(&now); if (tai_less(&cdb_valid, &now)) { if (fd != -1) { cdb_free(&c); close(fd); } fd = open_read("data.cdb"); if (fd == -1) return 0; cdb_init(&c,fd); tai_uint(&one_second, 1); tai_add(&cdb_valid, &now, &one_second); } byte_zero(clientloc,2); key[0] = 0; key[1] = '%'; byte_copy(key + 2,4,ip); r = cdb_find(&c,key,6); if (!r) r = cdb_find(&c,key,5); if (!r) r = cdb_find(&c,key,4); if (!r) r = cdb_find(&c,key,3); if (!r) r = cdb_find(&c,key,2); if (r == -1) return 0; if (r && (cdb_datalen(&c) == 2)) if (cdb_read(&c,clientloc,2,cdb_datapos(&c)) == -1) return 0; r = doit(q,qtype); return r; }
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"); }
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; }