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> 89a747e4fSDavid du Colombier #include <pool.h> 93e12c5d1SDavid du Colombier #include "dns.h" 103e12c5d1SDavid du Colombier 113e12c5d1SDavid du Colombier enum 123e12c5d1SDavid du Colombier { 139a747e4fSDavid du Colombier Maxrequest= 1024, 143e12c5d1SDavid du Colombier Ncache= 8, 157dd7cddfSDavid du Colombier Maxpath= 128, 167dd7cddfSDavid du Colombier Maxreply= 512, 177dd7cddfSDavid du Colombier Maxrrr= 16, 189a747e4fSDavid du Colombier Maxfdata= 8192, 193e12c5d1SDavid du Colombier 209a747e4fSDavid 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 */ 339a747e4fSDavid du Colombier int ref; 347dd7cddfSDavid du Colombier 359a747e4fSDavid 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; 6539734e7eSDavid du Colombier int traceactivity; 667dd7cddfSDavid du Colombier int cachedb; 677dd7cddfSDavid du Colombier ulong now; 687dd7cddfSDavid du Colombier int testing; 697dd7cddfSDavid du Colombier char *trace; 707dd7cddfSDavid du Colombier int needrefresh; 717dd7cddfSDavid du Colombier int resolver; 727dd7cddfSDavid du Colombier uchar ipaddr[IPaddrlen]; /* my ip address */ 737dd7cddfSDavid du Colombier int maxage; 74dc5a79c1SDavid du Colombier char *zonerefreshprogram; 75dc5a79c1SDavid du Colombier int sendnotifies; 763e12c5d1SDavid du Colombier 779a747e4fSDavid du Colombier void rversion(Job*); 789a747e4fSDavid du Colombier void rauth(Job*); 797dd7cddfSDavid du Colombier void rflush(Job*); 807dd7cddfSDavid du Colombier void rattach(Job*, Mfile*); 817dd7cddfSDavid du Colombier char* rwalk(Job*, Mfile*); 827dd7cddfSDavid du Colombier void ropen(Job*, Mfile*); 837dd7cddfSDavid du Colombier void rcreate(Job*, Mfile*); 847dd7cddfSDavid du Colombier void rread(Job*, Mfile*); 857dd7cddfSDavid du Colombier void rwrite(Job*, Mfile*, Request*); 867dd7cddfSDavid du Colombier void rclunk(Job*, Mfile*); 877dd7cddfSDavid du Colombier void rremove(Job*, Mfile*); 887dd7cddfSDavid du Colombier void rstat(Job*, Mfile*); 897dd7cddfSDavid du Colombier void rwstat(Job*, Mfile*); 907dd7cddfSDavid du Colombier void sendmsg(Job*, char*); 917dd7cddfSDavid du Colombier void mountinit(char*, char*); 923e12c5d1SDavid du Colombier void io(void); 933e12c5d1SDavid du Colombier int fillreply(Mfile*, int); 947dd7cddfSDavid du Colombier Job* newjob(void); 957dd7cddfSDavid du Colombier void freejob(Job*); 967dd7cddfSDavid du Colombier void setext(char*, int, char*); 973e12c5d1SDavid du Colombier 98219b2ee8SDavid du Colombier char *logfile = "dns"; 99219b2ee8SDavid du Colombier char *dbfile; 1007dd7cddfSDavid du Colombier char mntpt[Maxpath]; 1017dd7cddfSDavid du Colombier char *LOG; 1027dd7cddfSDavid du Colombier 1037dd7cddfSDavid du Colombier void 1047dd7cddfSDavid du Colombier usage(void) 1057dd7cddfSDavid du Colombier { 1067dd7cddfSDavid du Colombier fprint(2, "usage: %s [-rs] [-f ndb-file] [-x netmtpt]\n", argv0); 1077dd7cddfSDavid du Colombier exits("usage"); 1087dd7cddfSDavid du Colombier } 109219b2ee8SDavid du Colombier 1103e12c5d1SDavid du Colombier void 1113e12c5d1SDavid du Colombier main(int argc, char *argv[]) 1123e12c5d1SDavid du Colombier { 1133e12c5d1SDavid du Colombier int serve; 1147dd7cddfSDavid du Colombier char servefile[Maxpath]; 1157dd7cddfSDavid du Colombier char ext[Maxpath]; 1167dd7cddfSDavid du Colombier char *p; 117219b2ee8SDavid du Colombier 1183e12c5d1SDavid du Colombier serve = 0; 1197dd7cddfSDavid du Colombier setnetmtpt(mntpt, sizeof(mntpt), nil); 1207dd7cddfSDavid du Colombier ext[0] = 0; 1213e12c5d1SDavid du Colombier ARGBEGIN{ 1223e12c5d1SDavid du Colombier case 'd': 1233e12c5d1SDavid du Colombier debug = 1; 12439734e7eSDavid du Colombier traceactivity = 1; 1253e12c5d1SDavid du Colombier break; 126219b2ee8SDavid du Colombier case 'f': 1277dd7cddfSDavid du Colombier p = ARGF(); 1287dd7cddfSDavid du Colombier if(p == nil) 1297dd7cddfSDavid du Colombier usage(); 1307dd7cddfSDavid du Colombier dbfile = p; 1317dd7cddfSDavid du Colombier break; 1327dd7cddfSDavid du Colombier case 'x': 1337dd7cddfSDavid du Colombier p = ARGF(); 1347dd7cddfSDavid du Colombier if(p == nil) 1357dd7cddfSDavid du Colombier usage(); 1367dd7cddfSDavid du Colombier setnetmtpt(mntpt, sizeof(mntpt), p); 1377dd7cddfSDavid du Colombier setext(ext, sizeof(ext), mntpt); 1387dd7cddfSDavid du Colombier break; 1397dd7cddfSDavid du Colombier case 'r': 1407dd7cddfSDavid du Colombier resolver = 1; 141219b2ee8SDavid du Colombier break; 142b85a8364SDavid du Colombier case 'R': 143b85a8364SDavid du Colombier norecursion = 1; 144b85a8364SDavid du Colombier break; 1453e12c5d1SDavid du Colombier case 's': 1463e12c5d1SDavid du Colombier serve = 1; /* serve network */ 1477dd7cddfSDavid du Colombier cachedb = 1; 1487dd7cddfSDavid du Colombier break; 1497dd7cddfSDavid du Colombier case 'a': 1507dd7cddfSDavid du Colombier p = ARGF(); 1517dd7cddfSDavid du Colombier if(p == nil) 1527dd7cddfSDavid du Colombier usage(); 1537dd7cddfSDavid du Colombier maxage = atoi(p); 1547dd7cddfSDavid du Colombier break; 1557dd7cddfSDavid du Colombier case 't': 1567dd7cddfSDavid du Colombier testing = 1; 1573e12c5d1SDavid du Colombier break; 158dc5a79c1SDavid du Colombier case 'z': 159dc5a79c1SDavid du Colombier zonerefreshprogram = ARGF(); 160dc5a79c1SDavid du Colombier break; 161dc5a79c1SDavid du Colombier case 'n': 162dc5a79c1SDavid du Colombier sendnotifies = 1; 163dc5a79c1SDavid du Colombier break; 1643e12c5d1SDavid du Colombier }ARGEND 1653e12c5d1SDavid du Colombier USED(argc); 1663e12c5d1SDavid du Colombier USED(argv); 1673e12c5d1SDavid du Colombier 1689a747e4fSDavid du Colombier if(testing) mainmem->flags |= POOL_NOREUSE; 1697dd7cddfSDavid du Colombier rfork(RFREND|RFNOTEG); 1703e12c5d1SDavid du Colombier 1717dd7cddfSDavid du Colombier /* start syslog before we fork */ 1729a747e4fSDavid du Colombier fmtinstall('F', fcallfmt); 173219b2ee8SDavid du Colombier dninit(); 1749a747e4fSDavid du Colombier if(myipaddr(ipaddr, mntpt) < 0) 1757dd7cddfSDavid du Colombier sysfatal("can't read my ip address"); 176219b2ee8SDavid du Colombier 1777dd7cddfSDavid du Colombier syslog(0, logfile, "starting dns on %I", ipaddr); 1787dd7cddfSDavid du Colombier 1797dd7cddfSDavid du Colombier opendatabase(); 1807dd7cddfSDavid du Colombier 1817dd7cddfSDavid du Colombier snprint(servefile, sizeof(servefile), "#s/dns%s", ext); 1827dd7cddfSDavid du Colombier unmount(servefile, mntpt); 1837dd7cddfSDavid du Colombier remove(servefile); 1847dd7cddfSDavid du Colombier mountinit(servefile, mntpt); 1857dd7cddfSDavid du Colombier 1867dd7cddfSDavid du Colombier now = time(0); 1877dd7cddfSDavid du Colombier srand(now*getpid()); 1887dd7cddfSDavid du Colombier db2cache(1); 1897dd7cddfSDavid du Colombier 190bd389b36SDavid du Colombier if(serve) 1917dd7cddfSDavid du Colombier dnudpserver(mntpt); 192dc5a79c1SDavid du Colombier if(sendnotifies) 193dc5a79c1SDavid du Colombier notifyproc(); 194dc5a79c1SDavid du Colombier 1953e12c5d1SDavid du Colombier io(); 1967dd7cddfSDavid du Colombier syslog(0, logfile, "io returned, exiting"); 1973e12c5d1SDavid du Colombier exits(0); 1983e12c5d1SDavid du Colombier } 1993e12c5d1SDavid du Colombier 2007dd7cddfSDavid du Colombier /* 2017dd7cddfSDavid du Colombier * if a mount point is specified, set the cs extention to be the mount point 2027dd7cddfSDavid du Colombier * with '_'s replacing '/'s 2037dd7cddfSDavid du Colombier */ 2043e12c5d1SDavid du Colombier void 2057dd7cddfSDavid du Colombier setext(char *ext, int n, char *p) 2067dd7cddfSDavid du Colombier { 2077dd7cddfSDavid du Colombier int i, c; 2087dd7cddfSDavid du Colombier 2097dd7cddfSDavid du Colombier n--; 2107dd7cddfSDavid du Colombier for(i = 0; i < n; i++){ 2117dd7cddfSDavid du Colombier c = p[i]; 2127dd7cddfSDavid du Colombier if(c == 0) 2137dd7cddfSDavid du Colombier break; 2147dd7cddfSDavid du Colombier if(c == '/') 2157dd7cddfSDavid du Colombier c = '_'; 2167dd7cddfSDavid du Colombier ext[i] = c; 2177dd7cddfSDavid du Colombier } 2187dd7cddfSDavid du Colombier ext[i] = 0; 2197dd7cddfSDavid du Colombier } 2207dd7cddfSDavid du Colombier 2217dd7cddfSDavid du Colombier void 2227dd7cddfSDavid du Colombier mountinit(char *service, char *mntpt) 2233e12c5d1SDavid du Colombier { 2243e12c5d1SDavid du Colombier int f; 2253e12c5d1SDavid du Colombier int p[2]; 2263e12c5d1SDavid du Colombier char buf[32]; 2273e12c5d1SDavid du Colombier 2283e12c5d1SDavid du Colombier if(pipe(p) < 0) 2297dd7cddfSDavid du Colombier abort(); /* "pipe failed" */; 230219b2ee8SDavid du Colombier switch(rfork(RFFDG|RFPROC|RFNAMEG)){ 2313e12c5d1SDavid du Colombier case 0: 232219b2ee8SDavid du Colombier close(p[1]); 2333e12c5d1SDavid du Colombier break; 2343e12c5d1SDavid du Colombier case -1: 2357dd7cddfSDavid du Colombier abort(); /* "fork failed\n" */; 2363e12c5d1SDavid du Colombier default: 237219b2ee8SDavid du Colombier close(p[0]); 238219b2ee8SDavid du Colombier 2393e12c5d1SDavid du Colombier /* 2403e12c5d1SDavid du Colombier * make a /srv/dns 2413e12c5d1SDavid du Colombier */ 2423e12c5d1SDavid du Colombier f = create(service, 1, 0666); 2433e12c5d1SDavid du Colombier if(f < 0) 2447dd7cddfSDavid du Colombier abort(); /* service */; 245bd389b36SDavid du Colombier snprint(buf, sizeof(buf), "%d", p[1]); 2463e12c5d1SDavid du Colombier if(write(f, buf, strlen(buf)) != strlen(buf)) 2477dd7cddfSDavid du Colombier abort(); /* "write %s", service */; 2483e12c5d1SDavid du Colombier close(f); 2493e12c5d1SDavid du Colombier 2503e12c5d1SDavid du Colombier /* 2513e12c5d1SDavid du Colombier * put ourselves into the file system 2523e12c5d1SDavid du Colombier */ 2539a747e4fSDavid du Colombier if(mount(p[1], -1, mntpt, MAFTER, "") < 0) 2549a747e4fSDavid du Colombier fprint(2, "dns mount failed: %r\n"); 255219b2ee8SDavid du Colombier _exits(0); 2563e12c5d1SDavid du Colombier } 2573e12c5d1SDavid du Colombier mfd[0] = mfd[1] = p[0]; 2583e12c5d1SDavid du Colombier } 2593e12c5d1SDavid du Colombier 2603e12c5d1SDavid du Colombier Mfile* 2617dd7cddfSDavid du Colombier newfid(int fid, int needunused) 2623e12c5d1SDavid du Colombier { 2633e12c5d1SDavid du Colombier Mfile *mf; 2643e12c5d1SDavid du Colombier 2657dd7cddfSDavid du Colombier lock(&mfalloc); 2667dd7cddfSDavid du Colombier for(mf = mfalloc.inuse; mf != nil; mf = mf->next){ 2677dd7cddfSDavid du Colombier if(mf->fid == fid){ 2687dd7cddfSDavid du Colombier unlock(&mfalloc); 2697dd7cddfSDavid du Colombier if(needunused) 2707dd7cddfSDavid du Colombier return nil; 2713e12c5d1SDavid du Colombier return mf; 2723e12c5d1SDavid du Colombier } 2733e12c5d1SDavid du Colombier } 2749a747e4fSDavid du Colombier mf = emalloc(sizeof(*mf)); 2757dd7cddfSDavid du Colombier if(mf == nil) 2767dd7cddfSDavid du Colombier sysfatal("out of memory"); 2773e12c5d1SDavid du Colombier mf->fid = fid; 2787dd7cddfSDavid du Colombier mf->next = mfalloc.inuse; 2797dd7cddfSDavid du Colombier mfalloc.inuse = mf; 2807dd7cddfSDavid du Colombier unlock(&mfalloc); 2813e12c5d1SDavid du Colombier return mf; 2823e12c5d1SDavid du Colombier } 2833e12c5d1SDavid du Colombier 2843e12c5d1SDavid du Colombier void 2857dd7cddfSDavid du Colombier freefid(Mfile *mf) 2867dd7cddfSDavid du Colombier { 2877dd7cddfSDavid du Colombier Mfile **l; 2887dd7cddfSDavid du Colombier 2897dd7cddfSDavid du Colombier lock(&mfalloc); 2907dd7cddfSDavid du Colombier for(l = &mfalloc.inuse; *l != nil; l = &(*l)->next){ 2917dd7cddfSDavid du Colombier if(*l == mf){ 2927dd7cddfSDavid du Colombier *l = mf->next; 2939a747e4fSDavid du Colombier if(mf->user) 2949a747e4fSDavid du Colombier free(mf->user); 2957dd7cddfSDavid du Colombier free(mf); 2967dd7cddfSDavid du Colombier unlock(&mfalloc); 2977dd7cddfSDavid du Colombier return; 2987dd7cddfSDavid du Colombier } 2997dd7cddfSDavid du Colombier } 3007dd7cddfSDavid du Colombier sysfatal("freeing unused fid"); 3017dd7cddfSDavid du Colombier } 3027dd7cddfSDavid du Colombier 3037dd7cddfSDavid du Colombier Mfile* 3047dd7cddfSDavid du Colombier copyfid(Mfile *mf, int fid) 3057dd7cddfSDavid du Colombier { 3067dd7cddfSDavid du Colombier Mfile *nmf; 3077dd7cddfSDavid du Colombier 3087dd7cddfSDavid du Colombier nmf = newfid(fid, 1); 3097dd7cddfSDavid du Colombier if(nmf == nil) 3107dd7cddfSDavid du Colombier return nil; 3117dd7cddfSDavid du Colombier nmf->fid = fid; 3129a747e4fSDavid du Colombier nmf->user = estrdup(mf->user); 3139a747e4fSDavid du Colombier nmf->qid.type = mf->qid.type; 3147dd7cddfSDavid du Colombier nmf->qid.path = mf->qid.path; 3157dd7cddfSDavid du Colombier nmf->qid.vers = vers++; 3167dd7cddfSDavid du Colombier return nmf; 3177dd7cddfSDavid du Colombier } 3187dd7cddfSDavid du Colombier 3197dd7cddfSDavid du Colombier Job* 3207dd7cddfSDavid du Colombier newjob(void) 3217dd7cddfSDavid du Colombier { 3227dd7cddfSDavid du Colombier Job *job; 3237dd7cddfSDavid du Colombier 3249a747e4fSDavid du Colombier job = emalloc(sizeof(*job)); 3257dd7cddfSDavid du Colombier lock(&joblock); 3267dd7cddfSDavid du Colombier job->next = joblist; 3277dd7cddfSDavid du Colombier joblist = job; 3287dd7cddfSDavid du Colombier job->request.tag = -1; 3297dd7cddfSDavid du Colombier unlock(&joblock); 3307dd7cddfSDavid du Colombier return job; 3317dd7cddfSDavid du Colombier } 3327dd7cddfSDavid du Colombier 3337dd7cddfSDavid du Colombier void 3347dd7cddfSDavid du Colombier freejob(Job *job) 3357dd7cddfSDavid du Colombier { 3367dd7cddfSDavid du Colombier Job **l; 3377dd7cddfSDavid du Colombier 3387dd7cddfSDavid du Colombier lock(&joblock); 3397dd7cddfSDavid du Colombier for(l = &joblist; *l; l = &(*l)->next){ 3407dd7cddfSDavid du Colombier if((*l) == job){ 3417dd7cddfSDavid du Colombier *l = job->next; 3427dd7cddfSDavid du Colombier free(job); 3437dd7cddfSDavid du Colombier break; 3447dd7cddfSDavid du Colombier } 3457dd7cddfSDavid du Colombier } 3467dd7cddfSDavid du Colombier unlock(&joblock); 3477dd7cddfSDavid du Colombier } 3487dd7cddfSDavid du Colombier 3497dd7cddfSDavid du Colombier void 3507dd7cddfSDavid du Colombier flushjob(int tag) 3517dd7cddfSDavid du Colombier { 3527dd7cddfSDavid du Colombier Job *job; 3537dd7cddfSDavid du Colombier 3547dd7cddfSDavid du Colombier lock(&joblock); 3557dd7cddfSDavid du Colombier for(job = joblist; job; job = job->next){ 3567dd7cddfSDavid du Colombier if(job->request.tag == tag && job->request.type != Tflush){ 3577dd7cddfSDavid du Colombier job->flushed = 1; 3587dd7cddfSDavid du Colombier break; 3597dd7cddfSDavid du Colombier } 3607dd7cddfSDavid du Colombier } 3617dd7cddfSDavid du Colombier unlock(&joblock); 3627dd7cddfSDavid du Colombier } 3637dd7cddfSDavid du Colombier 3647dd7cddfSDavid du Colombier void 3653e12c5d1SDavid du Colombier io(void) 3663e12c5d1SDavid du Colombier { 3673e12c5d1SDavid du Colombier long n; 3683e12c5d1SDavid du Colombier Mfile *mf; 3699a747e4fSDavid du Colombier uchar mdata[IOHDRSZ + Maxfdata]; 3703e12c5d1SDavid du Colombier Request req; 3717dd7cddfSDavid du Colombier Job *job; 3723e12c5d1SDavid du Colombier 3733e12c5d1SDavid du Colombier /* 3743e12c5d1SDavid du Colombier * a slave process is sometimes forked to wait for replies from other 3753e12c5d1SDavid du Colombier * servers. The master process returns immediately via a longjmp 376219b2ee8SDavid du Colombier * through 'mret'. 3773e12c5d1SDavid du Colombier */ 3787dd7cddfSDavid du Colombier if(setjmp(req.mret)) 379*b4b9fc2fSDavid du Colombier putactivity(0); 3803e12c5d1SDavid du Colombier req.isslave = 0; 3817dd7cddfSDavid du Colombier for(;;){ 3829a747e4fSDavid du Colombier n = read9pmsg(mfd[0], mdata, sizeof mdata); 3837dd7cddfSDavid du Colombier if(n<=0){ 3847dd7cddfSDavid du Colombier syslog(0, logfile, "error reading mntpt: %r"); 3857dd7cddfSDavid du Colombier exits(0); 3867dd7cddfSDavid du Colombier } 3877dd7cddfSDavid du Colombier job = newjob(); 3889a747e4fSDavid du Colombier if(convM2S(mdata, n, &job->request) != n){ 3897dd7cddfSDavid du Colombier freejob(job); 3907dd7cddfSDavid du Colombier continue; 3917dd7cddfSDavid du Colombier } 3927dd7cddfSDavid du Colombier mf = newfid(job->request.fid, 0); 393219b2ee8SDavid du Colombier if(debug) 3947dd7cddfSDavid du Colombier syslog(0, logfile, "%F", &job->request); 3957dd7cddfSDavid du Colombier 396*b4b9fc2fSDavid du Colombier getactivity(&req, 0); 3977dd7cddfSDavid du Colombier req.aborttime = now + 60; /* don't spend more than 60 seconds */ 3987dd7cddfSDavid du Colombier 3997dd7cddfSDavid du Colombier switch(job->request.type){ 4003e12c5d1SDavid du Colombier default: 4019a747e4fSDavid du Colombier syslog(1, logfile, "unknown request type %d", job->request.type); 4023e12c5d1SDavid du Colombier break; 4039a747e4fSDavid du Colombier case Tversion: 4049a747e4fSDavid du Colombier rversion(job); 4053e12c5d1SDavid du Colombier break; 4069a747e4fSDavid du Colombier case Tauth: 4079a747e4fSDavid du Colombier rauth(job); 4083e12c5d1SDavid du Colombier break; 4093e12c5d1SDavid du Colombier case Tflush: 4107dd7cddfSDavid du Colombier rflush(job); 4113e12c5d1SDavid du Colombier break; 4123e12c5d1SDavid du Colombier case Tattach: 4137dd7cddfSDavid du Colombier rattach(job, mf); 4143e12c5d1SDavid du Colombier break; 4153e12c5d1SDavid du Colombier case Twalk: 4167dd7cddfSDavid du Colombier rwalk(job, mf); 4173e12c5d1SDavid du Colombier break; 4183e12c5d1SDavid du Colombier case Topen: 4197dd7cddfSDavid du Colombier ropen(job, mf); 4203e12c5d1SDavid du Colombier break; 4213e12c5d1SDavid du Colombier case Tcreate: 4227dd7cddfSDavid du Colombier rcreate(job, mf); 4233e12c5d1SDavid du Colombier break; 4243e12c5d1SDavid du Colombier case Tread: 4257dd7cddfSDavid du Colombier rread(job, mf); 4263e12c5d1SDavid du Colombier break; 4273e12c5d1SDavid du Colombier case Twrite: 4287dd7cddfSDavid du Colombier rwrite(job, mf, &req); 4293e12c5d1SDavid du Colombier break; 4303e12c5d1SDavid du Colombier case Tclunk: 4317dd7cddfSDavid du Colombier rclunk(job, mf); 4323e12c5d1SDavid du Colombier break; 4333e12c5d1SDavid du Colombier case Tremove: 4347dd7cddfSDavid du Colombier rremove(job, mf); 4353e12c5d1SDavid du Colombier break; 4363e12c5d1SDavid du Colombier case Tstat: 4377dd7cddfSDavid du Colombier rstat(job, mf); 4383e12c5d1SDavid du Colombier break; 4393e12c5d1SDavid du Colombier case Twstat: 4407dd7cddfSDavid du Colombier rwstat(job, mf); 4413e12c5d1SDavid du Colombier break; 4423e12c5d1SDavid du Colombier } 4437dd7cddfSDavid du Colombier 4447dd7cddfSDavid du Colombier freejob(job); 4457dd7cddfSDavid du Colombier 4463e12c5d1SDavid du Colombier /* 4473e12c5d1SDavid du Colombier * slave processes die after replying 4483e12c5d1SDavid du Colombier */ 4497dd7cddfSDavid du Colombier if(req.isslave){ 450*b4b9fc2fSDavid du Colombier putactivity(0); 4513e12c5d1SDavid du Colombier _exits(0); 4527dd7cddfSDavid du Colombier } 4537dd7cddfSDavid du Colombier 454*b4b9fc2fSDavid du Colombier putactivity(0); 4557dd7cddfSDavid du Colombier } 4563e12c5d1SDavid du Colombier } 4573e12c5d1SDavid du Colombier 4583e12c5d1SDavid du Colombier void 4599a747e4fSDavid du Colombier rversion(Job *job) 460219b2ee8SDavid du Colombier { 4619a747e4fSDavid du Colombier if(job->request.msize > IOHDRSZ + Maxfdata) 4629a747e4fSDavid du Colombier job->reply.msize = IOHDRSZ + Maxfdata; 4639a747e4fSDavid du Colombier else 4649a747e4fSDavid du Colombier job->reply.msize = job->request.msize; 4659a747e4fSDavid du Colombier if(strncmp(job->request.version, "9P2000", 6) != 0) 4669a747e4fSDavid du Colombier sendmsg(job, "unknown 9P version"); 4679a747e4fSDavid du Colombier else{ 4689a747e4fSDavid du Colombier job->reply.version = "9P2000"; 4697dd7cddfSDavid du Colombier sendmsg(job, 0); 470219b2ee8SDavid du Colombier } 4719a747e4fSDavid du Colombier } 472219b2ee8SDavid du Colombier 473219b2ee8SDavid du Colombier void 4749a747e4fSDavid du Colombier rauth(Job *job) 4753e12c5d1SDavid du Colombier { 4763ff48bf5SDavid du Colombier sendmsg(job, "dns: authentication not required"); 4777dd7cddfSDavid du Colombier } 4787dd7cddfSDavid du Colombier 4799a747e4fSDavid du Colombier /* 4809a747e4fSDavid du Colombier * don't flush till all the slaves are done 4819a747e4fSDavid du Colombier */ 4827dd7cddfSDavid du Colombier void 4837dd7cddfSDavid du Colombier rflush(Job *job) 4847dd7cddfSDavid du Colombier { 4857dd7cddfSDavid du Colombier flushjob(job->request.oldtag); 4867dd7cddfSDavid du Colombier sendmsg(job, 0); 4873e12c5d1SDavid du Colombier } 4883e12c5d1SDavid du Colombier 4893e12c5d1SDavid du Colombier void 4907dd7cddfSDavid du Colombier rattach(Job *job, Mfile *mf) 4913e12c5d1SDavid du Colombier { 4929a747e4fSDavid du Colombier if(mf->user != nil) 4939a747e4fSDavid du Colombier free(mf->user); 4949a747e4fSDavid du Colombier mf->user = estrdup(job->request.uname); 4953e12c5d1SDavid du Colombier mf->qid.vers = vers++; 4969a747e4fSDavid du Colombier mf->qid.type = QTDIR; 4979a747e4fSDavid du Colombier mf->qid.path = 0LL; 4987dd7cddfSDavid du Colombier job->reply.qid = mf->qid; 4997dd7cddfSDavid du Colombier sendmsg(job, 0); 5003e12c5d1SDavid du Colombier } 5013e12c5d1SDavid du Colombier 5023e12c5d1SDavid du Colombier char* 5037dd7cddfSDavid du Colombier rwalk(Job *job, Mfile *mf) 5043e12c5d1SDavid du Colombier { 5053e12c5d1SDavid du Colombier char *err; 5069a747e4fSDavid du Colombier char **elems; 5079a747e4fSDavid du Colombier int nelems; 5089a747e4fSDavid du Colombier int i; 5099a747e4fSDavid du Colombier Mfile *nmf; 5109a747e4fSDavid du Colombier Qid qid; 5113e12c5d1SDavid du Colombier 5123e12c5d1SDavid du Colombier err = 0; 5139a747e4fSDavid du Colombier nmf = nil; 5149a747e4fSDavid du Colombier elems = job->request.wname; 5159a747e4fSDavid du Colombier nelems = job->request.nwname; 5169a747e4fSDavid du Colombier job->reply.nwqid = 0; 5179a747e4fSDavid du Colombier 5189a747e4fSDavid du Colombier if(job->request.newfid != job->request.fid){ 5199a747e4fSDavid du Colombier /* clone fid */ 5209a747e4fSDavid du Colombier nmf = copyfid(mf, job->request.newfid); 5219a747e4fSDavid du Colombier if(nmf == nil){ 5229a747e4fSDavid du Colombier err = "clone bad newfid"; 5239a747e4fSDavid du Colombier goto send; 5249a747e4fSDavid du Colombier } 5259a747e4fSDavid du Colombier mf = nmf; 5269a747e4fSDavid du Colombier } 5279a747e4fSDavid du Colombier /* else nmf will be nil */ 5289a747e4fSDavid du Colombier 5299a747e4fSDavid du Colombier qid = mf->qid; 5309a747e4fSDavid du Colombier if(nelems > 0){ 5319a747e4fSDavid du Colombier /* walk fid */ 5329a747e4fSDavid du Colombier for(i=0; i<nelems && i<MAXWELEM; i++){ 5339a747e4fSDavid du Colombier if((qid.type & QTDIR) == 0){ 5343e12c5d1SDavid du Colombier err = "not a directory"; 5359a747e4fSDavid du Colombier break; 5363e12c5d1SDavid du Colombier } 5379a747e4fSDavid du Colombier if(strcmp(elems[i], "..") == 0 || strcmp(elems[i], ".") == 0){ 5389a747e4fSDavid du Colombier qid.type = QTDIR; 5399a747e4fSDavid du Colombier qid.path = Qdir; 5409a747e4fSDavid du Colombier Found: 5419a747e4fSDavid du Colombier job->reply.wqid[i] = qid; 5429a747e4fSDavid du Colombier job->reply.nwqid++; 5439a747e4fSDavid du Colombier continue; 5443e12c5d1SDavid du Colombier } 5459a747e4fSDavid du Colombier if(strcmp(elems[i], "dns") == 0){ 5469a747e4fSDavid du Colombier qid.type = QTFILE; 5479a747e4fSDavid du Colombier qid.path = Qdns; 5489a747e4fSDavid du Colombier goto Found; 5493e12c5d1SDavid du Colombier } 5509a747e4fSDavid du Colombier err = "file does not exist"; 5519a747e4fSDavid du Colombier break; 5529a747e4fSDavid du Colombier } 5539a747e4fSDavid du Colombier } 5549a747e4fSDavid du Colombier 5553e12c5d1SDavid du Colombier send: 5569a747e4fSDavid du Colombier if(nmf != nil && (err!=nil || job->reply.nwqid<nelems)) 5579a747e4fSDavid du Colombier freefid(nmf); 5589a747e4fSDavid du Colombier if(err == nil) 5599a747e4fSDavid du Colombier mf->qid = qid; 5607dd7cddfSDavid du Colombier sendmsg(job, err); 5613e12c5d1SDavid du Colombier return err; 5623e12c5d1SDavid du Colombier } 5633e12c5d1SDavid du Colombier 5643e12c5d1SDavid du Colombier void 5657dd7cddfSDavid du Colombier ropen(Job *job, Mfile *mf) 5663e12c5d1SDavid du Colombier { 5673e12c5d1SDavid du Colombier int mode; 5683e12c5d1SDavid du Colombier char *err; 5693e12c5d1SDavid du Colombier 5703e12c5d1SDavid du Colombier err = 0; 5717dd7cddfSDavid du Colombier mode = job->request.mode; 5729a747e4fSDavid du Colombier if(mf->qid.type & QTDIR){ 5733e12c5d1SDavid du Colombier if(mode) 5743e12c5d1SDavid du Colombier err = "permission denied"; 5753e12c5d1SDavid du Colombier } 5767dd7cddfSDavid du Colombier job->reply.qid = mf->qid; 5779a747e4fSDavid du Colombier job->reply.iounit = 0; 5787dd7cddfSDavid du Colombier sendmsg(job, err); 5793e12c5d1SDavid du Colombier } 5803e12c5d1SDavid du Colombier 5813e12c5d1SDavid du Colombier void 5827dd7cddfSDavid du Colombier rcreate(Job *job, Mfile *mf) 5833e12c5d1SDavid du Colombier { 5843e12c5d1SDavid du Colombier USED(mf); 5857dd7cddfSDavid du Colombier sendmsg(job, "creation permission denied"); 5863e12c5d1SDavid du Colombier } 5873e12c5d1SDavid du Colombier 5883e12c5d1SDavid du Colombier void 5897dd7cddfSDavid du Colombier rread(Job *job, Mfile *mf) 5903e12c5d1SDavid du Colombier { 5917dd7cddfSDavid du Colombier int i, n, cnt; 5927dd7cddfSDavid du Colombier long off; 5933e12c5d1SDavid du Colombier Dir dir; 5949a747e4fSDavid du Colombier uchar buf[Maxfdata]; 5953e12c5d1SDavid du Colombier char *err; 5969a747e4fSDavid du Colombier long clock; 5973e12c5d1SDavid du Colombier 5983e12c5d1SDavid du Colombier n = 0; 5993e12c5d1SDavid du Colombier err = 0; 6007dd7cddfSDavid du Colombier off = job->request.offset; 6017dd7cddfSDavid du Colombier cnt = job->request.count; 6029a747e4fSDavid du Colombier if(mf->qid.type & QTDIR){ 6039a747e4fSDavid du Colombier clock = time(0); 6043e12c5d1SDavid du Colombier if(off == 0){ 6059a747e4fSDavid du Colombier dir.name = "dns"; 6069a747e4fSDavid du Colombier dir.qid.type = QTFILE; 6073e12c5d1SDavid du Colombier dir.qid.vers = vers; 6083e12c5d1SDavid du Colombier dir.qid.path = Qdns; 6093e12c5d1SDavid du Colombier dir.mode = 0666; 6103e12c5d1SDavid du Colombier dir.length = 0; 6119a747e4fSDavid du Colombier dir.uid = mf->user; 6129a747e4fSDavid du Colombier dir.gid = mf->user; 6139a747e4fSDavid du Colombier dir.muid = mf->user; 6149a747e4fSDavid du Colombier dir.atime = clock; /* wrong */ 6159a747e4fSDavid du Colombier dir.mtime = clock; /* wrong */ 6169a747e4fSDavid du Colombier n = convD2M(&dir, buf, sizeof buf); 6173e12c5d1SDavid du Colombier } 6189a747e4fSDavid du Colombier job->reply.data = (char*)buf; 6193e12c5d1SDavid du Colombier } else { 6207dd7cddfSDavid du Colombier for(i = 1; i <= mf->nrr; i++) 6217dd7cddfSDavid du Colombier if(mf->rr[i] > off) 6223e12c5d1SDavid du Colombier break; 6237dd7cddfSDavid du Colombier if(i > mf->nrr) 6247dd7cddfSDavid du Colombier goto send; 6257dd7cddfSDavid du Colombier if(off + cnt > mf->rr[i]) 6267dd7cddfSDavid du Colombier n = mf->rr[i] - off; 6277dd7cddfSDavid du Colombier else 6287dd7cddfSDavid du Colombier n = cnt; 6297dd7cddfSDavid du Colombier job->reply.data = mf->reply + off; 6303e12c5d1SDavid du Colombier } 6313e12c5d1SDavid du Colombier send: 6327dd7cddfSDavid du Colombier job->reply.count = n; 6337dd7cddfSDavid du Colombier sendmsg(job, err); 6343e12c5d1SDavid du Colombier } 6353e12c5d1SDavid du Colombier 6363e12c5d1SDavid du Colombier void 6377dd7cddfSDavid du Colombier rwrite(Job *job, Mfile *mf, Request *req) 6383e12c5d1SDavid du Colombier { 6397dd7cddfSDavid du Colombier int cnt, rooted, status; 6407dd7cddfSDavid du Colombier long n; 6417dd7cddfSDavid du Colombier char *err, *p, *atype; 6427dd7cddfSDavid du Colombier RR *rp, *tp, *neg; 6437dd7cddfSDavid du Colombier int wantsav; 6443e12c5d1SDavid du Colombier 6453e12c5d1SDavid du Colombier err = 0; 6467dd7cddfSDavid du Colombier cnt = job->request.count; 6479a747e4fSDavid du Colombier if(mf->qid.type & QTDIR){ 6483e12c5d1SDavid du Colombier err = "can't write directory"; 6493e12c5d1SDavid du Colombier goto send; 6503e12c5d1SDavid du Colombier } 6513e12c5d1SDavid du Colombier if(cnt >= Maxrequest){ 6523e12c5d1SDavid du Colombier err = "request too long"; 6533e12c5d1SDavid du Colombier goto send; 6543e12c5d1SDavid du Colombier } 6557dd7cddfSDavid du Colombier job->request.data[cnt] = 0; 6567dd7cddfSDavid du Colombier if(cnt > 0 && job->request.data[cnt-1] == '\n') 6577dd7cddfSDavid du Colombier job->request.data[cnt-1] = 0; 6583e12c5d1SDavid du Colombier 6593e12c5d1SDavid du Colombier /* 6607dd7cddfSDavid du Colombier * special commands 661219b2ee8SDavid du Colombier */ 6627dd7cddfSDavid du Colombier if(strncmp(job->request.data, "debug", 5)==0 && job->request.data[5] == 0){ 663219b2ee8SDavid du Colombier debug ^= 1; 664219b2ee8SDavid du Colombier goto send; 6657dd7cddfSDavid du Colombier } else if(strncmp(job->request.data, "dump", 4)==0 && job->request.data[4] == 0){ 666219b2ee8SDavid du Colombier dndump("/lib/ndb/dnsdump"); 667219b2ee8SDavid du Colombier goto send; 6687dd7cddfSDavid du Colombier } else if(strncmp(job->request.data, "refresh", 7)==0 && job->request.data[7] == 0){ 6697dd7cddfSDavid du Colombier needrefresh = 1; 6707dd7cddfSDavid du Colombier goto send; 6719a747e4fSDavid du Colombier } else if(strncmp(job->request.data, "poolcheck", 9)==0 && job->request.data[9] == 0){ 6729a747e4fSDavid du Colombier poolcheck(mainmem); 6739a747e4fSDavid du Colombier goto send; 674219b2ee8SDavid du Colombier } 675219b2ee8SDavid du Colombier 676219b2ee8SDavid du Colombier /* 6777dd7cddfSDavid du Colombier * kill previous reply 6787dd7cddfSDavid du Colombier */ 6797dd7cddfSDavid du Colombier mf->nrr = 0; 6807dd7cddfSDavid du Colombier mf->rr[0] = 0; 6817dd7cddfSDavid du Colombier 6827dd7cddfSDavid du Colombier /* 6833e12c5d1SDavid du Colombier * break up request (into a name and a type) 6843e12c5d1SDavid du Colombier */ 6857dd7cddfSDavid du Colombier atype = strchr(job->request.data, ' '); 6863e12c5d1SDavid du Colombier if(atype == 0){ 6873e12c5d1SDavid du Colombier err = "illegal request"; 6883e12c5d1SDavid du Colombier goto send; 6893e12c5d1SDavid du Colombier } else 6903e12c5d1SDavid du Colombier *atype++ = 0; 6913e12c5d1SDavid du Colombier 6927dd7cddfSDavid du Colombier /* 6937dd7cddfSDavid du Colombier * tracing request 6947dd7cddfSDavid du Colombier */ 6957dd7cddfSDavid du Colombier if(strcmp(atype, "trace") == 0){ 6967dd7cddfSDavid du Colombier if(trace) 6977dd7cddfSDavid du Colombier free(trace); 6987dd7cddfSDavid du Colombier if(*job->request.data) 6999a747e4fSDavid du Colombier trace = estrdup(job->request.data); 7007dd7cddfSDavid du Colombier else 7017dd7cddfSDavid du Colombier trace = 0; 7027dd7cddfSDavid du Colombier goto send; 7037dd7cddfSDavid du Colombier } 7047dd7cddfSDavid du Colombier 7053e12c5d1SDavid du Colombier mf->type = rrtype(atype); 7063e12c5d1SDavid du Colombier if(mf->type < 0){ 7073e12c5d1SDavid du Colombier err = "unknown type"; 7083e12c5d1SDavid du Colombier goto send; 7093e12c5d1SDavid du Colombier } 7103e12c5d1SDavid du Colombier 7117dd7cddfSDavid du Colombier p = atype - 2; 7127dd7cddfSDavid du Colombier if(p >= job->request.data && *p == '.'){ 7137dd7cddfSDavid du Colombier rooted = 1; 7147dd7cddfSDavid du Colombier *p = 0; 7157dd7cddfSDavid du Colombier } else 7167dd7cddfSDavid du Colombier rooted = 0; 7173e12c5d1SDavid du Colombier 7187dd7cddfSDavid du Colombier p = job->request.data; 7197dd7cddfSDavid du Colombier if(*p == '!'){ 7207dd7cddfSDavid du Colombier wantsav = 1; 7217dd7cddfSDavid du Colombier p++; 7227dd7cddfSDavid du Colombier } else 7237dd7cddfSDavid du Colombier wantsav = 0; 7249a747e4fSDavid du Colombier dncheck(0, 1); 7257dd7cddfSDavid du Colombier rp = dnresolve(p, Cin, mf->type, req, 0, 0, Recurse, rooted, &status); 7269a747e4fSDavid du Colombier dncheck(0, 1); 7277dd7cddfSDavid du Colombier neg = rrremneg(&rp); 7287dd7cddfSDavid du Colombier if(neg){ 7297dd7cddfSDavid du Colombier status = neg->negrcode; 7307dd7cddfSDavid du Colombier rrfreelist(neg); 7317dd7cddfSDavid du Colombier } 7327dd7cddfSDavid du Colombier if(rp == 0){ 733271b8d73SDavid du Colombier switch(status){ 734271b8d73SDavid du Colombier case Rname: 7357dd7cddfSDavid du Colombier err = "name does not exist"; 736271b8d73SDavid du Colombier break; 737271b8d73SDavid du Colombier case Rserver: 738271b8d73SDavid du Colombier err = "dns failure"; 739271b8d73SDavid du Colombier break; 740271b8d73SDavid du Colombier default: 741271b8d73SDavid du Colombier err = "resource does not exist"; 742271b8d73SDavid du Colombier break; 743271b8d73SDavid du Colombier } 7447dd7cddfSDavid du Colombier } else { 74534f77ae3SDavid du Colombier lock(&joblock); 74634f77ae3SDavid du Colombier if(!job->flushed){ 7477dd7cddfSDavid du Colombier /* format data to be read later */ 7487dd7cddfSDavid du Colombier n = 0; 7497dd7cddfSDavid du Colombier mf->nrr = 0; 7507dd7cddfSDavid du Colombier for(tp = rp; mf->nrr < Maxrrr-1 && n < Maxreply && tp && 7517dd7cddfSDavid du Colombier tsame(mf->type, tp->type); tp = tp->next){ 7527dd7cddfSDavid du Colombier mf->rr[mf->nrr++] = n; 7537dd7cddfSDavid du Colombier if(wantsav) 7547dd7cddfSDavid du Colombier n += snprint(mf->reply+n, Maxreply-n, "%Q", tp); 7557dd7cddfSDavid du Colombier else 7567dd7cddfSDavid du Colombier n += snprint(mf->reply+n, Maxreply-n, "%R", tp); 7577dd7cddfSDavid du Colombier } 7587dd7cddfSDavid du Colombier mf->rr[mf->nrr] = n; 75934f77ae3SDavid du Colombier } 76034f77ae3SDavid du Colombier unlock(&joblock); 7617dd7cddfSDavid du Colombier rrfreelist(rp); 7627dd7cddfSDavid du Colombier } 7633e12c5d1SDavid du Colombier 7643e12c5d1SDavid du Colombier send: 7659a747e4fSDavid du Colombier dncheck(0, 1); 7667dd7cddfSDavid du Colombier job->reply.count = cnt; 7677dd7cddfSDavid du Colombier sendmsg(job, err); 7683e12c5d1SDavid du Colombier } 7693e12c5d1SDavid du Colombier 7703e12c5d1SDavid du Colombier void 7717dd7cddfSDavid du Colombier rclunk(Job *job, Mfile *mf) 7723e12c5d1SDavid du Colombier { 7737dd7cddfSDavid du Colombier freefid(mf); 7747dd7cddfSDavid du Colombier sendmsg(job, 0); 7753e12c5d1SDavid du Colombier } 7763e12c5d1SDavid du Colombier 7773e12c5d1SDavid du Colombier void 7787dd7cddfSDavid du Colombier rremove(Job *job, Mfile *mf) 7793e12c5d1SDavid du Colombier { 7803e12c5d1SDavid du Colombier USED(mf); 7817dd7cddfSDavid du Colombier sendmsg(job, "remove permission denied"); 7823e12c5d1SDavid du Colombier } 7833e12c5d1SDavid du Colombier 7843e12c5d1SDavid du Colombier void 7857dd7cddfSDavid du Colombier rstat(Job *job, Mfile *mf) 7863e12c5d1SDavid du Colombier { 7873e12c5d1SDavid du Colombier Dir dir; 7889a747e4fSDavid du Colombier uchar buf[IOHDRSZ+Maxfdata]; 7893e12c5d1SDavid du Colombier 7909a747e4fSDavid du Colombier if(mf->qid.type & QTDIR){ 7919a747e4fSDavid du Colombier dir.name = "."; 7929a747e4fSDavid du Colombier dir.mode = DMDIR|0555; 793219b2ee8SDavid du Colombier } else { 7949a747e4fSDavid du Colombier dir.name = "dns"; 7953e12c5d1SDavid du Colombier dir.mode = 0666; 796219b2ee8SDavid du Colombier } 797219b2ee8SDavid du Colombier dir.qid = mf->qid; 7983e12c5d1SDavid du Colombier dir.length = 0; 7999a747e4fSDavid du Colombier dir.uid = mf->user; 8009a747e4fSDavid du Colombier dir.gid = mf->user; 8019a747e4fSDavid du Colombier dir.muid = mf->user; 8023e12c5d1SDavid du Colombier dir.atime = dir.mtime = time(0); 8039a747e4fSDavid du Colombier job->reply.nstat = convD2M(&dir, buf, sizeof buf); 8049a747e4fSDavid du Colombier job->reply.stat = buf; 8057dd7cddfSDavid du Colombier sendmsg(job, 0); 8063e12c5d1SDavid du Colombier } 8073e12c5d1SDavid du Colombier 8083e12c5d1SDavid du Colombier void 8097dd7cddfSDavid du Colombier rwstat(Job *job, Mfile *mf) 8103e12c5d1SDavid du Colombier { 8113e12c5d1SDavid du Colombier USED(mf); 8127dd7cddfSDavid du Colombier sendmsg(job, "wstat permission denied"); 8133e12c5d1SDavid du Colombier } 8143e12c5d1SDavid du Colombier 8153e12c5d1SDavid du Colombier void 8167dd7cddfSDavid du Colombier sendmsg(Job *job, char *err) 8173e12c5d1SDavid du Colombier { 8183e12c5d1SDavid du Colombier int n; 8199a747e4fSDavid du Colombier uchar mdata[IOHDRSZ + Maxfdata]; 8209a747e4fSDavid du Colombier char ename[ERRMAX]; 8213e12c5d1SDavid du Colombier 8223e12c5d1SDavid du Colombier if(err){ 8237dd7cddfSDavid du Colombier job->reply.type = Rerror; 8249a747e4fSDavid du Colombier snprint(ename, sizeof(ename), "dns: %s", err); 8259a747e4fSDavid du Colombier job->reply.ename = ename; 8263e12c5d1SDavid du Colombier }else{ 8277dd7cddfSDavid du Colombier job->reply.type = job->request.type+1; 8283e12c5d1SDavid du Colombier } 8297dd7cddfSDavid du Colombier job->reply.tag = job->request.tag; 8309a747e4fSDavid du Colombier n = convS2M(&job->reply, mdata, sizeof mdata); 8319a747e4fSDavid du Colombier if(n == 0){ 8329a747e4fSDavid du Colombier syslog(1, logfile, "sendmsg convS2M of %F returns 0", &job->reply); 8339a747e4fSDavid du Colombier abort(); 8343e12c5d1SDavid du Colombier } 8359a747e4fSDavid du Colombier lock(&joblock); 8369a747e4fSDavid du Colombier if(job->flushed == 0) 8379a747e4fSDavid du Colombier if(write(mfd[1], mdata, n)!=n) 8389a747e4fSDavid du Colombier sysfatal("mount write"); 8397dd7cddfSDavid du Colombier unlock(&joblock); 8409a747e4fSDavid du Colombier if(debug) 8419a747e4fSDavid du Colombier syslog(0, logfile, "%F %d", &job->reply, n); 8423e12c5d1SDavid du Colombier } 8433e12c5d1SDavid du Colombier 8443e12c5d1SDavid du Colombier /* 8457dd7cddfSDavid du Colombier * the following varies between dnsdebug and dns 8463e12c5d1SDavid du Colombier */ 8473e12c5d1SDavid du Colombier void 8487dd7cddfSDavid du Colombier logreply(int id, uchar *addr, DNSmsg *mp) 8493e12c5d1SDavid du Colombier { 8507dd7cddfSDavid du Colombier RR *rp; 8513e12c5d1SDavid du Colombier 8527dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I flags:%s%s%s%s%s", id, addr, 8537dd7cddfSDavid du Colombier mp->flags & Fauth ? " auth" : "", 8547dd7cddfSDavid du Colombier mp->flags & Ftrunc ? " trunc" : "", 8557dd7cddfSDavid du Colombier mp->flags & Frecurse ? " rd" : "", 8567dd7cddfSDavid du Colombier mp->flags & Fcanrec ? " ra" : "", 8577dd7cddfSDavid du Colombier mp->flags & (Fauth|Rname) == (Fauth|Rname) ? 8587dd7cddfSDavid du Colombier " nx" : ""); 8597dd7cddfSDavid du Colombier for(rp = mp->qd; rp != nil; rp = rp->next) 8607dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I qd %s", id, addr, rp->owner->name); 8617dd7cddfSDavid du Colombier for(rp = mp->an; rp != nil; rp = rp->next) 8627dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I an %R", id, addr, rp); 8637dd7cddfSDavid du Colombier for(rp = mp->ns; rp != nil; rp = rp->next) 8647dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I ns %R", id, addr, rp); 8657dd7cddfSDavid du Colombier for(rp = mp->ar; rp != nil; rp = rp->next) 8667dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I ar %R", id, addr, rp); 8673e12c5d1SDavid du Colombier } 8687dd7cddfSDavid du Colombier 8697dd7cddfSDavid du Colombier void 8707dd7cddfSDavid du Colombier logsend(int id, int subid, uchar *addr, char *sname, char *rname, int type) 8717dd7cddfSDavid du Colombier { 8727dd7cddfSDavid du Colombier char buf[12]; 8737dd7cddfSDavid du Colombier 874*b4b9fc2fSDavid du Colombier syslog(0, LOG, "[%d] %d.%d: sending to %I/%s %s %s", 875*b4b9fc2fSDavid du Colombier getpid(), id, subid, addr, sname, rname, rrname(type, buf, sizeof buf)); 8767dd7cddfSDavid du Colombier } 8777dd7cddfSDavid du Colombier 8787dd7cddfSDavid du Colombier RR* 8797dd7cddfSDavid du Colombier getdnsservers(int class) 8807dd7cddfSDavid du Colombier { 8817dd7cddfSDavid du Colombier return dnsservers(class); 8823e12c5d1SDavid du Colombier } 883