Example #1
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);
}
Example #2
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;
}