Esempio n. 1
0
void s6dns_message_counts_pack (char *s, s6dns_message_counts_t const *counts)
{
  uint16_pack_big(s, counts->qd) ;
  uint16_pack_big(s+2, counts->an) ;
  uint16_pack_big(s+4, counts->ns) ;
  uint16_pack_big(s+6, counts->nr) ;
}
Esempio n. 2
0
int
socket_send4 (int s, char *buf, int len,
                const char ip[4], uint16 port, void *src)
{
    char cbuf[256];
    struct iovec iov;
    struct msghdr msgh;
    struct sockaddr_in sa;
    struct cmsghdr *cmsg = NULL;

    byte_zero (&sa, sizeof (sa));
    sa.sin_family = AF_INET;

    uint16_pack_big ((char *)&sa.sin_port, port);
    byte_copy ((char *)&sa.sin_addr, 4, ip);

    memset (cbuf, 0, sizeof (cbuf));
    memset (&msgh, 0, sizeof (msgh));

    iov.iov_len = len;
    iov.iov_base = buf;

    msgh.msg_iov = &iov;
    msgh.msg_iovlen = 1;

    msgh.msg_name = &sa;
    msgh.msg_namelen = sizeof (sa);

#ifdef IP_PKTINFO
    struct in_pktinfo *p = NULL;

    msgh.msg_control = cbuf;
    msgh.msg_controllen = CMSG_SPACE (sizeof (*p));

    cmsg = CMSG_FIRSTHDR (&msgh);
    cmsg->cmsg_type = IP_PKTINFO;
    cmsg->cmsg_level = IPPROTO_IP;
    cmsg->cmsg_len = CMSG_LEN (sizeof (*p));

    p = (struct in_pktinfo *) CMSG_DATA (cmsg);
    p->ipi_spec_dst = *(struct in_addr *)src;
#elif defined IP_SENDSRCADDR
    struct in_addr *p = NULL;

    msgh.msg_control = cbuf;
    msgh.msg_controllen = CMSG_SPACE (sizeof (*p));

    cmsg = CMSG_FIRSTHDR (&msgh);
    cmsg->cmsg_type = IP_SENDSRCADDR;
    cmsg->cmsg_level = IPPROTO_IP;
    cmsg->cmsg_len = CMSG_LEN (sizeof (*p));

    p = (struct in_addr *)CMSG_DATA (cmsg);
    p->s_addr = *(struct in_addr *)src;
#endif

    msgh.msg_flags = 0;
    msgh.msg_controllen = cmsg ? cmsg->cmsg_len : 0;
    return sendmsg (s, &msgh, 0);
}
Esempio n. 3
0
ssize_t socket_send6(int s,const char *buf,size_t len,const char ip[16],uint16 port,uint32 scope_id)
{
#ifdef LIBC_HAS_IP6
  struct sockaddr_in6 si;
#else
  struct sockaddr_in si;
#endif

  byte_zero(&si,sizeof si);
#ifdef LIBC_HAS_IP6
  if (noipv6) {
#endif
    if (ip6_isv4mapped(ip))
      return socket_send4(s,buf,len,ip+12,port);
    if (byte_equal(ip,16,V6loopback))
      return socket_send4(s,buf,len,ip4loopback,port);
#ifdef LIBC_HAS_IP6
    errno=EPROTONOSUPPORT;
    return -1;
  }
  si.sin6_family = AF_INET6;
  uint16_pack_big((char *) &si.sin6_port,port);
  byte_copy((char *) &si.sin6_addr,16,ip);
#ifdef LIBC_HAS_SCOPE_ID
  si.sin6_scope_id=scope_id;
#else
  si.sin6_scope_id=0;
#endif
  return winsock2errno(sendto(s,buf,len,0,(void*) &si,sizeof si));
#else
  errno=EPROTONOSUPPORT;
  return -1;
#endif
}
Esempio n. 4
0
static void trig (uint16 id, char what, char info)
{
  char pack[4] ;
  unixmessage_t m = { .s = pack, .len = 4, .fds = 0, .nfds = 0 } ;
  uint16_pack_big(pack, id) ;
  pack[2] = what ; pack[3] = info ;
  if (!unixmessage_put(unixmessage_sender_x, &m))
  {
    cleanup() ;
    strerr_diefu1sys(111, "build answer") ;
  }
}

static void answer (char c)
{
  unixmessage_t m = { .s = &c, .len = 1, .fds = 0, .nfds = 0 } ;
  if (!unixmessage_put(unixmessage_sender_1, &m))
  {
    cleanup() ;
    strerr_diefu1sys(111, "unixmessage_put") ;
  }
}

static void remove (unsigned int i)
{
  ftrigio_deepfree(a + i) ;
  a[i] = a[--n] ;
  a[i].b.c.x = a[i].buf ;
}
Esempio n. 5
0
int ftrigr_unsubscribe (ftrigr_ref a, uint16 i, tain_t const *deadline, tain_t *stamp)
{
  ftrigr1_t *p ;
  if (!i--) return (errno = EINVAL, 0) ;
  p = GENSETDYN_P(ftrigr1_t, &a->data, i) ;
  if (!p) return (errno = EINVAL, 0) ;
  switch (p->state)
  {
    case FR1STATE_WAITACK :
    case FR1STATE_WAITACKDATA :
    {
      char dummy ;
      ftrigr_check(a, i+1, &dummy) ;
      return 1 ;
    }
    default : break ;
  }
  {
    char err ;
    char pack[3] = "--U" ;
    uint16_pack_big(pack, i) ;
    if (!skaclient_send(&a->connection, pack, 3, &skaclient_default_cb, &err, deadline, stamp)) return 0 ;
    if (err) return (errno = err, 0) ;
  }
  *p = ftrigr1_zero ;
  return gensetdyn_delete(&a->data, i) ;
}
Esempio n. 6
0
int socket_send6(int s,const char *buf,unsigned int len,const char ip[16],uint16 port,uint32 scope_id)
{
#ifdef LIBC_HAS_IP6
    struct sockaddr_in6 sa;
#else
    struct sockaddr_in sa;
#endif

    byte_zero(&sa,sizeof sa);
#ifdef LIBC_HAS_IP6
    if (noipv6) {
#endif
        if (ip6_isv4mapped(ip))
            return socket_send4(s,buf,len,ip+12,port);
        if (byte_equal(ip,16,V6loopback))
            return socket_send4(s,buf,len,ip4loopback,port);
#ifdef LIBC_HAS_IP6
        errno=error_proto;
        return -1;
    }
    sa.sin6_family = AF_INET6;
    uint16_pack_big((char *) &sa.sin6_port,port);
    byte_copy((char *) &sa.sin6_addr,16,ip);
    return sendto(s,buf,len,0,(struct sockaddr *) &sa,sizeof sa);
#else
        errno=error_proto;
        return -1;
#endif
}
Esempio n. 7
0
int response_addname(char *d)
{
  unsigned int dlen;
  unsigned int i;
  char buf[2];

  dlen = dns_domain_length(d);

  while (*d) {
    for (i = 0;i < name_num;++i)
      if (dns_domain_equal(d,name[i])) {
        uint16_pack_big(buf,49152 + name_ptr[i]);
        return response_addbytes(buf,2);
      }
    if (dlen <= 128)
      if (name_num < NAMES) {
	byte_copy(name[name_num],dlen,d);
	name_ptr[name_num] = response_len;
	++name_num;
      }
    i = (unsigned char) *d;
    ++i;
    if (!response_addbytes(d,i)) return 0;
    d += i;
    dlen -= i;
  }
  return response_addbytes(d,1);
}
Esempio n. 8
0
void
response_rfinish (int x)
{
    uint16_pack_big (response + dpos - 2, response_len - dpos);
    if (!++response[x + 1])
        ++response[x];
}
Esempio n. 9
0
unsigned int ip6_scan (char const *s, char *ip6)
{
  static const unsigned char class[256] = "2222222222222222222222222222222222222222222222220000000000122222200000022222222222222222222222222000000222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" ;
  static const unsigned char table[5][3] = { "\024#\005", "\024\"\005", "\024\005\006", "\005\002\005", "\024\t\016" } ;
  uint16 tmp[8] = { 0, 0, 0, 0, 0, 0, 0, 0 } ;
  unsigned int pos = 8, j = 0, state = 0, i = 0 ;

  while (state < 5)
  {
    register unsigned char c = table[state][class[(unsigned char)s[i]] - '0'] ;
    state = c & 7 ;
    if (c & 0x20) { if (pos < 8) state = 5 ; else pos = j ; }
    if (c & 0x10)
    {
     if (tmp[j] & 0xf000) state = 5 ;
     else tmp[j] = (tmp[j] << 4) + fmtscan_num(s[i], 16) ;
    }
    if (c & 0x08) if ((++j > 7) && (state < 5)) state = 5 ;
    i++ ;
  }

  if (((pos < 8) && (j > 6)) || ((pos == 8) && (j < 8))) state = 5 ;
  if (state == 5) return (errno = EINVAL, 0) ; 
  for (state = j ; state > pos ; state--) tmp[state - j + 7] = tmp[state - 1] ;
  for (; state < pos + 8 - j ; state++) tmp[state] = 0 ;

  for (j = 0 ; j < 8 ; j++) uint16_pack_big(ip6 + (j<<1), tmp[j]) ;
  return i - 1 ;
}
Esempio n. 10
0
int dns_transmit_start(struct dns_transmit *d,const char servers[64],int flagrecursive,const char *q,const char qtype[2],const char localip[4])
{
  unsigned int len;

  dns_transmit_free(d);
  errno = error_io;

  len = dns_domain_length(q);
  d->querylen = len + 18;
  d->query = alloc(d->querylen);
  if (!d->query) return -1;

  uint16_pack_big(d->query,len + 16);
  byte_copy(d->query + 2,12,flagrecursive ? "\0\0\1\0\0\1\0\0\0\0\0\0" : "\0\0\0\0\0\1\0\0\0\0\0\0gcc-bug-workaround");
  byte_copy(d->query + 14,len,q);
  byte_copy(d->query + 14 + len,2,qtype);
  byte_copy(d->query + 16 + len,2,DNS_C_IN);

  byte_copy(d->qtype,2,qtype);
  d->servers = servers;
  byte_copy(d->localip,4,localip);

  d->udploop = flagrecursive ? 1 : 0;

  if (len + 16 > 512) return firsttcp(d);
  return firstudp(d);
}
Esempio n. 11
0
int socket_connect6(int s,const char ip[16],uint16 port,uint32 scope_id)
{
#ifdef LIBC_HAS_IP6
  struct sockaddr_in6 sa;

  if (noipv6) {
#endif
    if (ip6_isv4mapped(ip))
      return socket_connect4(s,ip+12,port);
    if (byte_equal(ip,16,V6loopback))
      return socket_connect4(s,ip4loopback,port);
#ifdef LIBC_HAS_IP6
  }
  byte_zero(&sa,sizeof sa);
  sa.sin6_family = PF_INET6;
  uint16_pack_big((char *) &sa.sin6_port,port);
  sa.sin6_flowinfo = 0;
  sa.sin6_scope_id = scope_id;
  byte_copy((char *) &sa.sin6_addr,16,ip);

  return connect(s,(struct sockaddr *) &sa,sizeof sa);
#else
  errno=EPROTONOSUPPORT;
  return -1;
#endif
}
Esempio n. 12
0
void print(char *buf,unsigned int len)
{
  char tcpheader[2];
  uint16_pack_big(tcpheader,len);
  buffer_put(&netwrite,tcpheader,2);
  buffer_put(&netwrite,buf,len);
  buffer_flush(&netwrite);
}
Esempio n. 13
0
int socket_bind6 (int s, char const *ip6, uint16 port)
{
  struct sockaddr_in6 sa ;
  byte_zero(&sa, sizeof sa) ;
  sa.sin6_family = AF_INET6 ;
  uint16_pack_big((char *)&sa.sin6_port, port) ;
  byte_copy(sa.sin6_addr.s6_addr, 16, ip6) ;
  return bind(s, (struct sockaddr *)&sa, sizeof sa) ;
}
Esempio n. 14
0
ssize_t socket_send4(int s,const char *buf,size_t len,const char ip[4],uint16 port) {
  struct sockaddr_in si;

  byte_zero(&si,sizeof si);
  si.sin_family = AF_INET;
  uint16_pack_big((char*) &si.sin_port,port);
  *((uint32*)&si.sin_addr) = *((uint32*)ip);
  return winsock2errno(sendto(s,buf,len,0,(void*) &si,sizeof si));
}
Esempio n. 15
0
int
socket_connect4(int s, const char* ip, uint16 port) {
  struct sockaddr_in si;
  byte_zero(&si, sizeof(si));
  si.sin_family = AF_INET;
  uint16_pack_big((char*)&si.sin_port, port);
  *((uint32*)&si.sin_addr) = *((uint32*)ip);
  return winsock2errno(connect(s, (struct sockaddr*)&si, sizeof(si)));
}
Esempio n. 16
0
static void trig (uint16 id, char what, char info)
{
  char pack[7] = "4:idwi," ;
  uint16_pack_big(pack+2, id) ;
  pack[4] = what ; pack[5] = info ;
  if (!bufalloc_put(&asyncout, pack, 7))
  {
    cleanup() ;
    strerr_diefu1sys(111, "build answer") ;
  }
}
Esempio n. 17
0
int socket_send4(int s,const char *buf,int len,const char ip[4],uint16 port)
{
  struct sockaddr_in sa;

  byte_zero(&sa,sizeof sa);
  sa.sin_family = AF_INET;
  uint16_pack_big((char *) &sa.sin_port,port);
  byte_copy((char *) &sa.sin_addr,4,ip);

  return sendto(s,buf,len,0,(struct sockaddr *) &sa,sizeof sa);
}
Esempio n. 18
0
int socket_connect4(int s,const char ip[4],uint16 port)
{
  struct sockaddr_in sa;

  byte_zero(&sa,sizeof sa);
  sa.sin_family = AF_INET;
  uint16_pack_big((char *) &sa.sin_port,port);
  byte_copy((char *) &sa.sin_addr,4,ip);

  return connect(s,(struct sockaddr *) &sa,sizeof sa);
}
Esempio n. 19
0
int socket_send6 (int s, char const *buf, unsigned int len, char const *ip6, uint16 port)
{
  struct sockaddr_in6 sa ;
  register int r ;
  byte_zero((char *)&sa, sizeof sa) ;
  sa.sin6_family = AF_INET6 ;
  uint16_pack_big((char *)&sa.sin6_port, port) ;
  byte_copy(sa.sin6_addr.s6_addr, 16, ip6) ;
  do r = sendto(s, buf, len, 0, (struct sockaddr *)&sa, sizeof sa) ;
  while ((r == -1) && (errno == EINTR)) ;
  return r ;
}
Esempio n. 20
0
void s6_svstatus_pack (char *pack, s6_svstatus_t const *sv)
{
  tain_pack(pack, &sv->stamp) ;
  tain_pack(pack + 12, &sv->readystamp) ;
  uint64_pack_big(pack + 24, (uint64)sv->pid) ;
  uint16_pack_big(pack + 32, (uint16)sv->wstat) ;
  pack[34] =
    sv->flagpaused |
    (sv->flagfinishing << 1) |
    (sv->flagwant << 2) |
    (sv->flagwantup << 3) |
    (sv->flagready << 4) ;
}
Esempio n. 21
0
int socket_connect6 (int s, char const *ip6, uint16 port)
{
  struct sockaddr_in6 sa ;
  register int r ;
  byte_zero(&sa, sizeof sa) ;
  sa.sin6_family = AF_INET6 ;
  uint16_pack_big((char *)&sa.sin6_port,port) ;
  byte_copy((char *)sa.sin6_addr.s6_addr, 16, ip6) ;
  do r = connect(s, (struct sockaddr *)&sa, sizeof sa) ;
  while ((r == -1) && (errno == EINTR)) ;
  if ((r == -1) && (errno == EALREADY)) errno = EINPROGRESS ;
  return r ;
}
Esempio n. 22
0
int socket_send4_tcp(int s, const char *buf, int len)
{
    struct iovec iov[2];
    char len_[2];
    int iovcnt;
    uint16_pack_big(len_, (unsigned short)len);
    iov[0].iov_base = len_;
    iov[0].iov_len = 2;
    iov[1].iov_base = buf;
    iov[1].iov_len = len;
    iovcnt = sizeof(iov) / sizeof(struct iovec);
    return writev(s, iov, iovcnt);
}
Esempio n. 23
0
void t_respond(int j)
{
  if (!t[j].active) return;
  log_querydone(&t[j].active,response_len);
  response_id(t[j].id);
  t[j].len = response_len + 2;
  t_free(j);
  t[j].buf = alloc(response_len + 2);
  if (!t[j].buf) { t_close(j); return; }
  uint16_pack_big(t[j].buf,response_len);
  byte_copy(t[j].buf + 2,response_len,response);
  t[j].pos = 0;
  t[j].state = -1;
}
Esempio n. 24
0
int s6lock_release (s6lock_t *a, uint16 i, tain_t const *deadline, tain_t *stamp)
{
  char *p = GENSETDYN_P(char, &a->data, i) ;
  if ((*p != EBUSY) && !error_isagain(*p))
  {
    s6lock_check(a, i) ;
    return 1 ;
  }
  {
    char err ;
    char pack[3] = "-->" ;
    uint16_pack_big(pack, i) ;
    if (!skaclient_send(&a->connection, pack, 3, &skaclient_default_cb, &err, deadline, stamp)) return 0 ;
    if (err) return (errno = err, 0) ;
  }
  *p = EINVAL ;
  return gensetdyn_delete(&a->data, i) ;
}
Esempio n. 25
0
int
parsetype (char *s, char type[2])
{
    unsigned long u = 0;

    if (!s[scan_ulong (s, &u)])
        uint16_pack_big (type, u);
    else if (case_equals (s, "any"))
        byte_copy (type, 2, DNS_T_ANY);
    else if (case_equals (s, "a"))
        byte_copy (type, 2, DNS_T_A);
    else if (case_equals (s, "ns"))
        byte_copy (type, 2, DNS_T_NS);
    else if (case_equals (s, "mx"))
        byte_copy (type, 2, DNS_T_MX);
    else if (case_equals (s, "ptr"))
        byte_copy (type, 2, DNS_T_PTR);
    else if (case_equals (s, "txt"))
        byte_copy (type, 2, DNS_T_TXT);
    else if (case_equals (s, "cname"))
        byte_copy (type, 2, DNS_T_CNAME);
    else if (case_equals (s, "soa"))
        byte_copy (type, 2, DNS_T_SOA);
    else if (case_equals (s, "hinfo"))
        byte_copy (type, 2, DNS_T_HINFO);
    else if (case_equals (s, "rp"))
        byte_copy (type,2,DNS_T_RP);
    else if (case_equals (s, "sig"))
        byte_copy (type, 2, DNS_T_SIG);
    else if (case_equals (s, "key"))
        byte_copy (type, 2, DNS_T_KEY);
    else if (case_equals (s, "aaaa"))
        byte_copy (type, 2, DNS_T_AAAA);
    else if (case_equals (s, "axfr"))
        byte_copy (type,2,DNS_T_AXFR);
    else
        return 0;

    return 1;
}
Esempio n. 26
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;
}
Esempio n. 27
0
int main()
{
  int fddata;
  int i;
  int j;
  int k;
  char ch;
  unsigned long ttl;
  char ttd[8];
  char loc[2];
  unsigned long u;
  char ip[4];
  char ip6[16];
  char type[2];
  char soa[20];
  char buf[4];

  umask(022);

  fddata = open_read("data");
  if (fddata == -1)
    strerr_die2sys(111,FATAL,"unable to open data: ");
  defaultsoa_init(fddata);

  buffer_init(&b,buffer_unixread,fddata,bspace,sizeof bspace);

  fdcdb = open_trunc("data.tmp");
  if (fdcdb == -1) die_datatmp();
  if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();

  while (match) {
    ++linenum;
    if (getln(&b,&line,&match,'\n') == -1)
      strerr_die2sys(111,FATAL,"unable to read line: ");

    while (line.len) {
      ch = line.s[line.len - 1];
      if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
      --line.len;
    }
    if (!line.len) continue;
    if (line.s[0] == '#') continue;
    if (line.s[0] == '-') continue;

    j = 1;
    for (i = 0;i < NUMFIELDS;++i) {
      if (j >= line.len) {
	if (!stralloc_copys(&f[i],"")) nomem();
      }
      else {
        k = byte_chr(line.s + j,line.len - j,':');
	if (!stralloc_copyb(&f[i],line.s + j,k)) nomem();
	j += k + 1;
      }
    }

    switch(line.s[0]) {

      case '%':
	locparse(&f[0],loc);
	if (!stralloc_copyb(&key,"\0%",2)) nomem();
	if (!stralloc_0(&f[1])) nomem();
	ipprefix_cat(&key,f[1].s);
        if (cdb_make_add(&cdb,key.s,key.len,loc,2) == -1)
          die_datatmp();
	break;

      case 'Z':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();

	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&u)) uint32_unpack_big(defaultsoa,&u);
	uint32_pack_big(soa,u);
	if (!stralloc_0(&f[4])) nomem();
	if (!scan_ulong(f[4].s,&u)) uint32_unpack_big(defaultsoa + 4,&u);
	uint32_pack_big(soa + 4,u);
	if (!stralloc_0(&f[5])) nomem();
	if (!scan_ulong(f[5].s,&u)) uint32_unpack_big(defaultsoa + 8,&u);
	uint32_pack_big(soa + 8,u);
	if (!stralloc_0(&f[6])) nomem();
	if (!scan_ulong(f[6].s,&u)) uint32_unpack_big(defaultsoa + 12,&u);
	uint32_pack_big(soa + 12,u);
	if (!stralloc_0(&f[7])) nomem();
	if (!scan_ulong(f[7].s,&u)) uint32_unpack_big(defaultsoa + 16,&u);
	uint32_pack_big(soa + 16,u);

	if (!stralloc_0(&f[8])) nomem();
	if (!scan_ulong(f[8].s,&ttl)) ttl = TTL_NEGATIVE;
	ttdparse(&f[9],ttd);
	locparse(&f[10],loc);

	rr_start(DNS_T_SOA,ttl,ttd,loc);
	if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
	rr_addname(d2);
	if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
	rr_addname(d2);
	rr_add(soa,20);
	rr_finish(d1);
	break;

      case '.': case '&':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS;
	ttdparse(&f[4],ttd);
	locparse(&f[5],loc);

	if (!stralloc_0(&f[1])) nomem();

	if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
	  if (!stralloc_cats(&f[2],".ns.")) nomem();
	  if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
	}
	if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();

	if (line.s[0] == '.') {
	  rr_start(DNS_T_SOA,ttl ? TTL_NEGATIVE : 0,ttd,loc);
	  rr_addname(d2);
	  rr_add("\12hostmaster",11);
	  rr_addname(d1);
	  rr_add(defaultsoa,20);
	  rr_finish(d1);
	}

	rr_start(DNS_T_NS,ttl,ttd,loc);
	rr_addname(d2);
	rr_finish(d1);

	if (ip4_scan(f[1].s,ip)) {
	  rr_start(DNS_T_A,ttl,ttd,loc);
	  rr_add(ip,4);
	  rr_finish(d2);
	}

	break;

      case '+': case '=':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	if (!stralloc_0(&f[1])) nomem();

	if (ip4_scan(f[1].s,ip)) {
	  rr_start(DNS_T_A,ttl,ttd,loc);
	  rr_add(ip,4);
	  rr_finish(d1);

	  if (line.s[0] == '=') {
	    dns_name4_domain(dptr,ip);
	    rr_start(DNS_T_PTR,ttl,ttd,loc);
	    rr_addname(d1);
	    rr_finish(dptr);
	  }
	}
	break;

      case '6': case '3':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	if (!stralloc_0(&f[1])) nomem();
	if (ip6_scan_flat(f[1].s,ip6)) {
	  rr_start(DNS_T_AAAA,ttl,ttd,loc);
	  rr_add(ip6,16);
	  rr_finish(d1);

	  if (line.s[0] == '6') {	/* emit both .ip6.arpa and .ip6.int */
	    dns_name6_domain(d6ptr,ip6,DNS_IP6_ARPA);
	    rr_start(DNS_T_PTR,ttl,ttd,loc);
	    rr_addname(d1);
	    rr_finish(d6ptr);

	    dns_name6_domain(d6ptr,ip6,DNS_IP6_INT);
	    rr_start(DNS_T_PTR,ttl,ttd,loc);
	    rr_addname(d1);
	    rr_finish(d6ptr);
	  }
	}
	break;

      case '@':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[4])) nomem();
	if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[5],ttd);
	locparse(&f[6],loc);

	if (!stralloc_0(&f[1])) nomem();

	if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
	  if (!stralloc_cats(&f[2],".mx.")) nomem();
	  if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
	}
	if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();

	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&u)) u = 0;

	rr_start(DNS_T_MX,ttl,ttd,loc);
	uint16_pack_big(buf,u);
	rr_add(buf,2);
	rr_addname(d2);
	rr_finish(d1);

	if (ip4_scan(f[1].s,ip)) {
	  rr_start(DNS_T_A,ttl,ttd,loc);
	  rr_add(ip,4);
	  rr_finish(d2);
	}
	break;

      case '^': case 'C':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	if (line.s[0] == 'C')
	  rr_start(DNS_T_CNAME,ttl,ttd,loc);
	else
	  rr_start(DNS_T_PTR,ttl,ttd,loc);
	rr_addname(d2);
	rr_finish(d1);
	break;

      case '\'':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	rr_start(DNS_T_TXT,ttl,ttd,loc);

	txtparse(&f[1]);
	i = 0;
	while (i < f[1].len) {
	  k = f[1].len - i;
	  if (k > 127) k = 127;
	  ch = k;
	  rr_add(&ch,1);
	  rr_add(f[1].s + i,k);
	  i += k;
	}

	rr_finish(d1);
	break;

      case ':':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[4],ttd);
	locparse(&f[5],loc);

	if (!stralloc_0(&f[1])) nomem();
	scan_ulong(f[1].s,&u);
	uint16_pack_big(type,u);
	if (byte_equal(type,2,DNS_T_AXFR))
	  syntaxerror(": type AXFR prohibited");
	if (byte_equal(type,2,"\0\0"))
	  syntaxerror(": type 0 prohibited");
	if (byte_equal(type,2,DNS_T_SOA))
	  syntaxerror(": type SOA prohibited");
	if (byte_equal(type,2,DNS_T_NS))
	  syntaxerror(": type NS prohibited");
	if (byte_equal(type,2,DNS_T_CNAME))
	  syntaxerror(": type CNAME prohibited");
	if (byte_equal(type,2,DNS_T_PTR))
	  syntaxerror(": type PTR prohibited");
	if (byte_equal(type,2,DNS_T_MX))
	  syntaxerror(": type MX prohibited");

	txtparse(&f[2]);

	rr_start(type,ttl,ttd,loc);
	rr_add(f[2].s,f[2].len);
	rr_finish(d1);
	break;

      default:
        syntaxerror(": unrecognized leading character");
    }
  }

  if (cdb_make_finish(&cdb) == -1) die_datatmp();
  if (fsync(fdcdb) == -1) die_datatmp();
  if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
  if (rename("data.tmp","data.cdb") == -1)
    strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");

  _exit(0);
}
Esempio n. 28
0
int main(int argc, char **argv)
{
  int fddata;
	uint32 loc;
	//int v;
	char ipa[4];
	//char ipb[4];
	//ip4_cidr_t *subnets = (ip4_cidr_t *)NULL;
	//unsigned int slen = 0;
	uint32 ipinta = 0U;
	//unsigned int ipintb = 0;
	unsigned short mask;
	uint32 uid = 0;
	uint32  mid = 0;
  int i;
  int j;
  int k;
  char ch;
  unsigned long ttl;
  char ttd[8];
  //uint32 loc;
	unsigned char keyloc[15];
  unsigned long u;
  char ip[4];
	char locp[4];
	//char map[9];
  char type[2];
  char soa[20];
  char buf[4];
  //int namlen = 0;
  umask(022);
  fddata = STDIN_FILENO;
	if (argc != 3) {
    fddata = open_read("data");
		if (fddata == -1) strerr_die2sys(111,FATAL,"unable to open data: ");
		if ( (fdcdb = open_trunc("data.tmp")) == -1) die_datatmp();
	} else {
		fddata = STDIN_FILENO;
		if ( (fdcdb = open_trunc(argv[1])) == -1) die_datatmp();
	}
	
  defaultsoa_init(fddata);

  buffer_init(&b,buffer_unixread,fddata,bspace,sizeof bspace);

  if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();

  while (match) {
    ++linenum;
    if (getln(&b,&line,&match,'\n') == -1)
      strerr_die2sys(111,FATAL,"unable to read line: ");

    while (line.len) {
      ch = line.s[line.len - 1];
      if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
      --line.len;
    }
    if (!line.len) continue;
    if (line.s[0] == '#') continue;
    if (line.s[0] == '-') continue;
		//write(1,line.s,line.len);
		//write(1,"\n",1);
    j = 1;
    for (i = 0;i < NUMFIELDS;++i) {
      if (j >= line.len) {
				if (!stralloc_copys(&f[i],"")) nomem();
      }
      else {
        k = byte_chr(line.s + j,line.len - j,':');
				if (!stralloc_copyb(&f[i],line.s + j,k)) nomem();
				j += k + 1;
      }
    }

	switch(line.s[0]) {
#ifdef USE_LOCMAPS
	case '%':
		//locparse(&f[0],loc);
		loc = gethash(f[0].s,f[0].len);
		uint32_pack(locp,loc);
		if (!stralloc_0(&f[1])) nomem();
		if (!stralloc_0(&f[2])) nomem();
		ip4_scan(f[1].s,ipa);
		//ip4_scan(f[2].s,ipb);
		scan_ushort(f[2].s,&mask);
		ip4_num(&ipinta,ipa);
		//ip4_num(&ipintb,ipb);
		//if (ipintb<ipinta) nomem();
		//if (ip4_deaggregate(ipinta,ipintb,&subnets,&slen) <= 0) nomem();
		mid = gethash(f[3].s,f[3].len);
		uid = gethash(f[4].s,f[4].len);
		//for (v = 0; v < slen; v++) {
		ipdb_key4build(keyloc,ipinta,(unsigned char )mask&0xff,mid,uid);
		//ipdb_key_from_uint(keyloc,ipinta,(unsigned char )mask&0xff,0,mid,uid);
		cdb_make_add(&cdb,keyloc,15,locp,4);
		//}
		uid = 0;
		//alloc_free(subnets);
		//subnets = NULL;
		//slen = 0;
		byte_zero(ipa,4);ipinta=0; //byte_zero(ipb,4);ipinta=0;ipintb=0;
		break;
#endif
 	case 'Z':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();

		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&u)) uint32_unpack_big(defaultsoa,&u);
		uint32_pack_big(soa,u);
		if (!stralloc_0(&f[4])) nomem();
		if (!scan_ulong(f[4].s,&u)) uint32_unpack_big(defaultsoa + 4,&u);
		uint32_pack_big(soa + 4,u);
		if (!stralloc_0(&f[5])) nomem();
		if (!scan_ulong(f[5].s,&u)) uint32_unpack_big(defaultsoa + 8,&u);
		uint32_pack_big(soa + 8,u);
		if (!stralloc_0(&f[6])) nomem();
		if (!scan_ulong(f[6].s,&u)) uint32_unpack_big(defaultsoa + 12,&u);
		uint32_pack_big(soa + 12,u);
		if (!stralloc_0(&f[7])) nomem();
		if (!scan_ulong(f[7].s,&u)) uint32_unpack_big(defaultsoa + 16,&u);
		uint32_pack_big(soa + 16,u);

		if (!stralloc_0(&f[8])) nomem();
		if (!scan_ulong(f[8].s,&ttl)) ttl = TTL_NEGATIVE;
		ttdparse(&f[9],ttd);
		loc = gethash(f[10].s,f[10].len);
		mid = gethash(f[11].s,f[11].len);
		uid = gethash(f[12].s,f[12].len);
		rr_addloq(DNS_T_SOA,d1,loc,mid,uid);

		rr_start(DNS_T_SOA,ttl,ttd,loc);
		if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
		rr_addname(d2);
		if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
		rr_addname(d2);
		rr_add(soa,20);
		rr_finish(d1);
		break;

	case '.': case '&':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS;
		ttdparse(&f[4],ttd);
		loc = gethash(f[5].s,f[5].len);
		mid = gethash(f[6].s,f[6].len);
		uid = gethash(f[7].s,f[7].len);

		if (!stralloc_0(&f[1])) nomem();

		if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
			if (!stralloc_cats(&f[2],".ns.")) nomem();
			if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
		}
		if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();

		if (line.s[0] == '.') {
			rr_start(DNS_T_SOA,ttl ? TTL_NEGATIVE : 0,ttd,loc);
			rr_addloq(DNS_T_SOA,d1,loc,mid,uid);
			rr_addname(d2);
			rr_add("\12hostmaster",11);
			rr_addname(d1);
			rr_add(defaultsoa,20);
			rr_finish(d1);
		}

		rr_start(DNS_T_NS,ttl,ttd,loc);
		rr_addname(d2);
		rr_addloq(DNS_T_NS,d2,loc,mid,uid);
		rr_finish(d1);

		if (ip4_scan(f[1].s,ip)) {
	  	rr_start(DNS_T_A,ttl,ttd,loc);
			rr_addloq(DNS_T_A,d2,loc,mid,uid);
			rr_add(ip,4);
			rr_finish(d2);
		}

		break;

	case '+': case '=':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[2])) nomem();
		if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[3],ttd);
		loc = gethash(f[4].s,f[4].len);
		mid = gethash(f[5].s,f[5].len);
		uid = gethash(f[6].s,f[6].len);

		if (!stralloc_0(&f[1])) nomem();

		if (ip4_scan(f[1].s,ip)) {
			rr_addloq(DNS_T_A,d1,loc,mid,uid);
			rr_start(DNS_T_A,ttl,ttd,loc);
			//dbger("+addloq:d=%s,loc=%u,uid=%u,mid=%u",d1,loc,uid,mid);
			rr_add(ip,4);
			rr_finish(d1);

			if (line.s[0] == '=') {
				rr_addloq(DNS_T_PTR,d1,loc,mid,uid); //??????????????????/ TODO: checkthis
				dns_name4_domain(dptr,ip);
				rr_start(DNS_T_PTR,ttl,ttd,loc);
				rr_addname(d1);
				rr_finish(dptr);
			}
		}
		break;

	case '@':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[4])) nomem();
		if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[5],ttd);
		loc = gethash(f[6].s,f[6].len);
		mid = gethash(f[7].s,f[7].len);
		uid = gethash(f[8].s,f[8].len);

		if (!stralloc_0(&f[1])) nomem();

		if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
			if (!stralloc_cats(&f[2],".mx.")) nomem();
			if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
		}
		if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();

		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&u)) u = 0;

		rr_addloq(DNS_T_MX,d1,loc,mid,uid);
		rr_start(DNS_T_MX,ttl,ttd,loc);
		uint16_pack_big(buf,u);
		rr_add(buf,2);
		rr_addname(d2);
		rr_finish(d1);

		if (ip4_scan(f[1].s,ip)) {
			rr_addloq(DNS_T_A,d2,loc,mid,uid);
			rr_start(DNS_T_A,ttl,ttd,loc);
			rr_add(ip,4);
			rr_finish(d2);
		}
		break;

	case '^': case 'C':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
		if (!stralloc_0(&f[2])) nomem();
		if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[3],ttd);
		loc = gethash(f[4].s,f[4].len);
		mid = gethash(f[5].s,f[5].len);
		uid = gethash(f[6].s,f[6].len);

		if (line.s[0] == 'C') {
			//rr_addloq(DNS_T_CNAME,d1,loc,mid,uid);
			//dbger("add loq for cname!");
			rr_addloq(DNS_T_A,d1,loc,mid,uid);
			rr_addloq(DNS_T_CNAME,d1,loc,mid,uid);
			rr_start(DNS_T_CNAME,ttl,ttd,loc);
		} else {
			rr_addloq(DNS_T_PTR,d1,loc,mid,uid);
			rr_start(DNS_T_PTR,ttl,ttd,loc);
		}
		rr_addname(d2);
		rr_finish(d1);
		break;

	case '\'':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[2])) nomem();
		if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[3],ttd);
		loc = gethash(f[4].s,f[4].len);
		mid = gethash(f[5].s,f[5].len);
		uid = gethash(f[6].s,f[6].len);

		rr_addloq(DNS_T_TXT,d1,loc,mid,uid);
		rr_start(DNS_T_TXT,ttl,ttd,loc);
		txtparse(&f[1]);
		i = 0;
		while (i < f[1].len) {
			k = f[1].len - i;
			if (k > 127) k = 127;
			ch = k;
			rr_add(&ch,1);
			rr_add(f[1].s + i,k);
			i += k;
		}

		rr_finish(d1);
		break;

	case ':':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[4],ttd);
		loc = gethash(f[5].s,f[5].len);
		mid = gethash(f[6].s,f[6].len);
		uid = gethash(f[7].s,f[7].len);

		if (!stralloc_0(&f[1])) nomem();
		scan_ulong(f[1].s,&u);
		uint16_pack_big(type,u);
		if (byte_equal(type,2,DNS_T_AXFR))
			syntaxerror(": type AXFR prohibited");
		if (byte_equal(type,2,"\0\0"))
			syntaxerror(": type 0 prohibited");
		if (byte_equal(type,2,DNS_T_SOA))
			syntaxerror(": type SOA prohibited");
		if (byte_equal(type,2,DNS_T_NS))
			syntaxerror(": type NS prohibited");
		if (byte_equal(type,2,DNS_T_CNAME))
			syntaxerror(": type CNAME prohibited");
		if (byte_equal(type,2,DNS_T_PTR))
			syntaxerror(": type PTR prohibited");
		if (byte_equal(type,2,DNS_T_MX))
			syntaxerror(": type MX prohibited");
		txtparse(&f[2]);
		rr_addloq(type,d1,loc,mid,uid);
		rr_start(type,ttl,ttd,loc);
		rr_add(f[2].s,f[2].len);
		rr_finish(d1);
		break;
	default:
		dienow("error here: %s\n", line.s);
		syntaxerror(": unrecognized leading character");
}
}

  if (cdb_make_finish(&cdb) == -1) die_datatmp();
  if (fsync(fdcdb) == -1) die_datatmp();
  if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
	if (argc  == 3) {
		if (rename(argv[1],argv[2]) == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");
	} else {
		if (rename("data.tmp","data.cdb") == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");
	}

  _exit(0);
}
Esempio n. 29
0
int
main(int argc, char *argv[])
{
    int fddata = 0;
    unsigned int i = 0, j = 0, k = 0;

    unsigned long u = 0;
    unsigned long ttl = 0;

    char ch = 0;
    char *x = NULL;
    char ttd[8], loc[2];
    char ip[4], type[2];
    char soa[20], buf[4];

    prog = strdup ((x = strrchr (argv[0], '/')) != NULL ? x + 1 : argv[0]);
    i = check_option (argc, argv);
    argv += i;
    argc -= i;

    umask(022);

    if ((fddata = open_read ("data")) == -1)
        err (-1, "could not open file `data'");
    defaultsoa_init (fddata);

    buffer_init (&b, buffer_unixread, fddata, bspace, sizeof bspace);

    if ((fdcdb = open_trunc ("data.tmp")) == -1)
        err (-1, "could not create file `data.tmp'");
    if (cdb_make_start (&cdb, fdcdb) == -1)
        err (-1, "could not create file `data.tmp'");

    while (match)
    {
        linenum++;
        if (getln (&b, &line, &match, '\n') == -1)
            err (-1, "could not read line: %ld", linenum);

        while (line.len)
        {
            ch = line.s[line.len - 1];
            if ((ch != ' ') && (ch != '\t') && (ch != '\n'))
                break;

            --line.len;
        }
        if (!line.len)
            continue;
        if (line.s[0] == '#')
            continue;
        if (line.s[0] == '-')
            continue;

        j = 1;
        for (i = 0; i < NUMFIELDS; i++)
        {
            if (j >= line.len)
            {
                if (!stralloc_copys (&f[i], ""))
                    err (-1, "could not allocate enough memory");
            }
            else
            {
                k = byte_chr (line.s + j, line.len - j, ':');
                if (!stralloc_copyb (&f[i], line.s + j, k))
                    err (-1, "could not allocate enough memory");
                j += k + 1;
            }
        }

        switch (line.s[0])
        {
        case '%':
            locparse (&f[0], loc);

            if (!stralloc_copyb (&key, "\0%", 2))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            ipprefix_cat (&key, f[1].s);

            if (cdb_make_add(&cdb,key.s,key.len,loc,2) == -1)
                err (-1, "could not create file `data.tmp'");

            break;

        case 'Z':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");

            if (!stralloc_0 (&f[3]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[3].s, &u))
                uint32_unpack_big (defaultsoa, (uint32 *)&u);
            uint32_pack_big (soa, u);

            if (!stralloc_0 (&f[4]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[4].s, &u))
                uint32_unpack_big (defaultsoa + 4, (uint32 *)&u);
            uint32_pack_big (soa + 4, u);

            if (!stralloc_0 (&f[5]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[5].s, &u))
                uint32_unpack_big (defaultsoa + 8, (uint32 *)&u);
            uint32_pack_big (soa + 8, u);

            if (!stralloc_0 (&f[6]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[6].s, &u))
                uint32_unpack_big (defaultsoa + 12, (uint32 *)&u);
            uint32_pack_big (soa + 12, u);

            if (!stralloc_0 (&f[7]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[7].s, &u))
                uint32_unpack_big (defaultsoa + 16, (uint32 *)&u);
            uint32_pack_big (soa + 16, u);

            if (!stralloc_0 (&f[8]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong(f[8].s,&ttl))
                ttl = TTL_NEGATIVE;

            ttdparse (&f[9], ttd);
            locparse (&f[10], loc);

            rr_start (DNS_T_SOA, ttl, ttd, loc);
            if (!dns_domain_fromdot (&d2, f[1].s, f[1].len))
                err (-1, "could not allocate enough memory");

            rr_addname (d2);
            if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                err (-1, "could not allocate enough memory");

            rr_addname (d2);
            rr_add (soa, 20);
            rr_finish (d1);

            break;

        case '.':
        case '&':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[3]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[3].s, &ttl))
                ttl = TTL_NS;

            ttdparse (&f[4], ttd);
            locparse (&f[5], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len)
            {
                if (!stralloc_cats (&f[2], ".ns."))
                    err (-1, "could not allocate enough memory");
                if (!stralloc_catb (&f[2], f[0].s, f[0].len))
                    err (-1, "could not allocate enough memory");
            }
            if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                err (-1, "could not allocate enough memory");

            if (line.s[0] == '.')
            {
                rr_start (DNS_T_SOA, ttl ? TTL_NEGATIVE : 0, ttd, loc);
                rr_addname (d2);

                rr_add ("\12hostmaster", 11);
                rr_addname (d1);

                rr_add (defaultsoa, 20);
                rr_finish (d1);
            }

            rr_start (DNS_T_NS, ttl, ttd, loc);
            rr_addname (d2);
            rr_finish (d1);

            if (ip4_scan (f[1].s, ip))
            {
                rr_start (DNS_T_A, ttl, ttd, loc);
                rr_add (ip, 4);
                rr_finish (d2);
            }

            break;

        case '+':
        case '=':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[2]))
                err (-1, "could not allocate enough memory");

            if (!scan_ulong (f[2].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[3], ttd);
            locparse (&f[4], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            if (ip4_scan (f[1].s, ip))
            {
                rr_start (DNS_T_A, ttl, ttd, loc);
                rr_add (ip, 4);
                rr_finish (d1);

                if (line.s[0] == '=')
                {
                    dns_name4_domain (dptr,ip);
                    rr_start (DNS_T_PTR, ttl, ttd, loc);
                    rr_addname (d1);
                    rr_finish (dptr);
                }
            }
            break;

        case '@':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[4]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[4].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[5], ttd);
            locparse (&f[6], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len)
            {
                if (!stralloc_cats (&f[2], ".mx."))
                    err (-1, "could not allocate enough memory");
                if (!stralloc_catb (&f[2], f[0].s, f[0].len))
                    err (-1, "could not allocate enough memory");
            }
            if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                err (-1, "could not allocate enough memory");

            if (!stralloc_0 (&f[3]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[3].s, &u))
                u = 0;

            rr_start (DNS_T_MX, ttl, ttd, loc);
            uint16_pack_big (buf, u);
            rr_add (buf, 2);
            rr_addname (d2);
            rr_finish (d1);

            if (ip4_scan (f[1].s, ip))
            {
                rr_start (DNS_T_A, ttl, ttd, loc);
                rr_add (ip, 4);
                rr_finish (d2);
            }
            break;

        case '^':
        case 'C':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!dns_domain_fromdot (&d2, f[1].s, f[1].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[2]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[2].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[3], ttd);
            locparse (&f[4], loc);

            if (line.s[0] == 'C')
                rr_start (DNS_T_CNAME, ttl, ttd, loc);
            else
                rr_start (DNS_T_PTR, ttl, ttd, loc);

            rr_addname (d2);
            rr_finish (d1);

            break;

        case '\'':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[2]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[2].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[3], ttd);
            locparse (&f[4], loc);

            rr_start (DNS_T_TXT, ttl, ttd, loc);

            txtparse (&f[1]);
            i = 0;
            while (i < f[1].len)
            {
                k = f[1].len - i;
                if (k > 127)
                    k = 127;
                ch = k;
                rr_add (&ch, 1);
                rr_add (f[1].s + i, k);
                i += k;
            }

            rr_finish (d1);
            break;

        case ':':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[3]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[3].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[4], ttd);
            locparse (&f[5], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");
            scan_ulong (f[1].s, &u);
            uint16_pack_big (type, u);
            if (byte_equal (type, 2, DNS_T_AXFR))
                syntaxerror (": type AXFR prohibited");
            if (byte_equal (type, 2, "\0\0"))
              syntaxerror (": type 0 prohibited");
            if (byte_equal (type, 2, DNS_T_SOA))
              syntaxerror (": type SOA prohibited");
            if (byte_equal (type, 2, DNS_T_NS))
              syntaxerror (": type NS prohibited");
            if (byte_equal (type, 2, DNS_T_CNAME))
              syntaxerror (": type CNAME prohibited");
            if (byte_equal (type, 2, DNS_T_PTR))
              syntaxerror (": type PTR prohibited");
            if (byte_equal (type, 2, DNS_T_MX))
              syntaxerror (": type MX prohibited");

            txtparse (&f[2]);

            rr_start (type, ttl, ttd, loc);
            rr_add (f[2].s, f[2].len);
            rr_finish (d1);

            break;

        default:
            syntaxerror (": unrecognized leading character");
        }
    }

    if (cdb_make_finish (&cdb) == -1)
        err (-1, "could not create file `data.tmp'");
    if (fsync (fdcdb) == -1)
        err (-1, "could not create file `data.tmp'");
    if (close (fdcdb) == -1)
        err (-1, "could not create file `data.tmp'"); /* NFS stupidity */
    if (rename ("data.tmp", "data.cdb") == -1)
        err (-1, "could not move `data.tmp' to `data.cdb'");

    return 0;
}