void axfrcheck (char *q) { int i = 0, j = 0; if (!axfr) return; for (;;) { if (!axfr[i] || (axfr[i] == '/')) { if (i > j) { if (!dns_domain_fromdot (&axfrok, axfr + j, i - j)) err (-1, "could not allocate enough memory"); if (dns_domain_equal (q, axfrok)) return; } j = i + 1; } if (!axfr[i]) break; ++i; } err (-1, "zone transfer request not allowed"); }
int tdlookup_init(void) { char *x; char ch; int i; int j; int k; x = env_get("LAME_A"); if (x) if (!ip4_scan(x,lameip)) byte_zero(lameip,4); x = env_get("LAME_MX"); if (x) if (!dns_domain_fromdot(&lamemx,x,str_len(x))) return 0; x = env_get("LAME_TXT"); if (x) { i = 0; j = str_len(x); while (i < j) { k = j - i; if (k > 255) k = 255; ch = k; if (!stralloc_append(&lametxt,&ch)) return 0; if (!stralloc_catb(&lametxt,x + i,k)) return 0; i += k; } } return 1; }
int dns_domain_prependb2(char **out, const char *d, const char *s1, unsigned int n1, const char *s2, unsigned int n2) { static stralloc sa; if (!stralloc_copyb(&sa, s1, n1)) return 0; if (s2 && n2) if (!stralloc_catb(&sa, s2, n2)) return 0; if (!dns_domain_todot_cat(&sa, d)) return 0; if (!dns_domain_fromdot(out, sa.s, sa.len)) return 0; return 1; }
int dns_mx(stralloc *out,const stralloc *fqdn) { if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; if (dns_resolve(q,DNS_T_MX) == -1) return -1; if (dns_mx_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; dns_transmit_free(&dns_resolve_tx); dns_domain_free(&q); return 0; }
static int doit(stralloc *out,stralloc *fqdn) { unsigned int i; char code; char ch; char ip[16]; if (!stralloc_copys(out,"")) return -1; if (!stralloc_readyplus(fqdn,1)) return -1; fqdn->s[fqdn->len]=0; if ((i=ip6_scan(fqdn->s,ip))) { if (!fqdn->s[i]) { stralloc_copyb(out,ip,16); return 0; } } if ((i=ip4_scan(fqdn->s,ip+12))) { if (!fqdn->s[i]) { byte_zero(ip,10); ip[10]=ip[11]=0xff; stralloc_copyb(out,ip,16); return 0; } } code = 0; for (i = 0;i <= fqdn->len;++i) { if (i < fqdn->len) ch = fqdn->s[i]; else ch = '.'; if ((ch == '[') || (ch == ']')) continue; if (ch == '.') { if (!stralloc_append(out,&code)) return -1; code = 0; continue; } if ((ch >= '0') && (ch <= '9')) { code *= 10; code += ch - '0'; continue; } if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; if (dns_resolve(q,DNS_T_AAAA) == -1) return -1; if (dns_ip6_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; dns_transmit_free(&dns_resolve_tx); dns_domain_free(&q); return 0; } out->len &= ~3; return 0; }
int main(int argc, char **argv) { char host[] = "duckduckgo.com"; char *dnsname= NULL; char dotted[256]; dns_domain_fromdot(host, strlen(host), &dnsname); printf("%s\n", dnsname); printundotted((uint8_t *)dnsname); todotted(dotted, (uint8_t *)dnsname); printf("%s\n", dotted); return 0; }
static int dnszones_dirinit2(struct dnszones *dnszones, const char *cfgdir, const char *vardir, const char *warning) { direntry *d; DIR *dir; struct stat st; const char *fqdn; unsigned char *q = 0; dir = opendir("."); if (!dir) return 0; for (;;) { errno = 0; d = readdir(dir); if (!d) break; if (d->d_name[0] == '.') continue; fqdn = d->d_name; if (str_equal(d->d_name, "@")) fqdn = "."; if (stat(d->d_name, &st) == -1) { warn_6(warning, "unable to stat ", d->d_name, ": ", e_str(errno), "\n"); continue; } if (!S_ISDIR(st.st_mode)) continue; if (!dns_domain_fromdot(&q, (unsigned char *)fqdn, str_len(fqdn))) { warn_6(warning, "unable init zone ", fqdn, ": ", e_str(errno), "\n"); continue; } if (dnszones_exist(dnszones, q)) { warn_4(warning, "unable to init zone ", fqdn, ": exist\n"); continue; } if (!dnszones_add(dnszones, d->d_name, &q, cfgdir, vardir)) { warn_6(warning, "unable init zone ", fqdn, ": ", e_str(errno), "\n"); break; } } if (errno) {closedir(dir); return 0;} closedir(dir); return 1; }
static int init2(DIR *dir) { direntry *d; const char *fqdn; static char *q; static stralloc text; char servers[64]; int serverslen; int i; int j; for (;;) { errno = 0; d = readdir(dir); if (!d) { if (errno) return 0; return 1; } if (d->d_name[0] != '.') { if (openreadclose(d->d_name,&text,32) != 1) return 0; if (!stralloc_append(&text,"\n")) return 0; fqdn = d->d_name; if (str_equal(fqdn,"@")) fqdn = "."; if (!dns_domain_fromdot(&q,fqdn,str_len(fqdn))) return 0; serverslen = 0; j = 0; for (i = 0;i < text.len;++i) if (text.s[i] == '\n') { if (serverslen <= 60) if (ip4_scan(text.s + j,servers + serverslen)) serverslen += 4; j = i + 1; } byte_zero(servers + serverslen,64 - serverslen); if (!stralloc_catb(&data,q,dns_domain_length(q))) return 0; if (!stralloc_catb(&data,servers,64)) return 0; } } }
int main(int argc,char **argv) { uint16 u16; if (!*argv) usage(); if (!*++argv) usage(); if (!parsetype(*argv,type)) usage(); if (!*++argv) usage(); if (!dns_domain_fromdot(&q,*argv,str_len(*argv))) oops(); if (*++argv) { if (!ip4_scan(*argv,ip)) usage(); } if (!stralloc_copys(&out,"")) oops(); /* uint16_unpack_big(type,&u16); if (!stralloc_catulong0(&out,u16,0)) oops(); if (!stralloc_cats(&out," ")) oops(); if (!dns_domain_todot_cat(&out,q)) oops(); if (!stralloc_cats(&out,":\n")) oops(); */ if (!response_query(q,type,DNS_C_IN)) oops(); response[3] &= ~128; response[2] &= ~1; response[2] |= 4; case_lowerb(q,dns_domain_length(q)); if (byte_equal(type,2,DNS_T_AXFR)) { response[3] &= ~15; response[3] |= 4; } else if (!respond(q,type,ip)) goto DONE; if (!printpacket_cat(&out,response,response_len)) oops(); DONE: buffer_putflush(buffer_1,out.s,out.len); _exit(0); }
/** Request the IPv4 address (A) records for a domain name. */ int dns_ip4_r(struct dns_transmit* tx, struct dns_result *out, const char* fqdn) { char *q = 0; ipv4addr ip; const char* x; if ((x = ipv4_scan(fqdn, &ip)) != 0 && *x == 0) { if (dns_result_alloc(out, DNS_T_A, 1, 0) < 0) return -1; memcpy(out->rr.ip4, &ip, sizeof ip); return 0; } if (!dns_domain_fromdot(&q,fqdn,strlen(fqdn))) return -1; if (dns_resolve(tx,q,DNS_T_A) == -1) { free(q); return -1; } free(q); if (dns_ip4_packet(out,tx->packet,tx->packetlen) == -1) return -1; dns_transmit_free(tx); return 0; }
int main () { stralloc out ={0}; stralloc sa ={0}; char ip[4]; char *dn =0; stralloc_copys(&sa, "abcdefg"); dns_ip4(&out, &sa); dns_ip4_qualify(&out, &sa, &sa); dns_name4(&out, ip); dns_mx(&out, &sa); dns_txt(&out, &sa); dns_domain_length(sa.s); dns_domain_equal(sa.s, sa.s); dns_domain_copy(&dn, sa.s); dns_domain_fromdot(&dn, sa.s, sa.len); return 0; }
void axfrcheck(char *q) { int i; int j; if (!axfr) return; i = j = 0; for (;;) { if (!axfr[i] || (axfr[i] == '/')) { if (i > j) { if (!dns_domain_fromdot(&axfrok,axfr + j,i - j)) nomem(); if (dns_domain_equal(q,axfrok)) return; } j = i + 1; } if (!axfr[i]) break; ++i; } strerr_die2x(111,FATAL,"disallowed zone transfer request"); }
int main(int argc,char **argv) { uint16 u16; dns_random_init(seed); if (!*argv) usage(); if (!*++argv) usage(); if (!parsetype(*argv,type)) usage(); if (!*++argv) usage(); if (!dns_domain_fromdot(&q,*argv,str_len(*argv))) oops(); if (!*++argv) usage(); if (!stralloc_copys(&out,*argv)) oops(); if (dns_ip6_qualify(&ip,&fqdn,&out) == -1) oops(); if (ip.len >= 256) ip.len = 256; byte_zero(servers,256); byte_copy(servers,ip.len,ip.s); if (!stralloc_copys(&out,"")) oops(); uint16_unpack_big(type,&u16); if (!stralloc_catulong0(&out,u16,0)) oops(); if (!stralloc_cats(&out," ")) oops(); if (!dns_domain_todot_cat(&out,q)) oops(); if (!stralloc_cats(&out,":\n")) oops(); if (resolve(q,type,servers) == -1) { if (!stralloc_cats(&out,error_str(errno))) oops(); if (!stralloc_cats(&out,"\n")) oops(); } else { if (!printpacket_cat(&out,tx.packet,tx.packetlen)) oops(); } buffer_putflush(buffer_1,out.s,out.len); _exit(0); }
int dns_ip4(stralloc *out,const stralloc *fqdn) { unsigned int i; char code; char ch; if (!stralloc_copys(out,"")) return -1; code = 0; for (i = 0;i <= fqdn->len;++i) { if (i < fqdn->len) ch = fqdn->s[i]; else ch = '.'; if ((ch == '[') || (ch == ']')) continue; if (ch == '.') { if (!stralloc_append(out,&code)) return -1; code = 0; continue; } if ((ch >= '0') && (ch <= '9')) { code *= 10; code += ch - '0'; continue; } if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; if (dns_resolve(q,DNS_T_A) == -1) return -1; if (dns_ip4_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; dns_transmit_free(&dns_resolve_tx); dns_domain_free(&q); return 0; } out->len &= ~3; return 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); }
main() { struct address t; int i; int j; int k; char ch; umask(022); if (!address_alloc_readyplus(&x,0)) nomem(); fd = open_read("data"); if (fd == -1) strerr_die2sys(111,FATAL,"unable to open data: "); buffer_init(&b,read,fd,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; 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]) { default: syntaxerror(": unrecognized leading character"); case '#': break; case '-': break; case '+': byte_zero(&t,sizeof t); if (!dns_domain_fromdot(&t.name,f[0].s,f[0].len)) nomem(); t.namelen = dns_domain_length(t.name); case_lowerb(t.name,t.namelen); if (!stralloc_0(&f[1])) nomem(); if (!ip4_scan(f[1].s,t.ip)) syntaxerror(": malformed IP address"); if (!stralloc_0(&f[2])) nomem(); if (!stralloc_0(&f[2])) nomem(); byte_copy(t.location,2,f[2].s); if (!address_alloc_append(&x,&t)) nomem(); break; case '%': if (!stralloc_0(&f[0])) nomem(); if (!stralloc_0(&f[0])) nomem(); if (!stralloc_copyb(&result,f[0].s,2)) nomem(); if (!stralloc_0(&f[1])) nomem(); if (!stralloc_copys(&key,"%")) nomem(); ipprefix_cat(&key,f[1].s); if (cdb_make_add(&cdb,key.s,key.len,result.s,result.len) == -1) die_datatmp(); break; } } close(fd); address_sort(x.s,x.len); i = 0; while (i < x.len) { for (j = i + 1; j < x.len; ++j) if (address_diff(x.s + i,x.s + j)) break; if (!stralloc_copys(&key,"+")) nomem(); if (!stralloc_catb(&key,x.s[i].location,2)) nomem(); if (!stralloc_catb(&key,x.s[i].name,x.s[i].namelen)) nomem(); if (!stralloc_copys(&result,"")) nomem(); while (i < j) if (!stralloc_catb(&result,x.s[i++].ip,4)) nomem(); if (cdb_make_add(&cdb,key.s,key.len,result.s,result.len) == -1) die_datatmp(); } 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); }
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; }
int main (int argc, char *argv[]) { char ch = 0; struct stat st; unsigned long ttl = 0; unsigned i = 0, j = 0, k = 0; prog = strdup ((d1 = strrchr (argv[0], '/')) != NULL ? d1 + 1 : argv[0]); i = check_option (argc, argv); argv += i; argc -= i; d1 = NULL; if (argc < 6) { usage (); return -1; } fn = *argv; argv++; fnnew = *argv; argv++; if (str_diff (*argv, "add")) { usage (); return -1; } argv++; if (str_equal (*argv, "ns")) mode = '.'; else if (str_equal (*argv, "childns")) mode = '&'; else if (str_equal (*argv, "host")) mode = '='; else if (str_equal (*argv, "alias")) mode = '+'; else if (str_equal (*argv, "mx")) mode = '@'; else errx (-1, "invalid record type `%s'", *argv); argv++; if (!dns_domain_fromdot (&target, *argv, str_len (*argv))) err (-1, "could not allocate enough memory"); argv++; if (!ip4_scan (*argv, targetip)) errx (-1, "could not parse IP `%s'", *argv); umask(077); fd = open_read (fn); if (fd == -1) err (-1, "could not read from `%s'", fn); if (fstat (fd, &st) == -1) err (-1, "could not read from `%s'", fn); buffer_init (&b, buffer_unixread, fd, bspace, sizeof bspace); fdnew = open_trunc (fnnew); if (fdnew == -1) err (-1, "could not write to `%s'", fnnew); if (fchmod (fdnew, st.st_mode & 0644) == -1) err (-1, "could not write to `%s'", fnnew); buffer_init (&bnew, buffer_unixwrite, fdnew, bnewspace, sizeof bnewspace); switch (mode) { case '.': case '&': ttl = TTL_NS; for (i = 0; i < 26; i++) { ch = 'a' + i; if (!stralloc_copyb (&f[0], &ch, 1)) err (-1, "could not allocate enough memory"); if (!stralloc_cats (&f[0], ".ns.")) err (-1, "could not allocate enough memory"); if (!dns_domain_todot_cat (&f[0], target)) err (-1, "could not allocate enough memory"); if (!dns_domain_fromdot (&names[i], f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); } break; case '+': case '=': ttl = TTL_POSITIVE; break; case '@': ttl = TTL_POSITIVE; for (i = 0; i < 26; i++) { ch = 'a' + i; if (!stralloc_copyb (&f[0], &ch, 1)) err (-1, "could not allocate enough memory"); if (!stralloc_cats (&f[0], ".mx.")) err (-1, "could not allocate enough memory"); if (!dns_domain_todot_cat (&f[0], target)) err (-1, "could not allocate enough memory"); if (!dns_domain_fromdot (&names[i], f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); } break; } while (match) { if (getln (&b, &line, &match, '\n') == -1) err (-1, "could not read from `%s'", fn); put (line.s, line.len); if (line.len && !match) put ("\n", 1); while (line.len) { ch = line.s[line.len - 1]; if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break; --line.len; } if (!line.len || 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(mode) { case '.': case '&': if (line.s[0] == mode) { if (!dns_domain_fromdot (&d1, f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); if (dns_domain_equal (d1, target)) { 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 (!stralloc_0 (&f[3])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[3].s, &ttl)) ttl = TTL_NS; for (i = 0; i < 26; i++) { if (dns_domain_equal (d2, names[i])) { used[i] = 1; break; } } } } break; case '=': if (line.s[0] == '=') { if (!dns_domain_fromdot (&d1, f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); if (dns_domain_equal (d1, target)) errx (-1, "host name is already used"); if (!stralloc_0 (&f[1])) err (-1, "could not allocate enough memory"); if (ip4_scan (f[1].s, ip)) if (byte_equal(ip, 4, targetip)) errx (-1, "IP address is already used"); } break; case '@': if (line.s[0] == '@') { if (!dns_domain_fromdot (&d1, f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); if (dns_domain_equal (d1, target)) { 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[4])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[4].s, &ttl)) ttl = TTL_POSITIVE; for (i = 0; i < 26; i++) { if (dns_domain_equal (d2, names[i])) { used[i] = 1; break; } } } } break; } } if (!stralloc_copyb (&f[0], &mode, 1)) err (-1, "could not allocate enough memory"); if (!dns_domain_todot_cat (&f[0], target)) err (-1, "could not allocate enough memory"); if (!stralloc_cats (&f[0], ":")) err (-1, "could not allocate enough memory"); if (!stralloc_catb (&f[0], ipstr, ip4_fmt (ipstr, targetip))) err (-1, "could not allocate enough memory"); switch (mode) { case '.': case '&': case '@': for (i = 0; i < 26; i++) { if (!used[i]) break; } if (i >= 26) errx (-1, "too many records for domain `%s'", target); ch = 'a' + i; if (!stralloc_cats (&f[0], ":")) err (-1, "could not allocate enough memory"); if (!stralloc_catb (&f[0], &ch, 1)) err (-1, "could not allocate enough memory"); if (mode == '@') if (!stralloc_cats (&f[0], ":")) err (-1, "could not allocate enough memory"); break; } if (!stralloc_cats (&f[0], ":")) err (-1, "could not allocate enough memory"); if (!stralloc_catb (&f[0], strnum, fmt_ulong (strnum, ttl))) err (-1, "could not allocate enough memory"); if (!stralloc_cats (&f[0], "\n")) err (-1, "could not allocate enough memory"); put (f[0].s, f[0].len); if (buffer_flush (&bnew) == -1) err (-1, "could not write to `%s'", fnnew); if (fsync (fdnew) == -1) err (-1, "could not write to `%s'", fnnew); if (close (fdnew) == -1) err (-1, "could not write to `%s'", fnnew); /* NFS dorks */ if (rename (fnnew, fn) == -1) err (-1, "could not move `%s' to `%s'", fnnew, fn); return 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); }
int main(int argc,char **argv) { unsigned long ttl; struct stat st; int i; int j; int k; char ch; if (!*argv) die_usage(); if (!*++argv) die_usage(); fn = *argv; if (!*++argv) die_usage(); fnnew = *argv; if (!*++argv) die_usage(); if (str_diff(*argv,"add")) die_usage(); if (!*++argv) die_usage(); if (str_equal(*argv,"ns")) mode = '.'; else if (str_equal(*argv,"childns")) mode = '&'; else if (str_equal(*argv,"host")) mode = '='; else if (str_equal(*argv,"host6")) mode = '6'; else if (str_equal(*argv,"alias")) mode = '+'; else if (str_equal(*argv,"alias6")) mode = '3'; else if (str_equal(*argv,"mx")) mode = '@'; else die_usage(); if (!*++argv) die_usage(); if (!dns_domain_fromdot(&target,*argv,str_len(*argv))) nomem(); if (!*++argv) die_usage(); if (mode == '6' || mode == '3') { if (!ip6_scan(*argv,targetip6)) die_usage(); } else { if (!ip4_scan(*argv,targetip)) die_usage(); } umask(077); fd = open_read(fn); if (fd == -1) die_read(); if (fstat(fd,&st) == -1) die_read(); buffer_init(&b,buffer_unixread,fd,bspace,sizeof bspace); fdnew = open_trunc(fnnew); if (fdnew == -1) die_write(); if (fchmod(fdnew,st.st_mode & 0644) == -1) die_write(); buffer_init(&bnew,buffer_unixwrite,fdnew,bnewspace,sizeof bnewspace); switch(mode) { case '.': case '&': ttl = TTL_NS; for (i = 0;i < 26;++i) { ch = 'a' + i; if (!stralloc_copyb(&f[0],&ch,1)) nomem(); if (!stralloc_cats(&f[0],".ns.")) nomem(); if (!dns_domain_todot_cat(&f[0],target)) nomem(); if (!dns_domain_fromdot(&names[i],f[0].s,f[0].len)) nomem(); } break; case '+': case '=': case '6': case '3': ttl = TTL_POSITIVE; break; case '@': ttl = TTL_POSITIVE; for (i = 0;i < 26;++i) { ch = 'a' + i; if (!stralloc_copyb(&f[0],&ch,1)) nomem(); if (!stralloc_cats(&f[0],".mx.")) nomem(); if (!dns_domain_todot_cat(&f[0],target)) nomem(); if (!dns_domain_fromdot(&names[i],f[0].s,f[0].len)) nomem(); } break; } while (match) { if (getln(&b,&line,&match,'\n') == -1) die_read(); put(line.s,line.len); if (line.len && !match) put("\n",1); 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; 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(mode) { case '.': case '&': if (line.s[0] == mode) { if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (dns_domain_equal(d1,target)) { 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 (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS; for (i = 0;i < 26;++i) if (dns_domain_equal(d2,names[i])) { used[i] = 1; break; } } } break; case '=': if (line.s[0] == '=') { if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (dns_domain_equal(d1,target)) strerr_die2x(100,FATAL,"host name already used"); if (!stralloc_0(&f[1])) nomem(); if (ip4_scan(f[1].s,ip)) if (byte_equal(ip,4,targetip)) strerr_die2x(100,FATAL,"IP address already used"); } break; case '6': if (line.s[0] == '6') { if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (dns_domain_equal(d1,target)) strerr_die2x(100,FATAL,"host name already used"); if (!stralloc_0(&f[1])) nomem(); if (ip6_scan(f[1].s,ip6)) if (byte_equal(ip,16,targetip6)) strerr_die2x(100,FATAL,"IPv6 address already used"); } break; case '@': if (line.s[0] == '@') { if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (dns_domain_equal(d1,target)) { 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[4])) nomem(); if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE; for (i = 0;i < 26;++i) if (dns_domain_equal(d2,names[i])) { used[i] = 1; break; } } } break; } } if (!stralloc_copyb(&f[0],&mode,1)) nomem(); if (!dns_domain_todot_cat(&f[0],target)) nomem(); if (!stralloc_cats(&f[0],":")) nomem(); if (mode == '6' || mode == '3') { if (!stralloc_catb(&f[0],ip6str,ip6_fmt_flat(ip6str,targetip6))) nomem(); } else { if (!stralloc_catb(&f[0],ipstr,ip4_fmt(ipstr,targetip))) nomem(); } switch(mode) { case '.': case '&': case '@': for (i = 0;i < 26;++i) if (!used[i]) break; if (i >= 26) strerr_die2x(100,FATAL,"too many records for that domain"); ch = 'a' + i; if (!stralloc_cats(&f[0],":")) nomem(); if (!stralloc_catb(&f[0],&ch,1)) nomem(); if (mode == '@') if (!stralloc_cats(&f[0],":")) nomem(); break; } if (!stralloc_cats(&f[0],":")) nomem(); if (!stralloc_catb(&f[0],strnum,fmt_ulong(strnum,ttl))) nomem(); if (!stralloc_cats(&f[0],"\n")) nomem(); put(f[0].s,f[0].len); if (buffer_flush(&bnew) == -1) die_write(); if (fsync(fdnew) == -1) die_write(); if (close(fdnew) == -1) die_write(); /* NFS dorks */ if (rename(fnnew,fn) == -1) strerr_die6sys(111,FATAL,"unable to move ",fnnew," to ",fn,": "); _exit(0); }