summaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/djbdns/APKBUILD4
-rw-r--r--main/djbdns/djbdns-1.05-jumbo-josb.patch1858
2 files changed, 1861 insertions, 1 deletions
diff --git a/main/djbdns/APKBUILD b/main/djbdns/APKBUILD
index dd8010c0a..cfb710055 100644
--- a/main/djbdns/APKBUILD
+++ b/main/djbdns/APKBUILD
@@ -1,7 +1,7 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=djbdns
pkgver=1.05
-pkgrel=31
+pkgrel=32
pkgdesc="Excellent high-performance DNS services"
url="http://cr.yp.to/djbdns.html"
license="public-domain"
@@ -11,6 +11,7 @@ source="http://cr.yp.to/djbdns/$pkgname-$pkgver.tar.gz
headtail.patch
dnsroots.patch
dnstracesort.patch
+ djbdns-1.05-jumbo-josb.patch
$pkgver-errno.patch
$pkgver-response.patch
tinydns.pre-install
@@ -76,6 +77,7 @@ md5sums="3147c5cd56832aa3b41955c7a51cbeb2 djbdns-1.05.tar.gz
0d2adaf9f1626043e8702b825cdccdd6 headtail.patch
7565048ebc981238879122c7f88cc143 dnsroots.patch
6fe7f473233f1c86b76261afd8345bf0 dnstracesort.patch
+adb6745606cae593eb5ea6870fc27bd4 djbdns-1.05-jumbo-josb.patch
c7be73fe2fb4ae02d5096fa2c1f55a68 1.05-errno.patch
1292500c04baba3995d9753fe40fdc94 1.05-response.patch
7695bf50559c09798ec852b578ac8698 tinydns.pre-install
diff --git a/main/djbdns/djbdns-1.05-jumbo-josb.patch b/main/djbdns/djbdns-1.05-jumbo-josb.patch
new file mode 100644
index 000000000..c1a685aef
--- /dev/null
+++ b/main/djbdns/djbdns-1.05-jumbo-josb.patch
@@ -0,0 +1,1858 @@
+Downloaded from:
+http://lizzy.dyndns.org/~jos/djbdns-1.05-jumbo-josb.patch
+
+This patch combines the following patches:
+- Claudiu Costin's jumbo-p13.patch
+ http://www.ro.kde.org/djbdns/mywork/jumbo/jumbo-p13.patch.gz
+- Guilherme Balena Versiani's djbdns SRV+NAPTR combined patch
+ http://mywebpage.netscape.com/guibv/djbdns-1.05-srvnaptr.diff
+
+diff -ruN djbdns-1.05-dist/CHANGES djbdns-1.05/CHANGES
+--- djbdns-1.05-dist/CHANGES 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/CHANGES 2008-08-11 19:33:30.000000000 -0700
+@@ -374,3 +374,5 @@
+ ui: servers print starting message.
+ internal: some respond() declarations.
+ version: djbdns 1.05.
++20010313
++ patch: to dump and reload the cache
+diff -ruN djbdns-1.05-dist/Makefile djbdns-1.05/Makefile
+--- djbdns-1.05-dist/Makefile 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/Makefile 2008-08-11 19:33:30.000000000 -0700
+@@ -4,6 +4,8 @@
+
+ default: it
+
++include Makefile.sig
++
+ alloc.a: \
+ makelib alloc.o alloc_re.o getln.o getln2.o stralloc_cat.o \
+ stralloc_catb.o stralloc_cats.o stralloc_copy.o stralloc_eady.o \
+@@ -149,13 +151,13 @@
+
+ cache.o: \
+ compile cache.c alloc.h byte.h uint32.h exit.h tai.h uint64.h cache.h \
+-uint32.h uint64.h
++uint32.h uint64.h env.h error.h open.h openreadclose.h
+ ./compile cache.c
+
+ cachetest: \
+-load cachetest.o cache.o libtai.a buffer.a alloc.a unix.a byte.a
+- ./load cachetest cache.o libtai.a buffer.a alloc.a unix.a \
+- byte.a
++load cachetest.o cache.o libtai.a buffer.a alloc.a unix.a byte.a env.a
++ ./load cachetest cache.o libtai.a buffer.a unix.a env.a \
++ alloc.a byte.a dns.a
+
+ cachetest.o: \
+ compile cachetest.c buffer.h exit.h cache.h uint32.h uint64.h str.h
+@@ -228,11 +230,11 @@
+ dns.a: \
+ makelib dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o dns_ipq.o dns_mx.o \
+ dns_name.o dns_nd.o dns_packet.o dns_random.o dns_rcip.o dns_rcrw.o \
+-dns_resolve.o dns_sortip.o dns_transmit.o dns_txt.o
++dns_resolve.o dns_rotateip.o dns_sortip.o dns_transmit.o dns_txt.o
+ ./makelib dns.a dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o \
+ dns_ipq.o dns_mx.o dns_name.o dns_nd.o dns_packet.o \
+ dns_random.o dns_rcip.o dns_rcrw.o dns_resolve.o \
+- dns_sortip.o dns_transmit.o dns_txt.o
++ dns_rotateip.o dns_sortip.o dns_transmit.o dns_txt.o
+
+ dns_dfd.o: \
+ compile dns_dfd.c error.h alloc.h byte.h dns.h stralloc.h gen_alloc.h \
+@@ -301,6 +303,10 @@
+ dns.h stralloc.h gen_alloc.h iopause.h taia.h
+ ./compile dns_resolve.c
+
++dns_rotateip.o: \
++compile dns_rotateip.c byte.h dns.h stralloc.h gen_alloc.h
++ ./compile dns_rotateip.c
++
+ dns_sortip.o: \
+ compile dns_sortip.c byte.h dns.h stralloc.h gen_alloc.h iopause.h \
+ taia.h tai.h uint64.h taia.h
+@@ -320,10 +326,10 @@
+ dnscache: \
+ load dnscache.o droproot.o okclient.o log.o cache.o query.o \
+ response.o dd.o roots.o iopause.o prot.o dns.a env.a alloc.a buffer.a \
+-libtai.a unix.a byte.a socket.lib
++libtai.a unix.a byte.a sig.a socket.lib
+ ./load dnscache droproot.o okclient.o log.o cache.o \
+ query.o response.o dd.o roots.o iopause.o prot.o dns.a \
+- env.a alloc.a buffer.a libtai.a unix.a byte.a `cat \
++ env.a alloc.a buffer.a libtai.a unix.a byte.a sig.a `cat \
+ socket.lib`
+
+ dnscache-conf: \
+@@ -626,9 +632,9 @@
+ ./compile parsetype.c
+
+ pickdns: \
+-load pickdns.o server.o response.o droproot.o qlog.o prot.o dns.a \
++load pickdns.o server.o iopause.o response.o droproot.o qlog.o prot.o dns.a \
+ env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib
+- ./load pickdns server.o response.o droproot.o qlog.o \
++ ./load pickdns server.o iopause.o response.o droproot.o qlog.o \
+ prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \
+ byte.a `cat socket.lib`
+
+@@ -704,9 +710,9 @@
+ ./compile random-ip.c
+
+ rbldns: \
+-load rbldns.o server.o response.o dd.o droproot.o qlog.o prot.o dns.a \
++load rbldns.o server.o iopause.o response.o dd.o droproot.o qlog.o prot.o dns.a \
+ env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib
+- ./load rbldns server.o response.o dd.o droproot.o qlog.o \
++ ./load rbldns server.o iopause.o response.o dd.o droproot.o qlog.o \
+ prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \
+ byte.a `cat socket.lib`
+
+@@ -774,7 +780,7 @@
+ compile server.c byte.h case.h env.h buffer.h strerr.h ip4.h uint16.h \
+ ndelay.h socket.h uint16.h droproot.h qlog.h uint16.h response.h \
+ uint32.h dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h \
+-taia.h
++taia.h iopause.h alloc.h
+ ./compile server.c
+
+ setup: \
+@@ -979,10 +985,10 @@
+ ./compile timeoutwrite.c
+
+ tinydns: \
+-load tinydns.o server.o droproot.o tdlookup.o response.o qlog.o \
++load tinydns.o server.o iopause.o droproot.o tdlookup.o response.o qlog.o \
+ prot.o dns.a libtai.a env.a cdb.a alloc.a buffer.a unix.a byte.a \
+ socket.lib
+- ./load tinydns server.o droproot.o tdlookup.o response.o \
++ ./load tinydns server.o iopause.o droproot.o tdlookup.o response.o \
+ qlog.o prot.o dns.a libtai.a env.a cdb.a alloc.a buffer.a \
+ unix.a byte.a `cat socket.lib`
+
+@@ -1084,10 +1090,10 @@
+ ./compile utime.c
+
+ walldns: \
+-load walldns.o server.o response.o droproot.o qlog.o prot.o dd.o \
++load walldns.o server.o iopause.o response.o droproot.o qlog.o prot.o dd.o \
+ dns.a env.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib
+- ./load walldns server.o response.o droproot.o qlog.o \
+- prot.o dd.o dns.a env.a cdb.a alloc.a buffer.a unix.a \
++ ./load walldns server.o iopause.o response.o droproot.o qlog.o \
++ prot.o dd.o dns.a libtai.a env.a cdb.a alloc.a buffer.a unix.a \
+ byte.a `cat socket.lib`
+
+ walldns-conf: \
+diff -ruN djbdns-1.05-dist/Makefile.sig djbdns-1.05/Makefile.sig
+--- djbdns-1.05-dist/Makefile.sig 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/Makefile.sig 2008-08-11 19:33:30.000000000 -0700
+@@ -0,0 +1,27 @@
++sig.o: \
++compile sig.c sig.h
++ ./compile sig.c
++
++sig_block.o: \
++compile sig_block.c sig.h hassgprm.h
++ ./compile sig_block.c
++
++sig_catch.o: \
++compile sig_catch.c sig.h hassgact.h
++ ./compile sig_catch.c
++
++sig_pause.o: \
++compile sig_pause.c sig.h hassgprm.h
++ ./compile sig_pause.c
++
++sig.a: \
++makelib sig.o sig_block.o sig_catch.o sig_pause.o
++ ./makelib sig.a sig.o sig_block.o sig_catch.o sig_pause.o
++
++hassgact.h: \
++choose compile load trysgact.c hassgact.h1 hassgact.h2
++ ./choose cl trysgact hassgact.h1 hassgact.h2 > hassgact.h
++
++hassgprm.h: \
++choose compile load trysgprm.c hassgprm.h1 hassgprm.h2
++ ./choose cl trysgprm hassgprm.h1 hassgprm.h2 > hassgprm.h
+diff -ruN djbdns-1.05-dist/README djbdns-1.05/README
+--- djbdns-1.05-dist/README 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/README 2008-08-11 19:33:30.000000000 -0700
+@@ -1,3 +1,9 @@
++patchlevel fg1
++20010313
++by Florent Guillaume <florent.guillaume@mail.com>
++patch home page: http://mapage.noos.fr/efgeor/djbdns/index.html
++Uses parts of Felix von Leitner's djb-0.5.2 package: http://www.fefe.de/djb/
++
+ djbdns 1.05
+ 20010211
+ Copyright 2001
+diff -ruN djbdns-1.05-dist/SYSDEPS djbdns-1.05/SYSDEPS
+--- djbdns-1.05-dist/SYSDEPS 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/SYSDEPS 2008-08-11 19:33:30.000000000 -0700
+@@ -7,4 +7,6 @@
+ direntry.h
+ hasshsgr.h
+ hasdevtcp.h
++hassgact.h
++hassgprm.h
+ socket.lib
+diff -ruN djbdns-1.05-dist/TARGETS djbdns-1.05/TARGETS
+--- djbdns-1.05-dist/TARGETS 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/TARGETS 2008-08-11 19:33:30.000000000 -0700
+@@ -214,3 +214,10 @@
+ it
+ setup
+ check
++sig.o
++sig.a
++sig_catch.o
++sig_block.o
++hassgact.h
++hassgprm.h
++sig_pause.o
+diff -ruN djbdns-1.05-dist/VERSION djbdns-1.05/VERSION
+--- djbdns-1.05-dist/VERSION 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/VERSION 2008-08-11 19:33:30.000000000 -0700
+@@ -1 +1 @@
+-djbdns 1.05
++djbdns 1.05-fg1
+diff -ruN djbdns-1.05-dist/auto_home.c djbdns-1.05/auto_home.c
+--- djbdns-1.05-dist/auto_home.c 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/auto_home.c 2008-08-12 09:17:21.000000000 -0700
+@@ -0,0 +1,3 @@
++const char auto_home[] = "\
++\057\165\163\162\057\154\157\143\141\154\
++";
+diff -ruN djbdns-1.05-dist/axfr-get.c djbdns-1.05/axfr-get.c
+--- djbdns-1.05-dist/axfr-get.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/axfr-get.c 2008-08-11 22:49:05.000000000 -0700
+@@ -209,6 +209,57 @@
+ if (!stralloc_cats(&line,".:")) return 0;
+ if (!stralloc_catulong0(&line,dist,0)) return 0;
+ }
++ else if (byte_equal(data,2,DNS_T_SRV)) {
++ uint16 priority, weight, port;
++ if (!stralloc_copys(&line,"S")) return 0;
++ if (!dns_domain_todot_cat(&line,d1)) return 0;
++ if (!stralloc_cats(&line,"::")) return 0;
++ pos = x_copy(buf,len,pos,data,2);
++ uint16_unpack_big(data,&priority);
++ pos = x_copy(buf,len,pos,data,2);
++ uint16_unpack_big(data,&weight);
++ pos = x_copy(buf,len,pos,data,2);
++ uint16_unpack_big(data,&port);
++ x_getname(buf,len,pos,&d1);
++ if (!dns_domain_todot_cat(&line,d1)) return 0;
++ if (!stralloc_cats(&line,".:")) return 0;
++ if (!stralloc_catulong0(&line,port,0)) return 0;
++ if (!stralloc_cats(&line,":")) return 0;
++ if (!stralloc_catulong0(&line,priority,0)) return 0;
++ if (!stralloc_cats(&line,":")) return 0;
++ if (!stralloc_catulong0(&line,weight,0)) return 0;
++ }
++ else if (byte_equal(data,2,DNS_T_NAPTR)) {
++ uint16 order, preference;
++ char flags[255], service[255], regexp[255];
++ char fs, ss, rs;
++ if (!stralloc_copys(&line,"N")) return 0;
++ if (!dns_domain_todot_cat(&line,d1)) return 0;
++ if (!stralloc_cats(&line,":")) return 0;
++ pos = x_copy(buf,len,pos,data,2);
++ uint16_unpack_big(data,&order);
++ pos = x_copy(buf,len,pos,data,2);
++ uint16_unpack_big(data,&preference);
++ pos = x_copy(buf,len,pos,&fs,1);
++ pos = x_copy(buf,len,pos,flags,fs);
++ pos = x_copy(buf,len,pos,&ss,1);
++ pos = x_copy(buf,len,pos,service,ss);
++ pos = x_copy(buf,len,pos,&rs,1);
++ pos = x_copy(buf,len,pos,regexp,rs);
++ x_getname(buf,len,pos,&d1);
++ if (!stralloc_catulong0(&line,order,0)) return 0;
++ if (!stralloc_cats(&line,":")) return 0;
++ if (!stralloc_catulong0(&line,preference,0)) return 0;
++ if (!stralloc_cats(&line,":")) return 0;
++ if (!stralloc_catb(&line,flags,fs)) return 0;
++ if (!stralloc_cats(&line,":")) return 0;
++ if (!stralloc_catb(&line,service,ss)) return 0;
++ if (!stralloc_cats(&line,":")) return 0;
++ if (!stralloc_catb(&line,regexp,rs)) return 0;
++ if (!stralloc_cats(&line,":")) return 0;
++ if (!dns_domain_todot_cat(&line,d1)) return 0;
++ if (!stralloc_cats(&line,".")) return 0;
++ }
+ else if (byte_equal(data,2,DNS_T_A) && (dlen == 4)) {
+ char ipstr[IP4_FMT];
+ if (!stralloc_copys(&line,"+")) return 0;
+@@ -217,6 +268,14 @@
+ x_copy(buf,len,pos,data,4);
+ if (!stralloc_catb(&line,ipstr,ip4_fmt(ipstr,data))) return 0;
+ }
++ else if (byte_equal(data,2,DNS_T_PTR)) {
++ if (!stralloc_copys(&line,"^")) return 0;
++ if (!dns_domain_todot_cat(&line,d1)) return 0;
++ if (!stralloc_cats(&line,":")) return 0;
++ x_getname(buf,len,pos,&d1);
++ if (!dns_domain_todot_cat(&line,d1)) return 0;
++ if (!stralloc_cats(&line,".")) return 0;
++ }
+ else {
+ unsigned char ch;
+ unsigned char ch2;
+diff -ruN djbdns-1.05-dist/cache.c djbdns-1.05/cache.c
+--- djbdns-1.05-dist/cache.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/cache.c 2008-08-11 19:33:30.000000000 -0700
+@@ -1,12 +1,23 @@
++#ifdef DUMPCACHE
++#include <stdio.h>
++#include <unistd.h>
++#include "env.h"
++#include "error.h"
++#include "open.h"
++#include "openreadclose.h"
++#endif
+ #include "alloc.h"
+ #include "byte.h"
+ #include "uint32.h"
+ #include "exit.h"
+ #include "tai.h"
+ #include "cache.h"
++#include "dns.h"
++#include "buffer.h"
+
+ uint64 cache_motion = 0;
+
++static char *rrobin;
+ static char *x = 0;
+ static uint32 size;
+ static uint32 hsize;
+@@ -87,6 +98,12 @@
+ uint32 u;
+ unsigned int loop;
+ double d;
++ static int trigger=0;
++
++ if (!trigger) {
++ rrobin = env_get("ROUNDROBIN");
++ trigger++;
++ }
+
+ if (!x) return 0;
+ if (keylen > MAXKEYLEN) return 0;
+@@ -111,7 +128,11 @@
+ u = get4(pos + 8);
+ if (u > size - pos - 20 - keylen) cache_impossible();
+ *datalen = u;
+-
++ if (byte_equal(key,2,DNS_T_A)) {
++ if (rrobin) {
++ dns_rotateip(x + pos + 20 + keylen,u);
++ }
++ }
+ return x + pos + 20 + keylen;
+ }
+ }
+@@ -205,3 +226,97 @@
+
+ return 1;
+ }
++
++#ifdef DUMPCACHE
++static int fd;
++
++static int cache_writeline(const char *buf, unsigned int len)
++{
++ int w;
++
++ while (len) {
++ w = write(fd,buf,len);
++ if (w == -1) {
++ if (errno == error_intr) continue;
++ close(fd);
++ return -1;
++ }
++ buf += w;
++ len -= w;
++ }
++ return 0;
++}
++
++int cache_dump(void)
++{
++ static char *fn;
++ static char *fntmp;
++ uint32 pos;
++ unsigned int len;
++
++ fn = env_get("DUMPCACHE");
++ if (!fn) return 999;
++ fntmp = env_get("DUMPCACHETMP");
++ if (!fntmp) return 999;
++ fd = open_trunc(fntmp);
++ if (fd == -1) return -1;
++
++ pos = oldest;
++ while (pos < unused) {
++ len = get4(pos + 4) + get4(pos + 8) + 16;
++ if (cache_writeline(x + pos + 4, len)) return -1;
++ pos += 4 + len;
++ }
++ pos = hsize;
++ while (pos < writer) {
++ len = get4(pos + 4) + get4(pos + 8) + 16;
++ if (cache_writeline(x + pos + 4, len)) return -1;
++ pos += 4 + len;
++ }
++
++ if (fsync(fd) == -1) return -1;
++ if (close(fd) == -1) return -1;
++ if (rename(fntmp,fn) == -1) return -1;
++ return 0;
++}
++
++int cache_slurp(const char *fn)
++{
++ static stralloc buf = {0};
++ char *p;
++ uint32 pos;
++ unsigned int len;
++ uint32 keylen;
++ uint32 datalen;
++ struct tai now;
++ struct tai expire;
++ int nb;
++
++ if (openreadclose(fn,&buf,16384) != 1) goto DIE;
++ tai_now(&now);
++ p = buf.s;
++ pos = 0;
++ len = buf.len;
++ nb = 0;
++ while (pos + 16 <= len) {
++ uint32_unpack(p + pos, &keylen);
++ uint32_unpack(p + pos + 4, &datalen);
++ tai_unpack(p + pos + 8, &expire);
++ pos += 16;
++ if (pos + keylen + datalen > len) break; /* missing data */
++ if (!tai_less(&expire,&now)) {
++ tai_sub(&expire,&expire,&now);
++ cache_set(p + pos, keylen, p + pos + keylen, datalen, (unsigned int)expire.x);
++ }
++ pos += keylen + datalen;
++ nb++;
++ }
++ alloc_free(buf.s); buf.s = 0;
++ return nb;
++
++ DIE:
++ alloc_free(buf.s); buf.s = 0;
++ if (errno == error_noent) return 0;
++ return -1;
++}
++#endif
+diff -ruN djbdns-1.05-dist/cache.h djbdns-1.05/cache.h
+--- djbdns-1.05-dist/cache.h 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/cache.h 2008-08-11 19:33:30.000000000 -0700
+@@ -8,5 +8,9 @@
+ extern int cache_init(unsigned int);
+ extern void cache_set(const char *,unsigned int,const char *,unsigned int,uint32);
+ extern char *cache_get(const char *,unsigned int,unsigned int *,uint32 *);
++#ifdef DUMPCACHE
++extern int cache_dump(void);
++extern int cache_slurp(const char *);
++#endif
+
+ #endif
+diff -ruN djbdns-1.05-dist/chkshsgr.c djbdns-1.05/chkshsgr.c
+--- djbdns-1.05-dist/chkshsgr.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/chkshsgr.c 2008-08-11 19:33:30.000000000 -0700
+@@ -1,4 +1,6 @@
+ #include "exit.h"
++#include <grp.h>
++#include <unistd.h>
+
+ int main()
+ {
+diff -ruN djbdns-1.05-dist/direntry.h djbdns-1.05/direntry.h
+--- djbdns-1.05-dist/direntry.h 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/direntry.h 2008-08-11 22:55:14.000000000 -0700
+@@ -0,0 +1,10 @@
++#ifndef DIRENTRY_H
++#define DIRENTRY_H
++
++/* sysdep: +dirent */
++
++#include <sys/types.h>
++#include <dirent.h>
++#define direntry struct dirent
++
++#endif
+diff -ruN djbdns-1.05-dist/dns.h djbdns-1.05/dns.h
+--- djbdns-1.05-dist/dns.h 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/dns.h 2008-08-11 22:49:25.000000000 -0700
+@@ -20,6 +20,8 @@
+ #define DNS_T_SIG "\0\30"
+ #define DNS_T_KEY "\0\31"
+ #define DNS_T_AAAA "\0\34"
++#define DNS_T_SRV "\0\41"
++#define DNS_T_NAPTR "\0\43"
+ #define DNS_T_AXFR "\0\374"
+ #define DNS_T_ANY "\0\377"
+
+@@ -43,6 +45,7 @@
+ extern unsigned int dns_random(unsigned int);
+
+ extern void dns_sortip(char *,unsigned int);
++extern void dns_rotateip(char *,unsigned int);
+
+ extern void dns_domain_free(char **);
+ extern int dns_domain_copy(char **,const char *);
+diff -ruN djbdns-1.05-dist/dns_rotateip.c djbdns-1.05/dns_rotateip.c
+--- djbdns-1.05-dist/dns_rotateip.c 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/dns_rotateip.c 2008-08-11 19:33:30.000000000 -0700
+@@ -0,0 +1,15 @@
++#include "byte.h"
++
++void dns_rotateip(char *s, unsigned int n)
++{
++ unsigned int i;
++ char tmp[4];
++
++ i = n >> 2;
++ while (i > 1) {
++ --i;
++ byte_copy(tmp,4,s + (i << 2));
++ byte_copy(s + (i << 2),4,s);
++ byte_copy(s,4,tmp);
++ }
++}
+diff -ruN djbdns-1.05-dist/dnscache-conf.c djbdns-1.05/dnscache-conf.c
+--- djbdns-1.05-dist/dnscache-conf.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/dnscache-conf.c 2008-08-11 19:33:30.000000000 -0700
+@@ -32,6 +32,10 @@
+ char *user;
+ char *loguser;
+ struct passwd *pw;
++#ifdef DUMPCACHE
++int useruid;
++int usergid;
++#endif
+ const char *myip;
+
+ uint32 seed[32];
+@@ -81,6 +85,14 @@
+ myip = argv[4];
+ if (!myip) myip = "127.0.0.1";
+
++#ifdef DUMPCACHE
++ pw = getpwnam(user);
++ seed_addtime();
++ if (!pw)
++ strerr_die3x(111,FATAL,"unknown account ",user);
++ useruid = pw->pw_uid;
++ usergid = pw->pw_gid;
++#endif
+ pw = getpwnam(loguser);
+ seed_addtime();
+ if (!pw)
+@@ -120,6 +132,14 @@
+ seed_addtime(); perm(0644);
+ seed_addtime(); start("env/DATALIMIT"); outs("3000000\n"); finish();
+ seed_addtime(); perm(0644);
++#ifdef DUMPCACHE
++ seed_addtime(); start("env/SLURPCACHE"); outs("dump/slurpcache\n"); finish();
++ seed_addtime(); perm(0644);
++ seed_addtime(); start("env/DUMPCACHE"); outs("dump/dumpcache\n"); finish();
++ seed_addtime(); perm(0644);
++ seed_addtime(); start("env/DUMPCACHETMP"); outs("dump/dumpcache.tmp\n"); finish();
++ seed_addtime(); perm(0644);
++#endif
+ seed_addtime(); start("run");
+ outs("#!/bin/sh\nexec 2>&1\nexec <seed\nexec envdir ./env sh -c '\n exec envuidgid "); outs(user);
+ outs(" softlimit -o250 -d \"$DATALIMIT\" ");
+@@ -131,6 +151,11 @@
+ seed_addtime(); perm(0755);
+ seed_addtime(); makedir("root");
+ seed_addtime(); perm(02755);
++#ifdef DUMPCACHE
++ seed_addtime(); makedir("root/dump");
++ seed_addtime(); owner(useruid,usergid);
++ seed_addtime(); perm(02755);
++#endif
+ seed_addtime(); makedir("root/ip");
+ seed_addtime(); perm(02755);
+ seed_addtime(); start("root/ip/127.0.0.1"); finish();
+diff -ruN djbdns-1.05-dist/dnscache.c djbdns-1.05/dnscache.c
+--- djbdns-1.05-dist/dnscache.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/dnscache.c 2008-08-11 19:33:30.000000000 -0700
+@@ -5,6 +5,7 @@
+ #include "strerr.h"
+ #include "error.h"
+ #include "ip4.h"
++#include "str.h"
+ #include "uint16.h"
+ #include "uint64.h"
+ #include "socket.h"
+@@ -22,6 +23,7 @@
+ #include "log.h"
+ #include "okclient.h"
+ #include "droproot.h"
++#include "sig.h"
+
+ static int packetquery(char *buf,unsigned int len,char **q,char qtype[2],char qclass[2],char id[2])
+ {
+@@ -47,12 +49,20 @@
+
+
+ static char myipoutgoing[4];
+-static char myipincoming[4];
+ static char buf[1024];
+ uint64 numqueries = 0;
+
++struct interf {
++ char ip[4];
++ int udp53;
++ int tcp53;
++ iopause_fd *udp53io;
++ iopause_fd *tcp53io;
++
++ struct interf *next;
++} ;
+
+-static int udp53;
++struct interf *interhead = 0;
+
+ #define MAXUDP 200
+ static struct udpclient {
+@@ -60,6 +70,7 @@
+ struct taia start;
+ uint64 active; /* query number, if active; otherwise 0 */
+ iopause_fd *io;
++ int fd;
+ char ip[4];
+ uint16 port;
+ char id[2];
+@@ -78,12 +89,12 @@
+ if (!u[j].active) return;
+ response_id(u[j].id);
+ if (response_len > 512) response_tc();
+- socket_send4(udp53,response,response_len,u[j].ip,u[j].port);
++ socket_send4(u[j].fd,response,response_len,u[j].ip,u[j].port);
+ log_querydone(&u[j].active,response_len);
+ u[j].active = 0; --uactive;
+ }
+
+-void u_new(void)
++void u_new(int fd)
+ {
+ int j;
+ int i;
+@@ -108,8 +119,9 @@
+
+ x = u + j;
+ taia_now(&x->start);
++ x->fd = fd;
+
+- len = socket_recv4(udp53,buf,sizeof buf,x->ip,&x->port);
++ len = socket_recv4(x->fd,buf,sizeof buf,x->ip,&x->port);
+ if (len == -1) return;
+ if (len >= sizeof buf) return;
+ if (x->port < 1024) if (x->port != 53) return;
+@@ -129,8 +141,6 @@
+ }
+
+
+-static int tcp53;
+-
+ #define MAXTCP 20
+ struct tcpclient {
+ struct query q;
+@@ -138,6 +148,7 @@
+ struct taia timeout;
+ uint64 active; /* query number or 1, if active; otherwise 0 */
+ iopause_fd *io;
++ int fd;
+ char ip[4]; /* send response to this address */
+ uint16 port; /* send response to this port */
+ char id[2];
+@@ -266,7 +277,7 @@
+ x->state = 0;
+ }
+
+-void t_new(void)
++void t_new(int fd)
+ {
+ int i;
+ int j;
+@@ -290,8 +301,9 @@
+
+ x = t + j;
+ taia_now(&x->start);
++ x->fd = fd;
+
+- x->tcp = socket_accept4(tcp53,x->ip,&x->port);
++ x->tcp = socket_accept4(x->fd,x->ip,&x->port);
+ if (x->tcp == -1) return;
+ if (x->port < 1024) if (x->port != 53) { close(x->tcp); return; }
+ if (!okclient(x->ip)) { close(x->tcp); return; }
+@@ -304,19 +316,44 @@
+ log_tcpopen(x->ip,x->port);
+ }
+
++#ifdef DUMPCACHE
++static void do_dump(void)
++{
++ int r;
++ r = cache_dump();
++ if (r < 0)
++ r = errno;
++ log_dump(r);
++}
++#endif
++
++#define FATAL "dnscache: fatal: "
++
++iopause_fd *io = 0;
++int numio;
++
++void hup_me()
++{
++ if (!roots_init())
++ strerr_die2sys(111,FATAL,"unable to read servers: ");
++
++ log_reread();
++}
+
+-iopause_fd io[3 + MAXUDP + MAXTCP];
+-iopause_fd *udp53io;
+-iopause_fd *tcp53io;
+
+ static void doit(void)
+ {
+ int j;
+ struct taia deadline;
+ struct taia stamp;
++ struct interf *inter;
+ int iolen;
+ int r;
+
++ io = (iopause_fd *) alloc((numio + 1 + MAXUDP + MAXTCP) * sizeof(iopause_fd));
++ if (!io)
++ strerr_die2sys(111,FATAL,"unable to alloc io: ");
++
+ for (;;) {
+ taia_now(&stamp);
+ taia_uint(&deadline,120);
+@@ -324,13 +361,15 @@
+
+ iolen = 0;
+
+- udp53io = io + iolen++;
+- udp53io->fd = udp53;
+- udp53io->events = IOPAUSE_READ;
+-
+- tcp53io = io + iolen++;
+- tcp53io->fd = tcp53;
+- tcp53io->events = IOPAUSE_READ;
++ for (inter = interhead; inter != 0; inter = inter->next) {
++ inter->udp53io = io + iolen++;
++ inter->udp53io->fd = inter->udp53;
++ inter->udp53io->events = IOPAUSE_READ;
++
++ inter->tcp53io = io + iolen++;
++ inter->tcp53io->fd = inter->tcp53;
++ inter->tcp53io->events = IOPAUSE_READ;
++ }
+
+ for (j = 0;j < MAXUDP;++j)
+ if (u[j].active) {
+@@ -372,46 +411,83 @@
+ t_rw(j);
+ }
+
+- if (udp53io)
+- if (udp53io->revents)
+- u_new();
+-
+- if (tcp53io)
+- if (tcp53io->revents)
+- t_new();
++ for (inter = interhead; inter != 0; inter = inter->next) {
++ if (inter->udp53io)
++ if (inter->udp53io->revents)
++ u_new(inter->udp53);
++
++ if (inter->tcp53io)
++ if (inter->tcp53io->revents)
++ t_new(inter->tcp53);
++ }
+ }
+ }
+
+-#define FATAL "dnscache: fatal: "
+-
+ char seed[128];
+
+ int main()
+ {
+ char *x;
++ char nxdip[4];
++ int len;
++ int pos;
++ int oldpos;
++ char iptmp[4];
++ char iperr[IP4_FMT];
++ struct interf *inter;
++ struct interf *itmp;
+ unsigned long cachesize;
+
+ x = env_get("IP");
+ if (!x)
+ strerr_die2x(111,FATAL,"$IP not set");
+- if (!ip4_scan(x,myipincoming))
+- strerr_die3x(111,FATAL,"unable to parse IP address ",x);
+
+- udp53 = socket_udp();
+- if (udp53 == -1)
+- strerr_die2sys(111,FATAL,"unable to create UDP socket: ");
+- if (socket_bind4_reuse(udp53,myipincoming,53) == -1)
+- strerr_die2sys(111,FATAL,"unable to bind UDP socket: ");
+-
+- tcp53 = socket_tcp();
+- if (tcp53 == -1)
+- strerr_die2sys(111,FATAL,"unable to create TCP socket: ");
+- if (socket_bind4_reuse(tcp53,myipincoming,53) == -1)
+- strerr_die2sys(111,FATAL,"unable to bind TCP socket: ");
++ len = str_len(x);
++ numio = pos = oldpos = 0;
++
++ while (pos < len) {
++ if (pos) oldpos = pos + 1;
++ pos = oldpos + str_chr(x + oldpos,'/');
++ x[pos] = 0;
++ if (!str_len(x + oldpos)) continue;
++
++ if (!ip4_scan(x + oldpos,iptmp))
++ strerr_die3x(111,FATAL,"unable to parse IP address ",x + oldpos);
++
++ inter = (struct interf *) alloc(sizeof(struct interf));
++
++ if (interhead == 0) interhead = inter;
++ else if (interhead->next == 0) interhead->next = inter;
++ else {
++ for (itmp = interhead; itmp->next != 0; itmp = itmp->next);
++ itmp->next = inter;
++ }
++
++ inter->next = 0;
++
++ inter->udp53 = socket_udp();
++ if (inter->udp53 == -1)
++ strerr_die4sys(111,FATAL,"unable to create UDP socket for IP address ",x + oldpos,": ");
++ if (socket_bind4_reuse(inter->udp53,iptmp,53) == -1)
++ strerr_die4sys(111,FATAL,"unable to bind UDP socket for IP address ",x + oldpos,": ");
++
++ inter->tcp53 = socket_tcp();
++ if (inter->tcp53 == -1)
++ strerr_die4sys(111,FATAL,"unable to create TCP socket for IP address ",x + oldpos,": ");
++ if (socket_bind4_reuse(inter->tcp53,iptmp,53) == -1)
++ strerr_die4sys(111,FATAL,"unable to bind TCP socket for IP address ",x + oldpos,": ");
++
++ numio++;
++ log_listen(iptmp);
++ }
++
++ if (interhead == 0)
++ strerr_die2x(111,FATAL,"no interfaces to listen on");
+
+ droproot(FATAL);
+
+- socket_tryreservein(udp53,131072);
++ for (inter = interhead; inter != 0; inter = inter->next)
++ socket_tryreservein(inter->udp53,131072);
+
+ byte_zero(seed,sizeof seed);
+ read(0,seed,sizeof seed);
+@@ -430,17 +506,42 @@
+ scan_ulong(x,&cachesize);
+ if (!cache_init(cachesize))
+ strerr_die3x(111,FATAL,"not enough memory for cache of size ",x);
++#ifdef DUMPCACHE
++ x = env_get("SLURPCACHE");
++ if (x) {
++ int nb = cache_slurp(x);
++ if (nb < 0)
++ strerr_die4sys(111,FATAL,"unable to slurp cache ",x," : ");
++ else
++ log_slurp(nb);
++ }
++#endif
+
+ if (env_get("HIDETTL"))
+ response_hidettl();
+ if (env_get("FORWARDONLY"))
+ query_forwardonly();
+
++ x = env_get("NXDSPECIAL");
++ if (x) {
++ if (!ip4_scan(x,nxdip))
++ strerr_die3x(111,FATAL,"unable to parse NXDSPECIAL IP address ",x);
++ query_nxdspecial(nxdip);
++ }
++
+ if (!roots_init())
+ strerr_die2sys(111,FATAL,"unable to read servers: ");
+
+- if (socket_listen(tcp53,20) == -1)
+- strerr_die2sys(111,FATAL,"unable to listen on TCP socket: ");
++ for (inter = interhead; inter != 0; inter = inter->next)
++ if (socket_listen(inter->tcp53,20) == -1) {
++ iperr[ip4_fmt(iperr,inter->ip)] = 0;
++ strerr_die4sys(111,FATAL,"unable to listen on TCP socket for IP ",iperr,": ");
++ }
++
++#ifdef DUMPCACHE
++ sig_catch(sig_alarm,do_dump);
++#endif
++ sig_catch(sig_hangup, hup_me);
+
+ log_startup();
+ doit();
+diff -ruN djbdns-1.05-dist/dnsfilter.c djbdns-1.05/dnsfilter.c
+--- djbdns-1.05-dist/dnsfilter.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/dnsfilter.c 2008-08-11 19:33:30.000000000 -0700
+@@ -41,6 +41,7 @@
+ iopause_fd *inio;
+ int flag0 = 1;
+
++int opt_replace = 0;
+ iopause_fd *io;
+ int iolen;
+
+@@ -51,12 +52,16 @@
+ void errout(int i)
+ {
+ int j;
+-
+- if (!stralloc_copys(&x[i].middle,":")) nomem();
+- if (!stralloc_cats(&x[i].middle,error_str(errno))) nomem();
+- for (j = 0;j < x[i].middle.len;++j)
+- if (x[i].middle.s[j] == ' ')
+- x[i].middle.s[j] = '-';
++
++ if (opt_replace)
++ x[i].middle.len=0;
++ else {
++ if (!stralloc_copys(&x[i].middle,":")) nomem();
++ if (!stralloc_cats(&x[i].middle,error_str(errno))) nomem();
++ for (j = 0;j < x[i].middle.len;++j)
++ if (x[i].middle.s[j] == ' ')
++ x[i].middle.s[j] = '-';
++ }
+ }
+
+ int main(int argc,char **argv)
+@@ -69,7 +74,7 @@
+ int j;
+ int r;
+
+- while ((opt = getopt(argc,argv,"c:l:")) != opteof)
++ while ((opt = getopt(argc,argv,"c:l:r")) != opteof)
+ switch(opt) {
+ case 'c':
+ scan_ulong(optarg,&u);
+@@ -83,8 +88,11 @@
+ if (u > 1000000) u = 1000000;
+ xmax = u;
+ break;
++ case 'r':
++ opt_replace = 1;
++ break;
+ default:
+- strerr_die1x(111,"dnsfilter: usage: dnsfilter [ -c concurrency ] [ -l lines ]");
++ strerr_die1x(111,"dnsfilter: usage: dnsfilter [ -c concurrency ] [ -l lines ] [-r]");
+ }
+
+ x = (struct line *) alloc(xmax * sizeof(struct line));
+@@ -140,8 +148,13 @@
+ else if (r == 1) {
+ if (dns_name_packet(&x[i].middle,x[i].dt.packet,x[i].dt.packetlen) == -1)
+ errout(i);
+- if (x[i].middle.len)
+- if (!stralloc_cats(&x[i].left,"=")) nomem();
++ if (x[i].middle.len) {
++ if (opt_replace) {
++ if (!stralloc_copys(&x[i].left, "")) nomem();
++ } else {
++ if (!stralloc_cats(&x[i].left, "=")) nomem();
++ }
++ }
+ x[i].flagactive = 0;
+ --numactive;
+ }
+diff -ruN djbdns-1.05-dist/hasdevtcp.h djbdns-1.05/hasdevtcp.h
+--- djbdns-1.05-dist/hasdevtcp.h 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/hasdevtcp.h 2008-08-11 22:55:09.000000000 -0700
+@@ -0,0 +1 @@
++/* sysdep: -devtcp */
+diff -ruN djbdns-1.05-dist/hassgact.h djbdns-1.05/hassgact.h
+--- djbdns-1.05-dist/hassgact.h 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/hassgact.h 2008-08-11 22:55:16.000000000 -0700
+@@ -0,0 +1,2 @@
++/* sysdep: +sigaction */
++#define HASSIGACTION 1
+diff -ruN djbdns-1.05-dist/hassgact.h1 djbdns-1.05/hassgact.h1
+--- djbdns-1.05-dist/hassgact.h1 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/hassgact.h1 2008-08-11 19:33:30.000000000 -0700
+@@ -0,0 +1 @@
++/* sysdep: -sigaction */
+diff -ruN djbdns-1.05-dist/hassgact.h2 djbdns-1.05/hassgact.h2
+--- djbdns-1.05-dist/hassgact.h2 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/hassgact.h2 2008-08-11 19:33:30.000000000 -0700
+@@ -0,0 +1,2 @@
++/* sysdep: +sigaction */
++#define HASSIGACTION 1
+diff -ruN djbdns-1.05-dist/hassgprm.h djbdns-1.05/hassgprm.h
+--- djbdns-1.05-dist/hassgprm.h 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/hassgprm.h 2008-08-11 22:55:15.000000000 -0700
+@@ -0,0 +1,2 @@
++/* sysdep: +sigprocmask */
++#define HASSIGPROCMASK 1
+diff -ruN djbdns-1.05-dist/hassgprm.h1 djbdns-1.05/hassgprm.h1
+--- djbdns-1.05-dist/hassgprm.h1 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/hassgprm.h1 2008-08-11 19:33:30.000000000 -0700
+@@ -0,0 +1 @@
++/* sysdep: -sigprocmask */
+diff -ruN djbdns-1.05-dist/hassgprm.h2 djbdns-1.05/hassgprm.h2
+--- djbdns-1.05-dist/hassgprm.h2 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/hassgprm.h2 2008-08-11 19:33:30.000000000 -0700
+@@ -0,0 +1,2 @@
++/* sysdep: +sigprocmask */
++#define HASSIGPROCMASK 1
+diff -ruN djbdns-1.05-dist/hasshsgr.h djbdns-1.05/hasshsgr.h
+--- djbdns-1.05-dist/hasshsgr.h 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/hasshsgr.h 2008-08-12 09:17:24.000000000 -0700
+@@ -0,0 +1 @@
++/* sysdep: -shortsetgroups */
+diff -ruN djbdns-1.05-dist/iopause.h djbdns-1.05/iopause.h
+--- djbdns-1.05-dist/iopause.h 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/iopause.h 2008-08-11 22:55:12.000000000 -0700
+@@ -0,0 +1,18 @@
++#ifndef IOPAUSE_H
++#define IOPAUSE_H
++
++/* sysdep: +poll */
++#define IOPAUSE_POLL
++
++#include <sys/types.h>
++#include <poll.h>
++
++typedef struct pollfd iopause_fd;
++#define IOPAUSE_READ POLLIN
++#define IOPAUSE_WRITE POLLOUT
++
++#include "taia.h"
++
++extern void iopause(iopause_fd *,unsigned int,struct taia *,struct taia *);
++
++#endif
+diff -ruN djbdns-1.05-dist/log.c djbdns-1.05/log.c
+--- djbdns-1.05-dist/log.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/log.c 2008-08-11 19:33:30.000000000 -0700
+@@ -88,12 +88,39 @@
+ }
+ }
+
++void log_reread(void)
++{
++ string("rereading servers configuration");
++ line();
++}
++
+ void log_startup(void)
+ {
+ string("starting");
+ line();
+ }
+
++void log_listen(const char addr[4])
++{
++ string("listening on ");
++ ip(addr);
++ line();
++}
++
++#ifdef DUMPCACHE
++void log_slurp(int nb)
++{
++ string("slurp "); number(nb);
++ line();
++}
++
++void log_dump(int err)
++{
++ string("dump err "); number(err);
++ line();
++}
++#endif
++
+ void log_query(uint64 *qnum,const char client[4],unsigned int port,const char id[2],const char *q,const char qtype[2])
+ {
+ string("query "); number(*qnum); space();
+diff -ruN djbdns-1.05-dist/log.h djbdns-1.05/log.h
+--- djbdns-1.05-dist/log.h 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/log.h 2008-08-11 19:33:30.000000000 -0700
+@@ -4,6 +4,12 @@
+ #include "uint64.h"
+
+ extern void log_startup(void);
++extern void log_listen(const char *);
++#ifdef DUMPCACHE
++extern void log_slurp(int);
++extern void log_dump(int);
++#endif
++extern void log_reread(void);
+
+ extern void log_query(uint64 *,const char *,unsigned int,const char *,const char *,const char *);
+ extern void log_querydrop(uint64 *);
+diff -ruN djbdns-1.05-dist/okclient.c djbdns-1.05/okclient.c
+--- djbdns-1.05-dist/okclient.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/okclient.c 2008-08-11 19:33:30.000000000 -0700
+@@ -1,5 +1,6 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
++#include "env.h"
+ #include "str.h"
+ #include "ip4.h"
+ #include "okclient.h"
+@@ -10,6 +11,14 @@
+ {
+ struct stat st;
+ int i;
++ static int init_done=0;
++ if (!init_done) {
++ if (env_get("OKCLIENT")) {
++ init_done=1;
++ } else
++ init_done=2;
++ }
++ if (init_done==1) return 1;
+
+ fn[0] = 'i';
+ fn[1] = 'p';
+diff -ruN djbdns-1.05-dist/parsetype.c djbdns-1.05/parsetype.c
+--- djbdns-1.05-dist/parsetype.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/parsetype.c 2008-08-11 22:49:52.000000000 -0700
+@@ -24,6 +24,8 @@
+ 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 if (case_equals(s,"srv")) byte_copy(type,2,DNS_T_SRV);
++ else if (case_equals(s,"naptr")) byte_copy(type,2,DNS_T_NAPTR);
+ else
+ return 0;
+
+diff -ruN djbdns-1.05-dist/printrecord.c djbdns-1.05/printrecord.c
+--- djbdns-1.05-dist/printrecord.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/printrecord.c 2008-08-11 23:10:20.000000000 -0700
+@@ -82,6 +82,56 @@
+ if (!stralloc_catulong0(out,ch,0)) return 0;
+ }
+ }
++ else if (byte_equal(misc,2,DNS_T_SRV)) {
++ if (!stralloc_cats(out," SRV ")) return 0;
++ pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0;
++ uint16_unpack_big(misc,&u16);
++ if (!stralloc_catulong0(out,u16,0)) return 0;
++ if (!stralloc_cats(out," ")) return 0;
++ pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0;
++ uint16_unpack_big(misc,&u16);
++ if (!stralloc_catulong0(out,u16,0)) return 0;
++ if (!stralloc_cats(out," ")) return 0;
++ pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0;
++ uint16_unpack_big(misc,&u16);
++ if (!stralloc_catulong0(out,u16,0)) return 0;
++ if (!stralloc_cats(out," ")) return 0;
++ pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
++ if (!dns_domain_todot_cat(out,d)) return 0;
++ }
++ else if (byte_equal(misc,2,DNS_T_NAPTR)) {
++ char str[255];
++ unsigned int oldpos;
++ if (!stralloc_cats(out," NAPTR ")) return 0;
++ pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0;
++ uint16_unpack_big(misc,&u16);
++ if (!stralloc_catulong0(out,u16,0)) return 0;
++ if (!stralloc_cats(out," ")) return 0;
++ pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0;
++ uint16_unpack_big(misc,&u16);
++ if (!stralloc_catulong0(out,u16,0)) return 0;
++ if (!stralloc_cats(out," ")) return 0;
++ pos = dns_packet_copy(buf,len,pos,&ch,1); if (!pos) return 0;
++ pos = dns_packet_copy(buf,len,pos,str,ch); if (!pos) return 0;
++ if (!stralloc_cats(out,"\"")) return 0;
++ if (!stralloc_catb(out,str,ch)) return 0;
++ if (!stralloc_cats(out,"\" ")) return 0;
++ pos = dns_packet_copy(buf,len,pos,&ch,1); if (!pos) return 0;
++ pos = dns_packet_copy(buf,len,pos,str,ch); if (!pos) return 0;
++ if (!stralloc_cats(out,"\"")) return 0;
++ if (!stralloc_catb(out,str,ch)) return 0;
++ if (!stralloc_cats(out,"\" ")) return 0;
++ pos = dns_packet_copy(buf,len,pos,&ch,1); if (!pos) return 0;
++ pos = dns_packet_copy(buf,len,pos,str,ch); if (!pos) return 0;
++ if (!stralloc_cats(out,"\"")) return 0;
++ if (!stralloc_catb(out,str,ch)) return 0;
++ if (!stralloc_cats(out,"\" ")) return 0;
++ pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
++ oldpos = out->len;
++ if (!dns_domain_todot_cat(out,d)) return 0;
++ if (out->len == oldpos)
++ if (!stralloc_cats(out,".")) return 0;
++ }
+ else {
+ if (!stralloc_cats(out," ")) return 0;
+ uint16_unpack_big(misc,&u16);
+diff -ruN djbdns-1.05-dist/prot.c djbdns-1.05/prot.c
+--- djbdns-1.05-dist/prot.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/prot.c 2008-08-11 19:33:30.000000000 -0700
+@@ -1,5 +1,7 @@
+ #include "hasshsgr.h"
+ #include "prot.h"
++#include <grp.h>
++#include <unistd.h>
+
+ int prot_gid(int gid)
+ {
+diff -ruN djbdns-1.05-dist/query.c djbdns-1.05/query.c
+--- djbdns-1.05-dist/query.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/query.c 2008-08-11 19:33:30.000000000 -0700
+@@ -20,6 +20,15 @@
+ flagforwardonly = 1;
+ }
+
++static int flagnxdspecial = 0;
++static char nxdip[4];
++
++void query_nxdspecial(const char ip[4])
++{
++ byte_copy(nxdip,4,ip);
++ flagnxdspecial = 1;
++}
++
+ static void cachegeneric(const char type[2],const char *d,const char *data,unsigned int datalen,uint32 ttl)
+ {
+ unsigned int len;
+@@ -246,6 +255,7 @@
+ case_lowerb(key + 2,dlen);
+ cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
+ if (cached) {
++ soattl = rcode = 0;
+ log_cachednxdomain(d);
+ goto NXDOMAIN;
+ }
+@@ -695,7 +705,12 @@
+ NXDOMAIN:
+ if (z->level) goto LOWERLEVEL;
+ if (!rqa(z)) goto DIE;
+- response_nxdomain();
++ if (flagnxdspecial && typematch(DNS_T_A,dtype)) {
++ if (!response_rstart(d,DNS_T_A,rcode == 3 ? soattl : ttl)) goto DIE;
++ if (!response_addbytes(nxdip,4)) goto DIE;
++ response_rfinish(RESPONSE_ANSWER);
++ } else
++ response_nxdomain();
+ cleanup(z);
+ return 1;
+ }
+diff -ruN djbdns-1.05-dist/query.h djbdns-1.05/query.h
+--- djbdns-1.05-dist/query.h 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/query.h 2008-08-11 19:33:30.000000000 -0700
+@@ -28,5 +28,6 @@
+ extern int query_get(struct query *,iopause_fd *,struct taia *);
+
+ extern void query_forwardonly(void);
++extern void query_nxdspecial(const char *);
+
+ #endif
+diff -ruN djbdns-1.05-dist/seek_set.c djbdns-1.05/seek_set.c
+--- djbdns-1.05-dist/seek_set.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/seek_set.c 2008-08-11 19:33:30.000000000 -0700
+@@ -1,4 +1,5 @@
+ #include <sys/types.h>
++#include <unistd.h>
+ #include "seek.h"
+
+ #define SET 0 /* sigh */
+diff -ruN djbdns-1.05-dist/select.h djbdns-1.05/select.h
+--- djbdns-1.05-dist/select.h 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/select.h 2008-08-11 22:55:14.000000000 -0700
+@@ -0,0 +1,11 @@
++#ifndef SELECT_H
++#define SELECT_H
++
++/* sysdep: +sysselect */
++
++#include <sys/types.h>
++#include <sys/time.h>
++#include <sys/select.h>
++extern int select();
++
++#endif
+diff -ruN djbdns-1.05-dist/server.c djbdns-1.05/server.c
+--- djbdns-1.05-dist/server.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/server.c 2008-08-11 19:33:30.000000000 -0700
+@@ -11,6 +11,8 @@
+ #include "qlog.h"
+ #include "response.h"
+ #include "dns.h"
++#include "alloc.h"
++#include "iopause.h"
+
+ extern char *fatal;
+ extern char *starting;
+@@ -25,6 +27,44 @@
+
+ static char *q;
+
++
++static void hex(unsigned char c)
++{
++ buffer_put(buffer_2,"0123456789abcdef" + (c >> 4),1);
++ buffer_put(buffer_2,"0123456789abcdef" + (c & 15),1);
++}
++
++static void put_ip(const char i[4])
++{
++ hex(i[0]);
++ hex(i[1]);
++ hex(i[2]);
++ hex(i[3]);
++}
++
++static void string(const char *s)
++{
++ buffer_puts(buffer_2,s);
++}
++
++static void line(void)
++{
++ string("\n");
++ buffer_flush(buffer_2);
++}
++
++void log_listen(const char addr[4])
++{
++ string("listening on ");
++ put_ip(addr);
++ line();
++}
++
++void nomem()
++{
++ strerr_die2x(111,fatal,"out of memory");
++}
++
+ static int doit(void)
+ {
+ unsigned int pos;
+@@ -51,6 +91,13 @@
+ response[3] &= ~128;
+ if (!(header[2] & 1)) response[2] &= ~1;
+
++ if ((header[2] & 126) == 0x24) /* NOTIFY + AA */
++ if (byte_equal(qtype,2,DNS_T_SOA)) {
++ response[2] |= 0x20; /* NOTIFY */
++ qlog(ip,port,header,q,qtype," N ");
++ return 1;
++ }
++
+ if (header[2] & 126) goto NOTIMP;
+ if (byte_equal(qtype,2,DNS_T_AXFR)) goto NOTIMP;
+
+@@ -59,7 +106,12 @@
+ qlog(ip,port,header,q,qtype," - ");
+ return 0;
+ }
+- qlog(ip,port,header,q,qtype," + ");
++
++ if ((response[2] & 4) && (response[3] & 3))
++ qlog(ip,port,header,q,qtype," X ");
++ else
++ qlog(ip,port,header,q,qtype," + ");
++
+ return 1;
+
+ NOTIMP:
+@@ -82,35 +134,75 @@
+ int main()
+ {
+ char *x;
+- int udp53;
++ int *udp53;
++ unsigned int off;
++ unsigned int cnt;
++ iopause_fd *iop;
+
+ x = env_get("IP");
+ if (!x)
+ strerr_die2x(111,fatal,"$IP not set");
+- if (!ip4_scan(x,ip))
+- strerr_die3x(111,fatal,"unable to parse IP address ",x);
+-
+- udp53 = socket_udp();
+- if (udp53 == -1)
+- strerr_die2sys(111,fatal,"unable to create UDP socket: ");
+- if (socket_bind4_reuse(udp53,ip,53) == -1)
+- strerr_die2sys(111,fatal,"unable to bind UDP socket: ");
++ off=0;
++ cnt=0;
++ while (x[off]) {
++ unsigned int l;
++ char dummy[4];
++ l=ip4_scan(x+off,dummy);
++ if (!l)
++ strerr_die3x(111,fatal,"unable to parse IP address ",x+off);
++ cnt++;
++ if (!x[off+l]) break;
++ if (x[off+l]!='/')
++ strerr_die3x(111,fatal,"unable to parse IP address ",x+off);
++ off+=l+1;
++ }
++ udp53=(int *) alloc(sizeof(int) *cnt);
++ if (!udp53) nomem();
++ iop=(iopause_fd *) alloc(sizeof(*iop) * cnt);
++ if (!iop) nomem();
++
++ off=0;
++ cnt=0;
++ while (x[off]) {
++ unsigned int l;
++ l=ip4_scan(x+off,ip);
++ udp53[cnt] = socket_udp();
++ if (udp53[cnt] == -1)
++ strerr_die2sys(111,fatal,"unable to create UDP socket: ");
++ if (socket_bind4_reuse(udp53[cnt],ip,53) == -1)
++ strerr_die2sys(111,fatal,"unable to bind UDP socket: ");
++ ndelay_off(udp53[cnt]);
++ socket_tryreservein(udp53[cnt],65536);
++ iop[cnt].fd=udp53[cnt];
++ iop[cnt].events=IOPAUSE_READ;
++ log_listen(ip);
++ cnt++;
++ if (!x[off+l]) break;
++ off+=l+1;
++ }
+
+ droproot(fatal);
+
+ initialize();
+-
+- ndelay_off(udp53);
+- socket_tryreservein(udp53,65536);
+
+ buffer_putsflush(buffer_2,starting);
+-
++
+ for (;;) {
+- len = socket_recv4(udp53,buf,sizeof buf,ip,&port);
+- if (len < 0) continue;
+- if (!doit()) continue;
+- if (response_len > 512) response_tc();
+- socket_send4(udp53,response,response_len,ip,port);
+- /* may block for buffer space; if it fails, too bad */
++ struct taia stamp;
++ struct taia deadline;
++ unsigned int i;
++ taia_now(&stamp);
++ taia_uint(&deadline,300);
++ taia_add(&deadline,&deadline,&stamp);
++ iopause(iop,cnt,&deadline,&stamp);
++ for (i=0;i<cnt;i++)
++ if (iop[i].revents) {
++ len = socket_recv4(udp53[i],buf,sizeof buf,ip,&port);
++ if (len < 0) continue;
++ if (!doit()) continue;
++ if (response_len > 512) response_tc();
++ socket_send4(udp53[i],response,response_len,ip,port);
++ /* may block for buffer space; if it fails, too bad */
++ }
+ }
+ }
+diff -ruN djbdns-1.05-dist/sig.c djbdns-1.05/sig.c
+--- djbdns-1.05-dist/sig.c 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/sig.c 2008-08-11 19:33:30.000000000 -0700
+@@ -0,0 +1,12 @@
++#include <signal.h>
++#include "sig.h"
++
++int sig_alarm = SIGALRM;
++int sig_child = SIGCHLD;
++int sig_cont = SIGCONT;
++int sig_hangup = SIGHUP;
++int sig_pipe = SIGPIPE;
++int sig_term = SIGTERM;
++
++void (*sig_defaulthandler)() = SIG_DFL;
++void (*sig_ignorehandler)() = SIG_IGN;
+diff -ruN djbdns-1.05-dist/sig.h djbdns-1.05/sig.h
+--- djbdns-1.05-dist/sig.h 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/sig.h 2008-08-11 19:33:30.000000000 -0700
+@@ -0,0 +1,25 @@
++#ifndef SIG_H
++#define SIG_H
++
++extern int sig_alarm;
++extern int sig_child;
++extern int sig_cont;
++extern int sig_hangup;
++extern int sig_pipe;
++extern int sig_term;
++
++extern void (*sig_defaulthandler)();
++extern void (*sig_ignorehandler)();
++
++extern void sig_catch(int,void (*)());
++#define sig_ignore(s) (sig_catch((s),sig_ignorehandler))
++#define sig_uncatch(s) (sig_catch((s),sig_defaulthandler))
++
++extern void sig_block(int);
++extern void sig_unblock(int);
++extern void sig_blocknone(void);
++extern void sig_pause(void);
++
++extern void sig_dfl(int);
++
++#endif
+diff -ruN djbdns-1.05-dist/sig_block.c djbdns-1.05/sig_block.c
+--- djbdns-1.05-dist/sig_block.c 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/sig_block.c 2008-08-11 19:33:30.000000000 -0700
+@@ -0,0 +1,38 @@
++#include <signal.h>
++#include "sig.h"
++#include "hassgprm.h"
++
++void sig_block(int sig)
++{
++#ifdef HASSIGPROCMASK
++ sigset_t ss;
++ sigemptyset(&ss);
++ sigaddset(&ss,sig);
++ sigprocmask(SIG_BLOCK,&ss,(sigset_t *) 0);
++#else
++ sigblock(1 << (sig - 1));
++#endif
++}
++
++void sig_unblock(int sig)
++{
++#ifdef HASSIGPROCMASK
++ sigset_t ss;
++ sigemptyset(&ss);
++ sigaddset(&ss,sig);
++ sigprocmask(SIG_UNBLOCK,&ss,(sigset_t *) 0);
++#else
++ sigsetmask(sigsetmask(~0) & ~(1 << (sig - 1)));
++#endif
++}
++
++void sig_blocknone(void)
++{
++#ifdef HASSIGPROCMASK
++ sigset_t ss;
++ sigemptyset(&ss);
++ sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0);
++#else
++ sigsetmask(0);
++#endif
++}
+diff -ruN djbdns-1.05-dist/sig_catch.c djbdns-1.05/sig_catch.c
+--- djbdns-1.05-dist/sig_catch.c 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/sig_catch.c 2008-08-11 19:33:30.000000000 -0700
+@@ -0,0 +1,16 @@
++#include <signal.h>
++#include "sig.h"
++#include "hassgact.h"
++
++void sig_catch(int sig,void (*f)())
++{
++#ifdef HASSIGACTION
++ struct sigaction sa;
++ sa.sa_handler = f;
++ sa.sa_flags = 0;
++ sigemptyset(&sa.sa_mask);
++ sigaction(sig,&sa,(struct sigaction *) 0);
++#else
++ signal(sig,f); /* won't work under System V, even nowadays---dorks */
++#endif
++}
+diff -ruN djbdns-1.05-dist/sig_pause.c djbdns-1.05/sig_pause.c
+--- djbdns-1.05-dist/sig_pause.c 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/sig_pause.c 2008-08-11 19:33:30.000000000 -0700
+@@ -0,0 +1,14 @@
++#include <signal.h>
++#include "sig.h"
++#include "hassgprm.h"
++
++void sig_pause(void)
++{
++#ifdef HASSIGPROCMASK
++ sigset_t ss;
++ sigemptyset(&ss);
++ sigsuspend(&ss);
++#else
++ sigpause(0);
++#endif
++}
+diff -ruN djbdns-1.05-dist/tinydns-data.c djbdns-1.05/tinydns-data.c
+--- djbdns-1.05-dist/tinydns-data.c 2008-08-11 19:32:53.000000000 -0700
++++ djbdns-1.05/tinydns-data.c 2008-08-11 22:56:09.000000000 -0700
+@@ -159,11 +159,7 @@
+ die_datatmp();
+ }
+
+-buffer b;
+-char bspace[1024];
+-
+ static stralloc line;
+-int match = 1;
+ unsigned long linenum = 0;
+
+ #define NUMFIELDS 15
+@@ -171,6 +167,8 @@
+
+ static char *d1;
+ static char *d2;
++static char *contact;
++
+ char dptr[DNS_NAME4_DOMAIN];
+
+ char strnum[FMT_ULONG];
+@@ -181,7 +179,7 @@
+ strerr_die4x(111,FATAL,"unable to parse data line ",strnum,why);
+ }
+
+-int main()
++int load(const char *fname)
+ {
+ int fddata;
+ int i;
+@@ -196,20 +194,20 @@
+ char type[2];
+ char soa[20];
+ char buf[4];
++ char naptr[4];
++ char srv[6];
++ int match;
++ buffer b;
++ char bspace[1024];
+
+- umask(022);
+-
+- fddata = open_read("data");
++ fddata = open_read(fname);
+ if (fddata == -1)
+- strerr_die2sys(111,FATAL,"unable to open data: ");
++ strerr_die4sys(111,FATAL,"unable to open ",fname,": ");
+ 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();
+-
++ match = 1;
+ while (match) {
+ ++linenum;
+ if (getln(&b,&line,&match,'\n') == -1)
+@@ -247,6 +245,11 @@
+ die_datatmp();
+ break;
+
++ case 'D':
++ if (!dns_domain_fromdot(&contact,f[0].s,f[0].len)) nomem();
++ if (f[0].len == 0) contact = NULL;
++ break;
++
+ case 'Z':
+ if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
+
+@@ -298,8 +301,13 @@
+ 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);
++ if (!contact) {
++ rr_add("\12hostmaster",11);
++ rr_addname(d1);
++ } else {
++ rr_addname(contact);
++ }
++
+ rr_add(defaultsoa,20);
+ rr_finish(d1);
+ }
+@@ -369,6 +377,43 @@
+ rr_finish(d2);
+ }
+ break;
++
++ case 'S':
++ if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
++ if (!stralloc_0(&f[6])) nomem();
++ if (!scan_ulong(f[6].s,&ttl)) ttl = TTL_POSITIVE;
++ ttdparse(&f[7],ttd);
++ locparse(&f[8],loc);
++
++ if (!stralloc_0(&f[1])) nomem();
++
++ if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
++ if (!stralloc_cats(&f[2],".srv.")) 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,&u)) u = 0;
++ uint16_pack_big(srv,u);
++ if (!stralloc_0(&f[5])) nomem();
++ if (!scan_ulong(f[5].s,&u)) u = 0;
++ uint16_pack_big(srv + 2,u);
++ if (!stralloc_0(&f[3])) nomem();
++ if (!scan_ulong(f[3].s,&u)) nomem();
++ uint16_pack_big(srv + 4,u);
++
++ rr_start(DNS_T_SRV,ttl,ttd,loc);
++ rr_add(srv,6);
++ 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();
+@@ -441,10 +486,61 @@
+ rr_finish(d1);
+ break;
+
++ case 'N':
++ if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
++ if (!dns_domain_fromdot(&d2,f[6].s,f[6].len)) nomem();
++ if (!stralloc_0(&f[7])) nomem();
++ if (!scan_ulong(f[7].s,&ttl)) ttl = TTL_POSITIVE;
++ ttdparse(&f[8],ttd);
++ locparse(&f[9],loc);
++
++ if (!stralloc_0(&f[1])) nomem();
++ if (!scan_ulong(f[1].s,&u)) u = 0;
++ uint16_pack_big(naptr,u);
++ if (!stralloc_0(&f[2])) nomem();
++ if (!scan_ulong(f[2].s,&u)) u = 0;
++ uint16_pack_big(naptr + 2,u);
++
++ txtparse(&f[3]); if (f[3].len > 255)
++ syntaxerror(": it is not allowed more than 255 chars in a label");
++ txtparse(&f[4]); if (f[4].len > 255)
++ syntaxerror(": it is not allowed more than 255 chars in a label");
++ txtparse(&f[5]); if (f[5].len > 255)
++ syntaxerror(": it is not allowed more than 255 chars in a label");
++
++ rr_start(DNS_T_NAPTR,ttl,ttd,loc);
++ rr_add(naptr,4);
++
++ ch = f[3].len; rr_add(&ch,1);
++ rr_add(f[3].s, f[3].len);
++ ch = f[4].len; rr_add(&ch,1);
++ rr_add(f[4].s, f[4].len);
++ ch = f[5].len; rr_add(&ch,1);
++ rr_add(f[5].s, f[5].len);
++
++ rr_addname(d2);
++ rr_finish(d1);
++ break;
++
+ default:
+ syntaxerror(": unrecognized leading character");
+ }
+ }
++ close(fddata);
++}
++
++int main(int argc, char **argv)
++{
++ umask(022);
++ fdcdb = open_trunc("data.tmp");
++ if (fdcdb == -1) die_datatmp();
++ if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();
++
++ if (argc == 1)
++ load("data");
++ while(--argc) {
++ load(argv[argc]);
++ }
+
+ if (cdb_make_finish(&cdb) == -1) die_datatmp();
+ if (fsync(fdcdb) == -1) die_datatmp();
+diff -ruN djbdns-1.05-dist/trysgact.c djbdns-1.05/trysgact.c
+--- djbdns-1.05-dist/trysgact.c 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/trysgact.c 2008-08-11 19:33:30.000000000 -0700
+@@ -0,0 +1,10 @@
++#include <signal.h>
++
++main()
++{
++ struct sigaction sa;
++ sa.sa_handler = 0;
++ sa.sa_flags = 0;
++ sigemptyset(&sa.sa_mask);
++ sigaction(0,&sa,(struct sigaction *) 0);
++}
+diff -ruN djbdns-1.05-dist/trysgprm.c djbdns-1.05/trysgprm.c
+--- djbdns-1.05-dist/trysgprm.c 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/trysgprm.c 2008-08-11 19:33:30.000000000 -0700
+@@ -0,0 +1,10 @@
++#include <signal.h>
++
++main()
++{
++ sigset_t ss;
++
++ sigemptyset(&ss);
++ sigaddset(&ss,SIGCHLD);
++ sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0);
++}
+diff -ruN djbdns-1.05-dist/uint32.h djbdns-1.05/uint32.h
+--- djbdns-1.05-dist/uint32.h 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/uint32.h 2008-08-11 22:55:10.000000000 -0700
+@@ -0,0 +1,11 @@
++#ifndef UINT32_H
++#define UINT32_H
++
++typedef unsigned long uint32;
++
++extern void uint32_pack(char *,uint32);
++extern void uint32_pack_big(char *,uint32);
++extern void uint32_unpack(const char *,uint32 *);
++extern void uint32_unpack_big(const char *,uint32 *);
++
++#endif
+diff -ruN djbdns-1.05-dist/uint64.h djbdns-1.05/uint64.h
+--- djbdns-1.05-dist/uint64.h 1969-12-31 16:00:00.000000000 -0800
++++ djbdns-1.05/uint64.h 2008-08-11 22:55:10.000000000 -0700
+@@ -0,0 +1,8 @@
++#ifndef UINT64_H
++#define UINT64_H
++
++/* sysdep: -ulong64 */
++
++typedef unsigned long long uint64;
++
++#endif