13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 3219b2ee8SDavid du Colombier #include <auth.h> 43e12c5d1SDavid du Colombier #include <fcall.h> 53e12c5d1SDavid du Colombier #include <bio.h> 63e12c5d1SDavid du Colombier #include <ctype.h> 77dd7cddfSDavid du Colombier #include <ip.h> 8*9a747e4fSDavid du Colombier #include <pool.h> 93e12c5d1SDavid du Colombier #include "dns.h" 103e12c5d1SDavid du Colombier 113e12c5d1SDavid du Colombier enum 123e12c5d1SDavid du Colombier { 13*9a747e4fSDavid du Colombier Maxrequest= 1024, 143e12c5d1SDavid du Colombier Ncache= 8, 157dd7cddfSDavid du Colombier Maxpath= 128, 167dd7cddfSDavid du Colombier Maxreply= 512, 177dd7cddfSDavid du Colombier Maxrrr= 16, 18*9a747e4fSDavid du Colombier Maxfdata= 8192, 193e12c5d1SDavid du Colombier 20*9a747e4fSDavid du Colombier Qdir= 0, 213e12c5d1SDavid du Colombier Qdns= 1, 223e12c5d1SDavid du Colombier }; 233e12c5d1SDavid du Colombier 243e12c5d1SDavid du Colombier typedef struct Mfile Mfile; 257dd7cddfSDavid du Colombier typedef struct Job Job; 263e12c5d1SDavid du Colombier typedef struct Network Network; 273e12c5d1SDavid du Colombier 283e12c5d1SDavid du Colombier int vers; /* incremented each clone/attach */ 293e12c5d1SDavid du Colombier 303e12c5d1SDavid du Colombier struct Mfile 313e12c5d1SDavid du Colombier { 327dd7cddfSDavid du Colombier Mfile *next; /* next free mfile */ 33*9a747e4fSDavid du Colombier int ref; 347dd7cddfSDavid du Colombier 35*9a747e4fSDavid du Colombier char *user; 363e12c5d1SDavid du Colombier Qid qid; 373e12c5d1SDavid du Colombier int fid; 383e12c5d1SDavid du Colombier 393e12c5d1SDavid du Colombier int type; /* reply type */ 407dd7cddfSDavid du Colombier char reply[Maxreply]; 417dd7cddfSDavid du Colombier ushort rr[Maxrrr]; /* offset of rr's */ 427dd7cddfSDavid du Colombier ushort nrr; /* number of rr's */ 433e12c5d1SDavid du Colombier }; 443e12c5d1SDavid du Colombier 457dd7cddfSDavid du Colombier // 467dd7cddfSDavid du Colombier // active local requests 477dd7cddfSDavid du Colombier // 487dd7cddfSDavid du Colombier struct Job 497dd7cddfSDavid du Colombier { 507dd7cddfSDavid du Colombier Job *next; 517dd7cddfSDavid du Colombier int flushed; 527dd7cddfSDavid du Colombier Fcall request; 537dd7cddfSDavid du Colombier Fcall reply; 547dd7cddfSDavid du Colombier }; 557dd7cddfSDavid du Colombier Lock joblock; 567dd7cddfSDavid du Colombier Job *joblist; 577dd7cddfSDavid du Colombier 587dd7cddfSDavid du Colombier struct { 597dd7cddfSDavid du Colombier Lock; 607dd7cddfSDavid du Colombier Mfile *inuse; /* active mfile's */ 617dd7cddfSDavid du Colombier } mfalloc; 627dd7cddfSDavid du Colombier 633e12c5d1SDavid du Colombier int mfd[2]; 643e12c5d1SDavid du Colombier int debug; 657dd7cddfSDavid du Colombier int cachedb; 667dd7cddfSDavid du Colombier ulong now; 677dd7cddfSDavid du Colombier int testing; 687dd7cddfSDavid du Colombier char *trace; 697dd7cddfSDavid du Colombier int needrefresh; 707dd7cddfSDavid du Colombier int resolver; 717dd7cddfSDavid du Colombier uchar ipaddr[IPaddrlen]; /* my ip address */ 727dd7cddfSDavid du Colombier int maxage; 733e12c5d1SDavid du Colombier 74*9a747e4fSDavid du Colombier void rversion(Job*); 75*9a747e4fSDavid du Colombier void rauth(Job*); 767dd7cddfSDavid du Colombier void rflush(Job*); 777dd7cddfSDavid du Colombier void rattach(Job*, Mfile*); 787dd7cddfSDavid du Colombier char* rwalk(Job*, Mfile*); 797dd7cddfSDavid du Colombier void ropen(Job*, Mfile*); 807dd7cddfSDavid du Colombier void rcreate(Job*, Mfile*); 817dd7cddfSDavid du Colombier void rread(Job*, Mfile*); 827dd7cddfSDavid du Colombier void rwrite(Job*, Mfile*, Request*); 837dd7cddfSDavid du Colombier void rclunk(Job*, Mfile*); 847dd7cddfSDavid du Colombier void rremove(Job*, Mfile*); 857dd7cddfSDavid du Colombier void rstat(Job*, Mfile*); 867dd7cddfSDavid du Colombier void rwstat(Job*, Mfile*); 877dd7cddfSDavid du Colombier void sendmsg(Job*, char*); 887dd7cddfSDavid du Colombier void mountinit(char*, char*); 893e12c5d1SDavid du Colombier void io(void); 903e12c5d1SDavid du Colombier int fillreply(Mfile*, int); 917dd7cddfSDavid du Colombier Job* newjob(void); 927dd7cddfSDavid du Colombier void freejob(Job*); 937dd7cddfSDavid du Colombier void setext(char*, int, char*); 943e12c5d1SDavid du Colombier 95219b2ee8SDavid du Colombier char *logfile = "dns"; 96219b2ee8SDavid du Colombier char *dbfile; 977dd7cddfSDavid du Colombier char mntpt[Maxpath]; 987dd7cddfSDavid du Colombier char *LOG; 997dd7cddfSDavid du Colombier 1007dd7cddfSDavid du Colombier void 1017dd7cddfSDavid du Colombier usage(void) 1027dd7cddfSDavid du Colombier { 1037dd7cddfSDavid du Colombier fprint(2, "usage: %s [-rs] [-f ndb-file] [-x netmtpt]\n", argv0); 1047dd7cddfSDavid du Colombier exits("usage"); 1057dd7cddfSDavid du Colombier } 106219b2ee8SDavid du Colombier 1073e12c5d1SDavid du Colombier void 1083e12c5d1SDavid du Colombier main(int argc, char *argv[]) 1093e12c5d1SDavid du Colombier { 1103e12c5d1SDavid du Colombier int serve; 1117dd7cddfSDavid du Colombier char servefile[Maxpath]; 1127dd7cddfSDavid du Colombier char ext[Maxpath]; 1137dd7cddfSDavid du Colombier char *p; 114219b2ee8SDavid du Colombier 1153e12c5d1SDavid du Colombier serve = 0; 1167dd7cddfSDavid du Colombier setnetmtpt(mntpt, sizeof(mntpt), nil); 1177dd7cddfSDavid du Colombier ext[0] = 0; 1183e12c5d1SDavid du Colombier ARGBEGIN{ 1193e12c5d1SDavid du Colombier case 'd': 1203e12c5d1SDavid du Colombier debug = 1; 1213e12c5d1SDavid du Colombier break; 122219b2ee8SDavid du Colombier case 'f': 1237dd7cddfSDavid du Colombier p = ARGF(); 1247dd7cddfSDavid du Colombier if(p == nil) 1257dd7cddfSDavid du Colombier usage(); 1267dd7cddfSDavid du Colombier dbfile = p; 1277dd7cddfSDavid du Colombier break; 1287dd7cddfSDavid du Colombier case 'x': 1297dd7cddfSDavid du Colombier p = ARGF(); 1307dd7cddfSDavid du Colombier if(p == nil) 1317dd7cddfSDavid du Colombier usage(); 1327dd7cddfSDavid du Colombier setnetmtpt(mntpt, sizeof(mntpt), p); 1337dd7cddfSDavid du Colombier setext(ext, sizeof(ext), mntpt); 1347dd7cddfSDavid du Colombier break; 1357dd7cddfSDavid du Colombier case 'r': 1367dd7cddfSDavid du Colombier resolver = 1; 137219b2ee8SDavid du Colombier break; 1383e12c5d1SDavid du Colombier case 's': 1393e12c5d1SDavid du Colombier serve = 1; /* serve network */ 1407dd7cddfSDavid du Colombier cachedb = 1; 1417dd7cddfSDavid du Colombier break; 1427dd7cddfSDavid du Colombier case 'a': 1437dd7cddfSDavid du Colombier p = ARGF(); 1447dd7cddfSDavid du Colombier if(p == nil) 1457dd7cddfSDavid du Colombier usage(); 1467dd7cddfSDavid du Colombier maxage = atoi(p); 1477dd7cddfSDavid du Colombier break; 1487dd7cddfSDavid du Colombier case 't': 1497dd7cddfSDavid du Colombier testing = 1; 1503e12c5d1SDavid du Colombier break; 1513e12c5d1SDavid du Colombier }ARGEND 1523e12c5d1SDavid du Colombier USED(argc); 1533e12c5d1SDavid du Colombier USED(argv); 1543e12c5d1SDavid du Colombier 155*9a747e4fSDavid du Colombier if(testing) mainmem->flags |= POOL_NOREUSE; 1567dd7cddfSDavid du Colombier rfork(RFREND|RFNOTEG); 1573e12c5d1SDavid du Colombier 1587dd7cddfSDavid du Colombier /* start syslog before we fork */ 159*9a747e4fSDavid du Colombier fmtinstall('F', fcallfmt); 160219b2ee8SDavid du Colombier dninit(); 161*9a747e4fSDavid du Colombier if(myipaddr(ipaddr, mntpt) < 0) 1627dd7cddfSDavid du Colombier sysfatal("can't read my ip address"); 163219b2ee8SDavid du Colombier 1647dd7cddfSDavid du Colombier syslog(0, logfile, "starting dns on %I", ipaddr); 1657dd7cddfSDavid du Colombier 1667dd7cddfSDavid du Colombier opendatabase(); 1677dd7cddfSDavid du Colombier 1687dd7cddfSDavid du Colombier snprint(servefile, sizeof(servefile), "#s/dns%s", ext); 1697dd7cddfSDavid du Colombier unmount(servefile, mntpt); 1707dd7cddfSDavid du Colombier remove(servefile); 1717dd7cddfSDavid du Colombier mountinit(servefile, mntpt); 1727dd7cddfSDavid du Colombier 1737dd7cddfSDavid du Colombier now = time(0); 1747dd7cddfSDavid du Colombier srand(now*getpid()); 1757dd7cddfSDavid du Colombier db2cache(1); 1767dd7cddfSDavid du Colombier 177bd389b36SDavid du Colombier if(serve) 1787dd7cddfSDavid du Colombier dnudpserver(mntpt); 1793e12c5d1SDavid du Colombier io(); 1807dd7cddfSDavid du Colombier syslog(0, logfile, "io returned, exiting"); 1813e12c5d1SDavid du Colombier exits(0); 1823e12c5d1SDavid du Colombier } 1833e12c5d1SDavid du Colombier 1847dd7cddfSDavid du Colombier /* 1857dd7cddfSDavid du Colombier * if a mount point is specified, set the cs extention to be the mount point 1867dd7cddfSDavid du Colombier * with '_'s replacing '/'s 1877dd7cddfSDavid du Colombier */ 1883e12c5d1SDavid du Colombier void 1897dd7cddfSDavid du Colombier setext(char *ext, int n, char *p) 1907dd7cddfSDavid du Colombier { 1917dd7cddfSDavid du Colombier int i, c; 1927dd7cddfSDavid du Colombier 1937dd7cddfSDavid du Colombier n--; 1947dd7cddfSDavid du Colombier for(i = 0; i < n; i++){ 1957dd7cddfSDavid du Colombier c = p[i]; 1967dd7cddfSDavid du Colombier if(c == 0) 1977dd7cddfSDavid du Colombier break; 1987dd7cddfSDavid du Colombier if(c == '/') 1997dd7cddfSDavid du Colombier c = '_'; 2007dd7cddfSDavid du Colombier ext[i] = c; 2017dd7cddfSDavid du Colombier } 2027dd7cddfSDavid du Colombier ext[i] = 0; 2037dd7cddfSDavid du Colombier } 2047dd7cddfSDavid du Colombier 2057dd7cddfSDavid du Colombier void 2067dd7cddfSDavid du Colombier mountinit(char *service, char *mntpt) 2073e12c5d1SDavid du Colombier { 2083e12c5d1SDavid du Colombier int f; 2093e12c5d1SDavid du Colombier int p[2]; 2103e12c5d1SDavid du Colombier char buf[32]; 2113e12c5d1SDavid du Colombier 2123e12c5d1SDavid du Colombier if(pipe(p) < 0) 2137dd7cddfSDavid du Colombier abort(); /* "pipe failed" */; 214219b2ee8SDavid du Colombier switch(rfork(RFFDG|RFPROC|RFNAMEG)){ 2153e12c5d1SDavid du Colombier case 0: 216219b2ee8SDavid du Colombier close(p[1]); 2173e12c5d1SDavid du Colombier break; 2183e12c5d1SDavid du Colombier case -1: 2197dd7cddfSDavid du Colombier abort(); /* "fork failed\n" */; 2203e12c5d1SDavid du Colombier default: 221219b2ee8SDavid du Colombier close(p[0]); 222219b2ee8SDavid du Colombier 2233e12c5d1SDavid du Colombier /* 2243e12c5d1SDavid du Colombier * make a /srv/dns 2253e12c5d1SDavid du Colombier */ 2263e12c5d1SDavid du Colombier f = create(service, 1, 0666); 2273e12c5d1SDavid du Colombier if(f < 0) 2287dd7cddfSDavid du Colombier abort(); /* service */; 229bd389b36SDavid du Colombier snprint(buf, sizeof(buf), "%d", p[1]); 2303e12c5d1SDavid du Colombier if(write(f, buf, strlen(buf)) != strlen(buf)) 2317dd7cddfSDavid du Colombier abort(); /* "write %s", service */; 2323e12c5d1SDavid du Colombier close(f); 2333e12c5d1SDavid du Colombier 2343e12c5d1SDavid du Colombier /* 2353e12c5d1SDavid du Colombier * put ourselves into the file system 2363e12c5d1SDavid du Colombier */ 237*9a747e4fSDavid du Colombier if(mount(p[1], -1, mntpt, MAFTER, "") < 0) 238*9a747e4fSDavid du Colombier fprint(2, "dns mount failed: %r\n"); 239219b2ee8SDavid du Colombier _exits(0); 2403e12c5d1SDavid du Colombier } 2413e12c5d1SDavid du Colombier mfd[0] = mfd[1] = p[0]; 2423e12c5d1SDavid du Colombier } 2433e12c5d1SDavid du Colombier 2443e12c5d1SDavid du Colombier Mfile* 2457dd7cddfSDavid du Colombier newfid(int fid, int needunused) 2463e12c5d1SDavid du Colombier { 2473e12c5d1SDavid du Colombier Mfile *mf; 2483e12c5d1SDavid du Colombier 2497dd7cddfSDavid du Colombier lock(&mfalloc); 2507dd7cddfSDavid du Colombier for(mf = mfalloc.inuse; mf != nil; mf = mf->next){ 2517dd7cddfSDavid du Colombier if(mf->fid == fid){ 2527dd7cddfSDavid du Colombier unlock(&mfalloc); 2537dd7cddfSDavid du Colombier if(needunused) 2547dd7cddfSDavid du Colombier return nil; 2553e12c5d1SDavid du Colombier return mf; 2563e12c5d1SDavid du Colombier } 2573e12c5d1SDavid du Colombier } 258*9a747e4fSDavid du Colombier mf = emalloc(sizeof(*mf)); 2597dd7cddfSDavid du Colombier if(mf == nil) 2607dd7cddfSDavid du Colombier sysfatal("out of memory"); 2613e12c5d1SDavid du Colombier mf->fid = fid; 2627dd7cddfSDavid du Colombier mf->next = mfalloc.inuse; 2637dd7cddfSDavid du Colombier mfalloc.inuse = mf; 2647dd7cddfSDavid du Colombier unlock(&mfalloc); 2653e12c5d1SDavid du Colombier return mf; 2663e12c5d1SDavid du Colombier } 2673e12c5d1SDavid du Colombier 2683e12c5d1SDavid du Colombier void 2697dd7cddfSDavid du Colombier freefid(Mfile *mf) 2707dd7cddfSDavid du Colombier { 2717dd7cddfSDavid du Colombier Mfile **l; 2727dd7cddfSDavid du Colombier 2737dd7cddfSDavid du Colombier lock(&mfalloc); 2747dd7cddfSDavid du Colombier for(l = &mfalloc.inuse; *l != nil; l = &(*l)->next){ 2757dd7cddfSDavid du Colombier if(*l == mf){ 2767dd7cddfSDavid du Colombier *l = mf->next; 277*9a747e4fSDavid du Colombier if(mf->user) 278*9a747e4fSDavid du Colombier free(mf->user); 2797dd7cddfSDavid du Colombier free(mf); 2807dd7cddfSDavid du Colombier unlock(&mfalloc); 2817dd7cddfSDavid du Colombier return; 2827dd7cddfSDavid du Colombier } 2837dd7cddfSDavid du Colombier } 2847dd7cddfSDavid du Colombier sysfatal("freeing unused fid"); 2857dd7cddfSDavid du Colombier } 2867dd7cddfSDavid du Colombier 2877dd7cddfSDavid du Colombier Mfile* 2887dd7cddfSDavid du Colombier copyfid(Mfile *mf, int fid) 2897dd7cddfSDavid du Colombier { 2907dd7cddfSDavid du Colombier Mfile *nmf; 2917dd7cddfSDavid du Colombier 2927dd7cddfSDavid du Colombier nmf = newfid(fid, 1); 2937dd7cddfSDavid du Colombier if(nmf == nil) 2947dd7cddfSDavid du Colombier return nil; 2957dd7cddfSDavid du Colombier nmf->fid = fid; 296*9a747e4fSDavid du Colombier nmf->user = estrdup(mf->user); 297*9a747e4fSDavid du Colombier nmf->qid.type = mf->qid.type; 2987dd7cddfSDavid du Colombier nmf->qid.path = mf->qid.path; 2997dd7cddfSDavid du Colombier nmf->qid.vers = vers++; 3007dd7cddfSDavid du Colombier return nmf; 3017dd7cddfSDavid du Colombier } 3027dd7cddfSDavid du Colombier 3037dd7cddfSDavid du Colombier Job* 3047dd7cddfSDavid du Colombier newjob(void) 3057dd7cddfSDavid du Colombier { 3067dd7cddfSDavid du Colombier Job *job; 3077dd7cddfSDavid du Colombier 308*9a747e4fSDavid du Colombier job = emalloc(sizeof(*job)); 3097dd7cddfSDavid du Colombier lock(&joblock); 3107dd7cddfSDavid du Colombier job->next = joblist; 3117dd7cddfSDavid du Colombier joblist = job; 3127dd7cddfSDavid du Colombier job->request.tag = -1; 3137dd7cddfSDavid du Colombier unlock(&joblock); 3147dd7cddfSDavid du Colombier return job; 3157dd7cddfSDavid du Colombier } 3167dd7cddfSDavid du Colombier 3177dd7cddfSDavid du Colombier void 3187dd7cddfSDavid du Colombier freejob(Job *job) 3197dd7cddfSDavid du Colombier { 3207dd7cddfSDavid du Colombier Job **l; 3217dd7cddfSDavid du Colombier 3227dd7cddfSDavid du Colombier lock(&joblock); 3237dd7cddfSDavid du Colombier for(l = &joblist; *l; l = &(*l)->next){ 3247dd7cddfSDavid du Colombier if((*l) == job){ 3257dd7cddfSDavid du Colombier *l = job->next; 3267dd7cddfSDavid du Colombier free(job); 3277dd7cddfSDavid du Colombier break; 3287dd7cddfSDavid du Colombier } 3297dd7cddfSDavid du Colombier } 3307dd7cddfSDavid du Colombier unlock(&joblock); 3317dd7cddfSDavid du Colombier } 3327dd7cddfSDavid du Colombier 3337dd7cddfSDavid du Colombier void 3347dd7cddfSDavid du Colombier flushjob(int tag) 3357dd7cddfSDavid du Colombier { 3367dd7cddfSDavid du Colombier Job *job; 3377dd7cddfSDavid du Colombier 3387dd7cddfSDavid du Colombier lock(&joblock); 3397dd7cddfSDavid du Colombier for(job = joblist; job; job = job->next){ 3407dd7cddfSDavid du Colombier if(job->request.tag == tag && job->request.type != Tflush){ 3417dd7cddfSDavid du Colombier job->flushed = 1; 3427dd7cddfSDavid du Colombier break; 3437dd7cddfSDavid du Colombier } 3447dd7cddfSDavid du Colombier } 3457dd7cddfSDavid du Colombier unlock(&joblock); 3467dd7cddfSDavid du Colombier } 3477dd7cddfSDavid du Colombier 3487dd7cddfSDavid du Colombier void 3493e12c5d1SDavid du Colombier io(void) 3503e12c5d1SDavid du Colombier { 3513e12c5d1SDavid du Colombier long n; 3523e12c5d1SDavid du Colombier Mfile *mf; 353*9a747e4fSDavid du Colombier uchar mdata[IOHDRSZ + Maxfdata]; 3543e12c5d1SDavid du Colombier Request req; 3557dd7cddfSDavid du Colombier Job *job; 3563e12c5d1SDavid du Colombier 3573e12c5d1SDavid du Colombier /* 3583e12c5d1SDavid du Colombier * a slave process is sometimes forked to wait for replies from other 3593e12c5d1SDavid du Colombier * servers. The master process returns immediately via a longjmp 360219b2ee8SDavid du Colombier * through 'mret'. 3613e12c5d1SDavid du Colombier */ 3627dd7cddfSDavid du Colombier if(setjmp(req.mret)) 3637dd7cddfSDavid du Colombier putactivity(); 3643e12c5d1SDavid du Colombier req.isslave = 0; 3657dd7cddfSDavid du Colombier for(;;){ 366*9a747e4fSDavid du Colombier n = read9pmsg(mfd[0], mdata, sizeof mdata); 3677dd7cddfSDavid du Colombier if(n<=0){ 3687dd7cddfSDavid du Colombier syslog(0, logfile, "error reading mntpt: %r"); 3697dd7cddfSDavid du Colombier exits(0); 3707dd7cddfSDavid du Colombier } 3717dd7cddfSDavid du Colombier job = newjob(); 372*9a747e4fSDavid du Colombier if(convM2S(mdata, n, &job->request) != n){ 3737dd7cddfSDavid du Colombier freejob(job); 3747dd7cddfSDavid du Colombier continue; 3757dd7cddfSDavid du Colombier } 3767dd7cddfSDavid du Colombier mf = newfid(job->request.fid, 0); 377219b2ee8SDavid du Colombier if(debug) 3787dd7cddfSDavid du Colombier syslog(0, logfile, "%F", &job->request); 3797dd7cddfSDavid du Colombier 3807dd7cddfSDavid du Colombier getactivity(&req); 3817dd7cddfSDavid du Colombier req.aborttime = now + 60; /* don't spend more than 60 seconds */ 3827dd7cddfSDavid du Colombier 3837dd7cddfSDavid du Colombier switch(job->request.type){ 3843e12c5d1SDavid du Colombier default: 385*9a747e4fSDavid du Colombier syslog(1, logfile, "unknown request type %d", job->request.type); 3863e12c5d1SDavid du Colombier break; 387*9a747e4fSDavid du Colombier case Tversion: 388*9a747e4fSDavid du Colombier rversion(job); 3893e12c5d1SDavid du Colombier break; 390*9a747e4fSDavid du Colombier case Tauth: 391*9a747e4fSDavid du Colombier rauth(job); 3923e12c5d1SDavid du Colombier break; 3933e12c5d1SDavid du Colombier case Tflush: 3947dd7cddfSDavid du Colombier rflush(job); 3953e12c5d1SDavid du Colombier break; 3963e12c5d1SDavid du Colombier case Tattach: 3977dd7cddfSDavid du Colombier rattach(job, mf); 3983e12c5d1SDavid du Colombier break; 3993e12c5d1SDavid du Colombier case Twalk: 4007dd7cddfSDavid du Colombier rwalk(job, mf); 4013e12c5d1SDavid du Colombier break; 4023e12c5d1SDavid du Colombier case Topen: 4037dd7cddfSDavid du Colombier ropen(job, mf); 4043e12c5d1SDavid du Colombier break; 4053e12c5d1SDavid du Colombier case Tcreate: 4067dd7cddfSDavid du Colombier rcreate(job, mf); 4073e12c5d1SDavid du Colombier break; 4083e12c5d1SDavid du Colombier case Tread: 4097dd7cddfSDavid du Colombier rread(job, mf); 4103e12c5d1SDavid du Colombier break; 4113e12c5d1SDavid du Colombier case Twrite: 4127dd7cddfSDavid du Colombier rwrite(job, mf, &req); 4133e12c5d1SDavid du Colombier break; 4143e12c5d1SDavid du Colombier case Tclunk: 4157dd7cddfSDavid du Colombier rclunk(job, mf); 4163e12c5d1SDavid du Colombier break; 4173e12c5d1SDavid du Colombier case Tremove: 4187dd7cddfSDavid du Colombier rremove(job, mf); 4193e12c5d1SDavid du Colombier break; 4203e12c5d1SDavid du Colombier case Tstat: 4217dd7cddfSDavid du Colombier rstat(job, mf); 4223e12c5d1SDavid du Colombier break; 4233e12c5d1SDavid du Colombier case Twstat: 4247dd7cddfSDavid du Colombier rwstat(job, mf); 4253e12c5d1SDavid du Colombier break; 4263e12c5d1SDavid du Colombier } 4277dd7cddfSDavid du Colombier 4287dd7cddfSDavid du Colombier freejob(job); 4297dd7cddfSDavid du Colombier 4303e12c5d1SDavid du Colombier /* 4313e12c5d1SDavid du Colombier * slave processes die after replying 4323e12c5d1SDavid du Colombier */ 4337dd7cddfSDavid du Colombier if(req.isslave){ 4347dd7cddfSDavid du Colombier putactivity(); 4353e12c5d1SDavid du Colombier _exits(0); 4367dd7cddfSDavid du Colombier } 4377dd7cddfSDavid du Colombier 4387dd7cddfSDavid du Colombier putactivity(); 4397dd7cddfSDavid du Colombier } 4403e12c5d1SDavid du Colombier } 4413e12c5d1SDavid du Colombier 4423e12c5d1SDavid du Colombier void 443*9a747e4fSDavid du Colombier rversion(Job *job) 444219b2ee8SDavid du Colombier { 445*9a747e4fSDavid du Colombier if(job->request.msize > IOHDRSZ + Maxfdata) 446*9a747e4fSDavid du Colombier job->reply.msize = IOHDRSZ + Maxfdata; 447*9a747e4fSDavid du Colombier else 448*9a747e4fSDavid du Colombier job->reply.msize = job->request.msize; 449*9a747e4fSDavid du Colombier if(strncmp(job->request.version, "9P2000", 6) != 0) 450*9a747e4fSDavid du Colombier sendmsg(job, "unknown 9P version"); 451*9a747e4fSDavid du Colombier else{ 452*9a747e4fSDavid du Colombier job->reply.version = "9P2000"; 4537dd7cddfSDavid du Colombier sendmsg(job, 0); 454219b2ee8SDavid du Colombier } 455*9a747e4fSDavid du Colombier } 456219b2ee8SDavid du Colombier 457219b2ee8SDavid du Colombier void 458*9a747e4fSDavid du Colombier rauth(Job *job) 4593e12c5d1SDavid du Colombier { 460*9a747e4fSDavid du Colombier sendmsg(job, "authentication not required"); 4617dd7cddfSDavid du Colombier } 4627dd7cddfSDavid du Colombier 463*9a747e4fSDavid du Colombier /* 464*9a747e4fSDavid du Colombier * don't flush till all the slaves are done 465*9a747e4fSDavid du Colombier */ 4667dd7cddfSDavid du Colombier void 4677dd7cddfSDavid du Colombier rflush(Job *job) 4687dd7cddfSDavid du Colombier { 4697dd7cddfSDavid du Colombier flushjob(job->request.oldtag); 4707dd7cddfSDavid du Colombier sendmsg(job, 0); 4713e12c5d1SDavid du Colombier } 4723e12c5d1SDavid du Colombier 4733e12c5d1SDavid du Colombier void 4747dd7cddfSDavid du Colombier rattach(Job *job, Mfile *mf) 4753e12c5d1SDavid du Colombier { 476*9a747e4fSDavid du Colombier if(mf->user != nil) 477*9a747e4fSDavid du Colombier free(mf->user); 478*9a747e4fSDavid du Colombier mf->user = estrdup(job->request.uname); 4793e12c5d1SDavid du Colombier mf->qid.vers = vers++; 480*9a747e4fSDavid du Colombier mf->qid.type = QTDIR; 481*9a747e4fSDavid du Colombier mf->qid.path = 0LL; 4827dd7cddfSDavid du Colombier job->reply.qid = mf->qid; 4837dd7cddfSDavid du Colombier sendmsg(job, 0); 4843e12c5d1SDavid du Colombier } 4853e12c5d1SDavid du Colombier 4863e12c5d1SDavid du Colombier char* 4877dd7cddfSDavid du Colombier rwalk(Job *job, Mfile *mf) 4883e12c5d1SDavid du Colombier { 4893e12c5d1SDavid du Colombier char *err; 490*9a747e4fSDavid du Colombier char **elems; 491*9a747e4fSDavid du Colombier int nelems; 492*9a747e4fSDavid du Colombier int i; 493*9a747e4fSDavid du Colombier Mfile *nmf; 494*9a747e4fSDavid du Colombier Qid qid; 4953e12c5d1SDavid du Colombier 4963e12c5d1SDavid du Colombier err = 0; 497*9a747e4fSDavid du Colombier nmf = nil; 498*9a747e4fSDavid du Colombier elems = job->request.wname; 499*9a747e4fSDavid du Colombier nelems = job->request.nwname; 500*9a747e4fSDavid du Colombier job->reply.nwqid = 0; 501*9a747e4fSDavid du Colombier 502*9a747e4fSDavid du Colombier if(job->request.newfid != job->request.fid){ 503*9a747e4fSDavid du Colombier /* clone fid */ 504*9a747e4fSDavid du Colombier if(job->request.newfid<0){ 505*9a747e4fSDavid du Colombier err = "clone newfid out of range"; 506*9a747e4fSDavid du Colombier goto send; 507*9a747e4fSDavid du Colombier } 508*9a747e4fSDavid du Colombier nmf = copyfid(mf, job->request.newfid); 509*9a747e4fSDavid du Colombier if(nmf == nil){ 510*9a747e4fSDavid du Colombier err = "clone bad newfid"; 511*9a747e4fSDavid du Colombier goto send; 512*9a747e4fSDavid du Colombier } 513*9a747e4fSDavid du Colombier mf = nmf; 514*9a747e4fSDavid du Colombier } 515*9a747e4fSDavid du Colombier /* else nmf will be nil */ 516*9a747e4fSDavid du Colombier 517*9a747e4fSDavid du Colombier qid = mf->qid; 518*9a747e4fSDavid du Colombier if(nelems > 0){ 519*9a747e4fSDavid du Colombier /* walk fid */ 520*9a747e4fSDavid du Colombier for(i=0; i<nelems && i<MAXWELEM; i++){ 521*9a747e4fSDavid du Colombier if((qid.type & QTDIR) == 0){ 5223e12c5d1SDavid du Colombier err = "not a directory"; 523*9a747e4fSDavid du Colombier break; 5243e12c5d1SDavid du Colombier } 525*9a747e4fSDavid du Colombier if(strcmp(elems[i], "..") == 0 || strcmp(elems[i], ".") == 0){ 526*9a747e4fSDavid du Colombier qid.type = QTDIR; 527*9a747e4fSDavid du Colombier qid.path = Qdir; 528*9a747e4fSDavid du Colombier Found: 529*9a747e4fSDavid du Colombier job->reply.wqid[i] = qid; 530*9a747e4fSDavid du Colombier job->reply.nwqid++; 531*9a747e4fSDavid du Colombier continue; 5323e12c5d1SDavid du Colombier } 533*9a747e4fSDavid du Colombier if(strcmp(elems[i], "dns") == 0){ 534*9a747e4fSDavid du Colombier qid.type = QTFILE; 535*9a747e4fSDavid du Colombier qid.path = Qdns; 536*9a747e4fSDavid du Colombier goto Found; 5373e12c5d1SDavid du Colombier } 538*9a747e4fSDavid du Colombier err = "file does not exist"; 539*9a747e4fSDavid du Colombier break; 540*9a747e4fSDavid du Colombier } 541*9a747e4fSDavid du Colombier } 542*9a747e4fSDavid du Colombier 5433e12c5d1SDavid du Colombier send: 544*9a747e4fSDavid du Colombier if(nmf != nil && (err!=nil || job->reply.nwqid<nelems)) 545*9a747e4fSDavid du Colombier freefid(nmf); 546*9a747e4fSDavid du Colombier if(err == nil) 547*9a747e4fSDavid du Colombier mf->qid = qid; 5487dd7cddfSDavid du Colombier sendmsg(job, err); 5493e12c5d1SDavid du Colombier return err; 5503e12c5d1SDavid du Colombier } 5513e12c5d1SDavid du Colombier 5523e12c5d1SDavid du Colombier void 5537dd7cddfSDavid du Colombier ropen(Job *job, Mfile *mf) 5543e12c5d1SDavid du Colombier { 5553e12c5d1SDavid du Colombier int mode; 5563e12c5d1SDavid du Colombier char *err; 5573e12c5d1SDavid du Colombier 5583e12c5d1SDavid du Colombier err = 0; 5597dd7cddfSDavid du Colombier mode = job->request.mode; 560*9a747e4fSDavid du Colombier if(mf->qid.type & QTDIR){ 5613e12c5d1SDavid du Colombier if(mode) 5623e12c5d1SDavid du Colombier err = "permission denied"; 5633e12c5d1SDavid du Colombier } 5647dd7cddfSDavid du Colombier job->reply.qid = mf->qid; 565*9a747e4fSDavid du Colombier job->reply.iounit = 0; 5667dd7cddfSDavid du Colombier sendmsg(job, err); 5673e12c5d1SDavid du Colombier } 5683e12c5d1SDavid du Colombier 5693e12c5d1SDavid du Colombier void 5707dd7cddfSDavid du Colombier rcreate(Job *job, Mfile *mf) 5713e12c5d1SDavid du Colombier { 5723e12c5d1SDavid du Colombier USED(mf); 5737dd7cddfSDavid du Colombier sendmsg(job, "creation permission denied"); 5743e12c5d1SDavid du Colombier } 5753e12c5d1SDavid du Colombier 5763e12c5d1SDavid du Colombier void 5777dd7cddfSDavid du Colombier rread(Job *job, Mfile *mf) 5783e12c5d1SDavid du Colombier { 5797dd7cddfSDavid du Colombier int i, n, cnt; 5807dd7cddfSDavid du Colombier long off; 5813e12c5d1SDavid du Colombier Dir dir; 582*9a747e4fSDavid du Colombier uchar buf[Maxfdata]; 5833e12c5d1SDavid du Colombier char *err; 584*9a747e4fSDavid du Colombier long clock; 5853e12c5d1SDavid du Colombier 5863e12c5d1SDavid du Colombier n = 0; 5873e12c5d1SDavid du Colombier err = 0; 5887dd7cddfSDavid du Colombier off = job->request.offset; 5897dd7cddfSDavid du Colombier cnt = job->request.count; 590*9a747e4fSDavid du Colombier if(mf->qid.type & QTDIR){ 591*9a747e4fSDavid du Colombier clock = time(0); 5923e12c5d1SDavid du Colombier if(off == 0){ 593*9a747e4fSDavid du Colombier dir.name = "dns"; 594*9a747e4fSDavid du Colombier dir.qid.type = QTFILE; 5953e12c5d1SDavid du Colombier dir.qid.vers = vers; 5963e12c5d1SDavid du Colombier dir.qid.path = Qdns; 5973e12c5d1SDavid du Colombier dir.mode = 0666; 5983e12c5d1SDavid du Colombier dir.length = 0; 599*9a747e4fSDavid du Colombier dir.uid = mf->user; 600*9a747e4fSDavid du Colombier dir.gid = mf->user; 601*9a747e4fSDavid du Colombier dir.muid = mf->user; 602*9a747e4fSDavid du Colombier dir.atime = clock; /* wrong */ 603*9a747e4fSDavid du Colombier dir.mtime = clock; /* wrong */ 604*9a747e4fSDavid du Colombier n = convD2M(&dir, buf, sizeof buf); 6053e12c5d1SDavid du Colombier } 606*9a747e4fSDavid du Colombier job->reply.data = (char*)buf; 6073e12c5d1SDavid du Colombier } else { 6087dd7cddfSDavid du Colombier for(i = 1; i <= mf->nrr; i++) 6097dd7cddfSDavid du Colombier if(mf->rr[i] > off) 6103e12c5d1SDavid du Colombier break; 6117dd7cddfSDavid du Colombier if(i > mf->nrr) 6127dd7cddfSDavid du Colombier goto send; 6137dd7cddfSDavid du Colombier if(off + cnt > mf->rr[i]) 6147dd7cddfSDavid du Colombier n = mf->rr[i] - off; 6157dd7cddfSDavid du Colombier else 6167dd7cddfSDavid du Colombier n = cnt; 6177dd7cddfSDavid du Colombier job->reply.data = mf->reply + off; 6183e12c5d1SDavid du Colombier } 6193e12c5d1SDavid du Colombier send: 6207dd7cddfSDavid du Colombier job->reply.count = n; 6217dd7cddfSDavid du Colombier sendmsg(job, err); 6223e12c5d1SDavid du Colombier } 6233e12c5d1SDavid du Colombier 6243e12c5d1SDavid du Colombier void 6257dd7cddfSDavid du Colombier rwrite(Job *job, Mfile *mf, Request *req) 6263e12c5d1SDavid du Colombier { 6277dd7cddfSDavid du Colombier int cnt, rooted, status; 6287dd7cddfSDavid du Colombier long n; 6297dd7cddfSDavid du Colombier char *err, *p, *atype; 6307dd7cddfSDavid du Colombier RR *rp, *tp, *neg; 6317dd7cddfSDavid du Colombier int wantsav; 6323e12c5d1SDavid du Colombier 6333e12c5d1SDavid du Colombier err = 0; 6347dd7cddfSDavid du Colombier cnt = job->request.count; 635*9a747e4fSDavid du Colombier if(mf->qid.type & QTDIR){ 6363e12c5d1SDavid du Colombier err = "can't write directory"; 6373e12c5d1SDavid du Colombier goto send; 6383e12c5d1SDavid du Colombier } 6393e12c5d1SDavid du Colombier if(cnt >= Maxrequest){ 6403e12c5d1SDavid du Colombier err = "request too long"; 6413e12c5d1SDavid du Colombier goto send; 6423e12c5d1SDavid du Colombier } 6437dd7cddfSDavid du Colombier job->request.data[cnt] = 0; 6447dd7cddfSDavid du Colombier if(cnt > 0 && job->request.data[cnt-1] == '\n') 6457dd7cddfSDavid du Colombier job->request.data[cnt-1] = 0; 6463e12c5d1SDavid du Colombier 6473e12c5d1SDavid du Colombier /* 6487dd7cddfSDavid du Colombier * special commands 649219b2ee8SDavid du Colombier */ 6507dd7cddfSDavid du Colombier if(strncmp(job->request.data, "debug", 5)==0 && job->request.data[5] == 0){ 651219b2ee8SDavid du Colombier debug ^= 1; 652219b2ee8SDavid du Colombier goto send; 6537dd7cddfSDavid du Colombier } else if(strncmp(job->request.data, "dump", 4)==0 && job->request.data[4] == 0){ 654219b2ee8SDavid du Colombier dndump("/lib/ndb/dnsdump"); 655219b2ee8SDavid du Colombier goto send; 6567dd7cddfSDavid du Colombier } else if(strncmp(job->request.data, "refresh", 7)==0 && job->request.data[7] == 0){ 6577dd7cddfSDavid du Colombier needrefresh = 1; 6587dd7cddfSDavid du Colombier goto send; 659*9a747e4fSDavid du Colombier } else if(strncmp(job->request.data, "poolcheck", 9)==0 && job->request.data[9] == 0){ 660*9a747e4fSDavid du Colombier poolcheck(mainmem); 661*9a747e4fSDavid du Colombier goto send; 662219b2ee8SDavid du Colombier } 663219b2ee8SDavid du Colombier 664219b2ee8SDavid du Colombier /* 6657dd7cddfSDavid du Colombier * kill previous reply 6667dd7cddfSDavid du Colombier */ 6677dd7cddfSDavid du Colombier mf->nrr = 0; 6687dd7cddfSDavid du Colombier mf->rr[0] = 0; 6697dd7cddfSDavid du Colombier 6707dd7cddfSDavid du Colombier /* 6713e12c5d1SDavid du Colombier * break up request (into a name and a type) 6723e12c5d1SDavid du Colombier */ 6737dd7cddfSDavid du Colombier atype = strchr(job->request.data, ' '); 6743e12c5d1SDavid du Colombier if(atype == 0){ 6753e12c5d1SDavid du Colombier err = "illegal request"; 6763e12c5d1SDavid du Colombier goto send; 6773e12c5d1SDavid du Colombier } else 6783e12c5d1SDavid du Colombier *atype++ = 0; 6793e12c5d1SDavid du Colombier 6807dd7cddfSDavid du Colombier /* 6817dd7cddfSDavid du Colombier * tracing request 6827dd7cddfSDavid du Colombier */ 6837dd7cddfSDavid du Colombier if(strcmp(atype, "trace") == 0){ 6847dd7cddfSDavid du Colombier if(trace) 6857dd7cddfSDavid du Colombier free(trace); 6867dd7cddfSDavid du Colombier if(*job->request.data) 687*9a747e4fSDavid du Colombier trace = estrdup(job->request.data); 6887dd7cddfSDavid du Colombier else 6897dd7cddfSDavid du Colombier trace = 0; 6907dd7cddfSDavid du Colombier goto send; 6917dd7cddfSDavid du Colombier } 6927dd7cddfSDavid du Colombier 6933e12c5d1SDavid du Colombier mf->type = rrtype(atype); 6943e12c5d1SDavid du Colombier if(mf->type < 0){ 6953e12c5d1SDavid du Colombier err = "unknown type"; 6963e12c5d1SDavid du Colombier goto send; 6973e12c5d1SDavid du Colombier } 6983e12c5d1SDavid du Colombier 6997dd7cddfSDavid du Colombier p = atype - 2; 7007dd7cddfSDavid du Colombier if(p >= job->request.data && *p == '.'){ 7017dd7cddfSDavid du Colombier rooted = 1; 7027dd7cddfSDavid du Colombier *p = 0; 7037dd7cddfSDavid du Colombier } else 7047dd7cddfSDavid du Colombier rooted = 0; 7053e12c5d1SDavid du Colombier 7067dd7cddfSDavid du Colombier p = job->request.data; 7077dd7cddfSDavid du Colombier if(*p == '!'){ 7087dd7cddfSDavid du Colombier wantsav = 1; 7097dd7cddfSDavid du Colombier p++; 7107dd7cddfSDavid du Colombier } else 7117dd7cddfSDavid du Colombier wantsav = 0; 712*9a747e4fSDavid du Colombier dncheck(0, 1); 7137dd7cddfSDavid du Colombier rp = dnresolve(p, Cin, mf->type, req, 0, 0, Recurse, rooted, &status); 714*9a747e4fSDavid du Colombier dncheck(0, 1); 7157dd7cddfSDavid du Colombier neg = rrremneg(&rp); 7167dd7cddfSDavid du Colombier if(neg){ 7177dd7cddfSDavid du Colombier status = neg->negrcode; 7187dd7cddfSDavid du Colombier rrfreelist(neg); 7197dd7cddfSDavid du Colombier } 7207dd7cddfSDavid du Colombier if(rp == 0){ 7217dd7cddfSDavid du Colombier if(status == Rname) 7227dd7cddfSDavid du Colombier err = "name does not exist"; 7237dd7cddfSDavid du Colombier else 7247dd7cddfSDavid du Colombier err = "no translation found"; 7257dd7cddfSDavid du Colombier } else { 7267dd7cddfSDavid du Colombier /* format data to be read later */ 7277dd7cddfSDavid du Colombier n = 0; 7287dd7cddfSDavid du Colombier mf->nrr = 0; 7297dd7cddfSDavid du Colombier for(tp = rp; mf->nrr < Maxrrr-1 && n < Maxreply && tp && 7307dd7cddfSDavid du Colombier tsame(mf->type, tp->type); tp = tp->next){ 7317dd7cddfSDavid du Colombier mf->rr[mf->nrr++] = n; 7327dd7cddfSDavid du Colombier if(wantsav) 7337dd7cddfSDavid du Colombier n += snprint(mf->reply+n, Maxreply-n, "%Q", tp); 7347dd7cddfSDavid du Colombier else 7357dd7cddfSDavid du Colombier n += snprint(mf->reply+n, Maxreply-n, "%R", tp); 7367dd7cddfSDavid du Colombier } 7377dd7cddfSDavid du Colombier mf->rr[mf->nrr] = n; 7387dd7cddfSDavid du Colombier rrfreelist(rp); 7397dd7cddfSDavid du Colombier } 7403e12c5d1SDavid du Colombier 7413e12c5d1SDavid du Colombier send: 742*9a747e4fSDavid du Colombier dncheck(0, 1); 7437dd7cddfSDavid du Colombier job->reply.count = cnt; 7447dd7cddfSDavid du Colombier sendmsg(job, err); 7453e12c5d1SDavid du Colombier } 7463e12c5d1SDavid du Colombier 7473e12c5d1SDavid du Colombier void 7487dd7cddfSDavid du Colombier rclunk(Job *job, Mfile *mf) 7493e12c5d1SDavid du Colombier { 7507dd7cddfSDavid du Colombier freefid(mf); 7517dd7cddfSDavid du Colombier sendmsg(job, 0); 7523e12c5d1SDavid du Colombier } 7533e12c5d1SDavid du Colombier 7543e12c5d1SDavid du Colombier void 7557dd7cddfSDavid du Colombier rremove(Job *job, Mfile *mf) 7563e12c5d1SDavid du Colombier { 7573e12c5d1SDavid du Colombier USED(mf); 7587dd7cddfSDavid du Colombier sendmsg(job, "remove permission denied"); 7593e12c5d1SDavid du Colombier } 7603e12c5d1SDavid du Colombier 7613e12c5d1SDavid du Colombier void 7627dd7cddfSDavid du Colombier rstat(Job *job, Mfile *mf) 7633e12c5d1SDavid du Colombier { 7643e12c5d1SDavid du Colombier Dir dir; 765*9a747e4fSDavid du Colombier uchar buf[IOHDRSZ+Maxfdata]; 7663e12c5d1SDavid du Colombier 767*9a747e4fSDavid du Colombier if(mf->qid.type & QTDIR){ 768*9a747e4fSDavid du Colombier dir.name = "."; 769*9a747e4fSDavid du Colombier dir.mode = DMDIR|0555; 770219b2ee8SDavid du Colombier } else { 771*9a747e4fSDavid du Colombier dir.name = "dns"; 7723e12c5d1SDavid du Colombier dir.mode = 0666; 773219b2ee8SDavid du Colombier } 774219b2ee8SDavid du Colombier dir.qid = mf->qid; 7753e12c5d1SDavid du Colombier dir.length = 0; 776*9a747e4fSDavid du Colombier dir.uid = mf->user; 777*9a747e4fSDavid du Colombier dir.gid = mf->user; 778*9a747e4fSDavid du Colombier dir.muid = mf->user; 7793e12c5d1SDavid du Colombier dir.atime = dir.mtime = time(0); 780*9a747e4fSDavid du Colombier job->reply.nstat = convD2M(&dir, buf, sizeof buf); 781*9a747e4fSDavid du Colombier job->reply.stat = buf; 7827dd7cddfSDavid du Colombier sendmsg(job, 0); 7833e12c5d1SDavid du Colombier } 7843e12c5d1SDavid du Colombier 7853e12c5d1SDavid du Colombier void 7867dd7cddfSDavid du Colombier rwstat(Job *job, Mfile *mf) 7873e12c5d1SDavid du Colombier { 7883e12c5d1SDavid du Colombier USED(mf); 7897dd7cddfSDavid du Colombier sendmsg(job, "wstat permission denied"); 7903e12c5d1SDavid du Colombier } 7913e12c5d1SDavid du Colombier 7923e12c5d1SDavid du Colombier void 7937dd7cddfSDavid du Colombier sendmsg(Job *job, char *err) 7943e12c5d1SDavid du Colombier { 7953e12c5d1SDavid du Colombier int n; 796*9a747e4fSDavid du Colombier uchar mdata[IOHDRSZ + Maxfdata]; 797*9a747e4fSDavid du Colombier char ename[ERRMAX]; 7983e12c5d1SDavid du Colombier 7993e12c5d1SDavid du Colombier if(err){ 8007dd7cddfSDavid du Colombier job->reply.type = Rerror; 801*9a747e4fSDavid du Colombier snprint(ename, sizeof(ename), "dns: %s", err); 802*9a747e4fSDavid du Colombier job->reply.ename = ename; 8033e12c5d1SDavid du Colombier }else{ 8047dd7cddfSDavid du Colombier job->reply.type = job->request.type+1; 8053e12c5d1SDavid du Colombier } 8067dd7cddfSDavid du Colombier job->reply.tag = job->request.tag; 807*9a747e4fSDavid du Colombier n = convS2M(&job->reply, mdata, sizeof mdata); 808*9a747e4fSDavid du Colombier if(n == 0){ 809*9a747e4fSDavid du Colombier syslog(1, logfile, "sendmsg convS2M of %F returns 0", &job->reply); 810*9a747e4fSDavid du Colombier abort(); 8113e12c5d1SDavid du Colombier } 812*9a747e4fSDavid du Colombier lock(&joblock); 813*9a747e4fSDavid du Colombier if(job->flushed == 0) 814*9a747e4fSDavid du Colombier if(write(mfd[1], mdata, n)!=n) 815*9a747e4fSDavid du Colombier sysfatal("mount write"); 8167dd7cddfSDavid du Colombier unlock(&joblock); 817*9a747e4fSDavid du Colombier if(debug) 818*9a747e4fSDavid du Colombier syslog(0, logfile, "%F %d", &job->reply, n); 8193e12c5d1SDavid du Colombier } 8203e12c5d1SDavid du Colombier 8213e12c5d1SDavid du Colombier /* 8227dd7cddfSDavid du Colombier * the following varies between dnsdebug and dns 8233e12c5d1SDavid du Colombier */ 8243e12c5d1SDavid du Colombier void 8257dd7cddfSDavid du Colombier logreply(int id, uchar *addr, DNSmsg *mp) 8263e12c5d1SDavid du Colombier { 8277dd7cddfSDavid du Colombier RR *rp; 8283e12c5d1SDavid du Colombier 8297dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I flags:%s%s%s%s%s", id, addr, 8307dd7cddfSDavid du Colombier mp->flags & Fauth ? " auth" : "", 8317dd7cddfSDavid du Colombier mp->flags & Ftrunc ? " trunc" : "", 8327dd7cddfSDavid du Colombier mp->flags & Frecurse ? " rd" : "", 8337dd7cddfSDavid du Colombier mp->flags & Fcanrec ? " ra" : "", 8347dd7cddfSDavid du Colombier mp->flags & (Fauth|Rname) == (Fauth|Rname) ? 8357dd7cddfSDavid du Colombier " nx" : ""); 8367dd7cddfSDavid du Colombier for(rp = mp->qd; rp != nil; rp = rp->next) 8377dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I qd %s", id, addr, rp->owner->name); 8387dd7cddfSDavid du Colombier for(rp = mp->an; rp != nil; rp = rp->next) 8397dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I an %R", id, addr, rp); 8407dd7cddfSDavid du Colombier for(rp = mp->ns; rp != nil; rp = rp->next) 8417dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I ns %R", id, addr, rp); 8427dd7cddfSDavid du Colombier for(rp = mp->ar; rp != nil; rp = rp->next) 8437dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I ar %R", id, addr, rp); 8443e12c5d1SDavid du Colombier } 8457dd7cddfSDavid du Colombier 8467dd7cddfSDavid du Colombier void 8477dd7cddfSDavid du Colombier logsend(int id, int subid, uchar *addr, char *sname, char *rname, int type) 8487dd7cddfSDavid du Colombier { 8497dd7cddfSDavid du Colombier char buf[12]; 8507dd7cddfSDavid du Colombier 8517dd7cddfSDavid du Colombier syslog(0, LOG, "%d.%d: sending to %I/%s %s %s", 852*9a747e4fSDavid du Colombier id, subid, addr, sname, rname, rrname(type, buf, sizeof buf)); 8537dd7cddfSDavid du Colombier } 8547dd7cddfSDavid du Colombier 8557dd7cddfSDavid du Colombier RR* 8567dd7cddfSDavid du Colombier getdnsservers(int class) 8577dd7cddfSDavid du Colombier { 8587dd7cddfSDavid du Colombier return dnsservers(class); 8593e12c5d1SDavid du Colombier } 860