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"
7*9a747e4fSDavid du Colombier #include "dosfs.h"
83e12c5d1SDavid du Colombier #include "fns.h"
93e12c5d1SDavid du Colombier
103e12c5d1SDavid du Colombier #include "errstr.h"
113e12c5d1SDavid du Colombier
12*9a747e4fSDavid du Colombier #define Reqsize (sizeof(Fcall)+Maxfdata)
13*9a747e4fSDavid du Colombier Fcall *req;
14*9a747e4fSDavid du Colombier Fcall *rep;
15*9a747e4fSDavid du Colombier
16*9a747e4fSDavid du Colombier uchar mdata[Maxiosize];
17*9a747e4fSDavid du Colombier char repdata[Maxfdata];
18*9a747e4fSDavid du Colombier uchar statbuf[STATMAX];
193e12c5d1SDavid du Colombier int errno;
20*9a747e4fSDavid du Colombier char errbuf[ERRMAX];
213e12c5d1SDavid du Colombier void rmservice(void);
223e12c5d1SDavid du Colombier char srvfile[64];
233e12c5d1SDavid du Colombier char *deffile;
247dd7cddfSDavid du Colombier int doabort;
25*9a747e4fSDavid du Colombier int trspaces;
26*9a747e4fSDavid du Colombier
27*9a747e4fSDavid du Colombier void (*fcalls[])(void) = {
28*9a747e4fSDavid du Colombier [Tversion] rversion,
29*9a747e4fSDavid du Colombier [Tflush] rflush,
30*9a747e4fSDavid du Colombier [Tauth] rauth,
31*9a747e4fSDavid du Colombier [Tattach] rattach,
32*9a747e4fSDavid du Colombier [Twalk] rwalk,
33*9a747e4fSDavid du Colombier [Topen] ropen,
34*9a747e4fSDavid du Colombier [Tcreate] rcreate,
35*9a747e4fSDavid du Colombier [Tread] rread,
36*9a747e4fSDavid du Colombier [Twrite] rwrite,
37*9a747e4fSDavid du Colombier [Tclunk] rclunk,
38*9a747e4fSDavid du Colombier [Tremove] rremove,
39*9a747e4fSDavid du Colombier [Tstat] rstat,
40*9a747e4fSDavid du Colombier [Twstat] rwstat,
41*9a747e4fSDavid du Colombier };
423e12c5d1SDavid du Colombier
433e12c5d1SDavid du Colombier void
usage(void)443e12c5d1SDavid du Colombier usage(void)
453e12c5d1SDavid du Colombier {
463e12c5d1SDavid du Colombier fprint(2, "usage: %s [-v] [-s] [-f devicefile] [srvname]\n", argv0);
473e12c5d1SDavid du Colombier exits("usage");
483e12c5d1SDavid du Colombier }
493e12c5d1SDavid du Colombier
503e12c5d1SDavid du Colombier void
main(int argc,char ** argv)513e12c5d1SDavid du Colombier main(int argc, char **argv)
523e12c5d1SDavid du Colombier {
53*9a747e4fSDavid du Colombier int stdio, srvfd, pipefd[2];
543e12c5d1SDavid du Colombier
55*9a747e4fSDavid du Colombier rep = malloc(sizeof(Fcall));
56*9a747e4fSDavid du Colombier req = malloc(Reqsize);
57*9a747e4fSDavid du Colombier if(rep == nil || req == nil)
58*9a747e4fSDavid du Colombier panic("out of memory");
593e12c5d1SDavid du Colombier stdio = 0;
603e12c5d1SDavid du Colombier ARGBEGIN{
61*9a747e4fSDavid du Colombier case ':':
62*9a747e4fSDavid du Colombier trspaces = 1;
63*9a747e4fSDavid du Colombier break;
647dd7cddfSDavid du Colombier case 'r':
657dd7cddfSDavid du Colombier readonly = 1;
667dd7cddfSDavid du Colombier break;
673e12c5d1SDavid du Colombier case 'v':
683e12c5d1SDavid du Colombier ++chatty;
693e12c5d1SDavid du Colombier break;
703e12c5d1SDavid du Colombier case 'f':
713e12c5d1SDavid du Colombier deffile = ARGF();
723e12c5d1SDavid du Colombier break;
733e12c5d1SDavid du Colombier case 's':
743e12c5d1SDavid du Colombier stdio = 1;
753e12c5d1SDavid du Colombier break;
767dd7cddfSDavid du Colombier case 'p':
777dd7cddfSDavid du Colombier doabort = 1;
787dd7cddfSDavid du Colombier break;
793e12c5d1SDavid du Colombier default:
803e12c5d1SDavid du Colombier usage();
813e12c5d1SDavid du Colombier }ARGEND
823e12c5d1SDavid du Colombier
833e12c5d1SDavid du Colombier if(argc == 0)
843e12c5d1SDavid du Colombier strcpy(srvfile, "#s/dos");
853e12c5d1SDavid du Colombier else if(argc == 1)
86*9a747e4fSDavid du Colombier snprint(srvfile, sizeof srvfile, "#s/%s", argv[0]);
873e12c5d1SDavid du Colombier else
883e12c5d1SDavid du Colombier usage();
893e12c5d1SDavid du Colombier
903e12c5d1SDavid du Colombier if(stdio){
913e12c5d1SDavid du Colombier pipefd[0] = 0;
923e12c5d1SDavid du Colombier pipefd[1] = 1;
933e12c5d1SDavid du Colombier }else{
943e12c5d1SDavid du Colombier close(0);
953e12c5d1SDavid du Colombier close(1);
963e12c5d1SDavid du Colombier open("/dev/null", OREAD);
973e12c5d1SDavid du Colombier open("/dev/null", OWRITE);
983e12c5d1SDavid du Colombier if(pipe(pipefd) < 0)
993e12c5d1SDavid du Colombier panic("pipe");
100*9a747e4fSDavid du Colombier srvfd = create(srvfile, OWRITE|ORCLOSE, 0600);
1013e12c5d1SDavid du Colombier if(srvfd < 0)
1023e12c5d1SDavid du Colombier panic(srvfile);
1033e12c5d1SDavid du Colombier fprint(srvfd, "%d", pipefd[0]);
1043e12c5d1SDavid du Colombier close(pipefd[0]);
1053e12c5d1SDavid du Colombier atexit(rmservice);
1067dd7cddfSDavid du Colombier fprint(2, "%s: serving %s\n", argv0, srvfile);
1073e12c5d1SDavid du Colombier }
1083e12c5d1SDavid du Colombier srvfd = pipefd[1];
1093e12c5d1SDavid du Colombier
1107dd7cddfSDavid du Colombier switch(rfork(RFNOWAIT|RFNOTEG|RFFDG|RFPROC|RFNAMEG)){
1113e12c5d1SDavid du Colombier case -1:
1123e12c5d1SDavid du Colombier panic("fork");
1133e12c5d1SDavid du Colombier default:
1143e12c5d1SDavid du Colombier _exits(0);
1153e12c5d1SDavid du Colombier case 0:
1163e12c5d1SDavid du Colombier break;
1173e12c5d1SDavid du Colombier }
1183e12c5d1SDavid du Colombier
1193e12c5d1SDavid du Colombier iotrack_init();
1203e12c5d1SDavid du Colombier
1213e12c5d1SDavid du Colombier if(!chatty){
1223e12c5d1SDavid du Colombier close(2);
1233e12c5d1SDavid du Colombier open("#c/cons", OWRITE);
1243e12c5d1SDavid du Colombier }
125*9a747e4fSDavid du Colombier
126*9a747e4fSDavid du Colombier io(srvfd);
1273e12c5d1SDavid du Colombier exits(0);
1283e12c5d1SDavid du Colombier }
1293e12c5d1SDavid du Colombier
1303e12c5d1SDavid du Colombier void
io(int srvfd)131*9a747e4fSDavid du Colombier io(int srvfd)
132*9a747e4fSDavid du Colombier {
133*9a747e4fSDavid du Colombier int n, pid;
134*9a747e4fSDavid du Colombier
135*9a747e4fSDavid du Colombier pid = getpid();
136*9a747e4fSDavid du Colombier
137*9a747e4fSDavid du Colombier fmtinstall('F', fcallfmt);
138*9a747e4fSDavid du Colombier for(;;){
139*9a747e4fSDavid du Colombier /*
140*9a747e4fSDavid du Colombier * reading from a pipe or a network device
141*9a747e4fSDavid du Colombier * will give an error after a few eof reads.
142*9a747e4fSDavid du Colombier * however, we cannot tell the difference
143*9a747e4fSDavid du Colombier * between a zero-length read and an interrupt
144*9a747e4fSDavid du Colombier * on the processes writing to us,
145*9a747e4fSDavid du Colombier * so we wait for the error.
146*9a747e4fSDavid du Colombier */
147*9a747e4fSDavid du Colombier n = read9pmsg(srvfd, mdata, sizeof mdata);
148*9a747e4fSDavid du Colombier if(n < 0)
149*9a747e4fSDavid du Colombier break;
150*9a747e4fSDavid du Colombier if(n == 0)
151*9a747e4fSDavid du Colombier continue;
152*9a747e4fSDavid du Colombier if(convM2S(mdata, n, req) == 0)
153*9a747e4fSDavid du Colombier continue;
154*9a747e4fSDavid du Colombier
155*9a747e4fSDavid du Colombier if(chatty)
156*9a747e4fSDavid du Colombier fprint(2, "dossrv %d:<-%F\n", pid, req);
157*9a747e4fSDavid du Colombier
158*9a747e4fSDavid du Colombier errno = 0;
159*9a747e4fSDavid du Colombier if(!fcalls[req->type])
160*9a747e4fSDavid du Colombier errno = Ebadfcall;
161*9a747e4fSDavid du Colombier else
162*9a747e4fSDavid du Colombier (*fcalls[req->type])();
163*9a747e4fSDavid du Colombier if(errno){
164*9a747e4fSDavid du Colombier rep->type = Rerror;
165*9a747e4fSDavid du Colombier rep->ename = xerrstr(errno);
166*9a747e4fSDavid du Colombier }else{
167*9a747e4fSDavid du Colombier rep->type = req->type + 1;
168*9a747e4fSDavid du Colombier rep->fid = req->fid;
169*9a747e4fSDavid du Colombier }
170*9a747e4fSDavid du Colombier rep->tag = req->tag;
171*9a747e4fSDavid du Colombier if(chatty)
172*9a747e4fSDavid du Colombier fprint(2, "dossrv %d:->%F\n", pid, rep);
173*9a747e4fSDavid du Colombier n = convS2M(rep, mdata, sizeof mdata);
174*9a747e4fSDavid du Colombier if(n == 0)
175*9a747e4fSDavid du Colombier panic("convS2M error on write");
176*9a747e4fSDavid du Colombier if(write(srvfd, mdata, n) != n)
177*9a747e4fSDavid du Colombier panic("mount write");
178*9a747e4fSDavid du Colombier }
179*9a747e4fSDavid du Colombier chat("server shut down");
180*9a747e4fSDavid du Colombier }
181*9a747e4fSDavid du Colombier
182*9a747e4fSDavid du Colombier void
rmservice(void)1833e12c5d1SDavid du Colombier rmservice(void)
1843e12c5d1SDavid du Colombier {
1853e12c5d1SDavid du Colombier remove(srvfile);
1863e12c5d1SDavid du Colombier }
1873e12c5d1SDavid du Colombier
1883e12c5d1SDavid du Colombier char *
xerrstr(int e)1893e12c5d1SDavid du Colombier xerrstr(int e)
1903e12c5d1SDavid du Colombier {
1913e12c5d1SDavid du Colombier if (e < 0 || e >= sizeof errmsg/sizeof errmsg[0])
1923e12c5d1SDavid du Colombier return "no such error";
193*9a747e4fSDavid du Colombier if(e == Eerrstr){
194*9a747e4fSDavid du Colombier errstr(errbuf, sizeof errbuf);
195*9a747e4fSDavid du Colombier return errbuf;
196*9a747e4fSDavid du Colombier }
1973e12c5d1SDavid du Colombier return errmsg[e];
1983e12c5d1SDavid du Colombier }
199*9a747e4fSDavid du Colombier
200*9a747e4fSDavid du Colombier int
eqqid(Qid q1,Qid q2)201*9a747e4fSDavid du Colombier eqqid(Qid q1, Qid q2)
202*9a747e4fSDavid du Colombier {
203*9a747e4fSDavid du Colombier return q1.path == q2.path && q1.type == q2.type && q1.vers == q2.vers;
204*9a747e4fSDavid du Colombier }
205