URI: 
       tremove unused - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 5c9f76b5e5dc5c0537896b0e487b101dad38a746
   DIR parent 54357361fbc3032b36688bb4c1d4ced1f14f08f6
  HTML Author: rsc <devnull@localhost>
       Date:   Tue, 14 Feb 2006 19:43:19 +0000
       
       remove unused
       
       Diffstat:
         M src/cmd/ndb/convM2DNS.c             |       1 -
         M src/cmd/ndb/dblookup.c              |      13 -------------
         M src/cmd/ndb/dn.c                    |      37 +++----------------------------
         M src/cmd/ndb/dnarea.c                |       4 +++-
         M src/cmd/ndb/dnnotify.c              |      35 ++++++++++++-------------------
         M src/cmd/ndb/dnresolve.c             |      22 ++++++++++------------
         M src/cmd/ndb/dns.c                   |     145 +++++++++++++------------------
         M src/cmd/ndb/dns.h                   |      23 +++++++++++++----------
         M src/cmd/ndb/dnsdebug.c              |      22 +++++++++++++++++-----
         M src/cmd/ndb/dnsquery.c              |      69 ++++++++++++-------------------
         M src/cmd/ndb/dnstcp.c                |     286 ++-----------------------------
         M src/cmd/ndb/dnudpserver.c           |      87 ++++++++++++-------------------
         M src/cmd/ndb/mkfile                  |       6 +++++-
       
       13 files changed, 193 insertions(+), 557 deletions(-)
       ---
   DIR diff --git a/src/cmd/ndb/convM2DNS.c b/src/cmd/ndb/convM2DNS.c
       t@@ -408,7 +408,6 @@ static RR*
        rrloop(Scan *sp, int count, int quest)
        {
                int i;
       -        static char errbuf[64];
                RR *first, *rp, **l;
        
                if(sp->err)
   DIR diff --git a/src/cmd/ndb/dblookup.c b/src/cmd/ndb/dblookup.c
       t@@ -78,9 +78,6 @@ dblookup(char *name, int class, int type, int auth, int ttl)
                char *wild, *cp;
                DN *dp, *ndp;
                int err;
       -        static int parallel;
       -        static int parfd[2];
       -        static char token[1];
        
                /* so far only internet lookups are implemented */
                if(class != Cin)
       t@@ -490,16 +487,6 @@ look(Ndbtuple *entry, Ndbtuple *line, char *attr)
                return 0;
        }
        
       -static RR**
       -linkrr(RR *rp, DN *dp, RR **l)
       -{
       -        rp->owner = dp;
       -        rp->auth = 1;
       -        rp->db = 1;
       -        *l = rp;
       -        return &rp->next;
       -}
       -
        /* these are answered specially by the tcp version */
        static RR*
        doaxfr(Ndb *db, char *name)
   DIR diff --git a/src/cmd/ndb/dn.c b/src/cmd/ndb/dn.c
       t@@ -4,6 +4,7 @@
        #include <ctype.h>
        #include <bio.h>
        #include <ndb.h>
       +#include <thread.h>
        #include "dns.h"
        
        /*
       t@@ -346,7 +347,6 @@ dnagedb(void)
                DN *dp;
                int i;
                RR *rp;
       -        static ulong nextage;
        
                lock(&dnlock);
        
       t@@ -370,7 +370,6 @@ dnauthdb(void)
                int i;
                Area *area;
                RR *rp;
       -        static ulong nextage;
        
                lock(&dnlock);
        
       t@@ -404,7 +403,7 @@ getactivity(Request *req)
        {
                int rv;
        
       -        if(traceactivity) syslog(0, "dns", "get %d by %d", dnvars.active, getpid());
       +        if(traceactivity) syslog(0, "dns", "get %d by %d.%d", dnvars.active, getpid(), threadid());
                lock(&dnvars.lk);
                while(dnvars.mutex){
                        unlock(&dnvars.lk);
       t@@ -423,7 +422,7 @@ putactivity(void)
        {
                static ulong lastclean;
        
       -        if(traceactivity) syslog(0, "dns", "put %d by %d", dnvars.active, getpid());
       +        if(traceactivity) syslog(0, "dns", "put %d by %d.%d", dnvars.active, getpid(), threadid());
                lock(&dnvars.lk);
                dnvars.active--;
                assert(dnvars.active >= 0); /* "dnvars.active %d", dnvars.active */;
       t@@ -1179,36 +1178,6 @@ warning(char *fmt, ...)
        }
        
        /*
       - *  create a slave process to handle a request to avoid one request blocking
       - *  another
       - */
       -void
       -slave(Request *req)
       -{
       -        static int slaveid;
       -
       -        if(req->isslave)
       -                return;                /* we're already a slave process */
       -
       -        /* limit parallelism */
       -        if(getactivity(req) > Maxactive){
       -                putactivity();
       -                return;
       -        }
       -
       -        switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){
       -        case -1:
       -                putactivity();
       -                break;
       -        case 0:
       -                req->isslave = 1;
       -                break;
       -        default:
       -                longjmp(req->mret, 1);
       -        }
       -}
       -
       -/*
         *  chasing down double free's
         */
        void
   DIR diff --git a/src/cmd/ndb/dnarea.c b/src/cmd/ndb/dnarea.c
       t@@ -3,6 +3,7 @@
        #include <bio.h>
        #include <ndb.h>
        #include <ip.h>
       +#include <thread.h>
        #include "dns.h"
        
        Area *owned;
       t@@ -90,6 +91,7 @@ freearea(Area **l)
         *  this entails running a command 'zonerefreshprogram'.  This could
         *  copy over databases from elsewhere or just do a zone transfer.
         */
       +/* XXX WRONG - can't use fork and exec */
        void
        refresh_areas(Area *s)
        {
       t@@ -110,7 +112,7 @@ refresh_areas(Area *s)
                                break;
                        case 0:
                                execl(zonerefreshprogram, "zonerefresh", s->soarr->owner->name, 0);
       -                        exits(0);
       +                        threadexitsall(0);
                                break;
                        default:
                                for(;;){
   DIR diff --git a/src/cmd/ndb/dnnotify.c b/src/cmd/ndb/dnnotify.c
       t@@ -46,6 +46,10 @@ syslog(0, logfile, "serial old %lud new %lud", a->soarr->soa->serial, repp->qd->
                a->needrefresh = 1;
        }
        
       +/*
       + * this isn't going to work as a thread!
       + */
       +
        static void
        ding(void *u, char *msg)
        {
       t@@ -62,10 +66,10 @@ static void
        send_notify(char *slave, RR *soa, Request *req)
        {
                int i, len, n, reqno, status, fd;
       -        uchar obuf[Maxudp+OUdphdrsize];
       -        uchar ibuf[Maxudp+OUdphdrsize];
       +        uchar obuf[Maxudp+Udphdrsize];
       +        uchar ibuf[Maxudp+Udphdrsize];
                RR *rp;
       -        OUdphdr *up = (OUdphdr*)obuf;
       +        Udphdr *up = (Udphdr*)obuf;
                char *err;
                DNSmsg repmsg;
        
       t@@ -93,14 +97,14 @@ send_notify(char *slave, RR *soa, Request *req)
                /* send 3 times or until we get anything back */
                for(i = 0; i < 3; i++){
        syslog(0, logfile, "sending %d byte notify to %s/%I.%d about %s", n, slave, up->raddr, nhgets(up->rport), soa->owner->name);
       -                if(udpwrite(fd, (OUdphdr*)obuf, obuf+OUdphdrsize, n) != n)
       +                if(udpwrite(fd, (Udphdr*)obuf, obuf+Udphdrsize, n) != n)
                                break;
                        alarm(2*1000);
       -                len = udpread(fd, (Udphdr*)ibuf, ibuf+OUdphdrsize, Maxudp);
       +                len = udpread(fd, (Udphdr*)ibuf, ibuf+Udphdrsize, Maxudp);
                        alarm(0);
       -                if(len <= OUdphdrsize)
       +                if(len <= Udphdrsize)
                                continue;
       -                err = convM2DNS(&ibuf[OUdphdrsize], len, &repmsg);
       +                err = convM2DNS(&ibuf[Udphdrsize], len, &repmsg);
                        if(err != nil)
                                continue;
                        if(repmsg.id == reqno && (repmsg.flags & Omask) == Onotify)
       t@@ -132,24 +136,11 @@ notify_areas(Area *a, Request *req)
         *  (also reads in new databases)
         */
        void
       -notifyproc(void)
       +notifyproc(void *v)
        {
                Request req;
       -        static int already;
       -
       -        if(already)
       -                return;
       -
       -        switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){
       -        case -1:
       -                return;
       -        case 0:
       -                break;
       -        default:
       -                return;
       -        }
        
       -        req.isslave = 1;        /* son't fork off subprocesses */
       +        USED(v);
        
                for(;;){
                        getactivity(&req);
   DIR diff --git a/src/cmd/ndb/dnresolve.c b/src/cmd/ndb/dnresolve.c
       t@@ -258,7 +258,7 @@ mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno)
        {
                DNSmsg m;
                int len;
       -        OUdphdr *uh = (OUdphdr*)buf;
       +        Udphdr *uh = (Udphdr*)buf;
        
                /* stuff port number into output buffer */
                memset(uh, 0, sizeof(*uh));
       t@@ -271,7 +271,7 @@ mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno)
                m.qd = rralloc(type);
                m.qd->owner = dp;
                m.qd->type = type;
       -        len = convDNS2M(&m, &buf[OUdphdrsize], Maxudp);
       +        len = convDNS2M(&m, &buf[Udphdrsize], Maxudp);
                if(len < 0)
                        abort(); /* "can't convert" */;
                rrfree(m.qd);
       t@@ -319,14 +319,14 @@ readreply(int fd, DN *dp, int type, ushort req,
        
                        /* timed read */
                        alarm((endtime - now) * 1000);
       -                len = udpread(fd, (OUdphdr*)ibuf, ibuf+OUdphdrsize, Maxudpin);
       +                len = udpread(fd, (Udphdr*)ibuf, ibuf+Udphdrsize, Maxudpin);
                        alarm(0);
                        if(len < 0)
                                return -1;        /* timed out */
                        
                        /* convert into internal format  */
                        memset(mp, 0, sizeof(*mp));
       -                err = convM2DNS(&ibuf[OUdphdrsize], len, mp);
       +                err = convM2DNS(&ibuf[Udphdrsize], len, mp);
                        if(err){
                                syslog(0, LOG, "input err %s: %I", err, ibuf);
                                continue;
       t@@ -544,6 +544,7 @@ netquery1(int fd, DN *dp, int type, RR *nsrp, Request *reqp, int depth, uchar *i
                Dest dest[Maxdest];
                DNSmsg m;
                ulong endtime;
       +        Udphdr *uh;
        
                /* pack request into a message */
                req = rand();
       t@@ -591,10 +592,9 @@ netquery1(int fd, DN *dp, int type, RR *nsrp, Request *reqp, int depth, uchar *i
                                if(debug)
                                        logsend(reqp->id, depth, obuf, p->s->name,
                                                dp->name, type);
       -{Udphdr *uh = (Udphdr*)obuf;
       -print("send %I %I %d %d\n", uh->raddr, uh->laddr, nhgets(uh->rport), nhgets(uh->lport));
       -}
       -                        if(udpwrite(fd, (OUdphdr*)obuf, obuf+OUdphdrsize, len) < 0)
       +                        uh = (Udphdr*)obuf;
       +                        fprint(2, "send %I %I %d %d\n", uh->raddr, uh->laddr, nhgets(uh->rport), nhgets(uh->lport));
       +                        if(udpwrite(fd, uh, obuf+Udphdrsize, len) < 0)
                                        warning("sending udp msg %r");
                                p->nx++;
                        }
       t@@ -732,10 +732,8 @@ netquery(DN *dp, int type, RR *nsrp, Request *reqp, int depth)
                        return 0;
        
                /* use alloced buffers rather than ones from the stack */
       -        ibuf = emalloc(Maxudpin+OUdphdrsize);
       -        obuf = emalloc(Maxudp+OUdphdrsize);
       -
       -        slave(reqp);
       +        ibuf = emalloc(Maxudpin+Udphdrsize);
       +        obuf = emalloc(Maxudp+Udphdrsize);
        
                /* prepare server RR's for incremental lookup */
                for(rp = nsrp; rp; rp = rp->next)
   DIR diff --git a/src/cmd/ndb/dns.c b/src/cmd/ndb/dns.c
       t@@ -6,6 +6,7 @@
        #include <ctype.h>
        #include <ip.h>
        #include <ndb.h>
       +#include <thread.h>
        #include "dns.h"
        
        enum
       t@@ -89,13 +90,14 @@ void        rremove(Job*, Mfile*);
        void        rstat(Job*, Mfile*);
        void        rwstat(Job*, Mfile*);
        void        sendmsg(Job*, char*);
       -void        mountinit(char*, char*);
       +void        mountinit(char*);
        void        io(void);
        int        fillreply(Mfile*, int);
        Job*        newjob(void);
        void        freejob(Job*);
        void        setext(char*, int, char*);
        
       +char *portname = "domain";
        char        *logfile = "dns";
        char        *dbfile;
        char        mntpt[Maxpath];
       t@@ -104,61 +106,52 @@ char        *LOG;
        void
        usage(void)
        {
       -        fprint(2, "usage: %s [-rs] [-f ndb-file] [-x netmtpt]\n", argv0);
       -        exits("usage");
       +        fprint(2, "usage: %s [-dnrstT] [-a maxage] [-f ndb-file] [-p port] [-x service] [-z zoneprog]\n", argv0);
       +        threadexitsall("usage");
        }
        
        void
       -main(int argc, char *argv[])
       +threadmain(int argc, char *argv[])
        {
       -        int        serve;
       -        char        servefile[Maxpath];
       -        char        ext[Maxpath];
       -        char        *p;
       +        int serveudp, servetcp;
       +        char *service;
        
       -        serve = 0;
       -//        setnetmtpt(mntpt, sizeof(mntpt), nil);
       -        ext[0] = 0;
       +        serveudp = 0;
       +        servetcp = 0;
       +        service = "dns";
                ARGBEGIN{
                case 'd':
                        debug = 1;
                        traceactivity = 1;
                        break;
                case 'f':
       -                p = ARGF();
       -                if(p == nil)
       -                        usage();
       -                dbfile = p;
       +                dbfile = EARGF(usage());
                        break;
       -        case 'i':
       -                haveip = 1;
       -                parseip(ipaddr, EARGF(usage()));
       +        case 'x':
       +                service = EARGF(usage());
                        break;
       -//        case 'x':
       -        //        p = ARGF();
       -        //        if(p == nil)
       -        //                usage();
       -        //        setnetmtpt(mntpt, sizeof(mntpt), p);
       -        //        setext(ext, sizeof(ext), mntpt);
       -        //        break;
                case 'r':
                        resolver = 1;
                        break;
                case 's':
       -                serve = 1;        /* serve network */
       +                serveudp = 1;        /* serve network */
       +                cachedb = 1;
       +                break;
       +        case 'T':
       +                servetcp = 1;
                        cachedb = 1;
                        break;
                case 'a':
       -                p = ARGF();
       -                if(p == nil)
       -                        usage();
       -                maxage = atoi(p);
       +                maxage = atoi(EARGF(usage()));
                        break;
                case 't':
                        testing = 1;
                        break;
                case 'z':
       -                zonerefreshprogram = ARGF();
       +                zonerefreshprogram = EARGF(usage());
       +                break;
       +        case 'p':
       +                portname = EARGF(usage());
                        break;
                case 'n':
                        sendnotifies = 1;
       t@@ -167,9 +160,7 @@ main(int argc, char *argv[])
                USED(argc);
                USED(argv);
        
       -//if(testing) mainmem->flags |= POOL_NOREUSE;
       -#define RFREND 0
       -        rfork(RFREND|RFNOTEG);
       +        rfork(RFNOTEG);
        
                /* start syslog before we fork */
                fmtinstall('F', fcallfmt);
       t@@ -181,25 +172,20 @@ main(int argc, char *argv[])
        
                opendatabase();
        
       -/*
       -        snprint(servefile, sizeof(servefile), "#s/dns%s", ext);
       -        unmount(servefile, mntpt);
       -        remove(servefile);
       -*/
       -        mountinit(servefile, mntpt);
       +        mountinit(service);
        
                now = time(0);
                srand(now*getpid());
                db2cache(1);
        
       -//        if(serve)
       -//                proccreate(dnudpserver, mntpt, STACK);
       +        if(serveudp)
       +                proccreate(dnudpserver, nil, STACK);
       +        if(servetcp)
       +                proccreate(dntcpserver, nil, STACK);
                if(sendnotifies)
       -                notifyproc();
       +                proccreate(notifyproc, nil, STACK);
        
                io();
       -        syslog(0, logfile, "io returned, exiting");
       -        exits(0);
        }
        
        int
       t@@ -231,25 +217,15 @@ setext(char *ext, int n, char *p)
        }
        
        void
       -mountinit(char *service, char *mntpt)
       +mountinit(char *service)
        {
                int p[2];
        
                if(pipe(p) < 0)
                        abort(); /* "pipe failed" */;
       -        switch(rfork(RFFDG|RFPROC|RFNAMEG)){
       -        case 0:
       -                close(p[1]);
       -                break;
       -        case -1:
       -                abort(); /* "fork failed\n" */;
       -        default:
       -                close(p[0]);
       -
       -                if(post9pservice(p[1], "dns") < 0)
       -                        fprint(2, "post9pservice dns: %r\n");
       -                _exits(0);
       -        }
       +        if(post9pservice(p[1], service) < 0)
       +                fprint(2, "post9pservice dns: %r\n");
       +        close(p[1]);
                mfd[0] = mfd[1] = p[0];
        }
        
       t@@ -286,7 +262,6 @@ freefid(Mfile *mf)
        {
                Mfile **l;
        
       -fprint(2, "freefid %d\n", mf->fid);
                lock(&mfalloc.lk);
                for(l = &mfalloc.inuse; *l != nil; l = &(*l)->next){
                        if(*l == mf){
       t@@ -363,7 +338,7 @@ flushjob(int tag)
        }
        
        void
       -io(void)
       +ioproc0(void *v)
        {
                long n;
                Mfile *mf;
       t@@ -371,19 +346,13 @@ io(void)
                Request req;
                Job *job;
        
       -        /*
       -         *  a slave process is sometimes forked to wait for replies from other
       -         *  servers.  The master process returns immediately via a longjmp
       -         *  through 'mret'.
       -         */
       -        if(setjmp(req.mret))
       -                putactivity();
       -        req.isslave = 0;
       +        USED(v);
       +
                for(;;){
                        n = read9pmsg(mfd[0], mdata, sizeof mdata);
                        if(n<=0){
                                syslog(0, logfile, "error reading mntpt: %r");
       -                        exits(0);
       +                        break;
                        }
                        job = newjob();
                        if(convM2S(mdata, n, &job->request) != n){
       t@@ -464,20 +433,20 @@ io(void)
                        }
        skip:
                        freejob(job);
       -        
       -                /*
       -                 *  slave processes die after replying
       -                 */
       -                if(req.isslave){
       -                        putactivity();
       -                        _exits(0);
       -                }
       -        
                        putactivity();
                }
        }
        
        void
       +io(void)
       +{
       +        int i;
       +
       +        for(i=0; i<Maxactive; i++)
       +                proccreate(ioproc0, 0, STACK);
       +}
       +
       +void
        rversion(Job *job)
        {
                if(job->request.msize > IOHDRSZ + Maxfdata)
       t@@ -667,6 +636,7 @@ rwrite(Job *job, Mfile *mf, Request *req)
                char *err, *p, *atype;
                RR *rp, *tp, *neg;
                int wantsav;
       +        static char *dumpfile;
        
                err = 0;
                cnt = job->request.count;
       t@@ -685,18 +655,21 @@ rwrite(Job *job, Mfile *mf, Request *req)
                /*
                 *  special commands
                 */
       -        if(strncmp(job->request.data, "debug", 5)==0 && job->request.data[5] == 0){
       +        p = job->request.data;
       +        if(strcmp(p, "debug")==0){
                        debug ^= 1;
                        goto send;
       -        } else if(strncmp(job->request.data, "dump", 4)==0 && job->request.data[4] == 0){
       -                dndump("/lib/ndb/dnsdump");
       +        } else if(strcmp(p, "dump")==0){
       +                if(dumpfile == nil)
       +                        dumpfile = unsharp("#9/ndb/dnsdump");
       +                dndump(dumpfile);
       +                goto send;
       +        } else if(strncmp(p, "dump ", 5) == 0){
       +                dndump(p+5);
                        goto send;
       -        } else if(strncmp(job->request.data, "refresh", 7)==0 && job->request.data[7] == 0){
       +        } else if(strcmp(p, "refresh")==0){
                        needrefresh = 1;
                        goto send;
       -//        } else if(strncmp(job->request.data, "poolcheck", 9)==0 && job->request.data[9] == 0){
       -//                poolcheck(mainmem);
       -//                goto send;
                }
        
                /*
   DIR diff --git a/src/cmd/ndb/dns.h b/src/cmd/ndb/dns.h
       t@@ -1,6 +1,3 @@
       -#define OUdphdrsize Udphdrsize
       -#define OUdphdr Udphdr
       -
        enum
        {
                /* RR types */
       t@@ -114,9 +111,7 @@ typedef struct Txt        Txt;
         */
        struct Request
        {
       -        int        isslave;        /* pid of slave */
                ulong        aborttime;        /* time at which we give up */
       -        jmp_buf        mret;                /* where master jumps to after starting a slave */
                int        id;
        };
        
       t@@ -291,6 +286,11 @@ enum
                OKneg,
        };
        
       +enum
       +{
       +        STACK = 32*1024
       +};
       +
        /* dn.c */
        extern char        *rrtname[];
        extern char        *rname[];
       t@@ -326,7 +326,6 @@ extern int        getactivity(Request*);
        extern void        putactivity(void);
        extern void        abort(); /* char*, ... */;
        extern void        warning(char*, ...);
       -extern void        slave(Request*);
        extern void        dncheck(void*, int);
        extern void        unique(RR*);
        extern int        subsume(char*, char*);
       t@@ -364,11 +363,13 @@ extern int        mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno);
        
        /* dnserver.c */
        extern void        dnserver(DNSmsg*, DNSmsg*, Request*);
       -extern void        dntcpserver(char*);
       +extern void        dnudpserver(void*);
       +extern void        dntcpserver(void*);
       +extern void        tcpproc(void*);
        
        /* dnnotify.c */
        extern void        dnnotify(DNSmsg*, DNSmsg*, Request*);
       -extern void        notifyproc(void);
       +extern void        notifyproc(void*);
        
        /* convDNS2M.c */
        extern int        convDNS2M(DNSmsg*, uchar*, int);
       t@@ -380,8 +381,8 @@ extern char*        convM2DNS(uchar*, int, DNSmsg*);
        extern void        mallocsanity(void*);
        extern void        lasthist(void*, int, ulong);
        
       -extern int debug;
       -extern int traceactivity;
       +extern int        debug;
       +extern int        traceactivity;
        extern char        *trace;
        extern int        testing;        /* test cache whenever removing a DN */
        extern int        cachedb;
       t@@ -397,6 +398,8 @@ extern ulong        now;                /* time base */
        extern Area        *owned;
        extern Area        *delegated;
        
       +extern char        *portname;
       +
        #pragma        varargck        type        "R"        RR*
        #pragma        varargck        type        "Q"        RR*
        
   DIR diff --git a/src/cmd/ndb/dnsdebug.c b/src/cmd/ndb/dnsdebug.c
       t@@ -4,6 +4,7 @@
        #include <ctype.h>
        #include <ip.h>
        #include <ndb.h>
       +#include <thread.h>
        #include "dns.h"
        
        enum
       t@@ -16,7 +17,6 @@ enum
        };
        
        static char *servername;
       -static RR *serverrr;
        static RR *serveraddrs;
        
        int        debug;
       t@@ -42,7 +42,14 @@ void doquery(char*, char*);
        void docmd(int, char**);
        
        void
       -main(int argc, char *argv[])
       +usage(void)
       +{
       +        fprint(2, "usage: dnsdebug -rxf [-p port] [query ...]\n");
       +        threadexitsall("usage");
       +}
       +
       +void
       +threadmain(int argc, char *argv[])
        {
                int n;
                Biobuf in;
       t@@ -52,6 +59,9 @@ main(int argc, char *argv[])
                strcpy(mntpt, "/net");
        
                ARGBEGIN{
       +        case 'p':        /* XXX */
       +                portname = EARGF(usage());
       +                break;
                case 'r':
                        resolver = 1;
                        break;
       t@@ -60,8 +70,10 @@ main(int argc, char *argv[])
                        strcpy(mntpt, "/net.alt");
                        break;
                case 'f':
       -                dbfile = ARGF();
       +                dbfile = EARGF(usage());
                        break;
       +        default:
       +                usage();
                }ARGEND
        
                now = time(0);
       t@@ -78,7 +90,7 @@ main(int argc, char *argv[])
        
                if(argc > 0){
                        docmd(argc, argv);
       -                exits(0);
       +                threadexitsall(0);
                }
        
                Binit(&in, 0, OREAD);
       t@@ -94,7 +106,7 @@ main(int argc, char *argv[])
                        docmd(n, f);
        
                }
       -        exits(0);
       +        threadexitsall(0);
        }
        
        static char*
   DIR diff --git a/src/cmd/ndb/dnsquery.c b/src/cmd/ndb/dnsquery.c
       t@@ -2,58 +2,43 @@
        #include <libc.h>
        #include <bio.h>
        #include <ndb.h>
       +#include <thread.h>
        #include "dns.h"
        #include "ip.h"
        
        void
       +usage(void)
       +{
       +        fprint(2, "usage: dnsquery [-x dns]\n");
       +        threadexitsall("usage");
       +}
       +
       +void
        main(int argc, char *argv[])
        {
       -        int fd, n, len, domount;
       +        char *dns;
       +        CFid *fd;
       +        int n, len;
                Biobuf in;
                char line[1024], *lp, *p, *np, *mtpt, *srv, *dns;
                char buf[1024];
        
       -        dns = "/net/dns";
       -        mtpt = "/net";
       -        srv = "/srv/dns";
       -        domount = 1;
       -        ARGBEGIN {
       +        dns = "dns";
       +        ARGBEGIN{
                case 'x':
       -                dns = "/net.alt/dns";
       -                mtpt = "/net.alt";
       -                srv = "/srv/dns_net.alt";
       +                dns = EARGF(usage());
                        break;
                default:
       -                fprint(2, "usage: %s -x [dns-mount-point]\n", argv0);
       -                exits("usage");
       -        } ARGEND;
       +                usage();
       +        }ARGEND;
        
       -        if(argc == 1){
       -                domount = 0;
       -                mtpt = argv[0];
       -        }
       +        if(argc)
       +                usage();
       +
       +        fd = nsopen(dns, nil, "dns", ORDWR);
       +        if(fd == nil)
       +                sysfatal("open %s!dns: %r", dns);
        
       -        fd = open(dns, ORDWR);
       -        if(fd < 0){
       -                if(domount == 0){
       -                        fprint(2, "can't open %s: %r\n", mtpt);
       -                        exits(0);
       -                }
       -                fd = open(srv, ORDWR);
       -                if(fd < 0){
       -                        print("can't open %s: %r\n", srv);
       -                        exits(0);
       -                }
       -                if(mount(fd, -1, mtpt, MBEFORE, "") < 0){
       -                        print("can't mount(%s, %s): %r\n", srv, mtpt);
       -                        exits(0);
       -                }
       -                fd = open(mtpt, ORDWR);
       -                if(fd < 0){
       -                        print("can't open %s: %r\n", mtpt);
       -                        exits(0);
       -                }
       -        }
                Binit(&in, 0, OREAD);
                for(print("> "); lp = Brdline(&in, '\n'); print("> ")){
                        n = Blinelen(&in)-1;
       t@@ -98,16 +83,16 @@ main(int argc, char *argv[])
                                n = strlen(line);
                        }
        
       -                seek(fd, 0, 0);
       -                if(write(fd, line, n) < 0) {
       +                fsseek(fd, 0, 0);
       +                if(fswrite(fd, line, n) < 0) {
                                print("!%r\n");
                                continue;
                        }
       -                seek(fd, 0, 0);
       -                while((n = read(fd, buf, sizeof(buf))) > 0){
       +                fsseek(fd, 0, 0);
       +                while((n = fsread(fd, buf, sizeof(buf))) > 0){
                                buf[n] = 0;
                                print("%s\n", buf);
                        }
                }
       -        exits(0);
       +        threadexitsall(0);
        }
   DIR diff --git a/src/cmd/ndb/dnstcp.c b/src/cmd/ndb/dnstcp.c
       t@@ -1,6 +1,9 @@
        #include <u.h>
        #include <libc.h>
        #include <ip.h>
       +#include <bio.h>
       +#include <ndb.h>
       +#include <thread.h>
        #include "dns.h"
        
        enum
       t@@ -13,312 +16,43 @@ char        *dbfile;
        int        debug;
        int        cachedb = 1;
        int        testing;
       -int traceactivity;
       +int        traceactivity;
        int        needrefresh;
        int         resolver;
        char        mntpt[Maxpath];
       -char        *caller = "";
        ulong        now;
        int        maxage;
        uchar        ipaddr[IPaddrlen];        /* my ip address */
        char        *LOG;
        char        *zonerefreshprogram;
       -
       -static int        readmsg(int, uchar*, int);
       -static void        reply(int, DNSmsg*, Request*);
       -static void        dnzone(DNSmsg*, DNSmsg*, Request*);
       -static void        getcaller(char*);
       -static void        refreshmain(char*);
       +char        *portname = "domain";
        
        void
       -main(int argc, char *argv[])
       +threadmain(int argc, char *argv[])
        {
       -        int len;
       -        Request req;
       -        DNSmsg reqmsg, repmsg;
       -        uchar buf[512];
       -        char tname[32];
       -        char *err;
                char *ext = "";
        
                ARGBEGIN{
       +        default:
       +                usage();
                case 'd':
                        debug++;
                        break;
                case 'f':
       -                dbfile = ARGF();
       +                dbfile = EARGF(usage());
                        break;
                case 'r':
                        resolver = 1;
                        break;
       -        case 'x':
       -                ext = ARGF();
       -                break;
                }ARGEND
        
                if(debug < 2)
                        debug = 0;
        
       -        if(argc > 0)
       -                getcaller(argv[0]);
       -
                dninit();
        
       -        snprint(mntpt, sizeof(mntpt), "/net%s", ext);
       -        if(myipaddr(ipaddr, mntpt) < 0)
       -                sysfatal("can't read my ip address");
       -        syslog(0, logfile, "dnstcp call from %s to %I", caller, ipaddr);
       -
                db2cache(1);
       -
       -        setjmp(req.mret);
       -        req.isslave = 0;
       -
       -        /* loop on requests */
       -        for(;; putactivity()){
       -                now = time(0);
       -                memset(&repmsg, 0, sizeof(repmsg));
       -                alarm(10*60*1000);
       -                len = readmsg(0, buf, sizeof(buf));
       -                alarm(0);
       -                if(len <= 0)
       -                        break;
       -                getactivity(&req);
       -                req.aborttime = now + 15*Min;
       -                err = convM2DNS(buf, len, &reqmsg);
       -                if(err){
       -                        syslog(0, logfile, "server: input error: %s from %I", err, buf);
       -                        break;
       -                }
       -                if(reqmsg.qdcount < 1){
       -                        syslog(0, logfile, "server: no questions from %I", buf);
       -                        break;
       -                }
       -                if(reqmsg.flags & Fresp){
       -                        syslog(0, logfile, "server: reply not request from %I", buf);
       -                        break;
       -                }
       -                if((reqmsg.flags & Omask) != Oquery){
       -                        syslog(0, logfile, "server: op %d from %I", reqmsg.flags & Omask, buf);
       -                        break;
       -                }
       -
       -                if(debug)
       -                        syslog(0, logfile, "%d: serve (%s) %d %s %s",
       -                                req.id, caller,
       -                                reqmsg.id,
       -                                reqmsg.qd->owner->name,
       -                                rrname(reqmsg.qd->type, tname, sizeof tname));
       -
       -                /* loop through each question */
       -                while(reqmsg.qd){
       -                        if(reqmsg.qd->type == Taxfr){
       -                                dnzone(&reqmsg, &repmsg, &req);
       -                        } else {
       -                                dnserver(&reqmsg, &repmsg, &req);
       -                                reply(1, &repmsg, &req);
       -                                rrfreelist(repmsg.qd);
       -                                rrfreelist(repmsg.an);
       -                                rrfreelist(repmsg.ns);
       -                                rrfreelist(repmsg.ar);
       -                        }
       -                }
       -
       -                rrfreelist(reqmsg.qd);
       -                rrfreelist(reqmsg.an);
       -                rrfreelist(reqmsg.ns);
       -                rrfreelist(reqmsg.ar);
       -
       -                if(req.isslave){
       -                        putactivity();
       -                        _exits(0);
       -                }
       -        }
       -        refreshmain(mntpt);
       -}
       -
       -static int
       -readmsg(int fd, uchar *buf, int max)
       -{
       -        int n;
       -        uchar x[2];
       -
       -        if(readn(fd, x, 2) != 2)
       -                return -1;
       -        n = (x[0]<<8) | x[1];
       -        if(n > max)
       -                return -1;
       -        if(readn(fd, buf, n) != n)
       -                return -1;
       -        return n;
       -}
       -
       -static void
       -reply(int fd, DNSmsg *rep, Request *req)
       -{
       -        int len, rv;
       -        char tname[32];
       -        uchar buf[4096];
       -        RR *rp;
       -
       -        if(debug){
       -                syslog(0, logfile, "%d: reply (%s) %s %s %ux",
       -                        req->id, caller,
       -                        rep->qd->owner->name,
       -                        rrname(rep->qd->type, tname, sizeof tname),
       -                        rep->flags);
       -                for(rp = rep->an; rp; rp = rp->next)
       -                        syslog(0, logfile, "an %R", rp);
       -                for(rp = rep->ns; rp; rp = rp->next)
       -                        syslog(0, logfile, "ns %R", rp);
       -                for(rp = rep->ar; rp; rp = rp->next)
       -                        syslog(0, logfile, "ar %R", rp);
       -        }
       -
       -
       -        len = convDNS2M(rep, buf+2, sizeof(buf) - 2);
       -        if(len <= 0)
       -                abort(); /* "dnserver: converting reply" */;
       -        buf[0] = len>>8;
       -        buf[1] = len;
       -        rv = write(fd, buf, len+2);
       -        if(rv != len+2){
       -                syslog(0, logfile, "sending reply: %d instead of %d", rv, len+2);
       -                exits(0);
       -        }
       -}
       -
       -/*
       - *  Hash table for domain names.  The hash is based only on the
       - *  first element of the domain name.
       - */
       -extern DN        *ht[HTLEN];
       -
       -static int
       -numelem(char *name)
       -{
       -        int i;
       -
       -        i = 1;
       -        for(; *name; name++)
       -                if(*name == '.')
       -                        i++;
       -        return i;
       -}
       -
       -int
       -inzone(DN *dp, char *name, int namelen, int depth)
       -{
       -        int n;
       -
       -        if(dp->name == 0)
       -                return 0;
       -        if(numelem(dp->name) != depth)
       -                return 0;
       -        n = strlen(dp->name);
       -        if(n < namelen)
       -                return 0;
       -        if(strcmp(name, dp->name + n - namelen) != 0)
       -                return 0;
       -        if(n > namelen && dp->name[n - namelen - 1] != '.')
       -                return 0;
       -        return 1;
       -}
       -
       -static void
       -dnzone(DNSmsg *reqp, DNSmsg *repp, Request *req)
       -{
       -        DN *dp, *ndp;
       -        RR r, *rp;
       -        int h, depth, found, nlen;
       -
       -        memset(repp, 0, sizeof(*repp));
       -        repp->id = reqp->id;
       -        repp->flags = Fauth | Fresp | Fcanrec | Oquery;
       -        repp->qd = reqp->qd;
       -        reqp->qd = reqp->qd->next;
       -        repp->qd->next = 0;
       -        dp = repp->qd->owner;
       -
       -        /* send the soa */
       -        repp->an = rrlookup(dp, Tsoa, NOneg);
       -        reply(1, repp, req);
       -        if(repp->an == 0)
       -                goto out;
       -        rrfreelist(repp->an);
       -
       -        nlen = strlen(dp->name);
       -
       -        /* construct a breadth first search of the name space (hard with a hash) */
       -        repp->an = &r;
       -        for(depth = numelem(dp->name); ; depth++){
       -                found = 0;
       -                for(h = 0; h < HTLEN; h++)
       -                        for(ndp = ht[h]; ndp; ndp = ndp->next)
       -                                if(inzone(ndp, dp->name, nlen, depth)){
       -                                        for(rp = ndp->rr; rp; rp = rp->next){
       -                                                /* there shouldn't be negatives, but just in case */
       -                                                if(rp->negative)
       -                                                        continue;
       -
       -                                                /* don't send an soa's, ns's are enough */
       -                                                if(rp->type == Tsoa)
       -                                                        continue;
       -
       -                                                r = *rp;
       -                                                r.next = 0;
       -                                                reply(1, repp, req);
       -                                        }
       -                                        found = 1;
       -                                }
       -                if(!found)
       -                        break;
       -        }
       -
       -        /* resend the soa */
       -        repp->an = rrlookup(dp, Tsoa, NOneg);
       -        reply(1, repp, req);
       -        rrfreelist(repp->an);
       -out:
       -        rrfree(repp->qd);
       -}
       -
       -static void
       -getcaller(char *dir)
       -{
       -        int fd, n;
       -        static char remote[128];
       -
       -        snprint(remote, sizeof(remote), "%s/remote", dir);
       -        fd = open(remote, OREAD);
       -        if(fd < 0)
       -                return;
       -        n = read(fd, remote, sizeof(remote)-1);
       -        close(fd);
       -        if(n <= 0)
       -                return;
       -        if(remote[n-1] == '\n')
       -                n--;
       -        remote[n] = 0;
       -        caller = remote;
       -}
       -
       -static void
       -refreshmain(char *net)
       -{
       -        int fd;
       -        char file[128];
       -
       -        snprint(file, sizeof(file), "%s/dns", net);
       -        if(debug)
       -                syslog(0, logfile, "refreshing %s", file);
       -        fd = open(file, ORDWR);
       -        if(fd < 0){
       -                syslog(0, logfile, "can't refresh %s", file);
       -                return;
       -        }
       -        fprint(fd, "refresh");
       -        close(fd);
       +        tcpproc(0);
        }
        
        /*
   DIR diff --git a/src/cmd/ndb/dnudpserver.c b/src/cmd/ndb/dnudpserver.c
       t@@ -3,6 +3,7 @@
        #include <ip.h>
        #include <bio.h>
        #include <ndb.h>
       +#include <thread.h>
        #include "dns.h"
        
        static int        udpannounce(char*);
       t@@ -10,21 +11,11 @@ static void        reply(int, uchar*, DNSmsg*, Request*);
        
        extern char *logfile;
        
       -static void
       -ding(void *x, char *msg)
       -{
       -        USED(x);
       -        if(strcmp(msg, "alarm") == 0)
       -                noted(NCONT);
       -        else
       -                noted(NDFLT);
       -}
       -
        typedef struct Inprogress Inprogress;
        struct Inprogress
        {
                int        inuse;
       -        OUdphdr        uh;
       +        Udphdr        uh;
                DN        *owner;
                int        type;
                int        id;
       t@@ -33,15 +24,15 @@ Inprogress inprog[Maxactive+2];
        
        /*
         *  record client id and ignore retransmissions.
       - *  we're still single thread at this point.
       + *  we're still single thread at this point.  BUG
         */
        static Inprogress*
        clientrxmit(DNSmsg *req, uchar *buf)
        {
                Inprogress *p, *empty;
       -        OUdphdr *uh;
       +        Udphdr *uh;
        
       -        uh = (OUdphdr *)buf;
       +        uh = (Udphdr *)buf;
                empty = 0;
                for(p = inprog; p < &inprog[Maxactive]; p++){
                        if(p->inuse == 0){
       t@@ -52,7 +43,7 @@ clientrxmit(DNSmsg *req, uchar *buf)
                        if(req->id == p->id)
                        if(req->qd->owner == p->owner)
                        if(req->qd->type == p->type)
       -                if(memcmp(uh, &p->uh, OUdphdrsize) == 0)
       +                if(memcmp(uh, &p->uh, Udphdrsize) == 0)
                                return 0;
                }
                if(empty == 0)
       t@@ -61,7 +52,7 @@ clientrxmit(DNSmsg *req, uchar *buf)
                empty->id = req->id;
                empty->owner = req->qd->owner;
                empty->type = req->qd->type;
       -        memmove(&empty->uh, uh, OUdphdrsize);
       +        memmove(&empty->uh, uh, Udphdrsize);
                empty->inuse = 1;
                return empty;
        }
       t@@ -69,52 +60,33 @@ clientrxmit(DNSmsg *req, uchar *buf)
        /*
         *  a process to act as a dns server for outside reqeusts
         */
       -void
       -dnudpserver(char *mntpt)
       +static void
       +udpproc(void *v)
        {
                int fd, len, op;
                Request req;
                DNSmsg reqmsg, repmsg;
       -        uchar buf[OUdphdrsize + Maxudp + 1024];
       +        uchar buf[Udphdrsize + Maxudp + 1024];
                char *err;
                Inprogress *p;
                char tname[32];
       -        OUdphdr *uh;
       -
       -        /* fork sharing text, data, and bss with parent */
       -        switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){
       -        case -1:
       -                break;
       -        case 0:
       -                break;
       -        default:
       -                return;
       -        }
       +        Udphdr *uh;
        
       -        fd = -1;
       -        notify(ding);
       -restart:
       -        if(fd >= 0)
       -                close(fd);
       -        while((fd = udpannounce(mntpt)) < 0)
       -                sleep(5000);
       -        if(setjmp(req.mret))
       -                putactivity();
       -        req.isslave = 0;
       +        fd = (int)v;
        
                /* loop on requests */
                for(;; putactivity()){
                        memset(&repmsg, 0, sizeof(repmsg));
                        memset(&reqmsg, 0, sizeof(reqmsg));
                        alarm(60*1000);
       -                len = udpread(fd, (OUdphdr*)buf, buf+OUdphdrsize, sizeof(buf)-OUdphdrsize);
       +                len = udpread(fd, (Udphdr*)buf, buf+Udphdrsize, sizeof(buf)-Udphdrsize);
                        alarm(0);
                        if(len <= 0)
       -                        goto restart;
       -                uh = (OUdphdr*)buf;
       +                        continue;
       +                uh = (Udphdr*)buf;
                        getactivity(&req);
                        req.aborttime = now + 30;        /* don't spend more than 30 seconds */
       -                err = convM2DNS(&buf[OUdphdrsize], len, &reqmsg);
       +                err = convM2DNS(&buf[Udphdrsize], len, &reqmsg);
                        if(err){
                                syslog(0, logfile, "server: input error: %s from %I", err, buf);
                                continue;
       t@@ -173,12 +145,6 @@ freereq:
                        rrfreelist(reqmsg.an);
                        rrfreelist(reqmsg.ns);
                        rrfreelist(reqmsg.ar);
       -
       -                if(req.isslave){
       -                        putactivity();
       -                        _exits(0);
       -                }
       -
                }
        }
        
       t@@ -192,8 +158,9 @@ udpannounce(char *mntpt)
                char buf[40];
                
                USED(mntpt);
       -        
       -        if((fd=announce("udp!*!nameserver", buf)) < 0)
       +
       +        snprint(buf, sizeof buf, "udp!*!%s", portname);
       +        if((fd=announce(buf, buf)) < 0)
                        warning("can't announce on dns udp port");
                return fd;
        }
       t@@ -211,7 +178,7 @@ reply(int fd, uchar *buf, DNSmsg *rep, Request *reqp)
                                rep->id, rep->qd->owner->name,
                                rrname(rep->qd->type, tname, sizeof tname), rep->an, rep->ns, rep->ar);
        
       -        len = convDNS2M(rep, &buf[OUdphdrsize], Maxudp);
       +        len = convDNS2M(rep, &buf[Udphdrsize], Maxudp);
                if(len <= 0){
                        syslog(0, logfile, "error converting reply: %s %d", rep->qd->owner->name,
                                rep->qd->type);
       t@@ -223,6 +190,18 @@ reply(int fd, uchar *buf, DNSmsg *rep, Request *reqp)
                                syslog(0, logfile, "ar %R", rp);
                        return;
                }
       -        if(udpwrite(fd, (OUdphdr*)buf, buf+OUdphdrsize, len) != len)
       +        if(udpwrite(fd, (Udphdr*)buf, buf+Udphdrsize, len) != len)
                        syslog(0, logfile, "error sending reply: %r");
        }
       +
       +void
       +dnudpserver(void *v)
       +{
       +        int i, fd;
       +
       +        while((fd = udpannounce(v)) < 0)
       +                sleep(5*1000);
       +        for(i=0; i<Maxactive; i++)
       +                proccreate(udpproc, (void*)fd, STACK);
       +}
       +
   DIR diff --git a/src/cmd/ndb/mkfile b/src/cmd/ndb/mkfile
       t@@ -1,7 +1,10 @@
        <$PLAN9/src/mkhdr
        
        TARG=\
       -#        dns\
       +        dns\
       +        dnsquery\
       +        dnsdebug\
       +        dnstcp\
                ndbmkdb\
                ndbquery\
                ndbmkhash\
       t@@ -20,6 +23,7 @@ DNSOFILES=\
                dn.$O\
                dnresolve.$O\
                dnserver.$O\
       +        dntcpserver.$O\
        
        $DNSOFILES dns.$O dnstcp.$O dnsdebug.$O: dns.h