13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 3*219b2ee8SDavid du Colombier #include <auth.h> 43e12c5d1SDavid du Colombier #include <fcall.h> 53e12c5d1SDavid du Colombier #include <bio.h> 63e12c5d1SDavid du Colombier #include <ctype.h> 73e12c5d1SDavid du Colombier #include <ndb.h> 83e12c5d1SDavid du Colombier #include <ip.h> 9*219b2ee8SDavid du Colombier #include <lock.h> 103e12c5d1SDavid du Colombier 113e12c5d1SDavid du Colombier enum 123e12c5d1SDavid du Colombier { 13*219b2ee8SDavid du Colombier Nreply= 8, 143e12c5d1SDavid du Colombier Maxreply= 256, 153e12c5d1SDavid du Colombier Maxrequest= 4*NAMELEN, 163e12c5d1SDavid du Colombier Ncache= 8, 173e12c5d1SDavid du Colombier 183e12c5d1SDavid du Colombier Qcs= 1, 193e12c5d1SDavid du Colombier }; 203e12c5d1SDavid du Colombier 213e12c5d1SDavid du Colombier typedef struct Mfile Mfile; 22*219b2ee8SDavid du Colombier typedef struct Mlist Mlist; 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 { 293e12c5d1SDavid du Colombier int busy; 30*219b2ee8SDavid du Colombier 313e12c5d1SDavid du Colombier char user[NAMELEN]; 323e12c5d1SDavid du Colombier Qid qid; 333e12c5d1SDavid du Colombier int fid; 343e12c5d1SDavid du Colombier 35*219b2ee8SDavid du Colombier int nreply; 36*219b2ee8SDavid du Colombier char *reply[Nreply]; 37*219b2ee8SDavid du Colombier int replylen[Nreply]; 38*219b2ee8SDavid du Colombier }; 39*219b2ee8SDavid du Colombier 40*219b2ee8SDavid du Colombier struct Mlist 41*219b2ee8SDavid du Colombier { 42*219b2ee8SDavid du Colombier Mlist *next; 43*219b2ee8SDavid du Colombier Mfile mf; 443e12c5d1SDavid du Colombier }; 453e12c5d1SDavid du Colombier 463e12c5d1SDavid du Colombier Fcall *rhp; 473e12c5d1SDavid du Colombier Fcall *thp; 48*219b2ee8SDavid du Colombier Mlist *mlist; 493e12c5d1SDavid du Colombier int mfd[2]; 503e12c5d1SDavid du Colombier char user[NAMELEN]; 513e12c5d1SDavid du Colombier int debug; 523e12c5d1SDavid du Colombier jmp_buf masterjmp; /* return through here after a slave process has been created */ 533e12c5d1SDavid du Colombier int *isslave; /* *isslave non-zero means this is a slave process */ 54bd389b36SDavid du Colombier char *dbfile; 553e12c5d1SDavid du Colombier 56*219b2ee8SDavid du Colombier void rsession(void); 573e12c5d1SDavid du Colombier void rflush(void); 583e12c5d1SDavid du Colombier void rattach(Mfile *); 593e12c5d1SDavid du Colombier void rclone(Mfile *); 603e12c5d1SDavid du Colombier char* rwalk(Mfile *); 613e12c5d1SDavid du Colombier void rclwalk(Mfile *); 623e12c5d1SDavid du Colombier void ropen(Mfile *); 633e12c5d1SDavid du Colombier void rcreate(Mfile *); 643e12c5d1SDavid du Colombier void rread(Mfile *); 653e12c5d1SDavid du Colombier void rwrite(Mfile *); 663e12c5d1SDavid du Colombier void rclunk(Mfile *); 673e12c5d1SDavid du Colombier void rremove(Mfile *); 683e12c5d1SDavid du Colombier void rstat(Mfile *); 693e12c5d1SDavid du Colombier void rauth(void); 703e12c5d1SDavid du Colombier void rwstat(Mfile *); 713e12c5d1SDavid du Colombier void sendmsg(char*); 723e12c5d1SDavid du Colombier void error(char*); 73*219b2ee8SDavid du Colombier void mountinit(char*, ulong); 743e12c5d1SDavid du Colombier void io(void); 753e12c5d1SDavid du Colombier void netinit(void); 763e12c5d1SDavid du Colombier void netadd(char*); 773e12c5d1SDavid du Colombier int lookup(Mfile*, char*, char*, char*); 78*219b2ee8SDavid du Colombier char *genquery(Mfile*, char*); 793e12c5d1SDavid du Colombier int mygetfields(char*, char**, int, char); 80bd389b36SDavid du Colombier int needproto(Network*, Ndbtuple*); 813e12c5d1SDavid du Colombier Ndbtuple* lookval(Ndbtuple*, Ndbtuple*, char*, char*); 823e12c5d1SDavid du Colombier Ndbtuple* reorder(Ndbtuple*, Ndbtuple*); 833e12c5d1SDavid du Colombier 84bd389b36SDavid du Colombier extern void paralloc(void); 85bd389b36SDavid du Colombier 863e12c5d1SDavid du Colombier char *mname[]={ 873e12c5d1SDavid du Colombier [Tnop] "Tnop", 883e12c5d1SDavid du Colombier [Tsession] "Tsession", 893e12c5d1SDavid du Colombier [Tflush] "Tflush", 903e12c5d1SDavid du Colombier [Tattach] "Tattach", 913e12c5d1SDavid du Colombier [Tclone] "Tclone", 923e12c5d1SDavid du Colombier [Twalk] "Twalk", 933e12c5d1SDavid du Colombier [Topen] "Topen", 943e12c5d1SDavid du Colombier [Tcreate] "Tcreate", 953e12c5d1SDavid du Colombier [Tclunk] "Tclunk", 963e12c5d1SDavid du Colombier [Tread] "Tread", 973e12c5d1SDavid du Colombier [Twrite] "Twrite", 983e12c5d1SDavid du Colombier [Tremove] "Tremove", 993e12c5d1SDavid du Colombier [Tstat] "Tstat", 1003e12c5d1SDavid du Colombier [Twstat] "Twstat", 1013e12c5d1SDavid du Colombier 0, 1023e12c5d1SDavid du Colombier }; 1033e12c5d1SDavid du Colombier 104bd389b36SDavid du Colombier Lock dblock; /* mutex on database operations */ 105bd389b36SDavid du Colombier 106*219b2ee8SDavid du Colombier char *logfile = "cs"; 107*219b2ee8SDavid du Colombier 108*219b2ee8SDavid du Colombier 1093e12c5d1SDavid du Colombier void 1103e12c5d1SDavid du Colombier main(int argc, char *argv[]) 1113e12c5d1SDavid du Colombier { 1123e12c5d1SDavid du Colombier Fcall rhdr; 1133e12c5d1SDavid du Colombier Fcall thdr; 114*219b2ee8SDavid du Colombier char *service = "#s/cs"; 115*219b2ee8SDavid du Colombier int justsetname; 1163e12c5d1SDavid du Colombier 117*219b2ee8SDavid du Colombier justsetname = 0; 1183e12c5d1SDavid du Colombier rhp = &rhdr; 1193e12c5d1SDavid du Colombier thp = &thdr; 1203e12c5d1SDavid du Colombier ARGBEGIN{ 1213e12c5d1SDavid du Colombier case 'd': 1223e12c5d1SDavid du Colombier debug = 1; 123*219b2ee8SDavid du Colombier service = "#s/dcs"; 1243e12c5d1SDavid du Colombier break; 125bd389b36SDavid du Colombier case 'f': 126bd389b36SDavid du Colombier dbfile = ARGF(); 127bd389b36SDavid du Colombier break; 128*219b2ee8SDavid du Colombier case 'n': 129*219b2ee8SDavid du Colombier justsetname = 1; 130*219b2ee8SDavid du Colombier break; 1313e12c5d1SDavid du Colombier }ARGEND 1323e12c5d1SDavid du Colombier USED(argc); 1333e12c5d1SDavid du Colombier USED(argv); 1343e12c5d1SDavid du Colombier 135*219b2ee8SDavid du Colombier if(justsetname){ 136*219b2ee8SDavid du Colombier netinit(); 137*219b2ee8SDavid du Colombier exits(0); 138*219b2ee8SDavid du Colombier } 139*219b2ee8SDavid du Colombier unmount(service, "/net"); 140*219b2ee8SDavid du Colombier remove(service); 141*219b2ee8SDavid du Colombier mountinit(service, MAFTER); 142*219b2ee8SDavid du Colombier 143*219b2ee8SDavid du Colombier lockinit(); 144*219b2ee8SDavid du Colombier fmtinstall('F', fcallconv); 1453e12c5d1SDavid du Colombier netinit(); 1463e12c5d1SDavid du Colombier 1473e12c5d1SDavid du Colombier io(); 148*219b2ee8SDavid du Colombier exits(0); 1493e12c5d1SDavid du Colombier } 1503e12c5d1SDavid du Colombier 1513e12c5d1SDavid du Colombier void 152*219b2ee8SDavid du Colombier mountinit(char *service, ulong flags) 1533e12c5d1SDavid du Colombier { 1543e12c5d1SDavid du Colombier int f; 1553e12c5d1SDavid du Colombier int p[2]; 1563e12c5d1SDavid du Colombier char buf[32]; 1573e12c5d1SDavid du Colombier 1583e12c5d1SDavid du Colombier if(pipe(p) < 0) 1593e12c5d1SDavid du Colombier error("pipe failed"); 160*219b2ee8SDavid du Colombier switch(rfork(RFFDG|RFPROC|RFNAMEG)){ 1613e12c5d1SDavid du Colombier case 0: 162*219b2ee8SDavid du Colombier close(p[1]); 1633e12c5d1SDavid du Colombier break; 1643e12c5d1SDavid du Colombier case -1: 1653e12c5d1SDavid du Colombier error("fork failed\n"); 1663e12c5d1SDavid du Colombier default: 1673e12c5d1SDavid du Colombier /* 1683e12c5d1SDavid du Colombier * make a /srv/cs 1693e12c5d1SDavid du Colombier */ 1703e12c5d1SDavid du Colombier f = create(service, 1, 0666); 1713e12c5d1SDavid du Colombier if(f < 0) 1723e12c5d1SDavid du Colombier error(service); 173bd389b36SDavid du Colombier snprint(buf, sizeof(buf), "%d", p[1]); 1743e12c5d1SDavid du Colombier if(write(f, buf, strlen(buf)) != strlen(buf)) 175*219b2ee8SDavid du Colombier error("write /srv/cs"); 1763e12c5d1SDavid du Colombier close(f); 1773e12c5d1SDavid du Colombier 1783e12c5d1SDavid du Colombier /* 1793e12c5d1SDavid du Colombier * put ourselves into the file system 1803e12c5d1SDavid du Colombier */ 181*219b2ee8SDavid du Colombier close(p[0]); 182*219b2ee8SDavid du Colombier if(mount(p[1], "/net", flags, "") < 0) 1833e12c5d1SDavid du Colombier error("mount failed\n"); 184*219b2ee8SDavid du Colombier _exits(0); 1853e12c5d1SDavid du Colombier } 1863e12c5d1SDavid du Colombier mfd[0] = mfd[1] = p[0]; 1873e12c5d1SDavid du Colombier } 1883e12c5d1SDavid du Colombier 1893e12c5d1SDavid du Colombier Mfile* 1903e12c5d1SDavid du Colombier newfid(int fid) 1913e12c5d1SDavid du Colombier { 192*219b2ee8SDavid du Colombier Mlist *f, *ff; 1933e12c5d1SDavid du Colombier Mfile *mf; 1943e12c5d1SDavid du Colombier 195*219b2ee8SDavid du Colombier ff = 0; 196*219b2ee8SDavid du Colombier for(f = mlist; f; f = f->next) 197*219b2ee8SDavid du Colombier if(f->mf.busy && f->mf.fid == fid) 198*219b2ee8SDavid du Colombier return &f->mf; 199*219b2ee8SDavid du Colombier else if(!ff && !f->mf.busy) 200*219b2ee8SDavid du Colombier ff = f; 201*219b2ee8SDavid du Colombier if(ff == 0){ 202*219b2ee8SDavid du Colombier ff = malloc(sizeof *f); 203*219b2ee8SDavid du Colombier if(ff == 0){ 204*219b2ee8SDavid du Colombier fprint(2, "cs: malloc(%d)\n", sizeof *ff); 205*219b2ee8SDavid du Colombier error("malloc failure"); 2063e12c5d1SDavid du Colombier } 207*219b2ee8SDavid du Colombier ff->next = mlist; 208*219b2ee8SDavid du Colombier mlist = ff; 2093e12c5d1SDavid du Colombier } 210*219b2ee8SDavid du Colombier mf = &ff->mf; 211*219b2ee8SDavid du Colombier memset(mf, 0, sizeof *mf); 2123e12c5d1SDavid du Colombier mf->fid = fid; 2133e12c5d1SDavid du Colombier return mf; 2143e12c5d1SDavid du Colombier } 2153e12c5d1SDavid du Colombier 2163e12c5d1SDavid du Colombier void 2173e12c5d1SDavid du Colombier io(void) 2183e12c5d1SDavid du Colombier { 2193e12c5d1SDavid du Colombier long n; 2203e12c5d1SDavid du Colombier Mfile *mf; 2213e12c5d1SDavid du Colombier int slaveflag; 2223e12c5d1SDavid du Colombier char mdata[MAXFDATA + MAXMSG]; 2233e12c5d1SDavid du Colombier 2243e12c5d1SDavid du Colombier /* 2253e12c5d1SDavid du Colombier * if we ask dns to fulfill requests, 2263e12c5d1SDavid du Colombier * a slave process is created to wait for replies. The 2273e12c5d1SDavid du Colombier * master process returns immediately via a longjmp's 2283e12c5d1SDavid du Colombier * through 'masterjmp'. 2293e12c5d1SDavid du Colombier * 2303e12c5d1SDavid du Colombier * *isslave is a pointer into the call stack to a variable 2313e12c5d1SDavid du Colombier * that tells whether or not the current process is a slave. 2323e12c5d1SDavid du Colombier */ 2333e12c5d1SDavid du Colombier slaveflag = 0; /* init slave variable */ 2343e12c5d1SDavid du Colombier isslave = &slaveflag; 2353e12c5d1SDavid du Colombier setjmp(masterjmp); 2363e12c5d1SDavid du Colombier 2373e12c5d1SDavid du Colombier for(;;){ 238*219b2ee8SDavid du Colombier n = read9p(mfd[0], mdata, sizeof mdata); 2393e12c5d1SDavid du Colombier if(n<=0) 2403e12c5d1SDavid du Colombier error("mount read"); 2413e12c5d1SDavid du Colombier if(convM2S(mdata, rhp, n) == 0){ 242*219b2ee8SDavid du Colombier syslog(1, logfile, "format error %ux %ux %ux %ux %ux", mdata[0], mdata[1], mdata[2], mdata[3], mdata[4]); 2433e12c5d1SDavid du Colombier continue; 2443e12c5d1SDavid du Colombier } 2453e12c5d1SDavid du Colombier if(rhp->fid<0) 2463e12c5d1SDavid du Colombier error("fid out of range"); 247bd389b36SDavid du Colombier lock(&dblock); 2483e12c5d1SDavid du Colombier mf = newfid(rhp->fid); 249*219b2ee8SDavid du Colombier if(debug) 250*219b2ee8SDavid du Colombier syslog(0, logfile, "%F", rhp); 2513e12c5d1SDavid du Colombier 2523e12c5d1SDavid du Colombier 2533e12c5d1SDavid du Colombier switch(rhp->type){ 2543e12c5d1SDavid du Colombier default: 255*219b2ee8SDavid du Colombier syslog(1, logfile, "unknown request type %d", rhp->type); 2563e12c5d1SDavid du Colombier break; 2573e12c5d1SDavid du Colombier case Tsession: 258*219b2ee8SDavid du Colombier rsession(); 2593e12c5d1SDavid du Colombier break; 2603e12c5d1SDavid du Colombier case Tnop: 2613e12c5d1SDavid du Colombier rflush(); 2623e12c5d1SDavid du Colombier break; 2633e12c5d1SDavid du Colombier case Tflush: 2643e12c5d1SDavid du Colombier rflush(); 2653e12c5d1SDavid du Colombier break; 2663e12c5d1SDavid du Colombier case Tattach: 2673e12c5d1SDavid du Colombier rattach(mf); 2683e12c5d1SDavid du Colombier break; 2693e12c5d1SDavid du Colombier case Tclone: 2703e12c5d1SDavid du Colombier rclone(mf); 2713e12c5d1SDavid du Colombier break; 2723e12c5d1SDavid du Colombier case Twalk: 2733e12c5d1SDavid du Colombier rwalk(mf); 2743e12c5d1SDavid du Colombier break; 2753e12c5d1SDavid du Colombier case Tclwalk: 2763e12c5d1SDavid du Colombier rclwalk(mf); 2773e12c5d1SDavid du Colombier break; 2783e12c5d1SDavid du Colombier case Topen: 2793e12c5d1SDavid du Colombier ropen(mf); 2803e12c5d1SDavid du Colombier break; 2813e12c5d1SDavid du Colombier case Tcreate: 2823e12c5d1SDavid du Colombier rcreate(mf); 2833e12c5d1SDavid du Colombier break; 2843e12c5d1SDavid du Colombier case Tread: 2853e12c5d1SDavid du Colombier rread(mf); 2863e12c5d1SDavid du Colombier break; 2873e12c5d1SDavid du Colombier case Twrite: 2883e12c5d1SDavid du Colombier rwrite(mf); 2893e12c5d1SDavid du Colombier break; 2903e12c5d1SDavid du Colombier case Tclunk: 2913e12c5d1SDavid du Colombier rclunk(mf); 2923e12c5d1SDavid du Colombier break; 2933e12c5d1SDavid du Colombier case Tremove: 2943e12c5d1SDavid du Colombier rremove(mf); 2953e12c5d1SDavid du Colombier break; 2963e12c5d1SDavid du Colombier case Tstat: 2973e12c5d1SDavid du Colombier rstat(mf); 2983e12c5d1SDavid du Colombier break; 2993e12c5d1SDavid du Colombier case Twstat: 3003e12c5d1SDavid du Colombier rwstat(mf); 3013e12c5d1SDavid du Colombier break; 3023e12c5d1SDavid du Colombier } 303bd389b36SDavid du Colombier unlock(&dblock); 3043e12c5d1SDavid du Colombier /* 3053e12c5d1SDavid du Colombier * slave processes die after replying 3063e12c5d1SDavid du Colombier */ 307*219b2ee8SDavid du Colombier if(*isslave){ 308*219b2ee8SDavid du Colombier if(debug) 309*219b2ee8SDavid du Colombier syslog(0, logfile, "slave death %d", getpid()); 3103e12c5d1SDavid du Colombier _exits(0); 3113e12c5d1SDavid du Colombier } 3123e12c5d1SDavid du Colombier } 313*219b2ee8SDavid du Colombier } 314*219b2ee8SDavid du Colombier 315*219b2ee8SDavid du Colombier void 316*219b2ee8SDavid du Colombier rsession(void) 317*219b2ee8SDavid du Colombier { 318*219b2ee8SDavid du Colombier memset(thp->authid, 0, sizeof(thp->authid)); 319*219b2ee8SDavid du Colombier memset(thp->authdom, 0, sizeof(thp->authdom)); 320*219b2ee8SDavid du Colombier memset(thp->chal, 0, sizeof(thp->chal)); 321*219b2ee8SDavid du Colombier sendmsg(0); 322*219b2ee8SDavid du Colombier } 3233e12c5d1SDavid du Colombier 3243e12c5d1SDavid du Colombier void 3253e12c5d1SDavid du Colombier rflush(void) /* synchronous so easy */ 3263e12c5d1SDavid du Colombier { 3273e12c5d1SDavid du Colombier sendmsg(0); 3283e12c5d1SDavid du Colombier } 3293e12c5d1SDavid du Colombier 3303e12c5d1SDavid du Colombier void 3313e12c5d1SDavid du Colombier rattach(Mfile *mf) 3323e12c5d1SDavid du Colombier { 3333e12c5d1SDavid du Colombier if(mf->busy == 0){ 3343e12c5d1SDavid du Colombier mf->busy = 1; 3353e12c5d1SDavid du Colombier strcpy(mf->user, rhp->uname); 3363e12c5d1SDavid du Colombier } 3373e12c5d1SDavid du Colombier mf->qid.vers = vers++; 3383e12c5d1SDavid du Colombier mf->qid.path = CHDIR; 3393e12c5d1SDavid du Colombier thp->qid = mf->qid; 3403e12c5d1SDavid du Colombier sendmsg(0); 3413e12c5d1SDavid du Colombier } 3423e12c5d1SDavid du Colombier 3433e12c5d1SDavid du Colombier void 3443e12c5d1SDavid du Colombier rclone(Mfile *mf) 3453e12c5d1SDavid du Colombier { 3463e12c5d1SDavid du Colombier Mfile *nmf; 3473e12c5d1SDavid du Colombier char *err=0; 3483e12c5d1SDavid du Colombier 3493e12c5d1SDavid du Colombier if(rhp->newfid<0){ 3503e12c5d1SDavid du Colombier err = "clone nfid out of range"; 3513e12c5d1SDavid du Colombier goto send; 3523e12c5d1SDavid du Colombier } 3533e12c5d1SDavid du Colombier nmf = newfid(rhp->newfid); 3543e12c5d1SDavid du Colombier if(nmf->busy){ 3553e12c5d1SDavid du Colombier err = "clone to used channel"; 3563e12c5d1SDavid du Colombier goto send; 3573e12c5d1SDavid du Colombier } 3583e12c5d1SDavid du Colombier *nmf = *mf; 3593e12c5d1SDavid du Colombier nmf->fid = rhp->newfid; 3603e12c5d1SDavid du Colombier nmf->qid.vers = vers++; 3613e12c5d1SDavid du Colombier send: 3623e12c5d1SDavid du Colombier sendmsg(err); 3633e12c5d1SDavid du Colombier } 3643e12c5d1SDavid du Colombier 3653e12c5d1SDavid du Colombier void 3663e12c5d1SDavid du Colombier rclwalk(Mfile *mf) 3673e12c5d1SDavid du Colombier { 3683e12c5d1SDavid du Colombier Mfile *nmf; 3693e12c5d1SDavid du Colombier 3703e12c5d1SDavid du Colombier if(rhp->newfid<0){ 3713e12c5d1SDavid du Colombier sendmsg("clone nfid out of range"); 3723e12c5d1SDavid du Colombier return; 3733e12c5d1SDavid du Colombier } 3743e12c5d1SDavid du Colombier nmf = newfid(rhp->newfid); 3753e12c5d1SDavid du Colombier if(nmf->busy){ 3763e12c5d1SDavid du Colombier sendmsg("clone to used channel"); 3773e12c5d1SDavid du Colombier return; 3783e12c5d1SDavid du Colombier } 3793e12c5d1SDavid du Colombier *nmf = *mf; 3803e12c5d1SDavid du Colombier nmf->fid = rhp->newfid; 3813e12c5d1SDavid du Colombier rhp->fid = rhp->newfid; 3823e12c5d1SDavid du Colombier nmf->qid.vers = vers++; 3833e12c5d1SDavid du Colombier if(rwalk(nmf)) 3843e12c5d1SDavid du Colombier nmf->busy = 0; 3853e12c5d1SDavid du Colombier } 3863e12c5d1SDavid du Colombier 3873e12c5d1SDavid du Colombier char* 3883e12c5d1SDavid du Colombier rwalk(Mfile *mf) 3893e12c5d1SDavid du Colombier { 3903e12c5d1SDavid du Colombier char *err; 3913e12c5d1SDavid du Colombier char *name; 3923e12c5d1SDavid du Colombier 3933e12c5d1SDavid du Colombier err = 0; 3943e12c5d1SDavid du Colombier name = rhp->name; 3953e12c5d1SDavid du Colombier if((mf->qid.path & CHDIR) == 0){ 3963e12c5d1SDavid du Colombier err = "not a directory"; 3973e12c5d1SDavid du Colombier goto send; 3983e12c5d1SDavid du Colombier } 3993e12c5d1SDavid du Colombier if(strcmp(name, ".") == 0){ 4003e12c5d1SDavid du Colombier mf->qid.path = CHDIR; 4013e12c5d1SDavid du Colombier goto send; 4023e12c5d1SDavid du Colombier } 4033e12c5d1SDavid du Colombier if(strcmp(name, "cs") == 0){ 4043e12c5d1SDavid du Colombier mf->qid.path = Qcs; 4053e12c5d1SDavid du Colombier goto send; 4063e12c5d1SDavid du Colombier } 4073e12c5d1SDavid du Colombier err = "nonexistent file"; 4083e12c5d1SDavid du Colombier send: 4093e12c5d1SDavid du Colombier thp->qid = mf->qid; 4103e12c5d1SDavid du Colombier sendmsg(err); 4113e12c5d1SDavid du Colombier return err; 4123e12c5d1SDavid du Colombier } 4133e12c5d1SDavid du Colombier 4143e12c5d1SDavid du Colombier void 4153e12c5d1SDavid du Colombier ropen(Mfile *mf) 4163e12c5d1SDavid du Colombier { 4173e12c5d1SDavid du Colombier int mode; 4183e12c5d1SDavid du Colombier char *err; 4193e12c5d1SDavid du Colombier 4203e12c5d1SDavid du Colombier err = 0; 4213e12c5d1SDavid du Colombier mode = rhp->mode; 4223e12c5d1SDavid du Colombier if(mf->qid.path & CHDIR){ 4233e12c5d1SDavid du Colombier if(mode) 4243e12c5d1SDavid du Colombier err = "permission denied"; 4253e12c5d1SDavid du Colombier } 4263e12c5d1SDavid du Colombier send: 4273e12c5d1SDavid du Colombier thp->qid = mf->qid; 4283e12c5d1SDavid du Colombier sendmsg(err); 4293e12c5d1SDavid du Colombier } 4303e12c5d1SDavid du Colombier 4313e12c5d1SDavid du Colombier void 4323e12c5d1SDavid du Colombier rcreate(Mfile *mf) 4333e12c5d1SDavid du Colombier { 4343e12c5d1SDavid du Colombier USED(mf); 4353e12c5d1SDavid du Colombier sendmsg("creation permission denied"); 4363e12c5d1SDavid du Colombier } 4373e12c5d1SDavid du Colombier 4383e12c5d1SDavid du Colombier void 4393e12c5d1SDavid du Colombier rread(Mfile *mf) 4403e12c5d1SDavid du Colombier { 441*219b2ee8SDavid du Colombier int i, n, cnt; 442*219b2ee8SDavid du Colombier long off, toff, clock; 4433e12c5d1SDavid du Colombier Dir dir; 4443e12c5d1SDavid du Colombier char buf[MAXFDATA]; 4453e12c5d1SDavid du Colombier char *err; 4463e12c5d1SDavid du Colombier 4473e12c5d1SDavid du Colombier n = 0; 4483e12c5d1SDavid du Colombier err = 0; 4493e12c5d1SDavid du Colombier off = rhp->offset; 4503e12c5d1SDavid du Colombier cnt = rhp->count; 4513e12c5d1SDavid du Colombier if(mf->qid.path & CHDIR){ 4523e12c5d1SDavid du Colombier if(off%DIRLEN || cnt%DIRLEN){ 4533e12c5d1SDavid du Colombier err = "bad offset"; 4543e12c5d1SDavid du Colombier goto send; 4553e12c5d1SDavid du Colombier } 4563e12c5d1SDavid du Colombier clock = time(0); 4573e12c5d1SDavid du Colombier if(off == 0){ 4583e12c5d1SDavid du Colombier memmove(dir.name, "cs", NAMELEN); 4593e12c5d1SDavid du Colombier dir.qid.vers = vers; 4603e12c5d1SDavid du Colombier dir.qid.path = Qcs; 4613e12c5d1SDavid du Colombier dir.mode = 0666; 4623e12c5d1SDavid du Colombier dir.length = 0; 4633e12c5d1SDavid du Colombier dir.hlength = 0; 4643e12c5d1SDavid du Colombier strcpy(dir.uid, mf->user); 4653e12c5d1SDavid du Colombier strcpy(dir.gid, mf->user); 4663e12c5d1SDavid du Colombier dir.atime = clock; /* wrong */ 4673e12c5d1SDavid du Colombier dir.mtime = clock; /* wrong */ 4683e12c5d1SDavid du Colombier convD2M(&dir, buf+n); 4693e12c5d1SDavid du Colombier n += DIRLEN; 4703e12c5d1SDavid du Colombier } 4713e12c5d1SDavid du Colombier thp->data = buf; 4723e12c5d1SDavid du Colombier } else { 473*219b2ee8SDavid du Colombier toff = 0; 474*219b2ee8SDavid du Colombier for(i = 0; mf->reply[i] && i < mf->nreply; i++){ 475*219b2ee8SDavid du Colombier n = mf->replylen[i]; 476*219b2ee8SDavid du Colombier if(off < toff + n) 477*219b2ee8SDavid du Colombier break; 478*219b2ee8SDavid du Colombier toff += n; 4793e12c5d1SDavid du Colombier } 480*219b2ee8SDavid du Colombier if(i >= mf->nreply){ 481*219b2ee8SDavid du Colombier n = 0; 482*219b2ee8SDavid du Colombier goto send; 483*219b2ee8SDavid du Colombier } 484*219b2ee8SDavid du Colombier thp->data = mf->reply[i] + (off - toff); 485*219b2ee8SDavid du Colombier if(cnt > toff - off + n) 486*219b2ee8SDavid du Colombier n = toff - off + n; 487*219b2ee8SDavid du Colombier else 488*219b2ee8SDavid du Colombier n = cnt; 4893e12c5d1SDavid du Colombier } 4903e12c5d1SDavid du Colombier send: 4913e12c5d1SDavid du Colombier thp->count = n; 4923e12c5d1SDavid du Colombier sendmsg(err); 4933e12c5d1SDavid du Colombier } 4943e12c5d1SDavid du Colombier 4953e12c5d1SDavid du Colombier void 4963e12c5d1SDavid du Colombier rwrite(Mfile *mf) 4973e12c5d1SDavid du Colombier { 4983e12c5d1SDavid du Colombier int cnt, n; 4993e12c5d1SDavid du Colombier char *err; 5003e12c5d1SDavid du Colombier char *field[3]; 5013e12c5d1SDavid du Colombier int rv; 5023e12c5d1SDavid du Colombier 5033e12c5d1SDavid du Colombier err = 0; 5043e12c5d1SDavid du Colombier cnt = rhp->count; 5053e12c5d1SDavid du Colombier if(mf->qid.path & CHDIR){ 5063e12c5d1SDavid du Colombier err = "can't write directory"; 5073e12c5d1SDavid du Colombier goto send; 5083e12c5d1SDavid du Colombier } 5093e12c5d1SDavid du Colombier if(cnt >= Maxrequest){ 5103e12c5d1SDavid du Colombier err = "request too long"; 5113e12c5d1SDavid du Colombier goto send; 5123e12c5d1SDavid du Colombier } 5133e12c5d1SDavid du Colombier rhp->data[cnt] = 0; 5143e12c5d1SDavid du Colombier 5153e12c5d1SDavid du Colombier /* 516*219b2ee8SDavid du Colombier * toggle debugging 517*219b2ee8SDavid du Colombier */ 518*219b2ee8SDavid du Colombier if(strncmp(rhp->data, "debug", 5)==0){ 519*219b2ee8SDavid du Colombier debug ^= 1; 520*219b2ee8SDavid du Colombier syslog(1, logfile, "debug %d", debug); 521*219b2ee8SDavid du Colombier goto send; 522*219b2ee8SDavid du Colombier } 523*219b2ee8SDavid du Colombier 524*219b2ee8SDavid du Colombier /* 5253e12c5d1SDavid du Colombier * add networks to the default list 5263e12c5d1SDavid du Colombier */ 5273e12c5d1SDavid du Colombier if(strncmp(rhp->data, "add ", 4)==0){ 5283e12c5d1SDavid du Colombier if(rhp->data[cnt-1] == '\n') 5293e12c5d1SDavid du Colombier rhp->data[cnt-1] = 0; 5303e12c5d1SDavid du Colombier netadd(rhp->data+4); 5313e12c5d1SDavid du Colombier goto send; 5323e12c5d1SDavid du Colombier } 5333e12c5d1SDavid du Colombier 5343e12c5d1SDavid du Colombier /* 535*219b2ee8SDavid du Colombier * look for a general query 536*219b2ee8SDavid du Colombier */ 537*219b2ee8SDavid du Colombier if(*rhp->data == '!'){ 538*219b2ee8SDavid du Colombier err = genquery(mf, rhp->data+1); 539*219b2ee8SDavid du Colombier goto send; 540*219b2ee8SDavid du Colombier } 541*219b2ee8SDavid du Colombier 542*219b2ee8SDavid du Colombier /* 5433e12c5d1SDavid du Colombier * break up name 5443e12c5d1SDavid du Colombier */ 5453e12c5d1SDavid du Colombier if(debug) 546*219b2ee8SDavid du Colombier syslog(0, logfile, "write %s", rhp->data); 5473e12c5d1SDavid du Colombier 5483e12c5d1SDavid du Colombier n = mygetfields(rhp->data, field, 3, '!'); 5493e12c5d1SDavid du Colombier rv = -1; 5503e12c5d1SDavid du Colombier switch(n){ 5513e12c5d1SDavid du Colombier case 1: 5523e12c5d1SDavid du Colombier rv = lookup(mf, "net", field[0], 0); 5533e12c5d1SDavid du Colombier break; 5543e12c5d1SDavid du Colombier case 2: 5553e12c5d1SDavid du Colombier rv = lookup(mf, field[0], field[1], 0); 5563e12c5d1SDavid du Colombier break; 5573e12c5d1SDavid du Colombier case 3: 5583e12c5d1SDavid du Colombier rv = lookup(mf, field[0], field[1], field[2]); 5593e12c5d1SDavid du Colombier break; 5603e12c5d1SDavid du Colombier } 5613e12c5d1SDavid du Colombier 5623e12c5d1SDavid du Colombier if(rv < 0) 5633e12c5d1SDavid du Colombier err = "can't translate address"; 5643e12c5d1SDavid du Colombier 5653e12c5d1SDavid du Colombier send: 5663e12c5d1SDavid du Colombier thp->count = cnt; 5673e12c5d1SDavid du Colombier sendmsg(err); 5683e12c5d1SDavid du Colombier } 5693e12c5d1SDavid du Colombier 5703e12c5d1SDavid du Colombier void 5713e12c5d1SDavid du Colombier rclunk(Mfile *mf) 5723e12c5d1SDavid du Colombier { 573*219b2ee8SDavid du Colombier int i; 574*219b2ee8SDavid du Colombier 575*219b2ee8SDavid du Colombier for(i = 0; i < mf->nreply; i++) 576*219b2ee8SDavid du Colombier free(mf->reply[i]); 5773e12c5d1SDavid du Colombier mf->busy = 0; 5783e12c5d1SDavid du Colombier mf->fid = 0; 5793e12c5d1SDavid du Colombier sendmsg(0); 5803e12c5d1SDavid du Colombier } 5813e12c5d1SDavid du Colombier 5823e12c5d1SDavid du Colombier void 5833e12c5d1SDavid du Colombier rremove(Mfile *mf) 5843e12c5d1SDavid du Colombier { 5853e12c5d1SDavid du Colombier USED(mf); 5863e12c5d1SDavid du Colombier sendmsg("remove permission denied"); 5873e12c5d1SDavid du Colombier } 5883e12c5d1SDavid du Colombier 5893e12c5d1SDavid du Colombier void 5903e12c5d1SDavid du Colombier rstat(Mfile *mf) 5913e12c5d1SDavid du Colombier { 5923e12c5d1SDavid du Colombier Dir dir; 5933e12c5d1SDavid du Colombier 594*219b2ee8SDavid du Colombier if(mf->qid.path & CHDIR){ 595*219b2ee8SDavid du Colombier strcpy(dir.name, "."); 596*219b2ee8SDavid du Colombier dir.mode = CHDIR|0555; 597*219b2ee8SDavid du Colombier } else { 598*219b2ee8SDavid du Colombier strcpy(dir.name, "cs"); 5993e12c5d1SDavid du Colombier dir.mode = 0666; 600*219b2ee8SDavid du Colombier } 601*219b2ee8SDavid du Colombier dir.qid = mf->qid; 6023e12c5d1SDavid du Colombier dir.length = 0; 6033e12c5d1SDavid du Colombier dir.hlength = 0; 6043e12c5d1SDavid du Colombier strcpy(dir.uid, mf->user); 6053e12c5d1SDavid du Colombier strcpy(dir.gid, mf->user); 6063e12c5d1SDavid du Colombier dir.atime = dir.mtime = time(0); 6073e12c5d1SDavid du Colombier convD2M(&dir, (char*)thp->stat); 6083e12c5d1SDavid du Colombier sendmsg(0); 6093e12c5d1SDavid du Colombier } 6103e12c5d1SDavid du Colombier 6113e12c5d1SDavid du Colombier void 6123e12c5d1SDavid du Colombier rwstat(Mfile *mf) 6133e12c5d1SDavid du Colombier { 6143e12c5d1SDavid du Colombier USED(mf); 6153e12c5d1SDavid du Colombier sendmsg("wstat permission denied"); 6163e12c5d1SDavid du Colombier } 6173e12c5d1SDavid du Colombier 6183e12c5d1SDavid du Colombier void 6193e12c5d1SDavid du Colombier sendmsg(char *err) 6203e12c5d1SDavid du Colombier { 6213e12c5d1SDavid du Colombier int n; 6223e12c5d1SDavid du Colombier char mdata[MAXFDATA + MAXMSG]; 6233e12c5d1SDavid du Colombier 6243e12c5d1SDavid du Colombier if(err){ 6253e12c5d1SDavid du Colombier thp->type = Rerror; 626bd389b36SDavid du Colombier snprint(thp->ename, sizeof(thp->ename), "cs: %s", err); 6273e12c5d1SDavid du Colombier }else{ 6283e12c5d1SDavid du Colombier thp->type = rhp->type+1; 6293e12c5d1SDavid du Colombier thp->fid = rhp->fid; 6303e12c5d1SDavid du Colombier } 6313e12c5d1SDavid du Colombier thp->tag = rhp->tag; 6323e12c5d1SDavid du Colombier n = convS2M(thp, mdata); 633*219b2ee8SDavid du Colombier if(n == 0){ 634*219b2ee8SDavid du Colombier syslog(1, logfile, "sendmsg convS2M of %F returns 0", thp); 635*219b2ee8SDavid du Colombier abort(); 636*219b2ee8SDavid du Colombier } 637*219b2ee8SDavid du Colombier if(write9p(mfd[1], mdata, n)!=n) 6383e12c5d1SDavid du Colombier error("mount write"); 639*219b2ee8SDavid du Colombier if(debug) 640*219b2ee8SDavid du Colombier syslog(0, logfile, "%F %d", thp, n); 6413e12c5d1SDavid du Colombier } 6423e12c5d1SDavid du Colombier 6433e12c5d1SDavid du Colombier void 6443e12c5d1SDavid du Colombier error(char *s) 6453e12c5d1SDavid du Colombier { 646bd389b36SDavid du Colombier syslog(1, "cs", "%s: %r", s); 647bd389b36SDavid du Colombier _exits(0); 6483e12c5d1SDavid du Colombier } 6493e12c5d1SDavid du Colombier 6503e12c5d1SDavid du Colombier /* 6513e12c5d1SDavid du Colombier * Network specific translators 6523e12c5d1SDavid du Colombier */ 653*219b2ee8SDavid du Colombier Ndbtuple* iplookup(Network*, char*, char*, int); 654*219b2ee8SDavid du Colombier char* iptrans(Ndbtuple*, Network*, char*); 655*219b2ee8SDavid du Colombier Ndbtuple* dklookup(Network*, char*, char*, int); 656*219b2ee8SDavid du Colombier char* dktrans(Ndbtuple*, Network*, char*); 657*219b2ee8SDavid du Colombier Ndbtuple* telcolookup(Network*, char*, char*, int); 658*219b2ee8SDavid du Colombier char* telcotrans(Ndbtuple*, Network*, char*); 6593e12c5d1SDavid du Colombier Ndbtuple* dnsiplookup(char*, Ndbs*, char*); 6603e12c5d1SDavid du Colombier 6613e12c5d1SDavid du Colombier struct Network 6623e12c5d1SDavid du Colombier { 6633e12c5d1SDavid du Colombier char *net; 6643e12c5d1SDavid du Colombier int nolookup; 665*219b2ee8SDavid du Colombier Ndbtuple *(*lookup)(Network*, char*, char*, int); 666*219b2ee8SDavid du Colombier char *(*trans)(Ndbtuple*, Network*, char*); 6673e12c5d1SDavid du Colombier int needproto; 6683e12c5d1SDavid du Colombier Network *next; 6693e12c5d1SDavid du Colombier int def; 6703e12c5d1SDavid du Colombier }; 6713e12c5d1SDavid du Colombier 6723e12c5d1SDavid du Colombier Network network[] = { 6733e12c5d1SDavid du Colombier { "il", 0, iplookup, iptrans, 1, }, 674*219b2ee8SDavid du Colombier { "fil", 0, iplookup, iptrans, 1, }, 6753e12c5d1SDavid du Colombier { "tcp", 0, iplookup, iptrans, 0, }, 6763e12c5d1SDavid du Colombier { "udp", 0, iplookup, iptrans, 0, }, 6773e12c5d1SDavid du Colombier { "dk", 1, dklookup, dktrans, 0, }, 678*219b2ee8SDavid du Colombier { "telco", 0, telcolookup, telcotrans, 0, }, 6793e12c5d1SDavid du Colombier { 0, 0, 0, 0, 0, }, 6803e12c5d1SDavid du Colombier }; 6813e12c5d1SDavid du Colombier 6823e12c5d1SDavid du Colombier char eaddr[Ndbvlen]; /* ascii ethernet address */ 6833e12c5d1SDavid du Colombier char ipaddr[Ndbvlen]; /* ascii internet address */ 6843e12c5d1SDavid du Colombier char dknet[Ndbvlen]; /* ascii datakit network name */ 6853e12c5d1SDavid du Colombier uchar ipa[4]; /* binary internet address */ 6863e12c5d1SDavid du Colombier char sysname[Ndbvlen]; 6873e12c5d1SDavid du Colombier int isdk; 6883e12c5d1SDavid du Colombier 6893e12c5d1SDavid du Colombier Network *netlist; /* networks ordered by preference */ 6903e12c5d1SDavid du Colombier Network *last; 6913e12c5d1SDavid du Colombier 6923e12c5d1SDavid du Colombier static Ndb *db; 6933e12c5d1SDavid du Colombier 6943e12c5d1SDavid du Colombier 6953e12c5d1SDavid du Colombier /* 6963e12c5d1SDavid du Colombier * get ip address and system name 6973e12c5d1SDavid du Colombier */ 6983e12c5d1SDavid du Colombier void 6993e12c5d1SDavid du Colombier ipid(void) 7003e12c5d1SDavid du Colombier { 7013e12c5d1SDavid du Colombier uchar addr[6]; 7023e12c5d1SDavid du Colombier Ndbtuple *t; 703*219b2ee8SDavid du Colombier char *p, *attr; 7043e12c5d1SDavid du Colombier Ndbs s; 7053e12c5d1SDavid du Colombier int f; 7063e12c5d1SDavid du Colombier static int isether; 7073e12c5d1SDavid du Colombier 7083e12c5d1SDavid du Colombier /* grab ether addr from the device */ 7093e12c5d1SDavid du Colombier if(isether == 0){ 7103e12c5d1SDavid du Colombier if(myetheraddr(addr, "/net/ether") >= 0){ 711bd389b36SDavid du Colombier snprint(eaddr, sizeof(eaddr), "%E", addr); 7123e12c5d1SDavid du Colombier isether = 1; 7133e12c5d1SDavid du Colombier } 7143e12c5d1SDavid du Colombier } 7153e12c5d1SDavid du Colombier 7163e12c5d1SDavid du Colombier /* grab ip addr from the device */ 7173e12c5d1SDavid du Colombier if(*ipa == 0){ 7183e12c5d1SDavid du Colombier if(myipaddr(ipa, "/net/tcp") >= 0){ 7193e12c5d1SDavid du Colombier if(*ipa) 720bd389b36SDavid du Colombier snprint(ipaddr, sizeof(ipaddr), "%I", ipa); 7213e12c5d1SDavid du Colombier } 7223e12c5d1SDavid du Colombier } 7233e12c5d1SDavid du Colombier 7243e12c5d1SDavid du Colombier /* use ether addr plus db to get ipaddr */ 7253e12c5d1SDavid du Colombier if(*ipa == 0 && isether){ 7263e12c5d1SDavid du Colombier t = ndbgetval(db, &s, "ether", eaddr, "ip", ipaddr); 7273e12c5d1SDavid du Colombier if(t){ 7283e12c5d1SDavid du Colombier ndbfree(t); 7293e12c5d1SDavid du Colombier parseip(ipa, ipaddr); 7303e12c5d1SDavid du Colombier } 7313e12c5d1SDavid du Colombier } 7323e12c5d1SDavid du Colombier 733*219b2ee8SDavid du Colombier /* use environment, ether addr, or ipaddr to get system name */ 7343e12c5d1SDavid du Colombier if(*sysname == 0){ 735*219b2ee8SDavid du Colombier /* environment has priority */ 736*219b2ee8SDavid du Colombier p = getenv("sysname"); 737*219b2ee8SDavid du Colombier if(p ){ 738*219b2ee8SDavid du Colombier attr = ipattr(p); 739*219b2ee8SDavid du Colombier if(strcmp(attr, "ip") != 0) 740*219b2ee8SDavid du Colombier strcpy(sysname, p); 741*219b2ee8SDavid du Colombier } 742*219b2ee8SDavid du Colombier 743*219b2ee8SDavid du Colombier /* next use ether and ip addresses to find system name */ 744*219b2ee8SDavid du Colombier if(*sysname == 0){ 7453e12c5d1SDavid du Colombier t = 0; 7463e12c5d1SDavid du Colombier if(isether) 7473e12c5d1SDavid du Colombier t = ndbgetval(db, &s, "ether", eaddr, "sys", sysname); 7483e12c5d1SDavid du Colombier if(t == 0 && *ipa) 7493e12c5d1SDavid du Colombier t = ndbgetval(db, &s, "ip", ipaddr, "sys", sysname); 750*219b2ee8SDavid du Colombier if(t) 751*219b2ee8SDavid du Colombier ndbfree(t); 752*219b2ee8SDavid du Colombier } 7533e12c5d1SDavid du Colombier 7543e12c5d1SDavid du Colombier /* set /dev/sysname if we now know it */ 755*219b2ee8SDavid du Colombier if(*sysname){ 7563e12c5d1SDavid du Colombier f = open("/dev/sysname", OWRITE); 7573e12c5d1SDavid du Colombier if(f >= 0){ 7583e12c5d1SDavid du Colombier write(f, sysname, strlen(sysname)); 7593e12c5d1SDavid du Colombier close(f); 7603e12c5d1SDavid du Colombier } 7613e12c5d1SDavid du Colombier } 7623e12c5d1SDavid du Colombier } 7633e12c5d1SDavid du Colombier } 7643e12c5d1SDavid du Colombier 7653e12c5d1SDavid du Colombier /* 7663e12c5d1SDavid du Colombier * set the datakit network name from a datakit network address 7673e12c5d1SDavid du Colombier */ 7683e12c5d1SDavid du Colombier int 7693e12c5d1SDavid du Colombier setdknet(char *x) 7703e12c5d1SDavid du Colombier { 7713e12c5d1SDavid du Colombier char *p; 7723e12c5d1SDavid du Colombier 7733e12c5d1SDavid du Colombier strncpy(dknet, x, sizeof(dknet)-2); 7743e12c5d1SDavid du Colombier p = strrchr(dknet, '/'); 7753e12c5d1SDavid du Colombier if(p == 0 || p == strchr(dknet, '/')){ 7763e12c5d1SDavid du Colombier *dknet = 0; 7773e12c5d1SDavid du Colombier return 0; 7783e12c5d1SDavid du Colombier } 7793e12c5d1SDavid du Colombier *++p = '*'; 7803e12c5d1SDavid du Colombier *(p+1) = 0; 7813e12c5d1SDavid du Colombier return 1; 7823e12c5d1SDavid du Colombier } 7833e12c5d1SDavid du Colombier 7843e12c5d1SDavid du Colombier /* 7853e12c5d1SDavid du Colombier * get datakit address 7863e12c5d1SDavid du Colombier */ 7873e12c5d1SDavid du Colombier void 7883e12c5d1SDavid du Colombier dkid(void) 7893e12c5d1SDavid du Colombier { 7903e12c5d1SDavid du Colombier Ndbtuple *t; 7913e12c5d1SDavid du Colombier Ndbs s; 7923e12c5d1SDavid du Colombier char dkname[Ndbvlen]; 7933e12c5d1SDavid du Colombier char raddr[Ndbvlen]; 7943e12c5d1SDavid du Colombier int i, f, n; 7953e12c5d1SDavid du Colombier static int isdknet; 7963e12c5d1SDavid du Colombier 7973e12c5d1SDavid du Colombier /* try for a datakit network name in the database */ 7983e12c5d1SDavid du Colombier if(isdknet == 0){ 7993e12c5d1SDavid du Colombier /* use ether and ip addresses to find dk name */ 8003e12c5d1SDavid du Colombier t = 0; 8013e12c5d1SDavid du Colombier if(t == 0 && *ipa) 8023e12c5d1SDavid du Colombier t = ndbgetval(db, &s, "ip", ipaddr, "dk", dkname); 8033e12c5d1SDavid du Colombier if(t == 0 && *sysname) 8043e12c5d1SDavid du Colombier t = ndbgetval(db, &s, "sys", sysname, "dk", dkname); 8053e12c5d1SDavid du Colombier if(t){ 8063e12c5d1SDavid du Colombier ndbfree(t); 8073e12c5d1SDavid du Colombier isdknet = setdknet(dkname); 8083e12c5d1SDavid du Colombier } 8093e12c5d1SDavid du Colombier } 8103e12c5d1SDavid du Colombier 8113e12c5d1SDavid du Colombier /* try for a datakit network name from a system we've connected to */ 8123e12c5d1SDavid du Colombier if(isdknet == 0){ 8133e12c5d1SDavid du Colombier for(i = 0; isdknet == 0 && i < 7; i++){ 814bd389b36SDavid du Colombier snprint(raddr, sizeof(raddr), "/net/dk/%d/remote", i); 8153e12c5d1SDavid du Colombier f = open(raddr, OREAD); 8163e12c5d1SDavid du Colombier if(f < 0){ 8173e12c5d1SDavid du Colombier isdknet = -1; 8183e12c5d1SDavid du Colombier break; 8193e12c5d1SDavid du Colombier } 8203e12c5d1SDavid du Colombier n = read(f, raddr, sizeof(raddr)-1); 8213e12c5d1SDavid du Colombier close(f); 8223e12c5d1SDavid du Colombier if(n > 0){ 8233e12c5d1SDavid du Colombier raddr[n] = 0; 8243e12c5d1SDavid du Colombier isdknet = setdknet(raddr); 8253e12c5d1SDavid du Colombier } 8263e12c5d1SDavid du Colombier } 8273e12c5d1SDavid du Colombier } 828*219b2ee8SDavid du Colombier /* hack for gnots */ 829*219b2ee8SDavid du Colombier if(isdknet <= 0) 830*219b2ee8SDavid du Colombier isdknet = setdknet("nj/astro/Nfs"); 8313e12c5d1SDavid du Colombier } 8323e12c5d1SDavid du Colombier 8333e12c5d1SDavid du Colombier /* 8343e12c5d1SDavid du Colombier * Set up a list of default networks by looking for 8353e12c5d1SDavid du Colombier * /net/ * /clone. 8363e12c5d1SDavid du Colombier */ 8373e12c5d1SDavid du Colombier void 8383e12c5d1SDavid du Colombier netinit(void) 8393e12c5d1SDavid du Colombier { 8403e12c5d1SDavid du Colombier char clone[256]; 8413e12c5d1SDavid du Colombier Dir d; 8423e12c5d1SDavid du Colombier Network *np; 8433e12c5d1SDavid du Colombier 8443e12c5d1SDavid du Colombier /* add the mounted networks to the default list */ 8453e12c5d1SDavid du Colombier for(np = network; np->net; np++){ 846bd389b36SDavid du Colombier snprint(clone, sizeof(clone), "/net/%s/clone", np->net); 8473e12c5d1SDavid du Colombier if(dirstat(clone, &d) < 0) 8483e12c5d1SDavid du Colombier continue; 8493e12c5d1SDavid du Colombier if(netlist) 8503e12c5d1SDavid du Colombier last->next = np; 8513e12c5d1SDavid du Colombier else 8523e12c5d1SDavid du Colombier netlist = np; 8533e12c5d1SDavid du Colombier last = np; 8543e12c5d1SDavid du Colombier np->next = 0; 8553e12c5d1SDavid du Colombier np->def = 1; 8563e12c5d1SDavid du Colombier } 8573e12c5d1SDavid du Colombier 8583e12c5d1SDavid du Colombier fmtinstall('E', eipconv); 8593e12c5d1SDavid du Colombier fmtinstall('I', eipconv); 8603e12c5d1SDavid du Colombier 861bd389b36SDavid du Colombier db = ndbopen(dbfile); 8623e12c5d1SDavid du Colombier ipid(); 8633e12c5d1SDavid du Colombier dkid(); 8643e12c5d1SDavid du Colombier 865*219b2ee8SDavid du Colombier if(debug) 866*219b2ee8SDavid du Colombier syslog(0, logfile, "sysname %s dknet %s eaddr %s ipaddr %s ipa %I\n", 8673e12c5d1SDavid du Colombier sysname, dknet, eaddr, ipaddr, ipa); 8683e12c5d1SDavid du Colombier } 8693e12c5d1SDavid du Colombier 8703e12c5d1SDavid du Colombier /* 8713e12c5d1SDavid du Colombier * add networks to the standard list 8723e12c5d1SDavid du Colombier */ 8733e12c5d1SDavid du Colombier void 8743e12c5d1SDavid du Colombier netadd(char *p) 8753e12c5d1SDavid du Colombier { 8763e12c5d1SDavid du Colombier Network *np; 8773e12c5d1SDavid du Colombier char *field[12]; 8783e12c5d1SDavid du Colombier int i, n; 8793e12c5d1SDavid du Colombier 8803e12c5d1SDavid du Colombier n = mygetfields(p, field, 12, ' '); 8813e12c5d1SDavid du Colombier for(i = 0; i < n; i++){ 8823e12c5d1SDavid du Colombier for(np = network; np->net; np++){ 8833e12c5d1SDavid du Colombier if(strcmp(field[i], np->net) != 0) 8843e12c5d1SDavid du Colombier continue; 8853e12c5d1SDavid du Colombier if(np->def) 8863e12c5d1SDavid du Colombier break; 8873e12c5d1SDavid du Colombier if(netlist) 8883e12c5d1SDavid du Colombier last->next = np; 8893e12c5d1SDavid du Colombier else 8903e12c5d1SDavid du Colombier netlist = np; 8913e12c5d1SDavid du Colombier last = np; 8923e12c5d1SDavid du Colombier np->next = 0; 8933e12c5d1SDavid du Colombier np->def = 1; 8943e12c5d1SDavid du Colombier } 8953e12c5d1SDavid du Colombier } 8963e12c5d1SDavid du Colombier } 8973e12c5d1SDavid du Colombier 8983e12c5d1SDavid du Colombier /* 899*219b2ee8SDavid du Colombier * make a tuple 900*219b2ee8SDavid du Colombier */ 901*219b2ee8SDavid du Colombier Ndbtuple* 902*219b2ee8SDavid du Colombier mktuple(char *attr, char *val) 903*219b2ee8SDavid du Colombier { 904*219b2ee8SDavid du Colombier Ndbtuple *t; 905*219b2ee8SDavid du Colombier 906*219b2ee8SDavid du Colombier t = malloc(sizeof(Ndbtuple)); 907*219b2ee8SDavid du Colombier strcpy(t->attr, attr); 908*219b2ee8SDavid du Colombier strncpy(t->val, val, sizeof(t->val)); 909*219b2ee8SDavid du Colombier t->val[sizeof(t->val)-1] = 0; 910*219b2ee8SDavid du Colombier t->line = t; 911*219b2ee8SDavid du Colombier t->entry = 0; 912*219b2ee8SDavid du Colombier return t; 913*219b2ee8SDavid du Colombier } 914*219b2ee8SDavid du Colombier 915*219b2ee8SDavid du Colombier /* 9163e12c5d1SDavid du Colombier * lookup a request. the network "net" means we should pick the 9173e12c5d1SDavid du Colombier * best network to get there. 9183e12c5d1SDavid du Colombier */ 9193e12c5d1SDavid du Colombier int 9203e12c5d1SDavid du Colombier lookup(Mfile *mf, char *net, char *host, char *serv) 9213e12c5d1SDavid du Colombier { 922*219b2ee8SDavid du Colombier Network *np, *p; 923*219b2ee8SDavid du Colombier char *cp; 924*219b2ee8SDavid du Colombier Ndbtuple *nt, *t; 925*219b2ee8SDavid du Colombier int i; 926*219b2ee8SDavid du Colombier char reply[Maxreply]; 9273e12c5d1SDavid du Colombier 9283e12c5d1SDavid du Colombier /* start transaction with a clean slate */ 929*219b2ee8SDavid du Colombier for(i = 0; i < Nreply; i++){ 930*219b2ee8SDavid du Colombier if(mf->reply[i]) 931*219b2ee8SDavid du Colombier free(mf->reply[i]); 932*219b2ee8SDavid du Colombier mf->reply[i] = 0; 933*219b2ee8SDavid du Colombier mf->replylen[i] = 0; 9343e12c5d1SDavid du Colombier } 935*219b2ee8SDavid du Colombier mf->nreply = 0; 9363e12c5d1SDavid du Colombier 9373e12c5d1SDavid du Colombier /* open up the standard db files */ 9383e12c5d1SDavid du Colombier if(db == 0) 939bd389b36SDavid du Colombier db = ndbopen(dbfile); 9403e12c5d1SDavid du Colombier if(db == 0) 9413e12c5d1SDavid du Colombier error("can't open network database\n"); 9423e12c5d1SDavid du Colombier 943*219b2ee8SDavid du Colombier nt = 0; 9443e12c5d1SDavid du Colombier if(strcmp(net, "net") == 0){ 9453e12c5d1SDavid du Colombier /* 9463e12c5d1SDavid du Colombier * go through set of default nets 9473e12c5d1SDavid du Colombier */ 9483e12c5d1SDavid du Colombier for(np = netlist; np; np = np->next){ 949*219b2ee8SDavid du Colombier nt = (*np->lookup)(np, host, serv, 0); 950*219b2ee8SDavid du Colombier if(nt){ 951*219b2ee8SDavid du Colombier if(needproto(np, nt) == 0) 952*219b2ee8SDavid du Colombier break; 953*219b2ee8SDavid du Colombier ndbfree(nt); 954*219b2ee8SDavid du Colombier nt = 0; 955bd389b36SDavid du Colombier } 9563e12c5d1SDavid du Colombier } 9573e12c5d1SDavid du Colombier 9583e12c5d1SDavid du Colombier /* 9593e12c5d1SDavid du Colombier * try first net that requires no table lookup 9603e12c5d1SDavid du Colombier */ 961*219b2ee8SDavid du Colombier if(nt == 0) 9623e12c5d1SDavid du Colombier for(np = netlist; np; np = np->next){ 9633e12c5d1SDavid du Colombier if(np->nolookup && *host != '$'){ 964*219b2ee8SDavid du Colombier nt = (*np->lookup)(np, host, serv, 1); 965*219b2ee8SDavid du Colombier if(nt) 9663e12c5d1SDavid du Colombier break; 9673e12c5d1SDavid du Colombier } 9683e12c5d1SDavid du Colombier } 9693e12c5d1SDavid du Colombier 970*219b2ee8SDavid du Colombier if(nt == 0) 9713e12c5d1SDavid du Colombier return -1; 972*219b2ee8SDavid du Colombier 973*219b2ee8SDavid du Colombier /* 974*219b2ee8SDavid du Colombier * create replies 975*219b2ee8SDavid du Colombier */ 976*219b2ee8SDavid du Colombier for(p = np; p; p = p->next){ 977*219b2ee8SDavid du Colombier for(t = nt; mf->nreply < Nreply && t; t = t->entry){ 978*219b2ee8SDavid du Colombier if(needproto(p, nt) < 0) 979*219b2ee8SDavid du Colombier continue; 980*219b2ee8SDavid du Colombier cp = (*p->trans)(t, p, serv); 981*219b2ee8SDavid du Colombier if(cp){ 982*219b2ee8SDavid du Colombier mf->replylen[mf->nreply] = strlen(cp); 983*219b2ee8SDavid du Colombier mf->reply[mf->nreply++] = cp; 984*219b2ee8SDavid du Colombier } 985*219b2ee8SDavid du Colombier } 986*219b2ee8SDavid du Colombier } 987*219b2ee8SDavid du Colombier for(p = netlist; mf->nreply < Nreply && p != np; p = p->next){ 988*219b2ee8SDavid du Colombier for(t = nt; mf->nreply < Nreply && t; t = t->entry){ 989*219b2ee8SDavid du Colombier if(needproto(p, nt) < 0) 990*219b2ee8SDavid du Colombier continue; 991*219b2ee8SDavid du Colombier cp = (*p->trans)(t, p, serv); 992*219b2ee8SDavid du Colombier if(cp){ 993*219b2ee8SDavid du Colombier mf->replylen[mf->nreply] = strlen(cp); 994*219b2ee8SDavid du Colombier mf->reply[mf->nreply++] = cp; 995*219b2ee8SDavid du Colombier } 996*219b2ee8SDavid du Colombier } 997*219b2ee8SDavid du Colombier } 998*219b2ee8SDavid du Colombier ndbfree(nt); 999*219b2ee8SDavid du Colombier return 0; 10003e12c5d1SDavid du Colombier } else { 10013e12c5d1SDavid du Colombier /* 10023e12c5d1SDavid du Colombier * look on a specific network 10033e12c5d1SDavid du Colombier */ 1004*219b2ee8SDavid du Colombier for(p = network; p->net; p++){ 1005*219b2ee8SDavid du Colombier if(strcmp(p->net, net) == 0){ 1006*219b2ee8SDavid du Colombier nt = (*p->lookup)(p, host, serv, 1); 1007*219b2ee8SDavid du Colombier if (nt == 0) 1008*219b2ee8SDavid du Colombier return -1; 1009*219b2ee8SDavid du Colombier 1010*219b2ee8SDavid du Colombier /* create replies */ 1011*219b2ee8SDavid du Colombier for(t = nt; mf->nreply < Nreply && t; t = t->entry){ 1012*219b2ee8SDavid du Colombier cp = (*p->trans)(t, p, serv); 1013*219b2ee8SDavid du Colombier if(cp){ 1014*219b2ee8SDavid du Colombier mf->replylen[mf->nreply] = strlen(cp); 1015*219b2ee8SDavid du Colombier mf->reply[mf->nreply++] = cp; 1016*219b2ee8SDavid du Colombier } 1017*219b2ee8SDavid du Colombier } 1018*219b2ee8SDavid du Colombier ndbfree(nt); 1019*219b2ee8SDavid du Colombier return 0; 10203e12c5d1SDavid du Colombier } 10213e12c5d1SDavid du Colombier } 10223e12c5d1SDavid du Colombier } 10233e12c5d1SDavid du Colombier 10243e12c5d1SDavid du Colombier /* 1025*219b2ee8SDavid du Colombier * not a known network, don't translate host or service 10263e12c5d1SDavid du Colombier */ 10273e12c5d1SDavid du Colombier if(serv) 1028*219b2ee8SDavid du Colombier snprint(reply, sizeof(reply), "/net/%s/clone %s!%s", 1029bd389b36SDavid du Colombier net, host, serv); 1030bd389b36SDavid du Colombier else 1031*219b2ee8SDavid du Colombier snprint(reply, sizeof(reply), "/net/%s/clone %s", 1032bd389b36SDavid du Colombier net, host); 1033*219b2ee8SDavid du Colombier mf->reply[0] = strdup(reply); 1034*219b2ee8SDavid du Colombier mf->replylen[0] = strlen(reply); 1035*219b2ee8SDavid du Colombier mf->nreply = 1; 10363e12c5d1SDavid du Colombier return 0; 10373e12c5d1SDavid du Colombier } 10383e12c5d1SDavid du Colombier 10393e12c5d1SDavid du Colombier /* 10403e12c5d1SDavid du Colombier * see if we can use this protocol 10413e12c5d1SDavid du Colombier */ 10423e12c5d1SDavid du Colombier int 10433e12c5d1SDavid du Colombier needproto(Network *np, Ndbtuple *t) 10443e12c5d1SDavid du Colombier { 10453e12c5d1SDavid du Colombier if(np->needproto == 0) 10463e12c5d1SDavid du Colombier return 0; 10473e12c5d1SDavid du Colombier for(; t; t = t->entry) 10483e12c5d1SDavid du Colombier if(strcmp(t->attr, "proto")==0 && strcmp(t->val, np->net)==0) 10493e12c5d1SDavid du Colombier return 0; 10503e12c5d1SDavid du Colombier return -1; 10513e12c5d1SDavid du Colombier } 10523e12c5d1SDavid du Colombier 10533e12c5d1SDavid du Colombier /* 10543e12c5d1SDavid du Colombier * translate an ip service name into a port number. If it's a numeric port 10553e12c5d1SDavid du Colombier * number, look for restricted access. 10563e12c5d1SDavid du Colombier * 10573e12c5d1SDavid du Colombier * the service '*' needs no translation. 10583e12c5d1SDavid du Colombier */ 10593e12c5d1SDavid du Colombier char* 10603e12c5d1SDavid du Colombier ipserv(Network *np, char *name, char *buf) 10613e12c5d1SDavid du Colombier { 10623e12c5d1SDavid du Colombier char *p; 10633e12c5d1SDavid du Colombier int alpha = 0; 10643e12c5d1SDavid du Colombier int restr = 0; 10653e12c5d1SDavid du Colombier char port[Ndbvlen]; 10663e12c5d1SDavid du Colombier Ndbtuple *t, *nt; 10673e12c5d1SDavid du Colombier Ndbs s; 10683e12c5d1SDavid du Colombier 10693e12c5d1SDavid du Colombier /* '*' means any service */ 10703e12c5d1SDavid du Colombier if(strcmp(name, "*")==0){ 10713e12c5d1SDavid du Colombier strcpy(buf, name); 10723e12c5d1SDavid du Colombier return buf; 10733e12c5d1SDavid du Colombier } 10743e12c5d1SDavid du Colombier 10753e12c5d1SDavid du Colombier /* see if it's numeric or symbolic */ 10763e12c5d1SDavid du Colombier port[0] = 0; 10773e12c5d1SDavid du Colombier for(p = name; *p; p++){ 10783e12c5d1SDavid du Colombier if(isdigit(*p)) 10793e12c5d1SDavid du Colombier ; 10803e12c5d1SDavid du Colombier else if(isalpha(*p) || *p == '-' || *p == '$') 10813e12c5d1SDavid du Colombier alpha = 1; 10823e12c5d1SDavid du Colombier else 10833e12c5d1SDavid du Colombier return 0; 10843e12c5d1SDavid du Colombier } 10853e12c5d1SDavid du Colombier if(alpha){ 10863e12c5d1SDavid du Colombier t = ndbgetval(db, &s, np->net, name, "port", port); 10873e12c5d1SDavid du Colombier if(t == 0) 10883e12c5d1SDavid du Colombier return 0; 10893e12c5d1SDavid du Colombier } else { 10903e12c5d1SDavid du Colombier t = ndbgetval(db, &s, "port", name, "port", port); 10913e12c5d1SDavid du Colombier if(t == 0){ 10923e12c5d1SDavid du Colombier strncpy(port, name, sizeof(port)); 10933e12c5d1SDavid du Colombier port[sizeof(port)-1] = 0; 10943e12c5d1SDavid du Colombier } 10953e12c5d1SDavid du Colombier } 10963e12c5d1SDavid du Colombier 10973e12c5d1SDavid du Colombier if(t){ 10983e12c5d1SDavid du Colombier for(nt = t; nt; nt = nt->entry) 10993e12c5d1SDavid du Colombier if(strcmp(nt->attr, "restricted") == 0) 11003e12c5d1SDavid du Colombier restr = 1; 11013e12c5d1SDavid du Colombier ndbfree(t); 11023e12c5d1SDavid du Colombier } 11033e12c5d1SDavid du Colombier sprint(buf, "%s%s", port, restr ? "!r" : ""); 11043e12c5d1SDavid du Colombier return buf; 11053e12c5d1SDavid du Colombier } 11063e12c5d1SDavid du Colombier 11073e12c5d1SDavid du Colombier /* 11083e12c5d1SDavid du Colombier * look for the value associated with this attribute for our system. 11093e12c5d1SDavid du Colombier * the precedence is highest to lowest: 11103e12c5d1SDavid du Colombier * - an attr/value pair in this system's entry 11113e12c5d1SDavid du Colombier * - an attr/value pair in this system's subnet entry 11123e12c5d1SDavid du Colombier * - an attr/value pair in this system's net entry 11133e12c5d1SDavid du Colombier */ 11143e12c5d1SDavid du Colombier void 11153e12c5d1SDavid du Colombier ipattrlookup(char *attr, char *buf) 11163e12c5d1SDavid du Colombier { 11173e12c5d1SDavid du Colombier Ndbtuple *t, *st; 11183e12c5d1SDavid du Colombier Ndbs s, ss; 11193e12c5d1SDavid du Colombier char ip[Ndbvlen+1]; 11203e12c5d1SDavid du Colombier uchar net[4]; 11213e12c5d1SDavid du Colombier uchar mask[4]; 11223e12c5d1SDavid du Colombier 11233e12c5d1SDavid du Colombier *buf = 0; 11243e12c5d1SDavid du Colombier 11253e12c5d1SDavid du Colombier /* 11263e12c5d1SDavid du Colombier * look for an entry for this system 11273e12c5d1SDavid du Colombier */ 11283e12c5d1SDavid du Colombier ipid(); 11293e12c5d1SDavid du Colombier if(*ipa == 0) 11303e12c5d1SDavid du Colombier return; 11313e12c5d1SDavid du Colombier t = ndbsearch(db, &s, "ip", ipaddr); 1132*219b2ee8SDavid du Colombier if(t){ 11333e12c5d1SDavid du Colombier /* 11343e12c5d1SDavid du Colombier * look for a closely bound attribute 11353e12c5d1SDavid du Colombier */ 11363e12c5d1SDavid du Colombier lookval(t, s.t, attr, buf); 11373e12c5d1SDavid du Colombier ndbfree(t); 11383e12c5d1SDavid du Colombier if(*buf) 11393e12c5d1SDavid du Colombier return; 1140*219b2ee8SDavid du Colombier } 11413e12c5d1SDavid du Colombier 11423e12c5d1SDavid du Colombier /* 11433e12c5d1SDavid du Colombier * Look up the client's network and find a subnet mask for it. 11443e12c5d1SDavid du Colombier * Fill in from the subnet (or net) entry anything we can't figure 11453e12c5d1SDavid du Colombier * out from the client record. 11463e12c5d1SDavid du Colombier */ 11473e12c5d1SDavid du Colombier maskip(ipa, classmask[CLASS(ipa)], net); 1148bd389b36SDavid du Colombier snprint(ip, sizeof(ip), "%I", net); 11493e12c5d1SDavid du Colombier t = ndbsearch(db, &s, "ip", ip); 11503e12c5d1SDavid du Colombier if(t){ 11513e12c5d1SDavid du Colombier /* got a net, look for a subnet */ 11523e12c5d1SDavid du Colombier if(lookval(t, s.t, "ipmask", ip)){ 11533e12c5d1SDavid du Colombier parseip(mask, ip); 11543e12c5d1SDavid du Colombier maskip(ipa, mask, net); 1155bd389b36SDavid du Colombier snprint(ip, sizeof(ip), "%I", net); 11563e12c5d1SDavid du Colombier st = ndbsearch(db, &ss, "ip", ip); 11573e12c5d1SDavid du Colombier if(st){ 11583e12c5d1SDavid du Colombier lookval(st, ss.t, attr, buf); 11593e12c5d1SDavid du Colombier ndbfree(st); 11603e12c5d1SDavid du Colombier } 11613e12c5d1SDavid du Colombier } 11623e12c5d1SDavid du Colombier 11633e12c5d1SDavid du Colombier 11643e12c5d1SDavid du Colombier /* fill in what the client and subnet entries didn't have */ 11653e12c5d1SDavid du Colombier if(*buf == 0) 11663e12c5d1SDavid du Colombier lookval(t, s.t, attr, buf); 11673e12c5d1SDavid du Colombier ndbfree(t); 11683e12c5d1SDavid du Colombier } 11693e12c5d1SDavid du Colombier } 11703e12c5d1SDavid du Colombier 11713e12c5d1SDavid du Colombier /* 11723e12c5d1SDavid du Colombier * lookup (and translate) an ip destination 11733e12c5d1SDavid du Colombier */ 1174*219b2ee8SDavid du Colombier Ndbtuple* 1175*219b2ee8SDavid du Colombier iplookup(Network *np, char *host, char *serv, int nolookup) 11763e12c5d1SDavid du Colombier { 11773e12c5d1SDavid du Colombier char *attr; 11783e12c5d1SDavid du Colombier Ndbtuple *t; 11793e12c5d1SDavid du Colombier Ndbs s; 11803e12c5d1SDavid du Colombier char ts[Ndbvlen+1]; 11813e12c5d1SDavid du Colombier char th[Ndbvlen+1]; 11823e12c5d1SDavid du Colombier char dollar[Ndbvlen+1]; 11833e12c5d1SDavid du Colombier 1184*219b2ee8SDavid du Colombier USED(nolookup); 1185*219b2ee8SDavid du Colombier 11863e12c5d1SDavid du Colombier /* 11873e12c5d1SDavid du Colombier * start with the service since it's the most likely to fail 11883e12c5d1SDavid du Colombier * and costs the least 11893e12c5d1SDavid du Colombier */ 11903e12c5d1SDavid du Colombier if(serv==0 || ipserv(np, serv, ts) == 0) 1191*219b2ee8SDavid du Colombier return 0; 11923e12c5d1SDavid du Colombier 11933e12c5d1SDavid du Colombier /* for dial strings with no host */ 1194*219b2ee8SDavid du Colombier if(strcmp(host, "*") == 0) 1195*219b2ee8SDavid du Colombier return mktuple("ip", "*"); 11963e12c5d1SDavid du Colombier 11973e12c5d1SDavid du Colombier /* 11983e12c5d1SDavid du Colombier * '$' means the rest of the name is an attribute that we 11993e12c5d1SDavid du Colombier * need to search for 12003e12c5d1SDavid du Colombier */ 12013e12c5d1SDavid du Colombier if(*host == '$'){ 12023e12c5d1SDavid du Colombier ipattrlookup(host+1, dollar); 12033e12c5d1SDavid du Colombier if(*dollar) 12043e12c5d1SDavid du Colombier host = dollar; 12053e12c5d1SDavid du Colombier } 12063e12c5d1SDavid du Colombier 12073e12c5d1SDavid du Colombier /* 12083e12c5d1SDavid du Colombier * just accept addresses 12093e12c5d1SDavid du Colombier */ 1210*219b2ee8SDavid du Colombier attr = ipattr(host); 1211*219b2ee8SDavid du Colombier if(strcmp(attr, "ip") == 0) 1212*219b2ee8SDavid du Colombier return mktuple("ip", host); 12133e12c5d1SDavid du Colombier 12143e12c5d1SDavid du Colombier /* 12153e12c5d1SDavid du Colombier * give the domain name server the first opportunity to 1216bd389b36SDavid du Colombier * resolve domain names. if that fails try the database. 12173e12c5d1SDavid du Colombier */ 12183e12c5d1SDavid du Colombier t = 0; 12193e12c5d1SDavid du Colombier if(strcmp(attr, "dom") == 0) 12203e12c5d1SDavid du Colombier t = dnsiplookup(host, &s, th); 12213e12c5d1SDavid du Colombier if(t == 0) 12223e12c5d1SDavid du Colombier t = ndbgetval(db, &s, attr, host, "ip", th); 12233e12c5d1SDavid du Colombier if(t == 0) 1224*219b2ee8SDavid du Colombier return 0; 1225bd389b36SDavid du Colombier 1226bd389b36SDavid du Colombier /* 1227bd389b36SDavid du Colombier * reorder the tuple to have the matched line first and 1228bd389b36SDavid du Colombier * save that in the request structure. 1229bd389b36SDavid du Colombier */ 1230*219b2ee8SDavid du Colombier return reorder(t, s.t); 12313e12c5d1SDavid du Colombier } 12323e12c5d1SDavid du Colombier 12333e12c5d1SDavid du Colombier /* 12343e12c5d1SDavid du Colombier * translate an ip address 12353e12c5d1SDavid du Colombier */ 1236*219b2ee8SDavid du Colombier char* 1237*219b2ee8SDavid du Colombier iptrans(Ndbtuple *t, Network *np, char *serv) 12383e12c5d1SDavid du Colombier { 12393e12c5d1SDavid du Colombier char ts[Ndbvlen+1]; 1240*219b2ee8SDavid du Colombier char reply[Maxreply]; 12413e12c5d1SDavid du Colombier 1242*219b2ee8SDavid du Colombier if(strcmp(t->attr, "ip") != 0) 12433e12c5d1SDavid du Colombier return 0; 1244*219b2ee8SDavid du Colombier 1245*219b2ee8SDavid du Colombier if(serv == 0 || ipserv(np, serv, ts) == 0) 1246*219b2ee8SDavid du Colombier return 0; 1247*219b2ee8SDavid du Colombier 1248*219b2ee8SDavid du Colombier if(*t->val == '*') 1249*219b2ee8SDavid du Colombier snprint(reply, sizeof(reply), "/net/%s/clone %s", 1250*219b2ee8SDavid du Colombier np->net, ts); 1251*219b2ee8SDavid du Colombier else 1252*219b2ee8SDavid du Colombier snprint(reply, sizeof(reply), "/net/%s/clone %s!%s", 1253*219b2ee8SDavid du Colombier np->net, t->val, ts); 1254*219b2ee8SDavid du Colombier 1255*219b2ee8SDavid du Colombier return strdup(reply); 12563e12c5d1SDavid du Colombier } 12573e12c5d1SDavid du Colombier 12583e12c5d1SDavid du Colombier /* 12593e12c5d1SDavid du Colombier * look for the value associated with this attribute for our system. 12603e12c5d1SDavid du Colombier * the precedence is highest to lowest: 12613e12c5d1SDavid du Colombier * - an attr/value pair in this system's entry 12623e12c5d1SDavid du Colombier * - an attr/value pair in this system's net entry 12633e12c5d1SDavid du Colombier */ 12643e12c5d1SDavid du Colombier void 12653e12c5d1SDavid du Colombier dkattrlookup(char *attr, char *buf) 12663e12c5d1SDavid du Colombier { 12673e12c5d1SDavid du Colombier Ndbtuple *t; 12683e12c5d1SDavid du Colombier Ndbs s; 12693e12c5d1SDavid du Colombier 12703e12c5d1SDavid du Colombier *buf = 0; 12713e12c5d1SDavid du Colombier 12723e12c5d1SDavid du Colombier dkid(); 12733e12c5d1SDavid du Colombier if(*dknet == 0) 12743e12c5d1SDavid du Colombier return; 12753e12c5d1SDavid du Colombier t = ndbsearch(db, &s, "dk", dknet); 12763e12c5d1SDavid du Colombier if(t){ 12773e12c5d1SDavid du Colombier lookval(t, s.t, attr, buf); 12783e12c5d1SDavid du Colombier ndbfree(t); 12793e12c5d1SDavid du Colombier } 12803e12c5d1SDavid du Colombier } 12813e12c5d1SDavid du Colombier 12823e12c5d1SDavid du Colombier /* 12833e12c5d1SDavid du Colombier * lookup (and translate) a datakit destination 12843e12c5d1SDavid du Colombier */ 1285*219b2ee8SDavid du Colombier Ndbtuple* 1286*219b2ee8SDavid du Colombier dklookup(Network *np, char *host, char *serv, int nolookup) 12873e12c5d1SDavid du Colombier { 12883e12c5d1SDavid du Colombier char *p; 1289*219b2ee8SDavid du Colombier int slash = 0; 12903e12c5d1SDavid du Colombier Ndbtuple *t, *nt; 12913e12c5d1SDavid du Colombier Ndbs s; 12923e12c5d1SDavid du Colombier char th[Ndbvlen+1]; 12933e12c5d1SDavid du Colombier char dollar[Ndbvlen+1]; 1294*219b2ee8SDavid du Colombier char *attr; 12953e12c5d1SDavid du Colombier 12963e12c5d1SDavid du Colombier USED(np); 12973e12c5d1SDavid du Colombier 12983e12c5d1SDavid du Colombier /* 12993e12c5d1SDavid du Colombier * '$' means the rest of the name is an attribute that we 13003e12c5d1SDavid du Colombier * need to search for 13013e12c5d1SDavid du Colombier */ 13023e12c5d1SDavid du Colombier if(*host == '$'){ 13033e12c5d1SDavid du Colombier dkattrlookup(host+1, dollar); 13043e12c5d1SDavid du Colombier if(*dollar) 13053e12c5d1SDavid du Colombier host = dollar; 13063e12c5d1SDavid du Colombier } 13073e12c5d1SDavid du Colombier 13083e12c5d1SDavid du Colombier for(p = host; *p; p++){ 1309*219b2ee8SDavid du Colombier if(isalnum(*p) || *p == '-' || *p == '.') 13103e12c5d1SDavid du Colombier ; 13113e12c5d1SDavid du Colombier else if(*p == '/') 13123e12c5d1SDavid du Colombier slash = 1; 13133e12c5d1SDavid du Colombier else 13143e12c5d1SDavid du Colombier return 0; 13153e12c5d1SDavid du Colombier } 13163e12c5d1SDavid du Colombier 1317*219b2ee8SDavid du Colombier /* hack for announcements */ 1318*219b2ee8SDavid du Colombier if(nolookup && serv == 0) 1319*219b2ee8SDavid du Colombier return mktuple("dk", host); 1320*219b2ee8SDavid du Colombier 1321*219b2ee8SDavid du Colombier /* let dk addresses be domain names */ 1322*219b2ee8SDavid du Colombier attr = ipattr(host); 1323*219b2ee8SDavid du Colombier 13243e12c5d1SDavid du Colombier /* don't translate paths, just believe the user */ 1325*219b2ee8SDavid du Colombier if(slash) 1326*219b2ee8SDavid du Colombier return mktuple("dk", host); 1327*219b2ee8SDavid du Colombier 1328*219b2ee8SDavid du Colombier t = ndbgetval(db, &s, attr, host, "dk", th); 1329*219b2ee8SDavid du Colombier if(t == 0){ 1330*219b2ee8SDavid du Colombier if(nolookup) 1331*219b2ee8SDavid du Colombier return mktuple("dk", host); 1332*219b2ee8SDavid du Colombier return 0; 1333*219b2ee8SDavid du Colombier } 13343e12c5d1SDavid du Colombier 13353e12c5d1SDavid du Colombier /* don't allow services in calls to consoles */ 13363e12c5d1SDavid du Colombier for(nt = t; nt; nt = nt->entry) 13373e12c5d1SDavid du Colombier if(strcmp("flavor", nt->attr)==0 13383e12c5d1SDavid du Colombier && strcmp("console", nt->val)==0 13393e12c5d1SDavid du Colombier && serv && *serv){ 13403e12c5d1SDavid du Colombier ndbfree(t); 13413e12c5d1SDavid du Colombier return 0; 13423e12c5d1SDavid du Colombier } 13433e12c5d1SDavid du Colombier 1344*219b2ee8SDavid du Colombier return reorder(t, s.t); 13453e12c5d1SDavid du Colombier } 13463e12c5d1SDavid du Colombier 13473e12c5d1SDavid du Colombier /* 13483e12c5d1SDavid du Colombier * translate a datakit address 13493e12c5d1SDavid du Colombier */ 1350*219b2ee8SDavid du Colombier char* 1351*219b2ee8SDavid du Colombier dktrans(Ndbtuple *t, Network *np, char *serv) 13523e12c5d1SDavid du Colombier { 1353*219b2ee8SDavid du Colombier char reply[Maxreply]; 13543e12c5d1SDavid du Colombier 1355*219b2ee8SDavid du Colombier if(strcmp(t->attr, "dk") != 0) 13563e12c5d1SDavid du Colombier return 0; 1357*219b2ee8SDavid du Colombier 1358*219b2ee8SDavid du Colombier if(serv) 1359*219b2ee8SDavid du Colombier snprint(reply, sizeof(reply), "/net/%s/clone %s!%s", np->net, 1360*219b2ee8SDavid du Colombier t->val, serv); 1361*219b2ee8SDavid du Colombier else 1362*219b2ee8SDavid du Colombier snprint(reply, sizeof(reply), "/net/%s/clone %s", np->net, 1363*219b2ee8SDavid du Colombier t->val); 1364*219b2ee8SDavid du Colombier return strdup(reply); 13653e12c5d1SDavid du Colombier } 13663e12c5d1SDavid du Colombier 1367*219b2ee8SDavid du Colombier /* 1368*219b2ee8SDavid du Colombier * lookup a telephone number 1369*219b2ee8SDavid du Colombier */ 1370*219b2ee8SDavid du Colombier Ndbtuple* 1371*219b2ee8SDavid du Colombier telcolookup(Network *np, char *host, char *serv, int nolookup) 1372*219b2ee8SDavid du Colombier { 1373*219b2ee8SDavid du Colombier Ndbtuple *t; 1374*219b2ee8SDavid du Colombier Ndbs s; 1375*219b2ee8SDavid du Colombier char th[Ndbvlen+1]; 1376*219b2ee8SDavid du Colombier 1377*219b2ee8SDavid du Colombier USED(np, nolookup, serv); 1378*219b2ee8SDavid du Colombier 1379*219b2ee8SDavid du Colombier t = ndbgetval(db, &s, "sys", host, "telco", th); 1380*219b2ee8SDavid du Colombier if(t == 0) 1381*219b2ee8SDavid du Colombier return mktuple("telco", host); 1382*219b2ee8SDavid du Colombier 1383*219b2ee8SDavid du Colombier return reorder(t, s.t); 1384*219b2ee8SDavid du Colombier } 1385*219b2ee8SDavid du Colombier 1386*219b2ee8SDavid du Colombier /* 1387*219b2ee8SDavid du Colombier * translate a telephone address 1388*219b2ee8SDavid du Colombier */ 1389*219b2ee8SDavid du Colombier char* 1390*219b2ee8SDavid du Colombier telcotrans(Ndbtuple *t, Network *np, char *serv) 1391*219b2ee8SDavid du Colombier { 1392*219b2ee8SDavid du Colombier char reply[Maxreply]; 1393*219b2ee8SDavid du Colombier 1394*219b2ee8SDavid du Colombier if(strcmp(t->attr, "telco") != 0) 1395*219b2ee8SDavid du Colombier return 0; 1396*219b2ee8SDavid du Colombier 1397*219b2ee8SDavid du Colombier if(serv) 1398*219b2ee8SDavid du Colombier snprint(reply, sizeof(reply), "/net/%s/clone %s!%s", np->net, 1399*219b2ee8SDavid du Colombier t->val, serv); 1400*219b2ee8SDavid du Colombier else 1401*219b2ee8SDavid du Colombier snprint(reply, sizeof(reply), "/net/%s/clone %s", np->net, 1402*219b2ee8SDavid du Colombier t->val); 1403*219b2ee8SDavid du Colombier return strdup(reply); 1404*219b2ee8SDavid du Colombier } 14053e12c5d1SDavid du Colombier int 14063e12c5d1SDavid du Colombier mygetfields(char *lp, char **fields, int n, char sep) 14073e12c5d1SDavid du Colombier { 14083e12c5d1SDavid du Colombier int i; 14093e12c5d1SDavid du Colombier char sep2=0; 14103e12c5d1SDavid du Colombier 14113e12c5d1SDavid du Colombier if(sep == ' ') 14123e12c5d1SDavid du Colombier sep2 = '\t'; 14133e12c5d1SDavid du Colombier for(i=0; lp && *lp && i<n; i++){ 14143e12c5d1SDavid du Colombier if(*lp==sep || *lp==sep2) 14153e12c5d1SDavid du Colombier *lp++ = 0; 14163e12c5d1SDavid du Colombier if(*lp == 0) 14173e12c5d1SDavid du Colombier break; 14183e12c5d1SDavid du Colombier fields[i] = lp; 14193e12c5d1SDavid du Colombier while(*lp && *lp!=sep && *lp!=sep2) 14203e12c5d1SDavid du Colombier lp++; 14213e12c5d1SDavid du Colombier } 14223e12c5d1SDavid du Colombier return i; 14233e12c5d1SDavid du Colombier } 14243e12c5d1SDavid du Colombier 14253e12c5d1SDavid du Colombier /* 14263e12c5d1SDavid du Colombier * Look for a pair with the given attribute. look first on the same line, 14273e12c5d1SDavid du Colombier * then in the whole entry. 14283e12c5d1SDavid du Colombier */ 14293e12c5d1SDavid du Colombier Ndbtuple* 14303e12c5d1SDavid du Colombier lookval(Ndbtuple *entry, Ndbtuple *line, char *attr, char *to) 14313e12c5d1SDavid du Colombier { 14323e12c5d1SDavid du Colombier Ndbtuple *nt; 14333e12c5d1SDavid du Colombier 14343e12c5d1SDavid du Colombier /* first look on same line (closer binding) */ 14353e12c5d1SDavid du Colombier for(nt = line;;){ 14363e12c5d1SDavid du Colombier if(strcmp(attr, nt->attr) == 0){ 14373e12c5d1SDavid du Colombier strncpy(to, nt->val, Ndbvlen); 14383e12c5d1SDavid du Colombier return nt; 14393e12c5d1SDavid du Colombier } 14403e12c5d1SDavid du Colombier nt = nt->line; 14413e12c5d1SDavid du Colombier if(nt == line) 14423e12c5d1SDavid du Colombier break; 14433e12c5d1SDavid du Colombier } 14443e12c5d1SDavid du Colombier /* search whole tuple */ 14453e12c5d1SDavid du Colombier for(nt = entry; nt; nt = nt->entry) 14463e12c5d1SDavid du Colombier if(strcmp(attr, nt->attr) == 0){ 14473e12c5d1SDavid du Colombier strncpy(to, nt->val, Ndbvlen); 14483e12c5d1SDavid du Colombier return nt; 14493e12c5d1SDavid du Colombier } 14503e12c5d1SDavid du Colombier return 0; 14513e12c5d1SDavid du Colombier } 14523e12c5d1SDavid du Colombier 14533e12c5d1SDavid du Colombier /* 14543e12c5d1SDavid du Colombier * reorder the tuple to put x's line first in the entry 14553e12c5d1SDavid du Colombier */ 14563e12c5d1SDavid du Colombier Ndbtuple* 14573e12c5d1SDavid du Colombier reorder(Ndbtuple *t, Ndbtuple *x) 14583e12c5d1SDavid du Colombier { 14593e12c5d1SDavid du Colombier Ndbtuple *nt; 14603e12c5d1SDavid du Colombier Ndbtuple *line; 14613e12c5d1SDavid du Colombier 1462*219b2ee8SDavid du Colombier /* find start of this entry's line */ 1463*219b2ee8SDavid du Colombier for(line = x; line->entry == line->line; line = line->line) 14643e12c5d1SDavid du Colombier ; 1465*219b2ee8SDavid du Colombier line = line->line; 1466*219b2ee8SDavid du Colombier if(line == t) 1467*219b2ee8SDavid du Colombier return t; /* already the first line */ 14683e12c5d1SDavid du Colombier 1469*219b2ee8SDavid du Colombier /* remove this line and everything after it from the entry */ 1470*219b2ee8SDavid du Colombier for(nt = t; nt->entry != line; nt = nt->entry) 1471*219b2ee8SDavid du Colombier ; 1472*219b2ee8SDavid du Colombier nt->entry = 0; 14733e12c5d1SDavid du Colombier 1474*219b2ee8SDavid du Colombier /* make that the start of the entry */ 1475*219b2ee8SDavid du Colombier for(nt = line; nt->entry; nt = nt->entry) 1476*219b2ee8SDavid du Colombier ; 14773e12c5d1SDavid du Colombier nt->entry = t; 14783e12c5d1SDavid du Colombier return line; 14793e12c5d1SDavid du Colombier } 14803e12c5d1SDavid du Colombier 14813e12c5d1SDavid du Colombier /* 14823e12c5d1SDavid du Colombier * create a slave process to handle a request to avoid one request blocking 14833e12c5d1SDavid du Colombier * another 14843e12c5d1SDavid du Colombier */ 14853e12c5d1SDavid du Colombier void 14863e12c5d1SDavid du Colombier slave(void) 14873e12c5d1SDavid du Colombier { 14883e12c5d1SDavid du Colombier if(*isslave) 14893e12c5d1SDavid du Colombier return; /* we're already a slave process */ 14903e12c5d1SDavid du Colombier 14913e12c5d1SDavid du Colombier switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){ 14923e12c5d1SDavid du Colombier case -1: 14933e12c5d1SDavid du Colombier break; 14943e12c5d1SDavid du Colombier case 0: 1495*219b2ee8SDavid du Colombier if(debug) 1496*219b2ee8SDavid du Colombier syslog(0, logfile, "slave %d", getpid()); 14973e12c5d1SDavid du Colombier *isslave = 1; 14983e12c5d1SDavid du Colombier break; 14993e12c5d1SDavid du Colombier default: 15003e12c5d1SDavid du Colombier longjmp(masterjmp, 1); 15013e12c5d1SDavid du Colombier } 15023e12c5d1SDavid du Colombier } 15033e12c5d1SDavid du Colombier 1504*219b2ee8SDavid du Colombier int 1505*219b2ee8SDavid du Colombier dnsmount(void) 1506*219b2ee8SDavid du Colombier { 1507*219b2ee8SDavid du Colombier int fd; 1508*219b2ee8SDavid du Colombier 1509*219b2ee8SDavid du Colombier fd = open("#s/dns", ORDWR); 1510*219b2ee8SDavid du Colombier if(fd < 0) 1511*219b2ee8SDavid du Colombier return -1; 1512*219b2ee8SDavid du Colombier if(mount(fd, "/net", MAFTER, "") < 0){ 1513*219b2ee8SDavid du Colombier close(fd); 1514*219b2ee8SDavid du Colombier return -1; 1515*219b2ee8SDavid du Colombier } 1516*219b2ee8SDavid du Colombier close(fd); 1517*219b2ee8SDavid du Colombier return 0; 1518*219b2ee8SDavid du Colombier } 1519*219b2ee8SDavid du Colombier 15203e12c5d1SDavid du Colombier /* 15213e12c5d1SDavid du Colombier * call the dns process and have it try to translate a name 15223e12c5d1SDavid du Colombier */ 15233e12c5d1SDavid du Colombier Ndbtuple* 15243e12c5d1SDavid du Colombier dnsiplookup(char *host, Ndbs *s, char *ht) 15253e12c5d1SDavid du Colombier { 15263e12c5d1SDavid du Colombier int fd, n; 15273e12c5d1SDavid du Colombier char buf[Ndbvlen + 4]; 15283e12c5d1SDavid du Colombier Ndbtuple *t, *nt, **le, **ll; 15293e12c5d1SDavid du Colombier char *fields[4]; 15303e12c5d1SDavid du Colombier 1531bd389b36SDavid du Colombier unlock(&dblock); 1532bd389b36SDavid du Colombier 15333e12c5d1SDavid du Colombier /* save the name before starting a slave */ 1534bd389b36SDavid du Colombier snprint(buf, sizeof(buf), "%s ip", host); 15353e12c5d1SDavid du Colombier 15363e12c5d1SDavid du Colombier slave(); 15373e12c5d1SDavid du Colombier 15383e12c5d1SDavid du Colombier fd = open("/net/dns", ORDWR); 1539*219b2ee8SDavid du Colombier if(fd < 0 && dnsmount() == 0) 1540*219b2ee8SDavid du Colombier fd = open("/net/dns", ORDWR); 1541bd389b36SDavid du Colombier if(fd < 0){ 1542bd389b36SDavid du Colombier lock(&dblock); 15433e12c5d1SDavid du Colombier return 0; 1544bd389b36SDavid du Colombier } 15453e12c5d1SDavid du Colombier 15463e12c5d1SDavid du Colombier t = 0; 1547*219b2ee8SDavid du Colombier ll = le = 0; 15483e12c5d1SDavid du Colombier if(write(fd, buf, strlen(buf)) >= 0){ 15493e12c5d1SDavid du Colombier seek(fd, 0, 0); 15503e12c5d1SDavid du Colombier ll = &t; 15513e12c5d1SDavid du Colombier le = &t; 15523e12c5d1SDavid du Colombier while((n = read(fd, buf, sizeof(buf)-1)) > 0){ 15533e12c5d1SDavid du Colombier buf[n] = 0; 15543e12c5d1SDavid du Colombier n = mygetfields(buf, fields, 4, ' '); 15553e12c5d1SDavid du Colombier if(n < 3) 15563e12c5d1SDavid du Colombier continue; 15573e12c5d1SDavid du Colombier nt = malloc(sizeof(Ndbtuple)); 15583e12c5d1SDavid du Colombier strcpy(nt->attr, "ip"); 15593e12c5d1SDavid du Colombier strncpy(nt->val, fields[2], Ndbvlen-1); 15603e12c5d1SDavid du Colombier *ll = nt; 15613e12c5d1SDavid du Colombier *le = nt; 15623e12c5d1SDavid du Colombier ll = &nt->line; 15633e12c5d1SDavid du Colombier le = &nt->entry; 15643e12c5d1SDavid du Colombier nt->line = t; 15653e12c5d1SDavid du Colombier } 15663e12c5d1SDavid du Colombier } 1567*219b2ee8SDavid du Colombier if(t){ 15683e12c5d1SDavid du Colombier strcpy(ht, t->val); 1569*219b2ee8SDavid du Colombier 1570*219b2ee8SDavid du Colombier /* add in domain name */ 1571*219b2ee8SDavid du Colombier nt = malloc(sizeof(Ndbtuple)); 1572*219b2ee8SDavid du Colombier strcpy(nt->attr, "dom"); 1573*219b2ee8SDavid du Colombier strcpy(nt->val, host); 1574*219b2ee8SDavid du Colombier *ll = nt; 1575*219b2ee8SDavid du Colombier *le = nt; 1576*219b2ee8SDavid du Colombier nt->line = t; 1577*219b2ee8SDavid du Colombier } 15783e12c5d1SDavid du Colombier close(fd); 15793e12c5d1SDavid du Colombier s->t = t; 1580bd389b36SDavid du Colombier lock(&dblock); 15813e12c5d1SDavid du Colombier return t; 15823e12c5d1SDavid du Colombier } 1583*219b2ee8SDavid du Colombier 1584*219b2ee8SDavid du Colombier int 1585*219b2ee8SDavid du Colombier qmatch(Ndbtuple *t, char **attr, char **val, int n) 1586*219b2ee8SDavid du Colombier { 1587*219b2ee8SDavid du Colombier int i, found; 1588*219b2ee8SDavid du Colombier Ndbtuple *nt; 1589*219b2ee8SDavid du Colombier 1590*219b2ee8SDavid du Colombier for(i = 1; i < n; i++){ 1591*219b2ee8SDavid du Colombier found = 0; 1592*219b2ee8SDavid du Colombier for(nt = t; nt; nt = nt->entry) 1593*219b2ee8SDavid du Colombier if(strcmp(attr[i], nt->attr) == 0) 1594*219b2ee8SDavid du Colombier if(strcmp(val[i], "*") == 0 1595*219b2ee8SDavid du Colombier || strcmp(val[i], nt->val) == 0){ 1596*219b2ee8SDavid du Colombier found = 1; 1597*219b2ee8SDavid du Colombier break; 1598*219b2ee8SDavid du Colombier } 1599*219b2ee8SDavid du Colombier if(found == 0) 1600*219b2ee8SDavid du Colombier break; 1601*219b2ee8SDavid du Colombier } 1602*219b2ee8SDavid du Colombier return i == n; 1603*219b2ee8SDavid du Colombier } 1604*219b2ee8SDavid du Colombier 1605*219b2ee8SDavid du Colombier void 1606*219b2ee8SDavid du Colombier qreply(Mfile *mf, Ndbtuple *t) 1607*219b2ee8SDavid du Colombier { 1608*219b2ee8SDavid du Colombier int i; 1609*219b2ee8SDavid du Colombier Ndbtuple *nt; 1610*219b2ee8SDavid du Colombier char buf[512]; 1611*219b2ee8SDavid du Colombier 1612*219b2ee8SDavid du Colombier buf[0] = 0; 1613*219b2ee8SDavid du Colombier for(nt = t; mf->nreply < Nreply && nt; nt = nt->entry){ 1614*219b2ee8SDavid du Colombier strcat(buf, nt->attr); 1615*219b2ee8SDavid du Colombier strcat(buf, "="); 1616*219b2ee8SDavid du Colombier strcat(buf, nt->val); 1617*219b2ee8SDavid du Colombier i = strlen(buf); 1618*219b2ee8SDavid du Colombier if(nt->line != nt->entry || sizeof(buf) - i < 2*Ndbvlen+2){ 1619*219b2ee8SDavid du Colombier mf->replylen[mf->nreply] = strlen(buf); 1620*219b2ee8SDavid du Colombier mf->reply[mf->nreply++] = strdup(buf); 1621*219b2ee8SDavid du Colombier buf[0] = 0; 1622*219b2ee8SDavid du Colombier } else 1623*219b2ee8SDavid du Colombier strcat(buf, " "); 1624*219b2ee8SDavid du Colombier } 1625*219b2ee8SDavid du Colombier } 1626*219b2ee8SDavid du Colombier 1627*219b2ee8SDavid du Colombier /* 1628*219b2ee8SDavid du Colombier * generic query lookup. 1629*219b2ee8SDavid du Colombier */ 1630*219b2ee8SDavid du Colombier char* 1631*219b2ee8SDavid du Colombier genquery(Mfile *mf, char *query) 1632*219b2ee8SDavid du Colombier { 1633*219b2ee8SDavid du Colombier int i, n; 1634*219b2ee8SDavid du Colombier char *p; 1635*219b2ee8SDavid du Colombier char *attr[32]; 1636*219b2ee8SDavid du Colombier char *val[32]; 1637*219b2ee8SDavid du Colombier char ip[Ndbvlen]; 1638*219b2ee8SDavid du Colombier Ndbtuple *t; 1639*219b2ee8SDavid du Colombier Ndbs s; 1640*219b2ee8SDavid du Colombier 1641*219b2ee8SDavid du Colombier n = mygetfields(query, attr, 32, ' '); 1642*219b2ee8SDavid du Colombier if(n == 0) 1643*219b2ee8SDavid du Colombier return "bad query"; 1644*219b2ee8SDavid du Colombier 1645*219b2ee8SDavid du Colombier /* parse pairs */ 1646*219b2ee8SDavid du Colombier for(i = 0; i < n; i++){ 1647*219b2ee8SDavid du Colombier p = strchr(attr[i], '='); 1648*219b2ee8SDavid du Colombier if(p == 0) 1649*219b2ee8SDavid du Colombier return "bad query"; 1650*219b2ee8SDavid du Colombier *p++ = 0; 1651*219b2ee8SDavid du Colombier val[i] = p; 1652*219b2ee8SDavid du Colombier } 1653*219b2ee8SDavid du Colombier 1654*219b2ee8SDavid du Colombier /* give dns a chance */ 1655*219b2ee8SDavid du Colombier if((strcmp(attr[0], "dom") == 0 || strcmp(attr[0], "ip") == 0) && val[0]){ 1656*219b2ee8SDavid du Colombier t = dnsiplookup(val[0], &s, ip); 1657*219b2ee8SDavid du Colombier if(t){ 1658*219b2ee8SDavid du Colombier if(qmatch(t, attr, val, n)){ 1659*219b2ee8SDavid du Colombier qreply(mf, t); 1660*219b2ee8SDavid du Colombier ndbfree(t); 1661*219b2ee8SDavid du Colombier return 0; 1662*219b2ee8SDavid du Colombier } 1663*219b2ee8SDavid du Colombier ndbfree(t); 1664*219b2ee8SDavid du Colombier } 1665*219b2ee8SDavid du Colombier } 1666*219b2ee8SDavid du Colombier 1667*219b2ee8SDavid du Colombier /* first pair is always the key. It can't be a '*' */ 1668*219b2ee8SDavid du Colombier t = ndbsearch(db, &s, attr[0], val[0]); 1669*219b2ee8SDavid du Colombier 1670*219b2ee8SDavid du Colombier /* search is the and of all the pairs */ 1671*219b2ee8SDavid du Colombier while(t){ 1672*219b2ee8SDavid du Colombier if(qmatch(t, attr, val, n)){ 1673*219b2ee8SDavid du Colombier qreply(mf, t); 1674*219b2ee8SDavid du Colombier ndbfree(t); 1675*219b2ee8SDavid du Colombier return 0; 1676*219b2ee8SDavid du Colombier } 1677*219b2ee8SDavid du Colombier 1678*219b2ee8SDavid du Colombier ndbfree(t); 1679*219b2ee8SDavid du Colombier t = ndbsnext(&s, attr[0], val[0]); 1680*219b2ee8SDavid du Colombier } 1681*219b2ee8SDavid du Colombier 1682*219b2ee8SDavid du Colombier return "no match"; 1683*219b2ee8SDavid du Colombier } 1684