Blame


1 78a779a3 2008-07-20 rsc #include <u.h>
2 78a779a3 2008-07-20 rsc #include <libc.h>
3 78a779a3 2008-07-20 rsc #include <auth.h>
4 78a779a3 2008-07-20 rsc #include <fcall.h>
5 20035ed4 2014-02-28 minux.ma #include <errno.h>
6 78a779a3 2008-07-20 rsc #include "dat.h"
7 78a779a3 2008-07-20 rsc #include "fns.h"
8 78a779a3 2008-07-20 rsc
9 78a779a3 2008-07-20 rsc enum
10 78a779a3 2008-07-20 rsc {
11 78a779a3 2008-07-20 rsc Maxfdata = 8192,
12 78a779a3 2008-07-20 rsc Maxiosize = IOHDRSZ+Maxfdata,
13 78a779a3 2008-07-20 rsc };
14 78a779a3 2008-07-20 rsc
15 78a779a3 2008-07-20 rsc void io(int);
16 78a779a3 2008-07-20 rsc void rversion(void);
17 78a779a3 2008-07-20 rsc void rattach(void);
18 78a779a3 2008-07-20 rsc void rauth(void);
19 78a779a3 2008-07-20 rsc void rclunk(void);
20 78a779a3 2008-07-20 rsc void rcreate(void);
21 78a779a3 2008-07-20 rsc void rflush(void);
22 78a779a3 2008-07-20 rsc void ropen(void);
23 78a779a3 2008-07-20 rsc void rread(void);
24 78a779a3 2008-07-20 rsc void rremove(void);
25 78a779a3 2008-07-20 rsc void rsession(void);
26 78a779a3 2008-07-20 rsc void rstat(void);
27 78a779a3 2008-07-20 rsc void rwalk(void);
28 78a779a3 2008-07-20 rsc void rwrite(void);
29 78a779a3 2008-07-20 rsc void rwstat(void);
30 78a779a3 2008-07-20 rsc
31 78a779a3 2008-07-20 rsc static int openflags(int);
32 78a779a3 2008-07-20 rsc static void usage(void);
33 78a779a3 2008-07-20 rsc
34 78a779a3 2008-07-20 rsc #define Reqsize (sizeof(Fcall)+Maxfdata)
35 78a779a3 2008-07-20 rsc
36 78a779a3 2008-07-20 rsc Fcall *req;
37 78a779a3 2008-07-20 rsc Fcall *rep;
38 78a779a3 2008-07-20 rsc
39 78a779a3 2008-07-20 rsc uchar mdata[Maxiosize];
40 78a779a3 2008-07-20 rsc char fdata[Maxfdata];
41 78a779a3 2008-07-20 rsc uchar statbuf[STATMAX];
42 78a779a3 2008-07-20 rsc
43 78a779a3 2008-07-20 rsc
44 78a779a3 2008-07-20 rsc extern Xfsub *xsublist[];
45 78a779a3 2008-07-20 rsc extern int nclust;
46 78a779a3 2008-07-20 rsc
47 78a779a3 2008-07-20 rsc jmp_buf err_lab[16];
48 78a779a3 2008-07-20 rsc int nerr_lab;
49 78a779a3 2008-07-20 rsc char err_msg[ERRMAX];
50 78a779a3 2008-07-20 rsc
51 78a779a3 2008-07-20 rsc int chatty;
52 78a779a3 2008-07-20 rsc int nojoliet;
53 78a779a3 2008-07-20 rsc int noplan9;
54 78a779a3 2008-07-20 rsc int norock;
55 78a779a3 2008-07-20 rsc
56 f134aa3c 2008-12-02 trisk void (*fcalls[Tmax])(void);
57 78a779a3 2008-07-20 rsc
58 f134aa3c 2008-12-02 trisk static void
59 f134aa3c 2008-12-02 trisk initfcalls(void)
60 f134aa3c 2008-12-02 trisk {
61 f134aa3c 2008-12-02 trisk fcalls[Tversion]= rversion;
62 f134aa3c 2008-12-02 trisk fcalls[Tflush]= rflush;
63 f134aa3c 2008-12-02 trisk fcalls[Tauth]= rauth;
64 f134aa3c 2008-12-02 trisk fcalls[Tattach]= rattach;
65 f134aa3c 2008-12-02 trisk fcalls[Twalk]= rwalk;
66 f134aa3c 2008-12-02 trisk fcalls[Topen]= ropen;
67 f134aa3c 2008-12-02 trisk fcalls[Tcreate]= rcreate;
68 f134aa3c 2008-12-02 trisk fcalls[Tread]= rread;
69 f134aa3c 2008-12-02 trisk fcalls[Twrite]= rwrite;
70 f134aa3c 2008-12-02 trisk fcalls[Tclunk]= rclunk;
71 f134aa3c 2008-12-02 trisk fcalls[Tremove]= rremove;
72 f134aa3c 2008-12-02 trisk fcalls[Tstat]= rstat;
73 f134aa3c 2008-12-02 trisk fcalls[Twstat]= rwstat;
74 f134aa3c 2008-12-02 trisk }
75 f134aa3c 2008-12-02 trisk
76 78a779a3 2008-07-20 rsc void
77 78a779a3 2008-07-20 rsc main(int argc, char **argv)
78 78a779a3 2008-07-20 rsc {
79 78a779a3 2008-07-20 rsc int srvfd, pipefd[2], stdio;
80 78a779a3 2008-07-20 rsc Xfsub **xs;
81 78a779a3 2008-07-20 rsc char *mtpt;
82 78a779a3 2008-07-20 rsc
83 f134aa3c 2008-12-02 trisk initfcalls();
84 78a779a3 2008-07-20 rsc stdio = 0;
85 78a779a3 2008-07-20 rsc mtpt = nil;
86 78a779a3 2008-07-20 rsc ARGBEGIN {
87 78a779a3 2008-07-20 rsc case '9':
88 78a779a3 2008-07-20 rsc noplan9 = 1;
89 78a779a3 2008-07-20 rsc break;
90 78a779a3 2008-07-20 rsc case 'c':
91 78a779a3 2008-07-20 rsc nclust = atoi(EARGF(usage()));
92 78a779a3 2008-07-20 rsc if (nclust <= 0)
93 78a779a3 2008-07-20 rsc sysfatal("nclust %d non-positive", nclust);
94 78a779a3 2008-07-20 rsc break;
95 78a779a3 2008-07-20 rsc case 'f':
96 78a779a3 2008-07-20 rsc deffile = EARGF(usage());
97 78a779a3 2008-07-20 rsc break;
98 78a779a3 2008-07-20 rsc case 'r':
99 78a779a3 2008-07-20 rsc norock = 1;
100 78a779a3 2008-07-20 rsc break;
101 78a779a3 2008-07-20 rsc case 's':
102 78a779a3 2008-07-20 rsc stdio = 1;
103 78a779a3 2008-07-20 rsc break;
104 78a779a3 2008-07-20 rsc case 'v':
105 78a779a3 2008-07-20 rsc chatty = 1;
106 78a779a3 2008-07-20 rsc break;
107 78a779a3 2008-07-20 rsc case 'J':
108 78a779a3 2008-07-20 rsc nojoliet = 1;
109 78a779a3 2008-07-20 rsc break;
110 78a779a3 2008-07-20 rsc case 'm':
111 78a779a3 2008-07-20 rsc mtpt = EARGF(usage());
112 78a779a3 2008-07-20 rsc break;
113 78a779a3 2008-07-20 rsc default:
114 78a779a3 2008-07-20 rsc usage();
115 78a779a3 2008-07-20 rsc } ARGEND
116 78a779a3 2008-07-20 rsc
117 78a779a3 2008-07-20 rsc switch(argc) {
118 78a779a3 2008-07-20 rsc case 0:
119 78a779a3 2008-07-20 rsc break;
120 78a779a3 2008-07-20 rsc case 1:
121 78a779a3 2008-07-20 rsc srvname = argv[0];
122 78a779a3 2008-07-20 rsc break;
123 78a779a3 2008-07-20 rsc default:
124 78a779a3 2008-07-20 rsc usage();
125 78a779a3 2008-07-20 rsc }
126 78a779a3 2008-07-20 rsc
127 78a779a3 2008-07-20 rsc iobuf_init();
128 78a779a3 2008-07-20 rsc for(xs=xsublist; *xs; xs++)
129 78a779a3 2008-07-20 rsc (*(*xs)->reset)();
130 78a779a3 2008-07-20 rsc
131 78a779a3 2008-07-20 rsc if(stdio) {
132 78a779a3 2008-07-20 rsc pipefd[0] = 0;
133 78a779a3 2008-07-20 rsc pipefd[1] = 1;
134 78a779a3 2008-07-20 rsc } else {
135 78a779a3 2008-07-20 rsc close(0);
136 78a779a3 2008-07-20 rsc close(1);
137 78a779a3 2008-07-20 rsc open("/dev/null", OREAD);
138 78a779a3 2008-07-20 rsc open("/dev/null", OWRITE);
139 78a779a3 2008-07-20 rsc if(pipe(pipefd) < 0)
140 78a779a3 2008-07-20 rsc panic(1, "pipe");
141 fa325e9b 2020-01-10 cross
142 78a779a3 2008-07-20 rsc if(post9pservice(pipefd[0], srvname, mtpt) < 0)
143 78a779a3 2008-07-20 rsc sysfatal("post9pservice: %r");
144 78a779a3 2008-07-20 rsc close(pipefd[0]);
145 78a779a3 2008-07-20 rsc }
146 78a779a3 2008-07-20 rsc srvfd = pipefd[1];
147 fa325e9b 2020-01-10 cross
148 78a779a3 2008-07-20 rsc switch(rfork(RFNOWAIT|RFNOTEG|RFFDG|RFPROC)){
149 78a779a3 2008-07-20 rsc case -1:
150 78a779a3 2008-07-20 rsc panic(1, "fork");
151 78a779a3 2008-07-20 rsc default:
152 78a779a3 2008-07-20 rsc _exits(0);
153 78a779a3 2008-07-20 rsc case 0:
154 78a779a3 2008-07-20 rsc break;
155 78a779a3 2008-07-20 rsc }
156 78a779a3 2008-07-20 rsc
157 78a779a3 2008-07-20 rsc io(srvfd);
158 78a779a3 2008-07-20 rsc exits(0);
159 78a779a3 2008-07-20 rsc }
160 78a779a3 2008-07-20 rsc
161 78a779a3 2008-07-20 rsc void
162 78a779a3 2008-07-20 rsc io(int srvfd)
163 78a779a3 2008-07-20 rsc {
164 78a779a3 2008-07-20 rsc int n, pid;
165 78a779a3 2008-07-20 rsc Fcall xreq, xrep;
166 78a779a3 2008-07-20 rsc
167 78a779a3 2008-07-20 rsc req = &xreq;
168 78a779a3 2008-07-20 rsc rep = &xrep;
169 78a779a3 2008-07-20 rsc pid = getpid();
170 78a779a3 2008-07-20 rsc fmtinstall('F', fcallfmt);
171 78a779a3 2008-07-20 rsc
172 78a779a3 2008-07-20 rsc for(;;){
173 78a779a3 2008-07-20 rsc /*
174 78a779a3 2008-07-20 rsc * reading from a pipe or a network device
175 78a779a3 2008-07-20 rsc * will give an error after a few eof reads.
176 78a779a3 2008-07-20 rsc * however, we cannot tell the difference
177 78a779a3 2008-07-20 rsc * between a zero-length read and an interrupt
178 78a779a3 2008-07-20 rsc * on the processes writing to us,
179 78a779a3 2008-07-20 rsc * so we wait for the error.
180 78a779a3 2008-07-20 rsc */
181 78a779a3 2008-07-20 rsc n = read9pmsg(srvfd, mdata, sizeof mdata);
182 78a779a3 2008-07-20 rsc if(n < 0)
183 78a779a3 2008-07-20 rsc break;
184 78a779a3 2008-07-20 rsc if(n == 0)
185 78a779a3 2008-07-20 rsc continue;
186 78a779a3 2008-07-20 rsc if(convM2S(mdata, n, req) == 0)
187 78a779a3 2008-07-20 rsc continue;
188 78a779a3 2008-07-20 rsc
189 78a779a3 2008-07-20 rsc if(chatty)
190 78a779a3 2008-07-20 rsc fprint(2, "9660srv %d:<-%F\n", pid, req);
191 78a779a3 2008-07-20 rsc
192 78a779a3 2008-07-20 rsc errno = 0;
193 78a779a3 2008-07-20 rsc if(!waserror()){
194 78a779a3 2008-07-20 rsc err_msg[0] = 0;
195 78a779a3 2008-07-20 rsc if(req->type >= nelem(fcalls) || !fcalls[req->type])
196 78a779a3 2008-07-20 rsc error("bad fcall type");
197 78a779a3 2008-07-20 rsc (*fcalls[req->type])();
198 78a779a3 2008-07-20 rsc poperror();
199 78a779a3 2008-07-20 rsc }
200 78a779a3 2008-07-20 rsc
201 78a779a3 2008-07-20 rsc if(err_msg[0]){
202 78a779a3 2008-07-20 rsc rep->type = Rerror;
203 78a779a3 2008-07-20 rsc rep->ename = err_msg;
204 78a779a3 2008-07-20 rsc }else{
205 78a779a3 2008-07-20 rsc rep->type = req->type + 1;
206 78a779a3 2008-07-20 rsc rep->fid = req->fid;
207 78a779a3 2008-07-20 rsc }
208 78a779a3 2008-07-20 rsc rep->tag = req->tag;
209 78a779a3 2008-07-20 rsc
210 78a779a3 2008-07-20 rsc if(chatty)
211 78a779a3 2008-07-20 rsc fprint(2, "9660srv %d:->%F\n", pid, rep);
212 78a779a3 2008-07-20 rsc n = convS2M(rep, mdata, sizeof mdata);
213 78a779a3 2008-07-20 rsc if(n == 0)
214 78a779a3 2008-07-20 rsc panic(1, "convS2M error on write");
215 78a779a3 2008-07-20 rsc if(write(srvfd, mdata, n) != n)
216 78a779a3 2008-07-20 rsc panic(1, "mount write");
217 78a779a3 2008-07-20 rsc if(nerr_lab != 0)
218 78a779a3 2008-07-20 rsc panic(0, "err stack %d");
219 78a779a3 2008-07-20 rsc }
220 78a779a3 2008-07-20 rsc chat("server shut down");
221 78a779a3 2008-07-20 rsc }
222 78a779a3 2008-07-20 rsc
223 78a779a3 2008-07-20 rsc static void
224 78a779a3 2008-07-20 rsc usage(void)
225 78a779a3 2008-07-20 rsc {
226 78a779a3 2008-07-20 rsc fprint(2, "usage: %s [-v] [-9Jr] [-s] [-f devicefile] [srvname]\n", argv0);
227 78a779a3 2008-07-20 rsc exits("usage");
228 78a779a3 2008-07-20 rsc }
229 78a779a3 2008-07-20 rsc
230 78a779a3 2008-07-20 rsc void
231 78a779a3 2008-07-20 rsc error(char *p)
232 78a779a3 2008-07-20 rsc {
233 78a779a3 2008-07-20 rsc strecpy(err_msg, err_msg+sizeof err_msg, p);
234 78a779a3 2008-07-20 rsc nexterror();
235 78a779a3 2008-07-20 rsc }
236 78a779a3 2008-07-20 rsc
237 78a779a3 2008-07-20 rsc void
238 78a779a3 2008-07-20 rsc nexterror(void)
239 78a779a3 2008-07-20 rsc {
240 78a779a3 2008-07-20 rsc longjmp(err_lab[--nerr_lab], 1);
241 78a779a3 2008-07-20 rsc }
242 78a779a3 2008-07-20 rsc
243 78a779a3 2008-07-20 rsc void*
244 78a779a3 2008-07-20 rsc ealloc(long n)
245 78a779a3 2008-07-20 rsc {
246 78a779a3 2008-07-20 rsc void *p;
247 78a779a3 2008-07-20 rsc
248 78a779a3 2008-07-20 rsc p = malloc(n);
249 78a779a3 2008-07-20 rsc if(p == 0)
250 78a779a3 2008-07-20 rsc error("no memory");
251 78a779a3 2008-07-20 rsc return p;
252 78a779a3 2008-07-20 rsc }
253 78a779a3 2008-07-20 rsc
254 78a779a3 2008-07-20 rsc void
255 78a779a3 2008-07-20 rsc setnames(Dir *d, char *n)
256 78a779a3 2008-07-20 rsc {
257 78a779a3 2008-07-20 rsc d->name = n;
258 78a779a3 2008-07-20 rsc d->uid = n+Maxname;
259 78a779a3 2008-07-20 rsc d->gid = n+Maxname*2;
260 78a779a3 2008-07-20 rsc d->muid = n+Maxname*3;
261 78a779a3 2008-07-20 rsc
262 78a779a3 2008-07-20 rsc d->name[0] = '\0';
263 78a779a3 2008-07-20 rsc d->uid[0] = '\0';
264 78a779a3 2008-07-20 rsc d->gid[0] = '\0';
265 78a779a3 2008-07-20 rsc d->muid[0] = '\0';
266 78a779a3 2008-07-20 rsc }
267 78a779a3 2008-07-20 rsc
268 78a779a3 2008-07-20 rsc void
269 78a779a3 2008-07-20 rsc rversion(void)
270 78a779a3 2008-07-20 rsc {
271 78a779a3 2008-07-20 rsc if(req->msize > Maxiosize)
272 78a779a3 2008-07-20 rsc rep->msize = Maxiosize;
273 78a779a3 2008-07-20 rsc else
274 78a779a3 2008-07-20 rsc rep->msize = req->msize;
275 78a779a3 2008-07-20 rsc rep->version = "9P2000";
276 78a779a3 2008-07-20 rsc }
277 78a779a3 2008-07-20 rsc
278 78a779a3 2008-07-20 rsc void
279 78a779a3 2008-07-20 rsc rauth(void)
280 78a779a3 2008-07-20 rsc {
281 78a779a3 2008-07-20 rsc error("9660srv: authentication not required");
282 78a779a3 2008-07-20 rsc }
283 78a779a3 2008-07-20 rsc
284 78a779a3 2008-07-20 rsc void
285 78a779a3 2008-07-20 rsc rflush(void)
286 78a779a3 2008-07-20 rsc {
287 78a779a3 2008-07-20 rsc }
288 78a779a3 2008-07-20 rsc
289 78a779a3 2008-07-20 rsc void
290 78a779a3 2008-07-20 rsc rattach(void)
291 78a779a3 2008-07-20 rsc {
292 78a779a3 2008-07-20 rsc Xfs *xf;
293 78a779a3 2008-07-20 rsc Xfile *root;
294 78a779a3 2008-07-20 rsc Xfsub **xs;
295 78a779a3 2008-07-20 rsc
296 78a779a3 2008-07-20 rsc chat("attach(fid=%d,uname=\"%s\",aname=\"%s\")...",
297 78a779a3 2008-07-20 rsc req->fid, req->uname, req->aname);
298 78a779a3 2008-07-20 rsc
299 78a779a3 2008-07-20 rsc if(waserror()){
300 78a779a3 2008-07-20 rsc xfile(req->fid, Clunk);
301 78a779a3 2008-07-20 rsc nexterror();
302 78a779a3 2008-07-20 rsc }
303 78a779a3 2008-07-20 rsc root = xfile(req->fid, Clean);
304 78a779a3 2008-07-20 rsc root->qid = (Qid){0, 0, QTDIR};
305 78a779a3 2008-07-20 rsc root->xf = xf = ealloc(sizeof(Xfs));
306 78a779a3 2008-07-20 rsc memset(xf, 0, sizeof(Xfs));
307 78a779a3 2008-07-20 rsc xf->ref = 1;
308 78a779a3 2008-07-20 rsc xf->d = getxdata(req->aname);
309 78a779a3 2008-07-20 rsc
310 78a779a3 2008-07-20 rsc for(xs=xsublist; *xs; xs++)
311 78a779a3 2008-07-20 rsc if((*(*xs)->attach)(root) >= 0){
312 78a779a3 2008-07-20 rsc poperror();
313 78a779a3 2008-07-20 rsc xf->s = *xs;
314 78a779a3 2008-07-20 rsc xf->rootqid = root->qid;
315 78a779a3 2008-07-20 rsc rep->qid = root->qid;
316 78a779a3 2008-07-20 rsc return;
317 78a779a3 2008-07-20 rsc }
318 78a779a3 2008-07-20 rsc error("unknown format");
319 78a779a3 2008-07-20 rsc }
320 78a779a3 2008-07-20 rsc
321 78a779a3 2008-07-20 rsc Xfile*
322 78a779a3 2008-07-20 rsc doclone(Xfile *of, int newfid)
323 78a779a3 2008-07-20 rsc {
324 78a779a3 2008-07-20 rsc Xfile *nf, *next;
325 78a779a3 2008-07-20 rsc
326 78a779a3 2008-07-20 rsc nf = xfile(newfid, Clean);
327 78a779a3 2008-07-20 rsc if(waserror()){
328 78a779a3 2008-07-20 rsc xfile(newfid, Clunk);
329 78a779a3 2008-07-20 rsc nexterror();
330 78a779a3 2008-07-20 rsc }
331 78a779a3 2008-07-20 rsc next = nf->next;
332 78a779a3 2008-07-20 rsc *nf = *of;
333 78a779a3 2008-07-20 rsc nf->next = next;
334 78a779a3 2008-07-20 rsc nf->fid = newfid;
335 78a779a3 2008-07-20 rsc refxfs(nf->xf, 1);
336 78a779a3 2008-07-20 rsc if(nf->len){
337 78a779a3 2008-07-20 rsc nf->ptr = ealloc(nf->len);
338 78a779a3 2008-07-20 rsc memmove(nf->ptr, of->ptr, nf->len);
339 78a779a3 2008-07-20 rsc }else
340 78a779a3 2008-07-20 rsc nf->ptr = of->ptr;
341 78a779a3 2008-07-20 rsc (*of->xf->s->clone)(of, nf);
342 78a779a3 2008-07-20 rsc poperror();
343 78a779a3 2008-07-20 rsc return nf;
344 78a779a3 2008-07-20 rsc }
345 78a779a3 2008-07-20 rsc
346 78a779a3 2008-07-20 rsc void
347 78a779a3 2008-07-20 rsc rwalk(void)
348 78a779a3 2008-07-20 rsc {
349 78a779a3 2008-07-20 rsc Xfile *f, *nf;
350 78a779a3 2008-07-20 rsc Isofile *oldptr;
351 78a779a3 2008-07-20 rsc int oldlen;
352 78a779a3 2008-07-20 rsc Qid oldqid;
353 78a779a3 2008-07-20 rsc
354 78a779a3 2008-07-20 rsc rep->nwqid = 0;
355 78a779a3 2008-07-20 rsc nf = nil;
356 78a779a3 2008-07-20 rsc f = xfile(req->fid, Asis);
357 78a779a3 2008-07-20 rsc if(req->fid != req->newfid)
358 78a779a3 2008-07-20 rsc f = nf = doclone(f, req->newfid);
359 78a779a3 2008-07-20 rsc
360 78a779a3 2008-07-20 rsc /* save old state in case of error */
361 78a779a3 2008-07-20 rsc oldqid = f->qid;
362 78a779a3 2008-07-20 rsc oldlen = f->len;
363 78a779a3 2008-07-20 rsc oldptr = f->ptr;
364 78a779a3 2008-07-20 rsc if(oldlen){
365 78a779a3 2008-07-20 rsc oldptr = ealloc(oldlen);
366 78a779a3 2008-07-20 rsc memmove(oldptr, f->ptr, oldlen);
367 78a779a3 2008-07-20 rsc }
368 78a779a3 2008-07-20 rsc
369 78a779a3 2008-07-20 rsc if(waserror()){
370 78a779a3 2008-07-20 rsc if(nf != nil)
371 78a779a3 2008-07-20 rsc xfile(req->newfid, Clunk);
372 78a779a3 2008-07-20 rsc if(rep->nwqid == req->nwname){
373 78a779a3 2008-07-20 rsc if(oldlen)
374 78a779a3 2008-07-20 rsc free(oldptr);
375 78a779a3 2008-07-20 rsc }else{
376 78a779a3 2008-07-20 rsc /* restore previous state */
377 78a779a3 2008-07-20 rsc f->qid = oldqid;
378 78a779a3 2008-07-20 rsc if(f->len)
379 78a779a3 2008-07-20 rsc free(f->ptr);
380 78a779a3 2008-07-20 rsc f->ptr = oldptr;
381 78a779a3 2008-07-20 rsc f->len = oldlen;
382 78a779a3 2008-07-20 rsc }
383 78a779a3 2008-07-20 rsc if(rep->nwqid==req->nwname || rep->nwqid > 0){
384 78a779a3 2008-07-20 rsc err_msg[0] = '\0';
385 78a779a3 2008-07-20 rsc return;
386 78a779a3 2008-07-20 rsc }
387 78a779a3 2008-07-20 rsc nexterror();
388 78a779a3 2008-07-20 rsc }
389 78a779a3 2008-07-20 rsc
390 78a779a3 2008-07-20 rsc for(rep->nwqid=0; rep->nwqid < req->nwname && rep->nwqid < MAXWELEM; rep->nwqid++){
391 78a779a3 2008-07-20 rsc chat("\twalking %s\n", req->wname[rep->nwqid]);
392 78a779a3 2008-07-20 rsc if(!(f->qid.type & QTDIR)){
393 78a779a3 2008-07-20 rsc chat("\tnot dir: type=%#x\n", f->qid.type);
394 78a779a3 2008-07-20 rsc error("walk in non-directory");
395 78a779a3 2008-07-20 rsc }
396 78a779a3 2008-07-20 rsc
397 78a779a3 2008-07-20 rsc if(strcmp(req->wname[rep->nwqid], "..")==0){
398 78a779a3 2008-07-20 rsc if(f->qid.path != f->xf->rootqid.path)
399 78a779a3 2008-07-20 rsc (*f->xf->s->walkup)(f);
400 78a779a3 2008-07-20 rsc }else
401 78a779a3 2008-07-20 rsc (*f->xf->s->walk)(f, req->wname[rep->nwqid]);
402 78a779a3 2008-07-20 rsc rep->wqid[rep->nwqid] = f->qid;
403 78a779a3 2008-07-20 rsc }
404 78a779a3 2008-07-20 rsc poperror();
405 78a779a3 2008-07-20 rsc if(oldlen)
406 78a779a3 2008-07-20 rsc free(oldptr);
407 78a779a3 2008-07-20 rsc }
408 78a779a3 2008-07-20 rsc
409 78a779a3 2008-07-20 rsc void
410 78a779a3 2008-07-20 rsc ropen(void)
411 78a779a3 2008-07-20 rsc {
412 78a779a3 2008-07-20 rsc Xfile *f;
413 78a779a3 2008-07-20 rsc
414 78a779a3 2008-07-20 rsc f = xfile(req->fid, Asis);
415 78a779a3 2008-07-20 rsc if(f->flags&Omodes)
416 78a779a3 2008-07-20 rsc error("open on open file");
417 78a779a3 2008-07-20 rsc if(req->mode&ORCLOSE)
418 78a779a3 2008-07-20 rsc error("no removes");
419 78a779a3 2008-07-20 rsc (*f->xf->s->open)(f, req->mode);
420 78a779a3 2008-07-20 rsc f->flags = openflags(req->mode);
421 78a779a3 2008-07-20 rsc rep->qid = f->qid;
422 78a779a3 2008-07-20 rsc rep->iounit = 0;
423 78a779a3 2008-07-20 rsc }
424 78a779a3 2008-07-20 rsc
425 78a779a3 2008-07-20 rsc void
426 78a779a3 2008-07-20 rsc rcreate(void)
427 78a779a3 2008-07-20 rsc {
428 78a779a3 2008-07-20 rsc error("no creates");
429 78a779a3 2008-07-20 rsc /*
430 78a779a3 2008-07-20 rsc Xfile *f;
431 78a779a3 2008-07-20 rsc
432 78a779a3 2008-07-20 rsc if(strcmp(req->name, ".") == 0 || strcmp(req->name, "..") == 0)
433 78a779a3 2008-07-20 rsc error("create . or ..");
434 78a779a3 2008-07-20 rsc f = xfile(req->fid, Asis);
435 78a779a3 2008-07-20 rsc if(f->flags&Omodes)
436 78a779a3 2008-07-20 rsc error("create on open file");
437 78a779a3 2008-07-20 rsc if(!(f->qid.path&CHDIR))
438 78a779a3 2008-07-20 rsc error("create in non-directory");
439 78a779a3 2008-07-20 rsc (*f->xf->s->create)(f, req->name, req->perm, req->mode);
440 78a779a3 2008-07-20 rsc chat("f->qid=0x%8.8lux...", f->qid.path);
441 78a779a3 2008-07-20 rsc f->flags = openflags(req->mode);
442 78a779a3 2008-07-20 rsc rep->qid = f->qid;
443 78a779a3 2008-07-20 rsc */
444 78a779a3 2008-07-20 rsc }
445 78a779a3 2008-07-20 rsc
446 78a779a3 2008-07-20 rsc void
447 78a779a3 2008-07-20 rsc rread(void)
448 78a779a3 2008-07-20 rsc {
449 78a779a3 2008-07-20 rsc Xfile *f;
450 78a779a3 2008-07-20 rsc
451 78a779a3 2008-07-20 rsc f=xfile(req->fid, Asis);
452 78a779a3 2008-07-20 rsc if (!(f->flags&Oread))
453 78a779a3 2008-07-20 rsc error("file not opened for reading");
454 78a779a3 2008-07-20 rsc if(f->qid.type & QTDIR)
455 78a779a3 2008-07-20 rsc rep->count = (*f->xf->s->readdir)(f, (uchar*)fdata, req->offset, req->count);
456 78a779a3 2008-07-20 rsc else
457 78a779a3 2008-07-20 rsc rep->count = (*f->xf->s->read)(f, fdata, req->offset, req->count);
458 78a779a3 2008-07-20 rsc rep->data = fdata;
459 78a779a3 2008-07-20 rsc }
460 78a779a3 2008-07-20 rsc
461 78a779a3 2008-07-20 rsc void
462 78a779a3 2008-07-20 rsc rwrite(void)
463 78a779a3 2008-07-20 rsc {
464 78a779a3 2008-07-20 rsc Xfile *f;
465 78a779a3 2008-07-20 rsc
466 78a779a3 2008-07-20 rsc f=xfile(req->fid, Asis);
467 78a779a3 2008-07-20 rsc if(!(f->flags&Owrite))
468 78a779a3 2008-07-20 rsc error("file not opened for writing");
469 78a779a3 2008-07-20 rsc rep->count = (*f->xf->s->write)(f, req->data, req->offset, req->count);
470 78a779a3 2008-07-20 rsc }
471 78a779a3 2008-07-20 rsc
472 78a779a3 2008-07-20 rsc void
473 78a779a3 2008-07-20 rsc rclunk(void)
474 78a779a3 2008-07-20 rsc {
475 78a779a3 2008-07-20 rsc Xfile *f;
476 78a779a3 2008-07-20 rsc
477 78a779a3 2008-07-20 rsc if(!waserror()){
478 78a779a3 2008-07-20 rsc f = xfile(req->fid, Asis);
479 78a779a3 2008-07-20 rsc (*f->xf->s->clunk)(f);
480 78a779a3 2008-07-20 rsc poperror();
481 78a779a3 2008-07-20 rsc }
482 78a779a3 2008-07-20 rsc xfile(req->fid, Clunk);
483 78a779a3 2008-07-20 rsc }
484 78a779a3 2008-07-20 rsc
485 78a779a3 2008-07-20 rsc void
486 78a779a3 2008-07-20 rsc rremove(void)
487 78a779a3 2008-07-20 rsc {
488 78a779a3 2008-07-20 rsc error("no removes");
489 78a779a3 2008-07-20 rsc }
490 78a779a3 2008-07-20 rsc
491 78a779a3 2008-07-20 rsc void
492 78a779a3 2008-07-20 rsc rstat(void)
493 78a779a3 2008-07-20 rsc {
494 78a779a3 2008-07-20 rsc Xfile *f;
495 78a779a3 2008-07-20 rsc Dir dir;
496 78a779a3 2008-07-20 rsc
497 78a779a3 2008-07-20 rsc chat("stat(fid=%d)...", req->fid);
498 78a779a3 2008-07-20 rsc f=xfile(req->fid, Asis);
499 78a779a3 2008-07-20 rsc setnames(&dir, fdata);
500 78a779a3 2008-07-20 rsc (*f->xf->s->stat)(f, &dir);
501 78a779a3 2008-07-20 rsc if(chatty)
502 78a779a3 2008-07-20 rsc showdir(2, &dir);
503 78a779a3 2008-07-20 rsc rep->nstat = convD2M(&dir, statbuf, sizeof statbuf);
504 78a779a3 2008-07-20 rsc rep->stat = statbuf;
505 78a779a3 2008-07-20 rsc }
506 78a779a3 2008-07-20 rsc
507 78a779a3 2008-07-20 rsc void
508 78a779a3 2008-07-20 rsc rwstat(void)
509 78a779a3 2008-07-20 rsc {
510 78a779a3 2008-07-20 rsc error("no wstat");
511 78a779a3 2008-07-20 rsc }
512 78a779a3 2008-07-20 rsc
513 78a779a3 2008-07-20 rsc static int
514 78a779a3 2008-07-20 rsc openflags(int mode)
515 78a779a3 2008-07-20 rsc {
516 78a779a3 2008-07-20 rsc int flags = 0;
517 78a779a3 2008-07-20 rsc
518 78a779a3 2008-07-20 rsc switch(mode & ~(OTRUNC|OCEXEC|ORCLOSE)){
519 78a779a3 2008-07-20 rsc case OREAD:
520 78a779a3 2008-07-20 rsc case OEXEC:
521 78a779a3 2008-07-20 rsc flags = Oread; break;
522 78a779a3 2008-07-20 rsc case OWRITE:
523 78a779a3 2008-07-20 rsc flags = Owrite; break;
524 78a779a3 2008-07-20 rsc case ORDWR:
525 78a779a3 2008-07-20 rsc flags = Oread|Owrite; break;
526 78a779a3 2008-07-20 rsc }
527 78a779a3 2008-07-20 rsc if(mode & ORCLOSE)
528 78a779a3 2008-07-20 rsc flags |= Orclose;
529 78a779a3 2008-07-20 rsc return flags;
530 78a779a3 2008-07-20 rsc }
531 78a779a3 2008-07-20 rsc
532 78a779a3 2008-07-20 rsc void
533 78a779a3 2008-07-20 rsc showdir(int fd, Dir *s)
534 78a779a3 2008-07-20 rsc {
535 78a779a3 2008-07-20 rsc char a_time[32], m_time[32];
536 78a779a3 2008-07-20 rsc char *p;
537 78a779a3 2008-07-20 rsc
538 78a779a3 2008-07-20 rsc strcpy(a_time, ctime(s->atime));
539 78a779a3 2008-07-20 rsc if(p=strchr(a_time, '\n')) /* assign = */
540 78a779a3 2008-07-20 rsc *p = 0;
541 78a779a3 2008-07-20 rsc strcpy(m_time, ctime(s->mtime));
542 78a779a3 2008-07-20 rsc if(p=strchr(m_time, '\n')) /* assign = */
543 78a779a3 2008-07-20 rsc *p = 0;
544 78a779a3 2008-07-20 rsc fprint(fd, "name=\"%s\" qid=(0x%llux,%lud) type=%d dev=%d \
545 78a779a3 2008-07-20 rsc mode=0x%8.8lux=0%luo atime=%s mtime=%s length=%lld uid=\"%s\" gid=\"%s\"...",
546 78a779a3 2008-07-20 rsc s->name, s->qid.path, s->qid.vers, s->type, s->dev,
547 78a779a3 2008-07-20 rsc s->mode, s->mode,
548 78a779a3 2008-07-20 rsc a_time, m_time, s->length, s->uid, s->gid);
549 78a779a3 2008-07-20 rsc }
550 78a779a3 2008-07-20 rsc
551 78a779a3 2008-07-20 rsc #define SIZE 1024
552 78a779a3 2008-07-20 rsc
553 78a779a3 2008-07-20 rsc void
554 78a779a3 2008-07-20 rsc chat(char *fmt, ...)
555 78a779a3 2008-07-20 rsc {
556 78a779a3 2008-07-20 rsc va_list arg;
557 78a779a3 2008-07-20 rsc
558 78a779a3 2008-07-20 rsc if(chatty){
559 78a779a3 2008-07-20 rsc va_start(arg, fmt);
560 78a779a3 2008-07-20 rsc vfprint(2, fmt, arg);
561 78a779a3 2008-07-20 rsc va_end(arg);
562 78a779a3 2008-07-20 rsc }
563 78a779a3 2008-07-20 rsc }
564 78a779a3 2008-07-20 rsc
565 78a779a3 2008-07-20 rsc void
566 78a779a3 2008-07-20 rsc panic(int rflag, char *fmt, ...)
567 78a779a3 2008-07-20 rsc {
568 78a779a3 2008-07-20 rsc va_list arg;
569 78a779a3 2008-07-20 rsc char buf[SIZE]; int n;
570 78a779a3 2008-07-20 rsc
571 78a779a3 2008-07-20 rsc n = sprint(buf, "%s %d: ", argv0, getpid());
572 78a779a3 2008-07-20 rsc va_start(arg, fmt);
573 78a779a3 2008-07-20 rsc vseprint(buf+n, buf+SIZE, fmt, arg);
574 78a779a3 2008-07-20 rsc va_end(arg);
575 78a779a3 2008-07-20 rsc fprint(2, (rflag ? "%s: %r\n" : "%s\n"), buf);
576 78a779a3 2008-07-20 rsc if(chatty){
577 78a779a3 2008-07-20 rsc fprint(2, "abort\n");
578 78a779a3 2008-07-20 rsc abort();
579 78a779a3 2008-07-20 rsc }
580 78a779a3 2008-07-20 rsc exits("panic");
581 78a779a3 2008-07-20 rsc }