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 "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; 193e12c5d1SDavid du Colombier 203e12c5d1SDavid du Colombier void 213e12c5d1SDavid du Colombier usage(void) 223e12c5d1SDavid du Colombier { 233e12c5d1SDavid du Colombier fprint(2, "usage: %s [-v] [-s] [-f devicefile] [srvname]\n", argv0); 243e12c5d1SDavid du Colombier exits("usage"); 253e12c5d1SDavid du Colombier } 263e12c5d1SDavid du Colombier 273e12c5d1SDavid du Colombier void 283e12c5d1SDavid du Colombier main(int argc, char **argv) 293e12c5d1SDavid du Colombier { 303e12c5d1SDavid du Colombier int srvfd, pipefd[2], n; 313e12c5d1SDavid du Colombier int stdio; 323e12c5d1SDavid du Colombier 333e12c5d1SDavid du Colombier stdio = 0; 343e12c5d1SDavid du Colombier ARGBEGIN{ 353e12c5d1SDavid du Colombier case 'v': 363e12c5d1SDavid du Colombier ++chatty; 373e12c5d1SDavid du Colombier break; 383e12c5d1SDavid du Colombier case 'f': 393e12c5d1SDavid du Colombier deffile = ARGF(); 403e12c5d1SDavid du Colombier break; 413e12c5d1SDavid du Colombier case 's': 423e12c5d1SDavid du Colombier stdio = 1; 433e12c5d1SDavid du Colombier break; 443e12c5d1SDavid du Colombier default: 453e12c5d1SDavid du Colombier usage(); 463e12c5d1SDavid du Colombier }ARGEND 473e12c5d1SDavid du Colombier 483e12c5d1SDavid du Colombier if(argc == 0) 493e12c5d1SDavid du Colombier strcpy(srvfile, "#s/dos"); 503e12c5d1SDavid du Colombier else if(argc == 1) 513e12c5d1SDavid du Colombier sprint(srvfile, "#s/%s", argv[0]); 523e12c5d1SDavid du Colombier else 533e12c5d1SDavid du Colombier usage(); 543e12c5d1SDavid du Colombier 553e12c5d1SDavid du Colombier if(stdio){ 563e12c5d1SDavid du Colombier pipefd[0] = 0; 573e12c5d1SDavid du Colombier pipefd[1] = 1; 583e12c5d1SDavid du Colombier }else{ 593e12c5d1SDavid du Colombier close(0); 603e12c5d1SDavid du Colombier close(1); 613e12c5d1SDavid du Colombier open("/dev/null", OREAD); 623e12c5d1SDavid du Colombier open("/dev/null", OWRITE); 633e12c5d1SDavid du Colombier if(pipe(pipefd) < 0) 643e12c5d1SDavid du Colombier panic("pipe"); 653e12c5d1SDavid du Colombier srvfd = create(srvfile, OWRITE, 0666); 663e12c5d1SDavid du Colombier if(srvfd < 0) 673e12c5d1SDavid du Colombier panic(srvfile); 683e12c5d1SDavid du Colombier fprint(srvfd, "%d", pipefd[0]); 693e12c5d1SDavid du Colombier close(pipefd[0]); 703e12c5d1SDavid du Colombier close(srvfd); 713e12c5d1SDavid du Colombier atexit(rmservice); 723e12c5d1SDavid du Colombier fprint(2, "%s %d: serving %s\n", argv0, getpid(), srvfile); 733e12c5d1SDavid du Colombier } 743e12c5d1SDavid du Colombier srvfd = pipefd[1]; 753e12c5d1SDavid du Colombier 763e12c5d1SDavid du Colombier switch(rfork(RFNOWAIT|RFNOTEG|RFFDG|RFPROC)){ 773e12c5d1SDavid du Colombier case -1: 783e12c5d1SDavid du Colombier panic("fork"); 793e12c5d1SDavid du Colombier default: 803e12c5d1SDavid du Colombier _exits(0); 813e12c5d1SDavid du Colombier case 0: 823e12c5d1SDavid du Colombier break; 833e12c5d1SDavid du Colombier } 843e12c5d1SDavid du Colombier 853e12c5d1SDavid du Colombier iotrack_init(); 863e12c5d1SDavid du Colombier 873e12c5d1SDavid du Colombier if(!chatty){ 883e12c5d1SDavid du Colombier close(2); 893e12c5d1SDavid du Colombier open("#c/cons", OWRITE); 903e12c5d1SDavid du Colombier } 91*219b2ee8SDavid du Colombier while((n = read9p(srvfd, data, sizeof data)) > 0){ 923e12c5d1SDavid du Colombier if(convM2S(data, &thdr, n) <= 0) 933e12c5d1SDavid du Colombier panic("convM2S"); 943e12c5d1SDavid du Colombier errno = 0; 953e12c5d1SDavid du Colombier switch(thdr.type){ 963e12c5d1SDavid du Colombier default: panic("type"); break; 973e12c5d1SDavid du Colombier case Tnop: rnop(); break; 983e12c5d1SDavid du Colombier case Tsession: rsession(); break; 993e12c5d1SDavid du Colombier case Tflush: rflush(); break; 1003e12c5d1SDavid du Colombier case Tattach: rattach(); break; 1013e12c5d1SDavid du Colombier case Tclone: rclone(); break; 1023e12c5d1SDavid du Colombier case Twalk: rwalk(); break; 1033e12c5d1SDavid du Colombier case Topen: ropen(); break; 1043e12c5d1SDavid du Colombier case Tcreate: rcreate(); break; 1053e12c5d1SDavid du Colombier case Tread: rread(); break; 1063e12c5d1SDavid du Colombier case Twrite: rwrite(); break; 1073e12c5d1SDavid du Colombier case Tclunk: rclunk(); break; 1083e12c5d1SDavid du Colombier case Tremove: rremove(); break; 1093e12c5d1SDavid du Colombier case Tstat: rstat(); break; 1103e12c5d1SDavid du Colombier case Twstat: rwstat(); break; 1113e12c5d1SDavid du Colombier } 1123e12c5d1SDavid du Colombier if(errno == 0) 1133e12c5d1SDavid du Colombier rhdr.type = thdr.type+1; 1143e12c5d1SDavid du Colombier else{ 1153e12c5d1SDavid du Colombier rhdr.type = Rerror; 1163e12c5d1SDavid du Colombier strncpy(rhdr.ename, xerrstr(errno), ERRLEN); 1173e12c5d1SDavid du Colombier } 1183e12c5d1SDavid du Colombier rhdr.fid = thdr.fid; 1193e12c5d1SDavid du Colombier rhdr.tag = thdr.tag; 1203e12c5d1SDavid du Colombier chat((errno==0 ? "OK\n" : "%s (%d)\n"), 1213e12c5d1SDavid du Colombier xerrstr(errno), errno); 1223e12c5d1SDavid du Colombier if((n = convS2M(&rhdr, data)) <= 0) 1233e12c5d1SDavid du Colombier panic("convS2M"); 124*219b2ee8SDavid du Colombier if(write9p(srvfd, data, n) != n) 1253e12c5d1SDavid du Colombier panic("write"); 1263e12c5d1SDavid du Colombier } 127*219b2ee8SDavid du Colombier chat((n<0) ? "server read error: %r\n" : "server EOF\n"); 1283e12c5d1SDavid du Colombier exits(0); 1293e12c5d1SDavid du Colombier } 1303e12c5d1SDavid du Colombier 1313e12c5d1SDavid du Colombier void 1323e12c5d1SDavid du Colombier rmservice(void) 1333e12c5d1SDavid du Colombier { 1343e12c5d1SDavid du Colombier remove(srvfile); 1353e12c5d1SDavid du Colombier } 1363e12c5d1SDavid du Colombier 1373e12c5d1SDavid du Colombier char * 1383e12c5d1SDavid du Colombier xerrstr(int e) 1393e12c5d1SDavid du Colombier { 1403e12c5d1SDavid du Colombier if (e < 0 || e >= sizeof errmsg/sizeof errmsg[0]) 1413e12c5d1SDavid du Colombier return "no such error"; 1423e12c5d1SDavid du Colombier else 1433e12c5d1SDavid du Colombier return errmsg[e]; 1443e12c5d1SDavid du Colombier } 145