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> 7*7dd7cddfSDavid du Colombier #include <ip.h> 83e12c5d1SDavid du Colombier #include "dns.h" 93e12c5d1SDavid du Colombier 103e12c5d1SDavid du Colombier enum 113e12c5d1SDavid du Colombier { 123e12c5d1SDavid du Colombier Maxrequest= 4*NAMELEN, 133e12c5d1SDavid du Colombier Ncache= 8, 14*7dd7cddfSDavid du Colombier Maxpath= 128, 15*7dd7cddfSDavid du Colombier Maxreply= 512, 16*7dd7cddfSDavid du Colombier Maxrrr= 16, 173e12c5d1SDavid du Colombier 183e12c5d1SDavid du Colombier Qdns= 1, 193e12c5d1SDavid du Colombier }; 203e12c5d1SDavid du Colombier 213e12c5d1SDavid du Colombier typedef struct Mfile Mfile; 22*7dd7cddfSDavid du Colombier typedef struct Job Job; 233e12c5d1SDavid du Colombier typedef struct Network Network; 243e12c5d1SDavid du Colombier 253e12c5d1SDavid du Colombier int vers; /* incremented each clone/attach */ 263e12c5d1SDavid du Colombier 273e12c5d1SDavid du Colombier struct Mfile 283e12c5d1SDavid du Colombier { 29*7dd7cddfSDavid du Colombier Mfile *next; /* next free mfile */ 30*7dd7cddfSDavid du Colombier 313e12c5d1SDavid du Colombier char user[NAMELEN]; 323e12c5d1SDavid du Colombier Qid qid; 333e12c5d1SDavid du Colombier int fid; 343e12c5d1SDavid du Colombier 353e12c5d1SDavid du Colombier int type; /* reply type */ 36*7dd7cddfSDavid du Colombier char reply[Maxreply]; 37*7dd7cddfSDavid du Colombier ushort rr[Maxrrr]; /* offset of rr's */ 38*7dd7cddfSDavid du Colombier ushort nrr; /* number of rr's */ 393e12c5d1SDavid du Colombier }; 403e12c5d1SDavid du Colombier 41*7dd7cddfSDavid du Colombier // 42*7dd7cddfSDavid du Colombier // active local requests 43*7dd7cddfSDavid du Colombier // 44*7dd7cddfSDavid du Colombier struct Job 45*7dd7cddfSDavid du Colombier { 46*7dd7cddfSDavid du Colombier Job *next; 47*7dd7cddfSDavid du Colombier int flushed; 48*7dd7cddfSDavid du Colombier Fcall request; 49*7dd7cddfSDavid du Colombier Fcall reply; 50*7dd7cddfSDavid du Colombier }; 51*7dd7cddfSDavid du Colombier Lock joblock; 52*7dd7cddfSDavid du Colombier Job *joblist; 53*7dd7cddfSDavid du Colombier 54*7dd7cddfSDavid du Colombier struct { 55*7dd7cddfSDavid du Colombier Lock; 56*7dd7cddfSDavid du Colombier Mfile *inuse; /* active mfile's */ 57*7dd7cddfSDavid du Colombier } mfalloc; 58*7dd7cddfSDavid du Colombier 593e12c5d1SDavid du Colombier int mfd[2]; 603e12c5d1SDavid du Colombier char user[NAMELEN]; 613e12c5d1SDavid du Colombier int debug; 62*7dd7cddfSDavid du Colombier int cachedb; 63*7dd7cddfSDavid du Colombier ulong now; 64*7dd7cddfSDavid du Colombier int testing; 65*7dd7cddfSDavid du Colombier char *trace; 66*7dd7cddfSDavid du Colombier int needrefresh; 67*7dd7cddfSDavid du Colombier int resolver; 68*7dd7cddfSDavid du Colombier uchar ipaddr[IPaddrlen]; /* my ip address */ 69*7dd7cddfSDavid du Colombier int maxage; 703e12c5d1SDavid du Colombier 71*7dd7cddfSDavid du Colombier void rsession(Job*); 72*7dd7cddfSDavid du Colombier void rsimple(Job*); 73*7dd7cddfSDavid du Colombier void rflush(Job*); 74*7dd7cddfSDavid du Colombier void rattach(Job*, Mfile*); 75*7dd7cddfSDavid du Colombier void rclone(Job*, Mfile*); 76*7dd7cddfSDavid du Colombier char* rwalk(Job*, Mfile*); 77*7dd7cddfSDavid du Colombier void rclwalk(Job*, Mfile*); 78*7dd7cddfSDavid du Colombier void ropen(Job*, Mfile*); 79*7dd7cddfSDavid du Colombier void rcreate(Job*, Mfile*); 80*7dd7cddfSDavid du Colombier void rread(Job*, Mfile*); 81*7dd7cddfSDavid du Colombier void rwrite(Job*, Mfile*, Request*); 82*7dd7cddfSDavid du Colombier void rclunk(Job*, Mfile*); 83*7dd7cddfSDavid du Colombier void rremove(Job*, Mfile*); 84*7dd7cddfSDavid du Colombier void rstat(Job*, Mfile*); 85*7dd7cddfSDavid du Colombier void rauth(Job*); 86*7dd7cddfSDavid du Colombier void rwstat(Job*, Mfile*); 87*7dd7cddfSDavid du Colombier void sendmsg(Job*, char*); 88*7dd7cddfSDavid du Colombier void mountinit(char*, char*); 893e12c5d1SDavid du Colombier void io(void); 903e12c5d1SDavid du Colombier int fillreply(Mfile*, int); 91*7dd7cddfSDavid du Colombier Job* newjob(void); 92*7dd7cddfSDavid du Colombier void freejob(Job*); 93*7dd7cddfSDavid du Colombier void setext(char*, int, char*); 943e12c5d1SDavid du Colombier 953e12c5d1SDavid du Colombier char *mname[]={ 963e12c5d1SDavid du Colombier [Tnop] "Tnop", 973e12c5d1SDavid du Colombier [Tsession] "Tsession", 983e12c5d1SDavid du Colombier [Tflush] "Tflush", 993e12c5d1SDavid du Colombier [Tattach] "Tattach", 1003e12c5d1SDavid du Colombier [Tclone] "Tclone", 1013e12c5d1SDavid du Colombier [Twalk] "Twalk", 1023e12c5d1SDavid du Colombier [Topen] "Topen", 1033e12c5d1SDavid du Colombier [Tcreate] "Tcreate", 1043e12c5d1SDavid du Colombier [Tclunk] "Tclunk", 1053e12c5d1SDavid du Colombier [Tread] "Tread", 1063e12c5d1SDavid du Colombier [Twrite] "Twrite", 1073e12c5d1SDavid du Colombier [Tremove] "Tremove", 1083e12c5d1SDavid du Colombier [Tstat] "Tstat", 1093e12c5d1SDavid du Colombier [Twstat] "Twstat", 1103e12c5d1SDavid du Colombier 0, 1113e12c5d1SDavid du Colombier }; 1123e12c5d1SDavid du Colombier 113219b2ee8SDavid du Colombier char *logfile = "dns"; 114219b2ee8SDavid du Colombier char *dbfile; 115*7dd7cddfSDavid du Colombier char mntpt[Maxpath]; 116*7dd7cddfSDavid du Colombier char *LOG; 117*7dd7cddfSDavid du Colombier 118*7dd7cddfSDavid du Colombier void 119*7dd7cddfSDavid du Colombier usage(void) 120*7dd7cddfSDavid du Colombier { 121*7dd7cddfSDavid du Colombier fprint(2, "usage: %s [-rs] [-f ndb-file] [-x netmtpt]\n", argv0); 122*7dd7cddfSDavid du Colombier exits("usage"); 123*7dd7cddfSDavid du Colombier } 124219b2ee8SDavid du Colombier 1253e12c5d1SDavid du Colombier void 1263e12c5d1SDavid du Colombier main(int argc, char *argv[]) 1273e12c5d1SDavid du Colombier { 1283e12c5d1SDavid du Colombier int serve; 129*7dd7cddfSDavid du Colombier char servefile[Maxpath]; 130*7dd7cddfSDavid du Colombier char buf[Maxpath]; 131*7dd7cddfSDavid du Colombier char ext[Maxpath]; 132*7dd7cddfSDavid du Colombier char *p; 133219b2ee8SDavid du Colombier 1343e12c5d1SDavid du Colombier serve = 0; 135*7dd7cddfSDavid du Colombier setnetmtpt(mntpt, sizeof(mntpt), nil); 136*7dd7cddfSDavid du Colombier ext[0] = 0; 1373e12c5d1SDavid du Colombier ARGBEGIN{ 1383e12c5d1SDavid du Colombier case 'd': 1393e12c5d1SDavid du Colombier debug = 1; 1403e12c5d1SDavid du Colombier break; 141219b2ee8SDavid du Colombier case 'f': 142*7dd7cddfSDavid du Colombier p = ARGF(); 143*7dd7cddfSDavid du Colombier if(p == nil) 144*7dd7cddfSDavid du Colombier usage(); 145*7dd7cddfSDavid du Colombier dbfile = p; 146*7dd7cddfSDavid du Colombier break; 147*7dd7cddfSDavid du Colombier case 'x': 148*7dd7cddfSDavid du Colombier p = ARGF(); 149*7dd7cddfSDavid du Colombier if(p == nil) 150*7dd7cddfSDavid du Colombier usage(); 151*7dd7cddfSDavid du Colombier setnetmtpt(mntpt, sizeof(mntpt), p); 152*7dd7cddfSDavid du Colombier setext(ext, sizeof(ext), mntpt); 153*7dd7cddfSDavid du Colombier break; 154*7dd7cddfSDavid du Colombier case 'r': 155*7dd7cddfSDavid du Colombier resolver = 1; 156219b2ee8SDavid du Colombier break; 1573e12c5d1SDavid du Colombier case 's': 1583e12c5d1SDavid du Colombier serve = 1; /* serve network */ 159*7dd7cddfSDavid du Colombier cachedb = 1; 160*7dd7cddfSDavid du Colombier break; 161*7dd7cddfSDavid du Colombier case 'a': 162*7dd7cddfSDavid du Colombier p = ARGF(); 163*7dd7cddfSDavid du Colombier if(p == nil) 164*7dd7cddfSDavid du Colombier usage(); 165*7dd7cddfSDavid du Colombier maxage = atoi(p); 166*7dd7cddfSDavid du Colombier break; 167*7dd7cddfSDavid du Colombier case 't': 168*7dd7cddfSDavid du Colombier testing = 1; 1693e12c5d1SDavid du Colombier break; 1703e12c5d1SDavid du Colombier }ARGEND 1713e12c5d1SDavid du Colombier USED(argc); 1723e12c5d1SDavid du Colombier USED(argv); 1733e12c5d1SDavid du Colombier 174*7dd7cddfSDavid du Colombier rfork(RFREND|RFNOTEG); 1753e12c5d1SDavid du Colombier 176*7dd7cddfSDavid du Colombier /* start syslog before we fork */ 177219b2ee8SDavid du Colombier fmtinstall('F', fcallconv); 178219b2ee8SDavid du Colombier dninit(); 179*7dd7cddfSDavid du Colombier snprint(buf, sizeof(buf), "%s/ipifc", mntpt); 180*7dd7cddfSDavid du Colombier if(myipaddr(ipaddr, buf) < 0) 181*7dd7cddfSDavid du Colombier sysfatal("can't read my ip address"); 182219b2ee8SDavid du Colombier 183*7dd7cddfSDavid du Colombier syslog(0, logfile, "starting dns on %I", ipaddr); 184*7dd7cddfSDavid du Colombier 185*7dd7cddfSDavid du Colombier opendatabase(); 186*7dd7cddfSDavid du Colombier 187*7dd7cddfSDavid du Colombier snprint(servefile, sizeof(servefile), "#s/dns%s", ext); 188*7dd7cddfSDavid du Colombier unmount(servefile, mntpt); 189*7dd7cddfSDavid du Colombier remove(servefile); 190*7dd7cddfSDavid du Colombier mountinit(servefile, mntpt); 191*7dd7cddfSDavid du Colombier 192*7dd7cddfSDavid du Colombier now = time(0); 193*7dd7cddfSDavid du Colombier srand(now*getpid()); 194*7dd7cddfSDavid du Colombier db2cache(1); 195*7dd7cddfSDavid du Colombier 196bd389b36SDavid du Colombier if(serve) 197*7dd7cddfSDavid du Colombier dnudpserver(mntpt); 1983e12c5d1SDavid du Colombier io(); 199*7dd7cddfSDavid du Colombier syslog(0, logfile, "io returned, exiting"); 2003e12c5d1SDavid du Colombier exits(0); 2013e12c5d1SDavid du Colombier } 2023e12c5d1SDavid du Colombier 203*7dd7cddfSDavid du Colombier /* 204*7dd7cddfSDavid du Colombier * if a mount point is specified, set the cs extention to be the mount point 205*7dd7cddfSDavid du Colombier * with '_'s replacing '/'s 206*7dd7cddfSDavid du Colombier */ 2073e12c5d1SDavid du Colombier void 208*7dd7cddfSDavid du Colombier setext(char *ext, int n, char *p) 209*7dd7cddfSDavid du Colombier { 210*7dd7cddfSDavid du Colombier int i, c; 211*7dd7cddfSDavid du Colombier 212*7dd7cddfSDavid du Colombier n--; 213*7dd7cddfSDavid du Colombier for(i = 0; i < n; i++){ 214*7dd7cddfSDavid du Colombier c = p[i]; 215*7dd7cddfSDavid du Colombier if(c == 0) 216*7dd7cddfSDavid du Colombier break; 217*7dd7cddfSDavid du Colombier if(c == '/') 218*7dd7cddfSDavid du Colombier c = '_'; 219*7dd7cddfSDavid du Colombier ext[i] = c; 220*7dd7cddfSDavid du Colombier } 221*7dd7cddfSDavid du Colombier ext[i] = 0; 222*7dd7cddfSDavid du Colombier } 223*7dd7cddfSDavid du Colombier 224*7dd7cddfSDavid du Colombier void 225*7dd7cddfSDavid du Colombier mountinit(char *service, char *mntpt) 2263e12c5d1SDavid du Colombier { 2273e12c5d1SDavid du Colombier int f; 2283e12c5d1SDavid du Colombier int p[2]; 2293e12c5d1SDavid du Colombier char buf[32]; 2303e12c5d1SDavid du Colombier 2313e12c5d1SDavid du Colombier if(pipe(p) < 0) 232*7dd7cddfSDavid du Colombier abort(); /* "pipe failed" */; 233219b2ee8SDavid du Colombier switch(rfork(RFFDG|RFPROC|RFNAMEG)){ 2343e12c5d1SDavid du Colombier case 0: 235219b2ee8SDavid du Colombier close(p[1]); 2363e12c5d1SDavid du Colombier break; 2373e12c5d1SDavid du Colombier case -1: 238*7dd7cddfSDavid du Colombier abort(); /* "fork failed\n" */; 2393e12c5d1SDavid du Colombier default: 240219b2ee8SDavid du Colombier close(p[0]); 241219b2ee8SDavid du Colombier 2423e12c5d1SDavid du Colombier /* 2433e12c5d1SDavid du Colombier * make a /srv/dns 2443e12c5d1SDavid du Colombier */ 2453e12c5d1SDavid du Colombier f = create(service, 1, 0666); 2463e12c5d1SDavid du Colombier if(f < 0) 247*7dd7cddfSDavid du Colombier abort(); /* service */; 248bd389b36SDavid du Colombier snprint(buf, sizeof(buf), "%d", p[1]); 2493e12c5d1SDavid du Colombier if(write(f, buf, strlen(buf)) != strlen(buf)) 250*7dd7cddfSDavid du Colombier abort(); /* "write %s", service */; 2513e12c5d1SDavid du Colombier close(f); 2523e12c5d1SDavid du Colombier 2533e12c5d1SDavid du Colombier /* 2543e12c5d1SDavid du Colombier * put ourselves into the file system 2553e12c5d1SDavid du Colombier */ 256*7dd7cddfSDavid du Colombier if(mount(p[1], mntpt, MAFTER, "") < 0) 257*7dd7cddfSDavid du Colombier abort(); /* "mount failed\n" */; 258219b2ee8SDavid du Colombier _exits(0); 2593e12c5d1SDavid du Colombier } 2603e12c5d1SDavid du Colombier mfd[0] = mfd[1] = p[0]; 2613e12c5d1SDavid du Colombier } 2623e12c5d1SDavid du Colombier 2633e12c5d1SDavid du Colombier #define INC 4 2643e12c5d1SDavid du Colombier Mfile* 265*7dd7cddfSDavid du Colombier newfid(int fid, int needunused) 2663e12c5d1SDavid du Colombier { 2673e12c5d1SDavid du Colombier Mfile *mf; 2683e12c5d1SDavid du Colombier 269*7dd7cddfSDavid du Colombier lock(&mfalloc); 270*7dd7cddfSDavid du Colombier for(mf = mfalloc.inuse; mf != nil; mf = mf->next){ 271*7dd7cddfSDavid du Colombier if(mf->fid == fid){ 272*7dd7cddfSDavid du Colombier unlock(&mfalloc); 273*7dd7cddfSDavid du Colombier if(needunused) 274*7dd7cddfSDavid du Colombier return nil; 2753e12c5d1SDavid du Colombier return mf; 2763e12c5d1SDavid du Colombier } 2773e12c5d1SDavid du Colombier } 278*7dd7cddfSDavid du Colombier mf = mallocz(sizeof(*mf), 1); 279*7dd7cddfSDavid du Colombier if(mf == nil) 280*7dd7cddfSDavid du Colombier sysfatal("out of memory"); 2813e12c5d1SDavid du Colombier mf->fid = fid; 282*7dd7cddfSDavid du Colombier mf->next = mfalloc.inuse; 283*7dd7cddfSDavid du Colombier mfalloc.inuse = mf; 284*7dd7cddfSDavid du Colombier unlock(&mfalloc); 2853e12c5d1SDavid du Colombier return mf; 2863e12c5d1SDavid du Colombier } 2873e12c5d1SDavid du Colombier 2883e12c5d1SDavid du Colombier void 289*7dd7cddfSDavid du Colombier freefid(Mfile *mf) 290*7dd7cddfSDavid du Colombier { 291*7dd7cddfSDavid du Colombier Mfile **l; 292*7dd7cddfSDavid du Colombier 293*7dd7cddfSDavid du Colombier lock(&mfalloc); 294*7dd7cddfSDavid du Colombier for(l = &mfalloc.inuse; *l != nil; l = &(*l)->next){ 295*7dd7cddfSDavid du Colombier if(*l == mf){ 296*7dd7cddfSDavid du Colombier *l = mf->next; 297*7dd7cddfSDavid du Colombier free(mf); 298*7dd7cddfSDavid du Colombier unlock(&mfalloc); 299*7dd7cddfSDavid du Colombier return; 300*7dd7cddfSDavid du Colombier } 301*7dd7cddfSDavid du Colombier } 302*7dd7cddfSDavid du Colombier sysfatal("freeing unused fid"); 303*7dd7cddfSDavid du Colombier } 304*7dd7cddfSDavid du Colombier 305*7dd7cddfSDavid du Colombier Mfile* 306*7dd7cddfSDavid du Colombier copyfid(Mfile *mf, int fid) 307*7dd7cddfSDavid du Colombier { 308*7dd7cddfSDavid du Colombier Mfile *nmf; 309*7dd7cddfSDavid du Colombier 310*7dd7cddfSDavid du Colombier nmf = newfid(fid, 1); 311*7dd7cddfSDavid du Colombier if(nmf == nil) 312*7dd7cddfSDavid du Colombier return nil; 313*7dd7cddfSDavid du Colombier nmf->fid = fid; 314*7dd7cddfSDavid du Colombier strncpy(nmf->user, mf->user, sizeof(mf->user)); 315*7dd7cddfSDavid du Colombier nmf->qid.path = mf->qid.path; 316*7dd7cddfSDavid du Colombier nmf->qid.vers = vers++; 317*7dd7cddfSDavid du Colombier return nmf; 318*7dd7cddfSDavid du Colombier } 319*7dd7cddfSDavid du Colombier 320*7dd7cddfSDavid du Colombier Job* 321*7dd7cddfSDavid du Colombier newjob(void) 322*7dd7cddfSDavid du Colombier { 323*7dd7cddfSDavid du Colombier Job *job; 324*7dd7cddfSDavid du Colombier 325*7dd7cddfSDavid du Colombier job = mallocz(sizeof(Job), 1); 326*7dd7cddfSDavid du Colombier lock(&joblock); 327*7dd7cddfSDavid du Colombier job->next = joblist; 328*7dd7cddfSDavid du Colombier joblist = job; 329*7dd7cddfSDavid du Colombier job->request.tag = -1; 330*7dd7cddfSDavid du Colombier unlock(&joblock); 331*7dd7cddfSDavid du Colombier return job; 332*7dd7cddfSDavid du Colombier } 333*7dd7cddfSDavid du Colombier 334*7dd7cddfSDavid du Colombier void 335*7dd7cddfSDavid du Colombier freejob(Job *job) 336*7dd7cddfSDavid du Colombier { 337*7dd7cddfSDavid du Colombier Job **l; 338*7dd7cddfSDavid du Colombier 339*7dd7cddfSDavid du Colombier lock(&joblock); 340*7dd7cddfSDavid du Colombier for(l = &joblist; *l; l = &(*l)->next){ 341*7dd7cddfSDavid du Colombier if((*l) == job){ 342*7dd7cddfSDavid du Colombier *l = job->next; 343*7dd7cddfSDavid du Colombier free(job); 344*7dd7cddfSDavid du Colombier break; 345*7dd7cddfSDavid du Colombier } 346*7dd7cddfSDavid du Colombier } 347*7dd7cddfSDavid du Colombier unlock(&joblock); 348*7dd7cddfSDavid du Colombier } 349*7dd7cddfSDavid du Colombier 350*7dd7cddfSDavid du Colombier void 351*7dd7cddfSDavid du Colombier flushjob(int tag) 352*7dd7cddfSDavid du Colombier { 353*7dd7cddfSDavid du Colombier Job *job; 354*7dd7cddfSDavid du Colombier 355*7dd7cddfSDavid du Colombier lock(&joblock); 356*7dd7cddfSDavid du Colombier for(job = joblist; job; job = job->next){ 357*7dd7cddfSDavid du Colombier if(job->request.tag == tag && job->request.type != Tflush){ 358*7dd7cddfSDavid du Colombier job->flushed = 1; 359*7dd7cddfSDavid du Colombier break; 360*7dd7cddfSDavid du Colombier } 361*7dd7cddfSDavid du Colombier } 362*7dd7cddfSDavid du Colombier unlock(&joblock); 363*7dd7cddfSDavid du Colombier } 364*7dd7cddfSDavid du Colombier 365*7dd7cddfSDavid du Colombier void 3663e12c5d1SDavid du Colombier io(void) 3673e12c5d1SDavid du Colombier { 3683e12c5d1SDavid du Colombier long n; 3693e12c5d1SDavid du Colombier Mfile *mf; 3703e12c5d1SDavid du Colombier char mdata[MAXFDATA + MAXMSG]; 3713e12c5d1SDavid du Colombier Request req; 372*7dd7cddfSDavid du Colombier Job *job; 3733e12c5d1SDavid du Colombier 3743e12c5d1SDavid du Colombier /* 3753e12c5d1SDavid du Colombier * a slave process is sometimes forked to wait for replies from other 3763e12c5d1SDavid du Colombier * servers. The master process returns immediately via a longjmp 377219b2ee8SDavid du Colombier * through 'mret'. 3783e12c5d1SDavid du Colombier */ 379*7dd7cddfSDavid du Colombier if(setjmp(req.mret)) 380*7dd7cddfSDavid du Colombier putactivity(); 3813e12c5d1SDavid du Colombier req.isslave = 0; 382*7dd7cddfSDavid du Colombier for(;;){ 3833e12c5d1SDavid du Colombier n = read(mfd[0], mdata, sizeof mdata); 384*7dd7cddfSDavid du Colombier if(n<=0){ 385*7dd7cddfSDavid du Colombier syslog(0, logfile, "error reading mntpt: %r"); 386*7dd7cddfSDavid du Colombier exits(0); 387*7dd7cddfSDavid du Colombier } 388*7dd7cddfSDavid du Colombier job = newjob(); 389*7dd7cddfSDavid du Colombier if(convM2S(mdata, &job->request, n) == 0){ 390*7dd7cddfSDavid du Colombier freejob(job); 391*7dd7cddfSDavid du Colombier continue; 392*7dd7cddfSDavid du Colombier } 393*7dd7cddfSDavid du Colombier mf = newfid(job->request.fid, 0); 394219b2ee8SDavid du Colombier if(debug) 395*7dd7cddfSDavid du Colombier syslog(0, logfile, "%F", &job->request); 396*7dd7cddfSDavid du Colombier 397*7dd7cddfSDavid du Colombier getactivity(&req); 398*7dd7cddfSDavid du Colombier req.aborttime = now + 60; /* don't spend more than 60 seconds */ 399*7dd7cddfSDavid du Colombier 400*7dd7cddfSDavid du Colombier switch(job->request.type){ 4013e12c5d1SDavid du Colombier default: 402*7dd7cddfSDavid du Colombier abort(); /* "type" */; 4033e12c5d1SDavid du Colombier break; 4043e12c5d1SDavid du Colombier case Tsession: 405*7dd7cddfSDavid du Colombier rsession(job); 4063e12c5d1SDavid du Colombier break; 4073e12c5d1SDavid du Colombier case Tnop: 408*7dd7cddfSDavid du Colombier rsimple(job); 4093e12c5d1SDavid du Colombier break; 4103e12c5d1SDavid du Colombier case Tflush: 411*7dd7cddfSDavid du Colombier rflush(job); 4123e12c5d1SDavid du Colombier break; 4133e12c5d1SDavid du Colombier case Tattach: 414*7dd7cddfSDavid du Colombier rattach(job, mf); 4153e12c5d1SDavid du Colombier break; 4163e12c5d1SDavid du Colombier case Tclone: 417*7dd7cddfSDavid du Colombier rclone(job, mf); 4183e12c5d1SDavid du Colombier break; 4193e12c5d1SDavid du Colombier case Twalk: 420*7dd7cddfSDavid du Colombier rwalk(job, mf); 4213e12c5d1SDavid du Colombier break; 4223e12c5d1SDavid du Colombier case Tclwalk: 423*7dd7cddfSDavid du Colombier rclwalk(job, mf); 4243e12c5d1SDavid du Colombier break; 4253e12c5d1SDavid du Colombier case Topen: 426*7dd7cddfSDavid du Colombier ropen(job, mf); 4273e12c5d1SDavid du Colombier break; 4283e12c5d1SDavid du Colombier case Tcreate: 429*7dd7cddfSDavid du Colombier rcreate(job, mf); 4303e12c5d1SDavid du Colombier break; 4313e12c5d1SDavid du Colombier case Tread: 432*7dd7cddfSDavid du Colombier rread(job, mf); 4333e12c5d1SDavid du Colombier break; 4343e12c5d1SDavid du Colombier case Twrite: 435*7dd7cddfSDavid du Colombier rwrite(job, mf, &req); 4363e12c5d1SDavid du Colombier break; 4373e12c5d1SDavid du Colombier case Tclunk: 438*7dd7cddfSDavid du Colombier rclunk(job, mf); 4393e12c5d1SDavid du Colombier break; 4403e12c5d1SDavid du Colombier case Tremove: 441*7dd7cddfSDavid du Colombier rremove(job, mf); 4423e12c5d1SDavid du Colombier break; 4433e12c5d1SDavid du Colombier case Tstat: 444*7dd7cddfSDavid du Colombier rstat(job, mf); 4453e12c5d1SDavid du Colombier break; 4463e12c5d1SDavid du Colombier case Twstat: 447*7dd7cddfSDavid du Colombier rwstat(job, mf); 4483e12c5d1SDavid du Colombier break; 4493e12c5d1SDavid du Colombier } 450*7dd7cddfSDavid du Colombier 451*7dd7cddfSDavid du Colombier freejob(job); 452*7dd7cddfSDavid du Colombier 4533e12c5d1SDavid du Colombier /* 4543e12c5d1SDavid du Colombier * slave processes die after replying 4553e12c5d1SDavid du Colombier */ 456*7dd7cddfSDavid du Colombier if(req.isslave){ 457*7dd7cddfSDavid du Colombier putactivity(); 4583e12c5d1SDavid du Colombier _exits(0); 459*7dd7cddfSDavid du Colombier } 460*7dd7cddfSDavid du Colombier 461*7dd7cddfSDavid du Colombier putactivity(); 462*7dd7cddfSDavid du Colombier } 4633e12c5d1SDavid du Colombier } 4643e12c5d1SDavid du Colombier 4653e12c5d1SDavid du Colombier void 466*7dd7cddfSDavid du Colombier rsession(Job *job) 467219b2ee8SDavid du Colombier { 468*7dd7cddfSDavid du Colombier memset(job->reply.authid, 0, sizeof(job->reply.authid)); 469*7dd7cddfSDavid du Colombier memset(job->reply.authdom, 0, sizeof(job->reply.authdom)); 470*7dd7cddfSDavid du Colombier memset(job->reply.chal, 0, sizeof(job->reply.chal)); 471*7dd7cddfSDavid du Colombier sendmsg(job, 0); 472219b2ee8SDavid du Colombier } 473219b2ee8SDavid du Colombier 474219b2ee8SDavid du Colombier void 475*7dd7cddfSDavid du Colombier rsimple(Job *job) 4763e12c5d1SDavid du Colombier { 477*7dd7cddfSDavid du Colombier sendmsg(job, 0); 478*7dd7cddfSDavid du Colombier } 479*7dd7cddfSDavid du Colombier 480*7dd7cddfSDavid du Colombier /* ignore flushes since the operation will time out */ 481*7dd7cddfSDavid du Colombier void 482*7dd7cddfSDavid du Colombier rflush(Job *job) 483*7dd7cddfSDavid du Colombier { 484*7dd7cddfSDavid du Colombier flushjob(job->request.oldtag); 485*7dd7cddfSDavid du Colombier sendmsg(job, 0); 4863e12c5d1SDavid du Colombier } 4873e12c5d1SDavid du Colombier 4883e12c5d1SDavid du Colombier void 489*7dd7cddfSDavid du Colombier rauth(Job *job) 4903e12c5d1SDavid du Colombier { 491*7dd7cddfSDavid du Colombier sendmsg(job, "Authentication failed"); 4923e12c5d1SDavid du Colombier } 4933e12c5d1SDavid du Colombier 4943e12c5d1SDavid du Colombier void 495*7dd7cddfSDavid du Colombier rattach(Job *job, Mfile *mf) 4963e12c5d1SDavid du Colombier { 497*7dd7cddfSDavid du Colombier strcpy(mf->user, job->request.uname); 4983e12c5d1SDavid du Colombier mf->qid.vers = vers++; 4993e12c5d1SDavid du Colombier mf->qid.path = CHDIR; 500*7dd7cddfSDavid du Colombier job->reply.qid = mf->qid; 501*7dd7cddfSDavid du Colombier sendmsg(job, 0); 5023e12c5d1SDavid du Colombier } 5033e12c5d1SDavid du Colombier 504*7dd7cddfSDavid du Colombier char *Eused; 505*7dd7cddfSDavid du Colombier 5063e12c5d1SDavid du Colombier void 507*7dd7cddfSDavid du Colombier rclone(Job *job, Mfile *mf) 5083e12c5d1SDavid du Colombier { 5093e12c5d1SDavid du Colombier Mfile *nmf; 5103e12c5d1SDavid du Colombier char *err=0; 5113e12c5d1SDavid du Colombier 512*7dd7cddfSDavid du Colombier nmf = copyfid(mf, job->request.newfid); 513*7dd7cddfSDavid du Colombier if(nmf == nil) 514*7dd7cddfSDavid du Colombier err = Eused; 515*7dd7cddfSDavid du Colombier sendmsg(job, err); 5163e12c5d1SDavid du Colombier } 5173e12c5d1SDavid du Colombier 5183e12c5d1SDavid du Colombier void 519*7dd7cddfSDavid du Colombier rclwalk(Job *job, Mfile *mf) 5203e12c5d1SDavid du Colombier { 5213e12c5d1SDavid du Colombier Mfile *nmf; 5223e12c5d1SDavid du Colombier 523*7dd7cddfSDavid du Colombier nmf = copyfid(mf, job->request.newfid); 524*7dd7cddfSDavid du Colombier if(nmf == nil){ 525*7dd7cddfSDavid du Colombier sendmsg(job, Eused); 5263e12c5d1SDavid du Colombier return; 5273e12c5d1SDavid du Colombier } 528*7dd7cddfSDavid du Colombier job->request.fid = job->request.newfid; 529*7dd7cddfSDavid du Colombier if(rwalk(job, nmf) != nil) 530*7dd7cddfSDavid du Colombier freefid(nmf); 5313e12c5d1SDavid du Colombier } 5323e12c5d1SDavid du Colombier 5333e12c5d1SDavid du Colombier char* 534*7dd7cddfSDavid du Colombier rwalk(Job *job, Mfile *mf) 5353e12c5d1SDavid du Colombier { 5363e12c5d1SDavid du Colombier char *err; 5373e12c5d1SDavid du Colombier char *name; 5383e12c5d1SDavid du Colombier 5393e12c5d1SDavid du Colombier err = 0; 540*7dd7cddfSDavid du Colombier name = job->request.name; 5413e12c5d1SDavid du Colombier if((mf->qid.path & CHDIR) == 0){ 5423e12c5d1SDavid du Colombier err = "not a directory"; 5433e12c5d1SDavid du Colombier goto send; 5443e12c5d1SDavid du Colombier } 5453e12c5d1SDavid du Colombier if(strcmp(name, ".") == 0){ 5463e12c5d1SDavid du Colombier mf->qid.path = CHDIR; 5473e12c5d1SDavid du Colombier goto send; 5483e12c5d1SDavid du Colombier } 5493e12c5d1SDavid du Colombier if(strcmp(name, "dns") == 0){ 5503e12c5d1SDavid du Colombier mf->qid.path = Qdns; 5513e12c5d1SDavid du Colombier goto send; 5523e12c5d1SDavid du Colombier } 5533e12c5d1SDavid du Colombier err = "nonexistent file"; 5543e12c5d1SDavid du Colombier send: 555*7dd7cddfSDavid du Colombier job->reply.qid = mf->qid; 556*7dd7cddfSDavid du Colombier sendmsg(job, err); 5573e12c5d1SDavid du Colombier return err; 5583e12c5d1SDavid du Colombier } 5593e12c5d1SDavid du Colombier 5603e12c5d1SDavid du Colombier void 561*7dd7cddfSDavid du Colombier ropen(Job *job, Mfile *mf) 5623e12c5d1SDavid du Colombier { 5633e12c5d1SDavid du Colombier int mode; 5643e12c5d1SDavid du Colombier char *err; 5653e12c5d1SDavid du Colombier 5663e12c5d1SDavid du Colombier err = 0; 567*7dd7cddfSDavid du Colombier mode = job->request.mode; 5683e12c5d1SDavid du Colombier if(mf->qid.path & CHDIR){ 5693e12c5d1SDavid du Colombier if(mode) 5703e12c5d1SDavid du Colombier err = "permission denied"; 5713e12c5d1SDavid du Colombier } 572*7dd7cddfSDavid du Colombier job->reply.qid = mf->qid; 573*7dd7cddfSDavid du Colombier sendmsg(job, err); 5743e12c5d1SDavid du Colombier } 5753e12c5d1SDavid du Colombier 5763e12c5d1SDavid du Colombier void 577*7dd7cddfSDavid du Colombier rcreate(Job *job, Mfile *mf) 5783e12c5d1SDavid du Colombier { 5793e12c5d1SDavid du Colombier USED(mf); 580*7dd7cddfSDavid du Colombier sendmsg(job, "creation permission denied"); 5813e12c5d1SDavid du Colombier } 5823e12c5d1SDavid du Colombier 5833e12c5d1SDavid du Colombier void 584*7dd7cddfSDavid du Colombier rread(Job *job, Mfile *mf) 5853e12c5d1SDavid du Colombier { 586*7dd7cddfSDavid du Colombier int i, n, cnt; 587*7dd7cddfSDavid du Colombier long off; 5883e12c5d1SDavid du Colombier Dir dir; 5893e12c5d1SDavid du Colombier char buf[MAXFDATA]; 5903e12c5d1SDavid du Colombier char *err; 5913e12c5d1SDavid du Colombier 5923e12c5d1SDavid du Colombier n = 0; 5933e12c5d1SDavid du Colombier err = 0; 594*7dd7cddfSDavid du Colombier off = job->request.offset; 595*7dd7cddfSDavid du Colombier cnt = job->request.count; 5963e12c5d1SDavid du Colombier if(mf->qid.path & CHDIR){ 5973e12c5d1SDavid du Colombier if(off%DIRLEN || cnt%DIRLEN){ 5983e12c5d1SDavid du Colombier err = "bad offset"; 5993e12c5d1SDavid du Colombier goto send; 6003e12c5d1SDavid du Colombier } 6013e12c5d1SDavid du Colombier if(off == 0){ 6023e12c5d1SDavid du Colombier memmove(dir.name, "dns", NAMELEN); 6033e12c5d1SDavid du Colombier dir.qid.vers = vers; 6043e12c5d1SDavid du Colombier dir.qid.path = Qdns; 6053e12c5d1SDavid du Colombier dir.mode = 0666; 6063e12c5d1SDavid du Colombier dir.length = 0; 6073e12c5d1SDavid du Colombier strcpy(dir.uid, mf->user); 6083e12c5d1SDavid du Colombier strcpy(dir.gid, mf->user); 609*7dd7cddfSDavid du Colombier dir.atime = now; 610*7dd7cddfSDavid du Colombier dir.mtime = now; 6113e12c5d1SDavid du Colombier convD2M(&dir, buf+n); 6123e12c5d1SDavid du Colombier n += DIRLEN; 6133e12c5d1SDavid du Colombier } 614*7dd7cddfSDavid du Colombier job->reply.data = buf; 6153e12c5d1SDavid du Colombier } else { 616*7dd7cddfSDavid du Colombier for(i = 1; i <= mf->nrr; i++) 617*7dd7cddfSDavid du Colombier if(mf->rr[i] > off) 6183e12c5d1SDavid du Colombier break; 619*7dd7cddfSDavid du Colombier if(i > mf->nrr) 620*7dd7cddfSDavid du Colombier goto send; 621*7dd7cddfSDavid du Colombier if(off + cnt > mf->rr[i]) 622*7dd7cddfSDavid du Colombier n = mf->rr[i] - off; 623*7dd7cddfSDavid du Colombier else 624*7dd7cddfSDavid du Colombier n = cnt; 625*7dd7cddfSDavid du Colombier job->reply.data = mf->reply + off; 6263e12c5d1SDavid du Colombier } 6273e12c5d1SDavid du Colombier send: 628*7dd7cddfSDavid du Colombier job->reply.count = n; 629*7dd7cddfSDavid du Colombier sendmsg(job, err); 6303e12c5d1SDavid du Colombier } 6313e12c5d1SDavid du Colombier 6323e12c5d1SDavid du Colombier void 633*7dd7cddfSDavid du Colombier rwrite(Job *job, Mfile *mf, Request *req) 6343e12c5d1SDavid du Colombier { 635*7dd7cddfSDavid du Colombier int cnt, rooted, status; 636*7dd7cddfSDavid du Colombier long n; 637*7dd7cddfSDavid du Colombier char *err, *p, *atype; 638*7dd7cddfSDavid du Colombier RR *rp, *tp, *neg; 639*7dd7cddfSDavid du Colombier int wantsav; 6403e12c5d1SDavid du Colombier 6413e12c5d1SDavid du Colombier err = 0; 642*7dd7cddfSDavid du Colombier cnt = job->request.count; 6433e12c5d1SDavid du Colombier if(mf->qid.path & CHDIR){ 6443e12c5d1SDavid du Colombier err = "can't write directory"; 6453e12c5d1SDavid du Colombier goto send; 6463e12c5d1SDavid du Colombier } 6473e12c5d1SDavid du Colombier if(cnt >= Maxrequest){ 6483e12c5d1SDavid du Colombier err = "request too long"; 6493e12c5d1SDavid du Colombier goto send; 6503e12c5d1SDavid du Colombier } 651*7dd7cddfSDavid du Colombier job->request.data[cnt] = 0; 652*7dd7cddfSDavid du Colombier if(cnt > 0 && job->request.data[cnt-1] == '\n') 653*7dd7cddfSDavid du Colombier job->request.data[cnt-1] = 0; 6543e12c5d1SDavid du Colombier 6553e12c5d1SDavid du Colombier /* 656*7dd7cddfSDavid du Colombier * special commands 657219b2ee8SDavid du Colombier */ 658*7dd7cddfSDavid du Colombier if(strncmp(job->request.data, "debug", 5)==0 && job->request.data[5] == 0){ 659219b2ee8SDavid du Colombier debug ^= 1; 660219b2ee8SDavid du Colombier goto send; 661*7dd7cddfSDavid du Colombier } else if(strncmp(job->request.data, "dump", 4)==0 && job->request.data[4] == 0){ 662219b2ee8SDavid du Colombier dndump("/lib/ndb/dnsdump"); 663219b2ee8SDavid du Colombier goto send; 664*7dd7cddfSDavid du Colombier } else if(strncmp(job->request.data, "refresh", 7)==0 && job->request.data[7] == 0){ 665*7dd7cddfSDavid du Colombier needrefresh = 1; 666*7dd7cddfSDavid du Colombier goto send; 667219b2ee8SDavid du Colombier } 668219b2ee8SDavid du Colombier 669219b2ee8SDavid du Colombier /* 670*7dd7cddfSDavid du Colombier * kill previous reply 671*7dd7cddfSDavid du Colombier */ 672*7dd7cddfSDavid du Colombier mf->nrr = 0; 673*7dd7cddfSDavid du Colombier mf->rr[0] = 0; 674*7dd7cddfSDavid du Colombier 675*7dd7cddfSDavid du Colombier /* 6763e12c5d1SDavid du Colombier * break up request (into a name and a type) 6773e12c5d1SDavid du Colombier */ 678*7dd7cddfSDavid du Colombier atype = strchr(job->request.data, ' '); 6793e12c5d1SDavid du Colombier if(atype == 0){ 6803e12c5d1SDavid du Colombier err = "illegal request"; 6813e12c5d1SDavid du Colombier goto send; 6823e12c5d1SDavid du Colombier } else 6833e12c5d1SDavid du Colombier *atype++ = 0; 6843e12c5d1SDavid du Colombier 685*7dd7cddfSDavid du Colombier /* 686*7dd7cddfSDavid du Colombier * tracing request 687*7dd7cddfSDavid du Colombier */ 688*7dd7cddfSDavid du Colombier if(strcmp(atype, "trace") == 0){ 689*7dd7cddfSDavid du Colombier if(trace) 690*7dd7cddfSDavid du Colombier free(trace); 691*7dd7cddfSDavid du Colombier if(*job->request.data) 692*7dd7cddfSDavid du Colombier trace = strdup(job->request.data); 693*7dd7cddfSDavid du Colombier else 694*7dd7cddfSDavid du Colombier trace = 0; 695*7dd7cddfSDavid du Colombier goto send; 696*7dd7cddfSDavid du Colombier } 697*7dd7cddfSDavid du Colombier 6983e12c5d1SDavid du Colombier mf->type = rrtype(atype); 6993e12c5d1SDavid du Colombier if(mf->type < 0){ 7003e12c5d1SDavid du Colombier err = "unknown type"; 7013e12c5d1SDavid du Colombier goto send; 7023e12c5d1SDavid du Colombier } 7033e12c5d1SDavid du Colombier 704*7dd7cddfSDavid du Colombier p = atype - 2; 705*7dd7cddfSDavid du Colombier if(p >= job->request.data && *p == '.'){ 706*7dd7cddfSDavid du Colombier rooted = 1; 707*7dd7cddfSDavid du Colombier *p = 0; 708*7dd7cddfSDavid du Colombier } else 709*7dd7cddfSDavid du Colombier rooted = 0; 7103e12c5d1SDavid du Colombier 711*7dd7cddfSDavid du Colombier p = job->request.data; 712*7dd7cddfSDavid du Colombier if(*p == '!'){ 713*7dd7cddfSDavid du Colombier wantsav = 1; 714*7dd7cddfSDavid du Colombier p++; 715*7dd7cddfSDavid du Colombier } else 716*7dd7cddfSDavid du Colombier wantsav = 0; 717*7dd7cddfSDavid du Colombier rp = dnresolve(p, Cin, mf->type, req, 0, 0, Recurse, rooted, &status); 718*7dd7cddfSDavid du Colombier neg = rrremneg(&rp); 719*7dd7cddfSDavid du Colombier if(neg){ 720*7dd7cddfSDavid du Colombier status = neg->negrcode; 721*7dd7cddfSDavid du Colombier rrfreelist(neg); 722*7dd7cddfSDavid du Colombier } 723*7dd7cddfSDavid du Colombier if(rp == 0){ 724*7dd7cddfSDavid du Colombier if(status == Rname) 725*7dd7cddfSDavid du Colombier err = "name does not exist"; 726*7dd7cddfSDavid du Colombier else 727*7dd7cddfSDavid du Colombier err = "no translation found"; 728*7dd7cddfSDavid du Colombier } else { 729*7dd7cddfSDavid du Colombier /* format data to be read later */ 730*7dd7cddfSDavid du Colombier n = 0; 731*7dd7cddfSDavid du Colombier mf->nrr = 0; 732*7dd7cddfSDavid du Colombier for(tp = rp; mf->nrr < Maxrrr-1 && n < Maxreply && tp && 733*7dd7cddfSDavid du Colombier tsame(mf->type, tp->type); tp = tp->next){ 734*7dd7cddfSDavid du Colombier mf->rr[mf->nrr++] = n; 735*7dd7cddfSDavid du Colombier if(wantsav) 736*7dd7cddfSDavid du Colombier n += snprint(mf->reply+n, Maxreply-n, "%Q", tp); 737*7dd7cddfSDavid du Colombier else 738*7dd7cddfSDavid du Colombier n += snprint(mf->reply+n, Maxreply-n, "%R", tp); 739*7dd7cddfSDavid du Colombier } 740*7dd7cddfSDavid du Colombier mf->rr[mf->nrr] = n; 741*7dd7cddfSDavid du Colombier rrfreelist(rp); 742*7dd7cddfSDavid du Colombier } 7433e12c5d1SDavid du Colombier 7443e12c5d1SDavid du Colombier send: 745*7dd7cddfSDavid du Colombier job->reply.count = cnt; 746*7dd7cddfSDavid du Colombier sendmsg(job, err); 7473e12c5d1SDavid du Colombier } 7483e12c5d1SDavid du Colombier 7493e12c5d1SDavid du Colombier void 750*7dd7cddfSDavid du Colombier rclunk(Job *job, Mfile *mf) 7513e12c5d1SDavid du Colombier { 752*7dd7cddfSDavid du Colombier freefid(mf); 753*7dd7cddfSDavid du Colombier sendmsg(job, 0); 7543e12c5d1SDavid du Colombier } 7553e12c5d1SDavid du Colombier 7563e12c5d1SDavid du Colombier void 757*7dd7cddfSDavid du Colombier rremove(Job *job, Mfile *mf) 7583e12c5d1SDavid du Colombier { 7593e12c5d1SDavid du Colombier USED(mf); 760*7dd7cddfSDavid du Colombier sendmsg(job, "remove permission denied"); 7613e12c5d1SDavid du Colombier } 7623e12c5d1SDavid du Colombier 7633e12c5d1SDavid du Colombier void 764*7dd7cddfSDavid du Colombier rstat(Job *job, Mfile *mf) 7653e12c5d1SDavid du Colombier { 7663e12c5d1SDavid du Colombier Dir dir; 7673e12c5d1SDavid du Colombier 768219b2ee8SDavid du Colombier if(mf->qid.path & CHDIR){ 769219b2ee8SDavid du Colombier strcpy(dir.name, "."); 770219b2ee8SDavid du Colombier dir.mode = CHDIR|0555; 771219b2ee8SDavid du Colombier } else { 772219b2ee8SDavid du Colombier strcpy(dir.name, "dns"); 7733e12c5d1SDavid du Colombier dir.mode = 0666; 774219b2ee8SDavid du Colombier } 775219b2ee8SDavid du Colombier dir.qid = mf->qid; 7763e12c5d1SDavid du Colombier dir.length = 0; 7773e12c5d1SDavid du Colombier strcpy(dir.uid, mf->user); 7783e12c5d1SDavid du Colombier strcpy(dir.gid, mf->user); 7793e12c5d1SDavid du Colombier dir.atime = dir.mtime = time(0); 780*7dd7cddfSDavid du Colombier convD2M(&dir, (char*)job->reply.stat); 781*7dd7cddfSDavid du Colombier sendmsg(job, 0); 7823e12c5d1SDavid du Colombier } 7833e12c5d1SDavid du Colombier 7843e12c5d1SDavid du Colombier void 785*7dd7cddfSDavid du Colombier rwstat(Job *job, Mfile *mf) 7863e12c5d1SDavid du Colombier { 7873e12c5d1SDavid du Colombier USED(mf); 788*7dd7cddfSDavid du Colombier sendmsg(job, "wstat permission denied"); 7893e12c5d1SDavid du Colombier } 7903e12c5d1SDavid du Colombier 7913e12c5d1SDavid du Colombier void 792*7dd7cddfSDavid du Colombier sendmsg(Job *job, char *err) 7933e12c5d1SDavid du Colombier { 7943e12c5d1SDavid du Colombier int n; 7953e12c5d1SDavid du Colombier char mdata[MAXFDATA + MAXMSG]; 7963e12c5d1SDavid du Colombier 7973e12c5d1SDavid du Colombier if(err){ 798*7dd7cddfSDavid du Colombier job->reply.type = Rerror; 799*7dd7cddfSDavid du Colombier snprint(job->reply.ename, sizeof(job->reply.ename), "dns: %s", err); 8003e12c5d1SDavid du Colombier }else{ 801*7dd7cddfSDavid du Colombier job->reply.type = job->request.type+1; 802*7dd7cddfSDavid du Colombier job->reply.fid = job->request.fid; 8033e12c5d1SDavid du Colombier } 804*7dd7cddfSDavid du Colombier job->reply.tag = job->request.tag; 805219b2ee8SDavid du Colombier if(debug) 806*7dd7cddfSDavid du Colombier syslog(0, logfile, "%F", &job->reply); 807*7dd7cddfSDavid du Colombier n = convS2M(&job->reply, mdata); 808*7dd7cddfSDavid du Colombier lock(&joblock); 809*7dd7cddfSDavid du Colombier if(job->flushed == 0){ 8103e12c5d1SDavid du Colombier if(write(mfd[1], mdata, n)!=n) 811*7dd7cddfSDavid du Colombier abort(); /* "mount write" */; 8123e12c5d1SDavid du Colombier } 813*7dd7cddfSDavid du Colombier unlock(&joblock); 8143e12c5d1SDavid du Colombier } 8153e12c5d1SDavid du Colombier 8163e12c5d1SDavid du Colombier /* 817*7dd7cddfSDavid du Colombier * the following varies between dnsdebug and dns 8183e12c5d1SDavid du Colombier */ 8193e12c5d1SDavid du Colombier void 820*7dd7cddfSDavid du Colombier logreply(int id, uchar *addr, DNSmsg *mp) 8213e12c5d1SDavid du Colombier { 822*7dd7cddfSDavid du Colombier RR *rp; 8233e12c5d1SDavid du Colombier 824*7dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I flags:%s%s%s%s%s", id, addr, 825*7dd7cddfSDavid du Colombier mp->flags & Fauth ? " auth" : "", 826*7dd7cddfSDavid du Colombier mp->flags & Ftrunc ? " trunc" : "", 827*7dd7cddfSDavid du Colombier mp->flags & Frecurse ? " rd" : "", 828*7dd7cddfSDavid du Colombier mp->flags & Fcanrec ? " ra" : "", 829*7dd7cddfSDavid du Colombier mp->flags & (Fauth|Rname) == (Fauth|Rname) ? 830*7dd7cddfSDavid du Colombier " nx" : ""); 831*7dd7cddfSDavid du Colombier for(rp = mp->qd; rp != nil; rp = rp->next) 832*7dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I qd %s", id, addr, rp->owner->name); 833*7dd7cddfSDavid du Colombier for(rp = mp->an; rp != nil; rp = rp->next) 834*7dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I an %R", id, addr, rp); 835*7dd7cddfSDavid du Colombier for(rp = mp->ns; rp != nil; rp = rp->next) 836*7dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I ns %R", id, addr, rp); 837*7dd7cddfSDavid du Colombier for(rp = mp->ar; rp != nil; rp = rp->next) 838*7dd7cddfSDavid du Colombier syslog(0, LOG, "%d: rcvd %I ar %R", id, addr, rp); 8393e12c5d1SDavid du Colombier } 840*7dd7cddfSDavid du Colombier 841*7dd7cddfSDavid du Colombier void 842*7dd7cddfSDavid du Colombier logsend(int id, int subid, uchar *addr, char *sname, char *rname, int type) 843*7dd7cddfSDavid du Colombier { 844*7dd7cddfSDavid du Colombier char buf[12]; 845*7dd7cddfSDavid du Colombier 846*7dd7cddfSDavid du Colombier syslog(0, LOG, "%d.%d: sending to %I/%s %s %s", 847*7dd7cddfSDavid du Colombier id, subid, addr, sname, rname, rrname(type, buf)); 848*7dd7cddfSDavid du Colombier } 849*7dd7cddfSDavid du Colombier 850*7dd7cddfSDavid du Colombier RR* 851*7dd7cddfSDavid du Colombier getdnsservers(int class) 852*7dd7cddfSDavid du Colombier { 853*7dd7cddfSDavid du Colombier return dnsservers(class); 8543e12c5d1SDavid du Colombier } 855