Exemple #1
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;
  }
}
Exemple #2
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);
  }
}
/* 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;
}
Exemple #4
0
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;
}
Exemple #5
0
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);
}
Exemple #6
0
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");
}
Exemple #7
0
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;
}