]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/dossrv/xfssrv.c
Backed out changeset 2737b9af622b
[plan9front.git] / sys / src / cmd / dossrv / xfssrv.c
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include <fcall.h>
5 #include "iotrack.h"
6 #include "dat.h"
7 #include "dosfs.h"
8 #include "fns.h"
9
10 #include "errstr.h"
11
12 #define Reqsize (sizeof(Fcall)+Maxfdata)
13 Fcall   *req;
14 Fcall   *rep;
15
16 uchar   mdata[Maxiosize];
17 char    repdata[Maxfdata];
18 uchar   statbuf[STATMAX];
19 int     errno;
20 char    errbuf[ERRMAX];
21 char    srvfile[64];
22 char    *deffile;
23 int     doabort;
24 int     trspaces;
25
26 void    (*fcalls[])(void) = {
27         [Tversion]      rversion,
28         [Tflush]        rflush,
29         [Tauth] rauth,
30         [Tattach]       rattach,
31         [Twalk]         rwalk,
32         [Topen]         ropen,
33         [Tcreate]       rcreate,
34         [Tread]         rread,
35         [Twrite]        rwrite,
36         [Tclunk]        rclunk,
37         [Tremove]       rremove,
38         [Tstat]         rstat,
39         [Twstat]        rwstat,
40 };
41
42 void
43 usage(void)
44 {
45         fprint(2, "usage: %s [-v] [-s] [-f devicefile] [srvname]\n", argv0);
46         exits("usage");
47 }
48
49 void
50 main(int argc, char **argv)
51 {
52         int stdio, srvfd, pipefd[2];
53
54         rep = malloc(sizeof(Fcall));
55         req = malloc(Reqsize);
56         if(rep == nil || req == nil)
57                 panic("out of memory");
58         stdio = 0;
59         ARGBEGIN{
60         case ':':
61                 trspaces = 1;
62                 break;
63         case 'r':
64                 readonly = 1;
65                 break;
66         case 'v':
67                 ++chatty;
68                 break;
69         case 'f':
70                 deffile = ARGF();
71                 break;
72         case 's':
73                 stdio = 1;
74                 break;
75         case 'p':
76                 doabort = 1;
77                 break;
78         default:
79                 usage();
80         }ARGEND
81
82         if(argc == 0)
83                 strcpy(srvfile, "#s/dos");
84         else if(argc == 1)
85                 snprint(srvfile, sizeof srvfile, "#s/%s", argv[0]);
86         else
87                 usage();
88
89         iotrack_init();
90
91         if(!stdio){
92                 if(pipe(pipefd) < 0)
93                         panic("pipe");
94                 srvfd = create(srvfile, OWRITE|ORCLOSE, 0600);
95                 if(srvfd < 0)
96                         panic(srvfile);
97                 fprint(srvfd, "%d", pipefd[0]);
98                 close(pipefd[0]);
99                 fprint(2, "%s: serving %s\n", argv0, srvfile);
100
101                 dup(pipefd[1], 0);
102                 dup(pipefd[1], 1);
103         }
104
105         switch(rfork(RFNOWAIT|RFNOTEG|RFFDG|RFPROC|RFNAMEG)){
106         case -1:
107                 panic("fork");
108         default:
109                 _exits(nil);
110         case 0:
111                 break;
112         }
113
114         if(!chatty){
115                 close(2);
116                 open("#c/cons", OWRITE);
117         }
118
119         io();
120         exits(nil);
121 }
122
123 void
124 io(void)
125 {
126         int n, pid;
127
128         pid = getpid();
129
130         fmtinstall('F', fcallfmt);
131         while((n = read9pmsg(0, mdata, sizeof mdata)) != 0){
132                 if(n < 0)
133                         panic("mount read");
134                 if(convM2S(mdata, n, req) != n)
135                         panic("convM2S format error");
136
137                 if(chatty)
138                         fprint(2, "dossrv %d:<-%F\n", pid, req);
139
140                 errno = 0;
141                 if(!fcalls[req->type])
142                         errno = Ebadfcall;
143                 else
144                         (*fcalls[req->type])();
145                 if(errno){
146                         rep->type = Rerror;
147                         rep->ename = xerrstr(errno);
148                 }else{
149                         rep->type = req->type + 1;
150                         rep->fid = req->fid;
151                 }
152                 rep->tag = req->tag;
153                 if(chatty)
154                         fprint(2, "dossrv %d:->%F\n", pid, rep);
155                 n = convS2M(rep, mdata, sizeof mdata);
156                 if(n == 0)
157                         panic("convS2M error on write");
158                 if(write(1, mdata, n) != n)
159                         panic("mount write");
160         }
161         chat("server shut down\n");
162 }
163
164 char *
165 xerrstr(int e)
166 {
167         if (e < 0 || e >= sizeof errmsg/sizeof errmsg[0])
168                 return "no such error";
169         if(e == Eerrstr){
170                 errstr(errbuf, sizeof errbuf);
171                 return errbuf;
172         }
173         return errmsg[e];
174 }
175
176 int
177 eqqid(Qid q1, Qid q2)
178 {
179         return q1.path == q2.path && q1.type == q2.type && q1.vers == q2.vers;
180 }