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 "iotrack.h" 63e12c5d1SDavid du Colombier #include "dat.h" 73e12c5d1SDavid du Colombier #include "fns.h" 83e12c5d1SDavid du Colombier 93e12c5d1SDavid du Colombier #include "errstr.h" 103e12c5d1SDavid du Colombier 113e12c5d1SDavid du Colombier Fcall thdr; 123e12c5d1SDavid du Colombier Fcall rhdr; 133e12c5d1SDavid du Colombier char data[sizeof(Fcall)+MAXFDATA]; 143e12c5d1SDavid du Colombier char fdata[MAXFDATA]; 153e12c5d1SDavid du Colombier int errno; 163e12c5d1SDavid du Colombier void rmservice(void); 173e12c5d1SDavid du Colombier char srvfile[64]; 183e12c5d1SDavid du Colombier char *deffile; 19*7dd7cddfSDavid du Colombier int doabort; 203e12c5d1SDavid du Colombier 213e12c5d1SDavid du Colombier void 223e12c5d1SDavid du Colombier usage(void) 233e12c5d1SDavid du Colombier { 243e12c5d1SDavid du Colombier fprint(2, "usage: %s [-v] [-s] [-f devicefile] [srvname]\n", argv0); 253e12c5d1SDavid du Colombier exits("usage"); 263e12c5d1SDavid du Colombier } 273e12c5d1SDavid du Colombier 283e12c5d1SDavid du Colombier void 293e12c5d1SDavid du Colombier main(int argc, char **argv) 303e12c5d1SDavid du Colombier { 313e12c5d1SDavid du Colombier int srvfd, pipefd[2], n; 323e12c5d1SDavid du Colombier int stdio; 333e12c5d1SDavid du Colombier 343e12c5d1SDavid du Colombier stdio = 0; 353e12c5d1SDavid du Colombier ARGBEGIN{ 36*7dd7cddfSDavid du Colombier case 'r': 37*7dd7cddfSDavid du Colombier readonly = 1; 38*7dd7cddfSDavid du Colombier break; 393e12c5d1SDavid du Colombier case 'v': 403e12c5d1SDavid du Colombier ++chatty; 413e12c5d1SDavid du Colombier break; 423e12c5d1SDavid du Colombier case 'f': 433e12c5d1SDavid du Colombier deffile = ARGF(); 443e12c5d1SDavid du Colombier break; 453e12c5d1SDavid du Colombier case 's': 463e12c5d1SDavid du Colombier stdio = 1; 473e12c5d1SDavid du Colombier break; 48*7dd7cddfSDavid du Colombier case 'p': 49*7dd7cddfSDavid du Colombier doabort = 1; 50*7dd7cddfSDavid du Colombier break; 513e12c5d1SDavid du Colombier default: 523e12c5d1SDavid du Colombier usage(); 533e12c5d1SDavid du Colombier }ARGEND 543e12c5d1SDavid du Colombier 553e12c5d1SDavid du Colombier if(argc == 0) 563e12c5d1SDavid du Colombier strcpy(srvfile, "#s/dos"); 573e12c5d1SDavid du Colombier else if(argc == 1) 583e12c5d1SDavid du Colombier sprint(srvfile, "#s/%s", argv[0]); 593e12c5d1SDavid du Colombier else 603e12c5d1SDavid du Colombier usage(); 613e12c5d1SDavid du Colombier 623e12c5d1SDavid du Colombier if(stdio){ 633e12c5d1SDavid du Colombier pipefd[0] = 0; 643e12c5d1SDavid du Colombier pipefd[1] = 1; 653e12c5d1SDavid du Colombier }else{ 663e12c5d1SDavid du Colombier close(0); 673e12c5d1SDavid du Colombier close(1); 683e12c5d1SDavid du Colombier open("/dev/null", OREAD); 693e12c5d1SDavid du Colombier open("/dev/null", OWRITE); 703e12c5d1SDavid du Colombier if(pipe(pipefd) < 0) 713e12c5d1SDavid du Colombier panic("pipe"); 723e12c5d1SDavid du Colombier srvfd = create(srvfile, OWRITE, 0666); 733e12c5d1SDavid du Colombier if(srvfd < 0) 743e12c5d1SDavid du Colombier panic(srvfile); 753e12c5d1SDavid du Colombier fprint(srvfd, "%d", pipefd[0]); 763e12c5d1SDavid du Colombier close(pipefd[0]); 773e12c5d1SDavid du Colombier close(srvfd); 783e12c5d1SDavid du Colombier atexit(rmservice); 79*7dd7cddfSDavid du Colombier fprint(2, "%s: serving %s\n", argv0, srvfile); 803e12c5d1SDavid du Colombier } 813e12c5d1SDavid du Colombier srvfd = pipefd[1]; 823e12c5d1SDavid du Colombier 83*7dd7cddfSDavid du Colombier switch(rfork(RFNOWAIT|RFNOTEG|RFFDG|RFPROC|RFNAMEG)){ 843e12c5d1SDavid du Colombier case -1: 853e12c5d1SDavid du Colombier panic("fork"); 863e12c5d1SDavid du Colombier default: 873e12c5d1SDavid du Colombier _exits(0); 883e12c5d1SDavid du Colombier case 0: 893e12c5d1SDavid du Colombier break; 903e12c5d1SDavid du Colombier } 913e12c5d1SDavid du Colombier 923e12c5d1SDavid du Colombier iotrack_init(); 933e12c5d1SDavid du Colombier 943e12c5d1SDavid du Colombier if(!chatty){ 953e12c5d1SDavid du Colombier close(2); 963e12c5d1SDavid du Colombier open("#c/cons", OWRITE); 973e12c5d1SDavid du Colombier } 98219b2ee8SDavid du Colombier while((n = read9p(srvfd, data, sizeof data)) > 0){ 993e12c5d1SDavid du Colombier if(convM2S(data, &thdr, n) <= 0) 1003e12c5d1SDavid du Colombier panic("convM2S"); 1013e12c5d1SDavid du Colombier errno = 0; 1023e12c5d1SDavid du Colombier switch(thdr.type){ 1033e12c5d1SDavid du Colombier default: panic("type"); break; 1043e12c5d1SDavid du Colombier case Tnop: rnop(); break; 1053e12c5d1SDavid du Colombier case Tsession: rsession(); break; 1063e12c5d1SDavid du Colombier case Tflush: rflush(); break; 1073e12c5d1SDavid du Colombier case Tattach: rattach(); break; 1083e12c5d1SDavid du Colombier case Tclone: rclone(); break; 1093e12c5d1SDavid du Colombier case Twalk: rwalk(); break; 1103e12c5d1SDavid du Colombier case Topen: ropen(); break; 1113e12c5d1SDavid du Colombier case Tcreate: rcreate(); break; 1123e12c5d1SDavid du Colombier case Tread: rread(); break; 1133e12c5d1SDavid du Colombier case Twrite: rwrite(); break; 1143e12c5d1SDavid du Colombier case Tclunk: rclunk(); break; 1153e12c5d1SDavid du Colombier case Tremove: rremove(); break; 1163e12c5d1SDavid du Colombier case Tstat: rstat(); break; 1173e12c5d1SDavid du Colombier case Twstat: rwstat(); break; 1183e12c5d1SDavid du Colombier } 1193e12c5d1SDavid du Colombier if(errno == 0) 1203e12c5d1SDavid du Colombier rhdr.type = thdr.type+1; 1213e12c5d1SDavid du Colombier else{ 1223e12c5d1SDavid du Colombier rhdr.type = Rerror; 1233e12c5d1SDavid du Colombier strncpy(rhdr.ename, xerrstr(errno), ERRLEN); 1243e12c5d1SDavid du Colombier } 1253e12c5d1SDavid du Colombier rhdr.fid = thdr.fid; 1263e12c5d1SDavid du Colombier rhdr.tag = thdr.tag; 1273e12c5d1SDavid du Colombier chat((errno==0 ? "OK\n" : "%s (%d)\n"), 1283e12c5d1SDavid du Colombier xerrstr(errno), errno); 1293e12c5d1SDavid du Colombier if((n = convS2M(&rhdr, data)) <= 0) 1303e12c5d1SDavid du Colombier panic("convS2M"); 131219b2ee8SDavid du Colombier if(write9p(srvfd, data, n) != n) 1323e12c5d1SDavid du Colombier panic("write"); 1333e12c5d1SDavid du Colombier } 134219b2ee8SDavid du Colombier chat((n<0) ? "server read error: %r\n" : "server EOF\n"); 1353e12c5d1SDavid du Colombier exits(0); 1363e12c5d1SDavid du Colombier } 1373e12c5d1SDavid du Colombier 1383e12c5d1SDavid du Colombier void 1393e12c5d1SDavid du Colombier rmservice(void) 1403e12c5d1SDavid du Colombier { 1413e12c5d1SDavid du Colombier remove(srvfile); 1423e12c5d1SDavid du Colombier } 1433e12c5d1SDavid du Colombier 1443e12c5d1SDavid du Colombier char * 1453e12c5d1SDavid du Colombier xerrstr(int e) 1463e12c5d1SDavid du Colombier { 1473e12c5d1SDavid du Colombier if (e < 0 || e >= sizeof errmsg/sizeof errmsg[0]) 1483e12c5d1SDavid du Colombier return "no such error"; 1493e12c5d1SDavid du Colombier else 1503e12c5d1SDavid du Colombier return errmsg[e]; 1513e12c5d1SDavid du Colombier } 152