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 "dat.h" 63e12c5d1SDavid du Colombier #include "fns.h" 73e12c5d1SDavid du Colombier 83e12c5d1SDavid du Colombier static int openflags(int); 93e12c5d1SDavid du Colombier static void rattach(void); 10219b2ee8SDavid du Colombier static void rsession(void); 113e12c5d1SDavid du Colombier static void rclone(void); 123e12c5d1SDavid du Colombier static void rclunk(void); 133e12c5d1SDavid du Colombier static void rcreate(void); 143e12c5d1SDavid du Colombier static void rflush(void); 153e12c5d1SDavid du Colombier static void rmservice(void); 163e12c5d1SDavid du Colombier static void rnop(void); 173e12c5d1SDavid du Colombier static void ropen(void); 183e12c5d1SDavid du Colombier static void rread(void); 193e12c5d1SDavid du Colombier static void rremove(void); 203e12c5d1SDavid du Colombier static void rsession(void); 213e12c5d1SDavid du Colombier static void rstat(void); 223e12c5d1SDavid du Colombier static void rwalk(void); 233e12c5d1SDavid du Colombier static void rwrite(void); 243e12c5d1SDavid du Colombier static void rwstat(void); 253e12c5d1SDavid du Colombier static void usage(void); 263e12c5d1SDavid du Colombier 273e12c5d1SDavid du Colombier static Fcall thdr; 283e12c5d1SDavid du Colombier static Fcall rhdr; 293e12c5d1SDavid du Colombier static char data[MAXMSG+MAXFDATA]; 303e12c5d1SDavid du Colombier static char fdata[MAXFDATA]; 313e12c5d1SDavid du Colombier static char srvfile[2*NAMELEN]; 323e12c5d1SDavid du Colombier 333e12c5d1SDavid du Colombier extern Xfsub *xsublist[]; 343e12c5d1SDavid du Colombier 353e12c5d1SDavid du Colombier jmp_buf err_lab[16]; 363e12c5d1SDavid du Colombier int nerr_lab; 373e12c5d1SDavid du Colombier char err_msg[ERRLEN]; 383e12c5d1SDavid du Colombier 393e12c5d1SDavid du Colombier int chatty; 40*7dd7cddfSDavid du Colombier int nojoliet; 41*7dd7cddfSDavid du Colombier int noplan9; 423e12c5d1SDavid du Colombier 433e12c5d1SDavid du Colombier void 443e12c5d1SDavid du Colombier main(int argc, char **argv) 453e12c5d1SDavid du Colombier { 463e12c5d1SDavid du Colombier int srvfd, pipefd[2], n, nw, stdio; 473e12c5d1SDavid du Colombier Xfsub **xs; 483e12c5d1SDavid du Colombier 493e12c5d1SDavid du Colombier stdio = 0; 503e12c5d1SDavid du Colombier ARGBEGIN { 513e12c5d1SDavid du Colombier case 'v': 52bd389b36SDavid du Colombier chatty = 1; 533e12c5d1SDavid du Colombier break; 543e12c5d1SDavid du Colombier case 'f': 553e12c5d1SDavid du Colombier deffile = ARGF(); 563e12c5d1SDavid du Colombier break; 573e12c5d1SDavid du Colombier case 's': 583e12c5d1SDavid du Colombier stdio = 1; 593e12c5d1SDavid du Colombier break; 60*7dd7cddfSDavid du Colombier case '9': 61*7dd7cddfSDavid du Colombier noplan9 = 1; 62*7dd7cddfSDavid du Colombier break; 63*7dd7cddfSDavid du Colombier case 'J': 64*7dd7cddfSDavid du Colombier nojoliet = 1; 65*7dd7cddfSDavid du Colombier break; 663e12c5d1SDavid du Colombier default: 673e12c5d1SDavid du Colombier usage(); 683e12c5d1SDavid du Colombier } ARGEND 693e12c5d1SDavid du Colombier 703e12c5d1SDavid du Colombier switch(argc) { 713e12c5d1SDavid du Colombier case 0: 723e12c5d1SDavid du Colombier break; 733e12c5d1SDavid du Colombier case 1: 743e12c5d1SDavid du Colombier srvname = argv[0]; 753e12c5d1SDavid du Colombier break; 763e12c5d1SDavid du Colombier default: 773e12c5d1SDavid du Colombier usage(); 783e12c5d1SDavid du Colombier } 793e12c5d1SDavid du Colombier 803e12c5d1SDavid du Colombier iobuf_init(); 813e12c5d1SDavid du Colombier for(xs=xsublist; *xs; xs++) 823e12c5d1SDavid du Colombier (*(*xs)->reset)(); 833e12c5d1SDavid du Colombier 843e12c5d1SDavid du Colombier if(stdio) { 853e12c5d1SDavid du Colombier pipefd[0] = 0; 863e12c5d1SDavid du Colombier pipefd[1] = 1; 873e12c5d1SDavid du Colombier } else { 883e12c5d1SDavid du Colombier close(0); 893e12c5d1SDavid du Colombier close(1); 903e12c5d1SDavid du Colombier open("/dev/null", OREAD); 913e12c5d1SDavid du Colombier open("/dev/null", OWRITE); 923e12c5d1SDavid du Colombier if(pipe(pipefd) < 0) 933e12c5d1SDavid du Colombier panic(1, "pipe"); 943e12c5d1SDavid du Colombier sprint(srvfile, "/srv/%s", srvname); 953e12c5d1SDavid du Colombier srvfd = create(srvfile, OWRITE, 0666); 963e12c5d1SDavid du Colombier if(srvfd < 0) 973e12c5d1SDavid du Colombier panic(1, srvfile); 983e12c5d1SDavid du Colombier atexit(rmservice); 993e12c5d1SDavid du Colombier fprint(srvfd, "%d", pipefd[0]); 1003e12c5d1SDavid du Colombier close(pipefd[0]); 1013e12c5d1SDavid du Colombier close(srvfd); 1023e12c5d1SDavid du Colombier fprint(2, "%s %d: serving %s\n", argv0, getpid(), srvfile); 1033e12c5d1SDavid du Colombier } 1043e12c5d1SDavid du Colombier srvfd = pipefd[1]; 1053e12c5d1SDavid du Colombier 1063e12c5d1SDavid du Colombier switch(rfork(RFNOWAIT|RFNOTEG|RFFDG|RFPROC)){ 1073e12c5d1SDavid du Colombier case -1: 1083e12c5d1SDavid du Colombier panic(1, "fork"); 1093e12c5d1SDavid du Colombier default: 1103e12c5d1SDavid du Colombier _exits(0); 1113e12c5d1SDavid du Colombier case 0: 1123e12c5d1SDavid du Colombier break; 1133e12c5d1SDavid du Colombier } 1143e12c5d1SDavid du Colombier 1153e12c5d1SDavid du Colombier while((n = read(srvfd, data, sizeof data)) > 0){ 1163e12c5d1SDavid du Colombier if(convM2S(data, &thdr, n) <= 0) 1173e12c5d1SDavid du Colombier panic(0, "convM2S"); 1183e12c5d1SDavid du Colombier if(!waserror()){ 1193e12c5d1SDavid du Colombier switch(thdr.type){ 1203e12c5d1SDavid du Colombier default: panic(0, "type %d", thdr.type); 1213e12c5d1SDavid du Colombier break; 1223e12c5d1SDavid du Colombier case Tnop: rnop(); break; 1233e12c5d1SDavid du Colombier case Tsession: rsession(); break; 1243e12c5d1SDavid du Colombier case Tflush: rflush(); break; 1253e12c5d1SDavid du Colombier case Tattach: rattach(); break; 1263e12c5d1SDavid du Colombier case Tclone: rclone(); break; 1273e12c5d1SDavid du Colombier case Twalk: rwalk(); break; 1283e12c5d1SDavid du Colombier case Topen: ropen(); break; 1293e12c5d1SDavid du Colombier case Tcreate: rcreate(); break; 1303e12c5d1SDavid du Colombier case Tread: rread(); break; 1313e12c5d1SDavid du Colombier case Twrite: rwrite(); break; 1323e12c5d1SDavid du Colombier case Tclunk: rclunk(); break; 1333e12c5d1SDavid du Colombier case Tremove: rremove(); break; 1343e12c5d1SDavid du Colombier case Tstat: rstat(); break; 1353e12c5d1SDavid du Colombier case Twstat: rwstat(); break; 1363e12c5d1SDavid du Colombier } 1373e12c5d1SDavid du Colombier poperror(); 1383e12c5d1SDavid du Colombier rhdr.type = thdr.type+1; 1393e12c5d1SDavid du Colombier }else{ 1403e12c5d1SDavid du Colombier rhdr.type = Rerror; 1413e12c5d1SDavid du Colombier strncpy(rhdr.ename, err_msg, ERRLEN); 1423e12c5d1SDavid du Colombier } 1433e12c5d1SDavid du Colombier rhdr.fid = thdr.fid; 1443e12c5d1SDavid du Colombier rhdr.tag = thdr.tag; 1453e12c5d1SDavid du Colombier chat((rhdr.type != Rerror ? "OK\n" : "%s\n"), err_msg); 1463e12c5d1SDavid du Colombier if((n = convS2M(&rhdr, (char *)data)) <= 0) 1473e12c5d1SDavid du Colombier panic(0, "convS2M"); 1483e12c5d1SDavid du Colombier nw = write(srvfd, data, n); 1493e12c5d1SDavid du Colombier if(nw != n) 1503e12c5d1SDavid du Colombier panic(1, "write"); 1513e12c5d1SDavid du Colombier if(nerr_lab != 0) 1523e12c5d1SDavid du Colombier panic(0, "err stack %d: %lux %lux %lux %lux %lux %lux", nerr_lab, 1533e12c5d1SDavid du Colombier err_lab[0][JMPBUFPC], err_lab[1][JMPBUFPC], 1543e12c5d1SDavid du Colombier err_lab[2][JMPBUFPC], err_lab[3][JMPBUFPC], 1553e12c5d1SDavid du Colombier err_lab[4][JMPBUFPC], err_lab[5][JMPBUFPC]); 1563e12c5d1SDavid du Colombier } 1573e12c5d1SDavid du Colombier if(n < 0) 1583e12c5d1SDavid du Colombier panic(1, "read"); 1593e12c5d1SDavid du Colombier chat("%s %d: exiting\n", argv0, getpid()); 1603e12c5d1SDavid du Colombier exits(0); 1613e12c5d1SDavid du Colombier } 1623e12c5d1SDavid du Colombier 1633e12c5d1SDavid du Colombier static void 1643e12c5d1SDavid du Colombier usage(void) 1653e12c5d1SDavid du Colombier { 1663e12c5d1SDavid du Colombier fprint(2, "usage: %s [-v] [-s] [-f devicefile] [srvname]\n", argv0); 1673e12c5d1SDavid du Colombier exits("usage"); 1683e12c5d1SDavid du Colombier } 1693e12c5d1SDavid du Colombier 1703e12c5d1SDavid du Colombier void 1713e12c5d1SDavid du Colombier error(char *p) 1723e12c5d1SDavid du Colombier { 1733e12c5d1SDavid du Colombier strncpy(err_msg, p, ERRLEN); 1743e12c5d1SDavid du Colombier nexterror(); 1753e12c5d1SDavid du Colombier } 1763e12c5d1SDavid du Colombier 1773e12c5d1SDavid du Colombier void 1783e12c5d1SDavid du Colombier nexterror(void) 1793e12c5d1SDavid du Colombier { 1803e12c5d1SDavid du Colombier longjmp(err_lab[--nerr_lab], 1); 1813e12c5d1SDavid du Colombier } 1823e12c5d1SDavid du Colombier 1833e12c5d1SDavid du Colombier void* 1843e12c5d1SDavid du Colombier ealloc(long n) 1853e12c5d1SDavid du Colombier { 1863e12c5d1SDavid du Colombier void *p; 1873e12c5d1SDavid du Colombier 1883e12c5d1SDavid du Colombier p = malloc(n); 1893e12c5d1SDavid du Colombier if(p == 0) 1903e12c5d1SDavid du Colombier error("no memory"); 1913e12c5d1SDavid du Colombier return p; 1923e12c5d1SDavid du Colombier } 1933e12c5d1SDavid du Colombier 1943e12c5d1SDavid du Colombier static void 1953e12c5d1SDavid du Colombier rmservice(void) 1963e12c5d1SDavid du Colombier { 1973e12c5d1SDavid du Colombier remove(srvfile); 1983e12c5d1SDavid du Colombier } 1993e12c5d1SDavid du Colombier 2003e12c5d1SDavid du Colombier static void 2013e12c5d1SDavid du Colombier rnop(void) 2023e12c5d1SDavid du Colombier { 2033e12c5d1SDavid du Colombier chat("nop..."); 2043e12c5d1SDavid du Colombier } 2053e12c5d1SDavid du Colombier 2063e12c5d1SDavid du Colombier static void 2073e12c5d1SDavid du Colombier rauth(void) 2083e12c5d1SDavid du Colombier { 2093e12c5d1SDavid du Colombier chat("auth..."); 2103e12c5d1SDavid du Colombier error(Eauth); 2113e12c5d1SDavid du Colombier } 2123e12c5d1SDavid du Colombier 2133e12c5d1SDavid du Colombier static void 2143e12c5d1SDavid du Colombier rsession(void) 2153e12c5d1SDavid du Colombier { 2163e12c5d1SDavid du Colombier chat("session..."); 217219b2ee8SDavid du Colombier memset(rhdr.authid, 0, sizeof(rhdr.authid)); 218219b2ee8SDavid du Colombier memset(rhdr.authdom, 0, sizeof(rhdr.authdom)); 219219b2ee8SDavid du Colombier memset(rhdr.chal, 0, sizeof(rhdr.chal)); 2203e12c5d1SDavid du Colombier } 2213e12c5d1SDavid du Colombier 2223e12c5d1SDavid du Colombier static void 2233e12c5d1SDavid du Colombier rflush(void) 2243e12c5d1SDavid du Colombier { 2253e12c5d1SDavid du Colombier chat("flush..."); 2263e12c5d1SDavid du Colombier } 2273e12c5d1SDavid du Colombier 2283e12c5d1SDavid du Colombier static void 2293e12c5d1SDavid du Colombier rattach(void) 2303e12c5d1SDavid du Colombier { 2313e12c5d1SDavid du Colombier Xfile *root; 2323e12c5d1SDavid du Colombier Xfs *xf; 2333e12c5d1SDavid du Colombier Xfsub **xs; 2343e12c5d1SDavid du Colombier 2353e12c5d1SDavid du Colombier chat("attach(fid=%d,uname=\"%s\",aname=\"%s\",auth=\"%s\")...", 2363e12c5d1SDavid du Colombier thdr.fid, thdr.uname, thdr.aname, thdr.auth); 2373e12c5d1SDavid du Colombier 2383e12c5d1SDavid du Colombier if(waserror()){ 2393e12c5d1SDavid du Colombier xfile(thdr.fid, Clunk); 2403e12c5d1SDavid du Colombier nexterror(); 2413e12c5d1SDavid du Colombier } 2423e12c5d1SDavid du Colombier root = xfile(thdr.fid, Clean); 2433e12c5d1SDavid du Colombier root->qid = (Qid){CHDIR, 0}; 2443e12c5d1SDavid du Colombier root->xf = xf = ealloc(sizeof(Xfs)); 2453e12c5d1SDavid du Colombier memset(xf, 0, sizeof(Xfs)); 2463e12c5d1SDavid du Colombier xf->ref = 1; 2473e12c5d1SDavid du Colombier xf->d = getxdata(thdr.aname); 2483e12c5d1SDavid du Colombier 2493e12c5d1SDavid du Colombier for(xs=xsublist; *xs; xs++) 2503e12c5d1SDavid du Colombier if((*(*xs)->attach)(root) >= 0){ 2513e12c5d1SDavid du Colombier poperror(); 2523e12c5d1SDavid du Colombier xf->s = *xs; 2533e12c5d1SDavid du Colombier xf->rootqid = root->qid; 2543e12c5d1SDavid du Colombier rhdr.qid = root->qid; 2553e12c5d1SDavid du Colombier return; 2563e12c5d1SDavid du Colombier } 2573e12c5d1SDavid du Colombier error("unknown format"); 2583e12c5d1SDavid du Colombier } 2593e12c5d1SDavid du Colombier 2603e12c5d1SDavid du Colombier static void 2613e12c5d1SDavid du Colombier rclone(void) 2623e12c5d1SDavid du Colombier { 2633e12c5d1SDavid du Colombier Xfile *of, *nf, *next; 2643e12c5d1SDavid du Colombier 2653e12c5d1SDavid du Colombier chat("clone(fid=%d,newfid=%d)...", thdr.fid, thdr.newfid); 2663e12c5d1SDavid du Colombier of = xfile(thdr.fid, Asis); 2673e12c5d1SDavid du Colombier nf = xfile(thdr.newfid, Clean); 2683e12c5d1SDavid du Colombier if(waserror()){ 2693e12c5d1SDavid du Colombier xfile(thdr.newfid, Clunk); 2703e12c5d1SDavid du Colombier nexterror(); 2713e12c5d1SDavid du Colombier } 2723e12c5d1SDavid du Colombier next = nf->next; 2733e12c5d1SDavid du Colombier *nf = *of; 2743e12c5d1SDavid du Colombier nf->next = next; 2753e12c5d1SDavid du Colombier nf->fid = thdr.newfid; 2763e12c5d1SDavid du Colombier refxfs(nf->xf, 1); 2773e12c5d1SDavid du Colombier if(nf->len){ 2783e12c5d1SDavid du Colombier nf->ptr = ealloc(nf->len); 2793e12c5d1SDavid du Colombier memmove(nf->ptr, of->ptr, nf->len); 2803e12c5d1SDavid du Colombier }else 2813e12c5d1SDavid du Colombier nf->ptr = of->ptr; 2823e12c5d1SDavid du Colombier (*of->xf->s->clone)(of, nf); 2833e12c5d1SDavid du Colombier poperror(); 2843e12c5d1SDavid du Colombier } 2853e12c5d1SDavid du Colombier 2863e12c5d1SDavid du Colombier static void 2873e12c5d1SDavid du Colombier rwalk(void) 2883e12c5d1SDavid du Colombier { 2893e12c5d1SDavid du Colombier Xfile *f; 2903e12c5d1SDavid du Colombier 2913e12c5d1SDavid du Colombier chat("walk(fid=%d,name=\"%s\")...", thdr.fid, thdr.name); 2923e12c5d1SDavid du Colombier f=xfile(thdr.fid, Asis); 2933e12c5d1SDavid du Colombier if(!(f->qid.path & CHDIR)){ 2943e12c5d1SDavid du Colombier chat("qid.path=0x%x...", f->qid.path); 2953e12c5d1SDavid du Colombier error("walk in non-directory"); 2963e12c5d1SDavid du Colombier } 2973e12c5d1SDavid du Colombier if(strcmp(thdr.name, ".")==0) 2983e12c5d1SDavid du Colombier /* nop */; 2993e12c5d1SDavid du Colombier else if(strcmp(thdr.name, "..")==0){ 3003e12c5d1SDavid du Colombier if(f->qid.path==f->xf->rootqid.path) 3013e12c5d1SDavid du Colombier error("walkup from root"); 3023e12c5d1SDavid du Colombier (*f->xf->s->walkup)(f); 3033e12c5d1SDavid du Colombier }else 3043e12c5d1SDavid du Colombier (*f->xf->s->walk)(f, thdr.name); 3053e12c5d1SDavid du Colombier rhdr.qid = f->qid; 3063e12c5d1SDavid du Colombier } 3073e12c5d1SDavid du Colombier 3083e12c5d1SDavid du Colombier static void 3093e12c5d1SDavid du Colombier ropen(void) 3103e12c5d1SDavid du Colombier { 3113e12c5d1SDavid du Colombier Xfile *f; 3123e12c5d1SDavid du Colombier 3133e12c5d1SDavid du Colombier chat("open(fid=%d,mode=%d)...", thdr.fid, thdr.mode); 3143e12c5d1SDavid du Colombier f = xfile(thdr.fid, Asis); 3153e12c5d1SDavid du Colombier if(f->flags&Omodes) 3163e12c5d1SDavid du Colombier error("open on open file"); 3173e12c5d1SDavid du Colombier (*f->xf->s->open)(f, thdr.mode); 3183e12c5d1SDavid du Colombier chat("f->qid=0x%8.8lux...", f->qid.path); 3193e12c5d1SDavid du Colombier f->flags = openflags(thdr.mode); 3203e12c5d1SDavid du Colombier rhdr.qid = f->qid; 3213e12c5d1SDavid du Colombier } 3223e12c5d1SDavid du Colombier 3233e12c5d1SDavid du Colombier static void 3243e12c5d1SDavid du Colombier rcreate(void) 3253e12c5d1SDavid du Colombier { 3263e12c5d1SDavid du Colombier Xfile *f; 3273e12c5d1SDavid du Colombier 3283e12c5d1SDavid du Colombier chat("create(fid=%d,name=\"%s\",perm=%uo,mode=%d)...", 3293e12c5d1SDavid du Colombier thdr.fid, thdr.name, thdr.perm, thdr.mode); 3303e12c5d1SDavid du Colombier if(strcmp(thdr.name, ".") == 0 || strcmp(thdr.name, "..") == 0) 3313e12c5d1SDavid du Colombier error("create . or .."); 3323e12c5d1SDavid du Colombier f = xfile(thdr.fid, Asis); 3333e12c5d1SDavid du Colombier if(f->flags&Omodes) 3343e12c5d1SDavid du Colombier error("create on open file"); 3353e12c5d1SDavid du Colombier if(!(f->qid.path&CHDIR)) 3363e12c5d1SDavid du Colombier error("create in non-directory"); 3373e12c5d1SDavid du Colombier (*f->xf->s->create)(f, thdr.name, thdr.perm, thdr.mode); 3383e12c5d1SDavid du Colombier chat("f->qid=0x%8.8lux...", f->qid.path); 3393e12c5d1SDavid du Colombier f->flags = openflags(thdr.mode); 3403e12c5d1SDavid du Colombier rhdr.qid = f->qid; 3413e12c5d1SDavid du Colombier } 3423e12c5d1SDavid du Colombier 3433e12c5d1SDavid du Colombier static void 3443e12c5d1SDavid du Colombier rread(void) 3453e12c5d1SDavid du Colombier { 3463e12c5d1SDavid du Colombier Xfile *f; 3473e12c5d1SDavid du Colombier 3483e12c5d1SDavid du Colombier chat("read(fid=%d,offset=%d,count=%d)...", 3493e12c5d1SDavid du Colombier thdr.fid, thdr.offset, thdr.count); 3503e12c5d1SDavid du Colombier f=xfile(thdr.fid, Asis); 3513e12c5d1SDavid du Colombier if (!(f->flags&Oread)) 3523e12c5d1SDavid du Colombier error("file not opened for reading"); 3533e12c5d1SDavid du Colombier if(f->qid.path & CHDIR){ 3543e12c5d1SDavid du Colombier if(thdr.count%DIRLEN || thdr.offset%DIRLEN){ 3553e12c5d1SDavid du Colombier chat("count%%%d=%d,offset%%%d=%d...", 3563e12c5d1SDavid du Colombier DIRLEN, thdr.count%DIRLEN, 3573e12c5d1SDavid du Colombier DIRLEN, thdr.offset%DIRLEN); 3583e12c5d1SDavid du Colombier error("bad offset or count"); 3593e12c5d1SDavid du Colombier } 3603e12c5d1SDavid du Colombier rhdr.count = (*f->xf->s->readdir)(f, fdata, thdr.offset, thdr.count); 3613e12c5d1SDavid du Colombier }else 3623e12c5d1SDavid du Colombier rhdr.count = (*f->xf->s->read)(f, fdata, thdr.offset, thdr.count); 3633e12c5d1SDavid du Colombier rhdr.data = fdata; 3643e12c5d1SDavid du Colombier chat("rcnt=%d...", rhdr.count); 3653e12c5d1SDavid du Colombier } 3663e12c5d1SDavid du Colombier 3673e12c5d1SDavid du Colombier static void 3683e12c5d1SDavid du Colombier rwrite(void) 3693e12c5d1SDavid du Colombier { 3703e12c5d1SDavid du Colombier Xfile *f; 3713e12c5d1SDavid du Colombier 3723e12c5d1SDavid du Colombier chat("write(fid=%d,offset=%d,count=%d)...", 3733e12c5d1SDavid du Colombier thdr.fid, thdr.offset, thdr.count); 3743e12c5d1SDavid du Colombier f=xfile(thdr.fid, Asis); 3753e12c5d1SDavid du Colombier if(!(f->flags&Owrite)) 3763e12c5d1SDavid du Colombier error("file not opened for writing"); 3773e12c5d1SDavid du Colombier rhdr.count = (*f->xf->s->write)(f, thdr.data, thdr.offset, thdr.count); 3783e12c5d1SDavid du Colombier chat("rcnt=%d...", rhdr.count); 3793e12c5d1SDavid du Colombier } 3803e12c5d1SDavid du Colombier 3813e12c5d1SDavid du Colombier static void 3823e12c5d1SDavid du Colombier rclunk(void) 3833e12c5d1SDavid du Colombier { 3843e12c5d1SDavid du Colombier Xfile *f; 3853e12c5d1SDavid du Colombier 3863e12c5d1SDavid du Colombier chat("clunk(fid=%d)...", thdr.fid); 3873e12c5d1SDavid du Colombier if(!waserror()){ 3883e12c5d1SDavid du Colombier f = xfile(thdr.fid, Asis); 3893e12c5d1SDavid du Colombier if(f->flags&Orclose) 3903e12c5d1SDavid du Colombier (*f->xf->s->remove)(f); 3913e12c5d1SDavid du Colombier else 3923e12c5d1SDavid du Colombier (*f->xf->s->clunk)(f); 3933e12c5d1SDavid du Colombier poperror(); 3943e12c5d1SDavid du Colombier } 3953e12c5d1SDavid du Colombier xfile(thdr.fid, Clunk); 3963e12c5d1SDavid du Colombier } 3973e12c5d1SDavid du Colombier 3983e12c5d1SDavid du Colombier static void 3993e12c5d1SDavid du Colombier rremove(void) 4003e12c5d1SDavid du Colombier { 4013e12c5d1SDavid du Colombier Xfile *f; 4023e12c5d1SDavid du Colombier 4033e12c5d1SDavid du Colombier chat("remove(fid=%d)...", thdr.fid); 4043e12c5d1SDavid du Colombier if(waserror()){ 4053e12c5d1SDavid du Colombier xfile(thdr.fid, Clunk); 4063e12c5d1SDavid du Colombier nexterror(); 4073e12c5d1SDavid du Colombier } 4083e12c5d1SDavid du Colombier f=xfile(thdr.fid, Asis); 4093e12c5d1SDavid du Colombier (*f->xf->s->remove)(f); 4103e12c5d1SDavid du Colombier poperror(); 4113e12c5d1SDavid du Colombier xfile(thdr.fid, Clunk); 4123e12c5d1SDavid du Colombier } 4133e12c5d1SDavid du Colombier 4143e12c5d1SDavid du Colombier static void 4153e12c5d1SDavid du Colombier rstat(void) 4163e12c5d1SDavid du Colombier { 4173e12c5d1SDavid du Colombier Xfile *f; 4183e12c5d1SDavid du Colombier Dir dir; 4193e12c5d1SDavid du Colombier 4203e12c5d1SDavid du Colombier chat("stat(fid=%d)...", thdr.fid); 4213e12c5d1SDavid du Colombier f=xfile(thdr.fid, Asis); 4223e12c5d1SDavid du Colombier (*f->xf->s->stat)(f, &dir); 4233e12c5d1SDavid du Colombier if(chatty) 4243e12c5d1SDavid du Colombier showdir(2, &dir); 4253e12c5d1SDavid du Colombier convD2M(&dir, rhdr.stat); 4263e12c5d1SDavid du Colombier } 4273e12c5d1SDavid du Colombier 4283e12c5d1SDavid du Colombier static void 4293e12c5d1SDavid du Colombier rwstat(void) 4303e12c5d1SDavid du Colombier { 4313e12c5d1SDavid du Colombier Xfile *f; 4323e12c5d1SDavid du Colombier Dir dir; 4333e12c5d1SDavid du Colombier 4343e12c5d1SDavid du Colombier chat("wstat(fid=%d)...", thdr.fid); 4353e12c5d1SDavid du Colombier f=xfile(thdr.fid, Asis); 4363e12c5d1SDavid du Colombier convM2D(rhdr.stat, &dir); 4373e12c5d1SDavid du Colombier (*f->xf->s->wstat)(f, &dir); 4383e12c5d1SDavid du Colombier } 4393e12c5d1SDavid du Colombier 4403e12c5d1SDavid du Colombier static int 4413e12c5d1SDavid du Colombier openflags(int mode) 4423e12c5d1SDavid du Colombier { 4433e12c5d1SDavid du Colombier int flags = 0; 4443e12c5d1SDavid du Colombier 4453e12c5d1SDavid du Colombier switch(mode & ~(OTRUNC|OCEXEC|ORCLOSE)){ 4463e12c5d1SDavid du Colombier case OREAD: 4473e12c5d1SDavid du Colombier case OEXEC: 4483e12c5d1SDavid du Colombier flags = Oread; break; 4493e12c5d1SDavid du Colombier case OWRITE: 4503e12c5d1SDavid du Colombier flags = Owrite; break; 4513e12c5d1SDavid du Colombier case ORDWR: 4523e12c5d1SDavid du Colombier flags = Oread|Owrite; break; 4533e12c5d1SDavid du Colombier } 4543e12c5d1SDavid du Colombier if(mode & ORCLOSE) 4553e12c5d1SDavid du Colombier flags |= Orclose; 4563e12c5d1SDavid du Colombier return flags; 4573e12c5d1SDavid du Colombier } 4583e12c5d1SDavid du Colombier 4593e12c5d1SDavid du Colombier void 4603e12c5d1SDavid du Colombier showdir(int fd, Dir *s) 4613e12c5d1SDavid du Colombier { 4623e12c5d1SDavid du Colombier char a_time[32], m_time[32]; 4633e12c5d1SDavid du Colombier char *p; 4643e12c5d1SDavid du Colombier 4653e12c5d1SDavid du Colombier strcpy(a_time, ctime(s->atime)); 4663e12c5d1SDavid du Colombier if(p=strchr(a_time, '\n')) /* assign = */ 4673e12c5d1SDavid du Colombier *p = 0; 4683e12c5d1SDavid du Colombier strcpy(m_time, ctime(s->mtime)); 4693e12c5d1SDavid du Colombier if(p=strchr(m_time, '\n')) /* assign = */ 4703e12c5d1SDavid du Colombier *p = 0; 471*7dd7cddfSDavid du Colombier fprint(fd, "name=\"%s\" qid=(0x%8.8lux,%lud) type=%d dev=%d \ 472*7dd7cddfSDavid du Colombier mode=0x%8.8lux=0%luo atime=%s mtime=%s length=%lld uid=\"%s\" gid=\"%s\"...", 4733e12c5d1SDavid du Colombier s->name, s->qid.path, s->qid.vers, s->type, s->dev, 4743e12c5d1SDavid du Colombier s->mode, s->mode, 4753e12c5d1SDavid du Colombier a_time, m_time, s->length, s->uid, s->gid); 4763e12c5d1SDavid du Colombier } 4773e12c5d1SDavid du Colombier 4783e12c5d1SDavid du Colombier #define SIZE 1024 4793e12c5d1SDavid du Colombier 4803e12c5d1SDavid du Colombier void 4813e12c5d1SDavid du Colombier chat(char *fmt, ...) 4823e12c5d1SDavid du Colombier { 483*7dd7cddfSDavid du Colombier va_list arg; 4843e12c5d1SDavid du Colombier char buf[SIZE], *out; 4853e12c5d1SDavid du Colombier 4863e12c5d1SDavid du Colombier if(chatty){ 487*7dd7cddfSDavid du Colombier va_start(arg, fmt); 488*7dd7cddfSDavid du Colombier out = doprint(buf, buf+SIZE, fmt, arg); 489*7dd7cddfSDavid du Colombier va_end(arg); 4903e12c5d1SDavid du Colombier write(2, buf, out-buf); 4913e12c5d1SDavid du Colombier } 4923e12c5d1SDavid du Colombier } 4933e12c5d1SDavid du Colombier 4943e12c5d1SDavid du Colombier void 4953e12c5d1SDavid du Colombier panic(int rflag, char *fmt, ...) 4963e12c5d1SDavid du Colombier { 497*7dd7cddfSDavid du Colombier va_list arg; 4983e12c5d1SDavid du Colombier char buf[SIZE]; int n; 4993e12c5d1SDavid du Colombier 5003e12c5d1SDavid du Colombier n = sprint(buf, "%s %d: ", argv0, getpid()); 501*7dd7cddfSDavid du Colombier va_start(arg, fmt); 502*7dd7cddfSDavid du Colombier doprint(buf+n, buf+SIZE, fmt, arg); 503*7dd7cddfSDavid du Colombier va_end(arg); 5043e12c5d1SDavid du Colombier fprint(2, (rflag ? "%s: %r\n" : "%s\n"), buf); 5053e12c5d1SDavid du Colombier if(chatty){ 5063e12c5d1SDavid du Colombier fprint(2, "abort\n"); 5073e12c5d1SDavid du Colombier abort(); 5083e12c5d1SDavid du Colombier } 5093e12c5d1SDavid du Colombier exits("panic"); 5103e12c5d1SDavid du Colombier } 511