Blame


1 b3994ec5 2003-12-11 devnull #include <u.h>
2 b3994ec5 2003-12-11 devnull #include <libc.h>
3 b3994ec5 2003-12-11 devnull #include <draw.h>
4 b3994ec5 2003-12-11 devnull #include <thread.h>
5 b3994ec5 2003-12-11 devnull #include <cursor.h>
6 b3994ec5 2003-12-11 devnull #include <mouse.h>
7 b3994ec5 2003-12-11 devnull #include <keyboard.h>
8 b3994ec5 2003-12-11 devnull #include <frame.h>
9 b3994ec5 2003-12-11 devnull #include <fcall.h>
10 b3994ec5 2003-12-11 devnull #include <plumb.h>
11 b3994ec5 2003-12-11 devnull #include "dat.h"
12 b3994ec5 2003-12-11 devnull #include "fns.h"
13 b3994ec5 2003-12-11 devnull
14 b3994ec5 2003-12-11 devnull static int sfd;
15 b3994ec5 2003-12-11 devnull
16 b3994ec5 2003-12-11 devnull enum
17 b3994ec5 2003-12-11 devnull {
18 b3994ec5 2003-12-11 devnull Nhash = 16,
19 b3994ec5 2003-12-11 devnull DEBUG = 0
20 b3994ec5 2003-12-11 devnull };
21 b3994ec5 2003-12-11 devnull
22 b3994ec5 2003-12-11 devnull static Fid *fids[Nhash];
23 b3994ec5 2003-12-11 devnull
24 b3994ec5 2003-12-11 devnull Fid *newfid(int);
25 b3994ec5 2003-12-11 devnull
26 b3994ec5 2003-12-11 devnull static Xfid* fsysflush(Xfid*, Fid*);
27 b3994ec5 2003-12-11 devnull static Xfid* fsysauth(Xfid*, Fid*);
28 b3994ec5 2003-12-11 devnull static Xfid* fsysversion(Xfid*, Fid*);
29 b3994ec5 2003-12-11 devnull static Xfid* fsysattach(Xfid*, Fid*);
30 b3994ec5 2003-12-11 devnull static Xfid* fsyswalk(Xfid*, Fid*);
31 b3994ec5 2003-12-11 devnull static Xfid* fsysopen(Xfid*, Fid*);
32 b3994ec5 2003-12-11 devnull static Xfid* fsyscreate(Xfid*, Fid*);
33 b3994ec5 2003-12-11 devnull static Xfid* fsysread(Xfid*, Fid*);
34 b3994ec5 2003-12-11 devnull static Xfid* fsyswrite(Xfid*, Fid*);
35 b3994ec5 2003-12-11 devnull static Xfid* fsysclunk(Xfid*, Fid*);
36 b3994ec5 2003-12-11 devnull static Xfid* fsysremove(Xfid*, Fid*);
37 b3994ec5 2003-12-11 devnull static Xfid* fsysstat(Xfid*, Fid*);
38 b3994ec5 2003-12-11 devnull static Xfid* fsyswstat(Xfid*, Fid*);
39 b3994ec5 2003-12-11 devnull
40 8ad51794 2004-03-25 devnull Xfid* (*fcall[Tmax])(Xfid*, Fid*);
41 8ad51794 2004-03-25 devnull
42 8ad51794 2004-03-25 devnull static void
43 8ad51794 2004-03-25 devnull initfcall(void)
44 b3994ec5 2003-12-11 devnull {
45 8ad51794 2004-03-25 devnull fcall[Tflush] = fsysflush;
46 8ad51794 2004-03-25 devnull fcall[Tversion] = fsysversion;
47 8ad51794 2004-03-25 devnull fcall[Tauth] = fsysauth;
48 8ad51794 2004-03-25 devnull fcall[Tattach] = fsysattach;
49 8ad51794 2004-03-25 devnull fcall[Twalk] = fsyswalk;
50 8ad51794 2004-03-25 devnull fcall[Topen] = fsysopen;
51 8ad51794 2004-03-25 devnull fcall[Tcreate] = fsyscreate;
52 8ad51794 2004-03-25 devnull fcall[Tread] = fsysread;
53 8ad51794 2004-03-25 devnull fcall[Twrite] = fsyswrite;
54 8ad51794 2004-03-25 devnull fcall[Tclunk] = fsysclunk;
55 8ad51794 2004-03-25 devnull fcall[Tremove]= fsysremove;
56 8ad51794 2004-03-25 devnull fcall[Tstat] = fsysstat;
57 8ad51794 2004-03-25 devnull fcall[Twstat] = fsyswstat;
58 8ad51794 2004-03-25 devnull }
59 b3994ec5 2003-12-11 devnull
60 b3994ec5 2003-12-11 devnull char Eperm[] = "permission denied";
61 b3994ec5 2003-12-11 devnull char Eexist[] = "file does not exist";
62 b3994ec5 2003-12-11 devnull char Enotdir[] = "not a directory";
63 b3994ec5 2003-12-11 devnull
64 b3994ec5 2003-12-11 devnull Dirtab dirtab[]=
65 b3994ec5 2003-12-11 devnull {
66 b3994ec5 2003-12-11 devnull { ".", QTDIR, Qdir, 0500|DMDIR },
67 b3994ec5 2003-12-11 devnull { "acme", QTDIR, Qacme, 0500|DMDIR },
68 b3994ec5 2003-12-11 devnull { "cons", QTFILE, Qcons, 0600 },
69 b3994ec5 2003-12-11 devnull { "consctl", QTFILE, Qconsctl, 0000 },
70 b3994ec5 2003-12-11 devnull { "draw", QTDIR, Qdraw, 0000|DMDIR }, /* to suppress graphics progs started in acme */
71 b3994ec5 2003-12-11 devnull { "editout", QTFILE, Qeditout, 0200 },
72 b3994ec5 2003-12-11 devnull { "index", QTFILE, Qindex, 0400 },
73 b3994ec5 2003-12-11 devnull { "label", QTFILE, Qlabel, 0600 },
74 b3994ec5 2003-12-11 devnull { "new", QTDIR, Qnew, 0500|DMDIR },
75 b3994ec5 2003-12-11 devnull { nil, }
76 b3994ec5 2003-12-11 devnull };
77 b3994ec5 2003-12-11 devnull
78 b3994ec5 2003-12-11 devnull Dirtab dirtabw[]=
79 b3994ec5 2003-12-11 devnull {
80 b3994ec5 2003-12-11 devnull { ".", QTDIR, Qdir, 0500|DMDIR },
81 b3994ec5 2003-12-11 devnull { "addr", QTFILE, QWaddr, 0600 },
82 b3994ec5 2003-12-11 devnull { "body", QTAPPEND, QWbody, 0600|DMAPPEND },
83 b3994ec5 2003-12-11 devnull { "ctl", QTFILE, QWctl, 0600 },
84 b3994ec5 2003-12-11 devnull { "data", QTFILE, QWdata, 0600 },
85 b3994ec5 2003-12-11 devnull { "editout", QTFILE, QWeditout, 0200 },
86 9d01e221 2005-01-30 devnull { "errors", QTFILE, QWerrors, 0200 },
87 b3994ec5 2003-12-11 devnull { "event", QTFILE, QWevent, 0600 },
88 b3994ec5 2003-12-11 devnull { "rdsel", QTFILE, QWrdsel, 0400 },
89 b3994ec5 2003-12-11 devnull { "wrsel", QTFILE, QWwrsel, 0200 },
90 b3994ec5 2003-12-11 devnull { "tag", QTAPPEND, QWtag, 0600|DMAPPEND },
91 012a8a02 2004-10-22 devnull { "xdata", QTFILE, QWxdata, 0600 },
92 b3994ec5 2003-12-11 devnull { nil, }
93 b3994ec5 2003-12-11 devnull };
94 b3994ec5 2003-12-11 devnull
95 b3994ec5 2003-12-11 devnull typedef struct Mnt Mnt;
96 b3994ec5 2003-12-11 devnull struct Mnt
97 b3994ec5 2003-12-11 devnull {
98 b3994ec5 2003-12-11 devnull QLock lk;
99 b3994ec5 2003-12-11 devnull int id;
100 b3994ec5 2003-12-11 devnull Mntdir *md;
101 b3994ec5 2003-12-11 devnull };
102 b3994ec5 2003-12-11 devnull
103 b3994ec5 2003-12-11 devnull Mnt mnt;
104 b3994ec5 2003-12-11 devnull
105 b3994ec5 2003-12-11 devnull Xfid* respond(Xfid*, Fcall*, char*);
106 b3994ec5 2003-12-11 devnull int dostat(int, Dirtab*, uchar*, int, uint);
107 b3994ec5 2003-12-11 devnull uint getclock(void);
108 b3994ec5 2003-12-11 devnull
109 b3994ec5 2003-12-11 devnull char *user = "Wile E. Coyote";
110 b3994ec5 2003-12-11 devnull static int closing = 0;
111 b3994ec5 2003-12-11 devnull int messagesize = Maxblock+IOHDRSZ; /* good start */
112 b3994ec5 2003-12-11 devnull
113 b3994ec5 2003-12-11 devnull void fsysproc(void *);
114 b3994ec5 2003-12-11 devnull
115 b3994ec5 2003-12-11 devnull void
116 b3994ec5 2003-12-11 devnull fsysinit(void)
117 b3994ec5 2003-12-11 devnull {
118 b3994ec5 2003-12-11 devnull int p[2];
119 5a8e63b2 2004-02-29 devnull char *u;
120 b3994ec5 2003-12-11 devnull
121 8ad51794 2004-03-25 devnull initfcall();
122 b3994ec5 2003-12-11 devnull if(pipe(p) < 0)
123 b3994ec5 2003-12-11 devnull error("can't create pipe");
124 b3994ec5 2003-12-11 devnull if(post9pservice(p[0], "acme") < 0)
125 b3994ec5 2003-12-11 devnull error("can't post service");
126 b3994ec5 2003-12-11 devnull sfd = p[1];
127 b3994ec5 2003-12-11 devnull fmtinstall('F', fcallfmt);
128 b3994ec5 2003-12-11 devnull if((u = getuser()) != nil)
129 b3994ec5 2003-12-11 devnull user = estrdup(u);
130 334cb1e9 2004-12-27 devnull proccreate(fsysproc, nil, STACK);
131 b3994ec5 2003-12-11 devnull }
132 b3994ec5 2003-12-11 devnull
133 b3994ec5 2003-12-11 devnull void
134 b3994ec5 2003-12-11 devnull fsysproc(void *v)
135 b3994ec5 2003-12-11 devnull {
136 b3994ec5 2003-12-11 devnull int n;
137 b3994ec5 2003-12-11 devnull Xfid *x;
138 b3994ec5 2003-12-11 devnull Fid *f;
139 b3994ec5 2003-12-11 devnull Fcall t;
140 b3994ec5 2003-12-11 devnull uchar *buf;
141 391363f5 2005-09-26 devnull
142 391363f5 2005-09-26 devnull threadsetname("fsysproc");
143 b3994ec5 2003-12-11 devnull
144 b3994ec5 2003-12-11 devnull USED(v);
145 b3994ec5 2003-12-11 devnull x = nil;
146 b3994ec5 2003-12-11 devnull for(;;){
147 b3994ec5 2003-12-11 devnull buf = emalloc(messagesize+UTFmax); /* overflow for appending partial rune in xfidwrite */
148 334cb1e9 2004-12-27 devnull n = read9pmsg(sfd, buf, messagesize);
149 b3994ec5 2003-12-11 devnull if(n <= 0){
150 b3994ec5 2003-12-11 devnull if(closing)
151 b3994ec5 2003-12-11 devnull break;
152 b3994ec5 2003-12-11 devnull error("i/o error on server channel");
153 b3994ec5 2003-12-11 devnull }
154 b3994ec5 2003-12-11 devnull if(x == nil){
155 b3994ec5 2003-12-11 devnull sendp(cxfidalloc, nil);
156 b3994ec5 2003-12-11 devnull x = recvp(cxfidalloc);
157 b3994ec5 2003-12-11 devnull }
158 b3994ec5 2003-12-11 devnull x->buf = buf;
159 b3994ec5 2003-12-11 devnull if(convM2S(buf, n, &x->fcall) != n)
160 b3994ec5 2003-12-11 devnull error("convert error in convM2S");
161 b3994ec5 2003-12-11 devnull if(DEBUG)
162 b3994ec5 2003-12-11 devnull fprint(2, "%F\n", &x->fcall);
163 8c061315 2005-03-18 devnull if(fcall[x->fcall.type] == nil)
164 b3994ec5 2003-12-11 devnull x = respond(x, &t, "bad fcall type");
165 b3994ec5 2003-12-11 devnull else{
166 07494878 2005-01-27 devnull switch(x->fcall.type){
167 07494878 2005-01-27 devnull case Tversion:
168 07494878 2005-01-27 devnull case Tauth:
169 07494878 2005-01-27 devnull case Tflush:
170 b3994ec5 2003-12-11 devnull f = nil;
171 07494878 2005-01-27 devnull break;
172 07494878 2005-01-27 devnull case Tattach:
173 07494878 2005-01-27 devnull f = newfid(x->fcall.fid);
174 07494878 2005-01-27 devnull break;
175 07494878 2005-01-27 devnull default:
176 b3994ec5 2003-12-11 devnull f = newfid(x->fcall.fid);
177 07494878 2005-01-27 devnull if(!f->busy){
178 07494878 2005-01-27 devnull x->f = f;
179 07494878 2005-01-27 devnull x = respond(x, &t, "fid not in use");
180 07494878 2005-01-27 devnull continue;
181 07494878 2005-01-27 devnull }
182 07494878 2005-01-27 devnull break;
183 07494878 2005-01-27 devnull }
184 b3994ec5 2003-12-11 devnull x->f = f;
185 b3994ec5 2003-12-11 devnull x = (*fcall[x->fcall.type])(x, f);
186 b3994ec5 2003-12-11 devnull }
187 b3994ec5 2003-12-11 devnull }
188 b3994ec5 2003-12-11 devnull }
189 b3994ec5 2003-12-11 devnull
190 b3994ec5 2003-12-11 devnull Mntdir*
191 b3994ec5 2003-12-11 devnull fsysaddid(Rune *dir, int ndir, Rune **incl, int nincl)
192 b3994ec5 2003-12-11 devnull {
193 b3994ec5 2003-12-11 devnull Mntdir *m;
194 b3994ec5 2003-12-11 devnull int id;
195 b3994ec5 2003-12-11 devnull
196 b3994ec5 2003-12-11 devnull qlock(&mnt.lk);
197 b3994ec5 2003-12-11 devnull id = ++mnt.id;
198 b3994ec5 2003-12-11 devnull m = emalloc(sizeof *m);
199 b3994ec5 2003-12-11 devnull m->id = id;
200 b3994ec5 2003-12-11 devnull m->dir = dir;
201 b3994ec5 2003-12-11 devnull m->ref = 1; /* one for Command, one will be incremented in attach */
202 b3994ec5 2003-12-11 devnull m->ndir = ndir;
203 b3994ec5 2003-12-11 devnull m->next = mnt.md;
204 b3994ec5 2003-12-11 devnull m->incl = incl;
205 b3994ec5 2003-12-11 devnull m->nincl = nincl;
206 b3994ec5 2003-12-11 devnull mnt.md = m;
207 b3994ec5 2003-12-11 devnull qunlock(&mnt.lk);
208 b3994ec5 2003-12-11 devnull return m;
209 b3994ec5 2003-12-11 devnull }
210 b3994ec5 2003-12-11 devnull
211 b3994ec5 2003-12-11 devnull void
212 8ad51794 2004-03-25 devnull fsysincid(Mntdir *m)
213 8ad51794 2004-03-25 devnull {
214 8ad51794 2004-03-25 devnull qlock(&mnt.lk);
215 8ad51794 2004-03-25 devnull m->ref++;
216 8ad51794 2004-03-25 devnull qunlock(&mnt.lk);
217 8ad51794 2004-03-25 devnull }
218 8ad51794 2004-03-25 devnull
219 8ad51794 2004-03-25 devnull void
220 b3994ec5 2003-12-11 devnull fsysdelid(Mntdir *idm)
221 b3994ec5 2003-12-11 devnull {
222 b3994ec5 2003-12-11 devnull Mntdir *m, *prev;
223 b3994ec5 2003-12-11 devnull int i;
224 b3994ec5 2003-12-11 devnull char buf[64];
225 b3994ec5 2003-12-11 devnull
226 b3994ec5 2003-12-11 devnull if(idm == nil)
227 b3994ec5 2003-12-11 devnull return;
228 b3994ec5 2003-12-11 devnull qlock(&mnt.lk);
229 b3994ec5 2003-12-11 devnull if(--idm->ref > 0){
230 b3994ec5 2003-12-11 devnull qunlock(&mnt.lk);
231 b3994ec5 2003-12-11 devnull return;
232 b3994ec5 2003-12-11 devnull }
233 b3994ec5 2003-12-11 devnull prev = nil;
234 b3994ec5 2003-12-11 devnull for(m=mnt.md; m; m=m->next){
235 b3994ec5 2003-12-11 devnull if(m == idm){
236 b3994ec5 2003-12-11 devnull if(prev)
237 b3994ec5 2003-12-11 devnull prev->next = m->next;
238 b3994ec5 2003-12-11 devnull else
239 b3994ec5 2003-12-11 devnull mnt.md = m->next;
240 b3994ec5 2003-12-11 devnull for(i=0; i<m->nincl; i++)
241 b3994ec5 2003-12-11 devnull free(m->incl[i]);
242 b3994ec5 2003-12-11 devnull free(m->incl);
243 b3994ec5 2003-12-11 devnull free(m->dir);
244 b3994ec5 2003-12-11 devnull free(m);
245 b3994ec5 2003-12-11 devnull qunlock(&mnt.lk);
246 b3994ec5 2003-12-11 devnull return;
247 b3994ec5 2003-12-11 devnull }
248 b3994ec5 2003-12-11 devnull prev = m;
249 b3994ec5 2003-12-11 devnull }
250 b3994ec5 2003-12-11 devnull qunlock(&mnt.lk);
251 b3994ec5 2003-12-11 devnull sprint(buf, "fsysdelid: can't find id %d\n", idm->id);
252 b3994ec5 2003-12-11 devnull sendp(cerr, estrdup(buf));
253 b3994ec5 2003-12-11 devnull }
254 b3994ec5 2003-12-11 devnull
255 b3994ec5 2003-12-11 devnull /*
256 b3994ec5 2003-12-11 devnull * Called only in exec.c:/^run(), from a different FD group
257 b3994ec5 2003-12-11 devnull */
258 b3994ec5 2003-12-11 devnull Mntdir*
259 b3994ec5 2003-12-11 devnull fsysmount(Rune *dir, int ndir, Rune **incl, int nincl)
260 b3994ec5 2003-12-11 devnull {
261 b3994ec5 2003-12-11 devnull return fsysaddid(dir, ndir, incl, nincl);
262 b3994ec5 2003-12-11 devnull }
263 b3994ec5 2003-12-11 devnull
264 b3994ec5 2003-12-11 devnull void
265 b3994ec5 2003-12-11 devnull fsysclose(void)
266 b3994ec5 2003-12-11 devnull {
267 b3994ec5 2003-12-11 devnull closing = 1;
268 d242e5ad 2005-07-22 devnull /*
269 d242e5ad 2005-07-22 devnull * apparently this is not kosher on openbsd.
270 d242e5ad 2005-07-22 devnull * perhaps because fsysproc is reading from sfd right now,
271 d242e5ad 2005-07-22 devnull * the close hangs indefinitely.
272 b3994ec5 2003-12-11 devnull close(sfd);
273 d242e5ad 2005-07-22 devnull */
274 b3994ec5 2003-12-11 devnull }
275 b3994ec5 2003-12-11 devnull
276 b3994ec5 2003-12-11 devnull Xfid*
277 b3994ec5 2003-12-11 devnull respond(Xfid *x, Fcall *t, char *err)
278 b3994ec5 2003-12-11 devnull {
279 b3994ec5 2003-12-11 devnull int n;
280 b3994ec5 2003-12-11 devnull
281 b3994ec5 2003-12-11 devnull if(err){
282 b3994ec5 2003-12-11 devnull t->type = Rerror;
283 b3994ec5 2003-12-11 devnull t->ename = err;
284 b3994ec5 2003-12-11 devnull }else
285 b3994ec5 2003-12-11 devnull t->type = x->fcall.type+1;
286 b3994ec5 2003-12-11 devnull t->fid = x->fcall.fid;
287 b3994ec5 2003-12-11 devnull t->tag = x->fcall.tag;
288 b3994ec5 2003-12-11 devnull if(x->buf == nil)
289 b3994ec5 2003-12-11 devnull x->buf = emalloc(messagesize);
290 b3994ec5 2003-12-11 devnull n = convS2M(t, x->buf, messagesize);
291 b3994ec5 2003-12-11 devnull if(n <= 0)
292 5a8e63b2 2004-02-29 devnull {
293 5a8e63b2 2004-02-29 devnull fprint(2, "convert error (n=%d, msgsize %d): have %F\n", n, messagesize, &x->fcall);
294 5a8e63b2 2004-02-29 devnull fprint(2, "\tresponse: %F\n", t);
295 b3994ec5 2003-12-11 devnull error("convert error in convS2M");
296 5a8e63b2 2004-02-29 devnull }
297 b3994ec5 2003-12-11 devnull if(write(sfd, x->buf, n) != n)
298 b3994ec5 2003-12-11 devnull error("write error in respond");
299 b3994ec5 2003-12-11 devnull free(x->buf);
300 b3994ec5 2003-12-11 devnull x->buf = nil;
301 b3994ec5 2003-12-11 devnull if(DEBUG)
302 b3994ec5 2003-12-11 devnull fprint(2, "r: %F\n", t);
303 b3994ec5 2003-12-11 devnull return x;
304 b3994ec5 2003-12-11 devnull }
305 b3994ec5 2003-12-11 devnull
306 b3994ec5 2003-12-11 devnull static
307 b3994ec5 2003-12-11 devnull Xfid*
308 b3994ec5 2003-12-11 devnull fsysversion(Xfid *x, Fid *f)
309 b3994ec5 2003-12-11 devnull {
310 b3994ec5 2003-12-11 devnull Fcall t;
311 b3994ec5 2003-12-11 devnull
312 b3994ec5 2003-12-11 devnull USED(f);
313 b3994ec5 2003-12-11 devnull if(x->fcall.msize < 256)
314 b3994ec5 2003-12-11 devnull return respond(x, &t, "version: message size too small");
315 b3994ec5 2003-12-11 devnull messagesize = x->fcall.msize;
316 b3994ec5 2003-12-11 devnull t.msize = messagesize;
317 b3994ec5 2003-12-11 devnull if(strncmp(x->fcall.version, "9P2000", 6) != 0)
318 b3994ec5 2003-12-11 devnull return respond(x, &t, "unrecognized 9P version");
319 b3994ec5 2003-12-11 devnull t.version = "9P2000";
320 b3994ec5 2003-12-11 devnull return respond(x, &t, nil);
321 b3994ec5 2003-12-11 devnull }
322 b3994ec5 2003-12-11 devnull
323 b3994ec5 2003-12-11 devnull static
324 b3994ec5 2003-12-11 devnull Xfid*
325 b3994ec5 2003-12-11 devnull fsysauth(Xfid *x, Fid *f)
326 b3994ec5 2003-12-11 devnull {
327 5aa723da 2005-02-11 devnull Fcall t;
328 5aa723da 2005-02-11 devnull
329 b3994ec5 2003-12-11 devnull USED(f);
330 5aa723da 2005-02-11 devnull return respond(x, &t, "acme: authentication not required");
331 b3994ec5 2003-12-11 devnull }
332 b3994ec5 2003-12-11 devnull
333 b3994ec5 2003-12-11 devnull static
334 b3994ec5 2003-12-11 devnull Xfid*
335 b3994ec5 2003-12-11 devnull fsysflush(Xfid *x, Fid *f)
336 b3994ec5 2003-12-11 devnull {
337 b3994ec5 2003-12-11 devnull USED(f);
338 be22ae2d 2004-03-26 devnull sendp(x->c, (void*)xfidflush);
339 b3994ec5 2003-12-11 devnull return nil;
340 b3994ec5 2003-12-11 devnull }
341 b3994ec5 2003-12-11 devnull
342 b3994ec5 2003-12-11 devnull static
343 b3994ec5 2003-12-11 devnull Xfid*
344 b3994ec5 2003-12-11 devnull fsysattach(Xfid *x, Fid *f)
345 b3994ec5 2003-12-11 devnull {
346 b3994ec5 2003-12-11 devnull Fcall t;
347 b3994ec5 2003-12-11 devnull int id;
348 b3994ec5 2003-12-11 devnull Mntdir *m;
349 49588d5d 2003-12-17 devnull char buf[128];
350 b3994ec5 2003-12-11 devnull
351 b3994ec5 2003-12-11 devnull if(strcmp(x->fcall.uname, user) != 0)
352 b3994ec5 2003-12-11 devnull return respond(x, &t, Eperm);
353 b3994ec5 2003-12-11 devnull f->busy = TRUE;
354 b3994ec5 2003-12-11 devnull f->open = FALSE;
355 b3994ec5 2003-12-11 devnull f->qid.path = Qdir;
356 b3994ec5 2003-12-11 devnull f->qid.type = QTDIR;
357 b3994ec5 2003-12-11 devnull f->qid.vers = 0;
358 b3994ec5 2003-12-11 devnull f->dir = dirtab;
359 b3994ec5 2003-12-11 devnull f->nrpart = 0;
360 b3994ec5 2003-12-11 devnull f->w = nil;
361 b3994ec5 2003-12-11 devnull t.qid = f->qid;
362 b3994ec5 2003-12-11 devnull f->mntdir = nil;
363 b3994ec5 2003-12-11 devnull id = atoi(x->fcall.aname);
364 b3994ec5 2003-12-11 devnull qlock(&mnt.lk);
365 b3994ec5 2003-12-11 devnull for(m=mnt.md; m; m=m->next)
366 b3994ec5 2003-12-11 devnull if(m->id == id){
367 b3994ec5 2003-12-11 devnull f->mntdir = m;
368 b3994ec5 2003-12-11 devnull m->ref++;
369 b3994ec5 2003-12-11 devnull break;
370 b3994ec5 2003-12-11 devnull }
371 8ad51794 2004-03-25 devnull if(m == nil && x->fcall.aname[0]){
372 49588d5d 2003-12-17 devnull snprint(buf, sizeof buf, "unknown id '%s' in attach", x->fcall.aname);
373 49588d5d 2003-12-17 devnull sendp(cerr, estrdup(buf));
374 49588d5d 2003-12-17 devnull }
375 b3994ec5 2003-12-11 devnull qunlock(&mnt.lk);
376 b3994ec5 2003-12-11 devnull return respond(x, &t, nil);
377 b3994ec5 2003-12-11 devnull }
378 b3994ec5 2003-12-11 devnull
379 b3994ec5 2003-12-11 devnull static
380 b3994ec5 2003-12-11 devnull Xfid*
381 b3994ec5 2003-12-11 devnull fsyswalk(Xfid *x, Fid *f)
382 b3994ec5 2003-12-11 devnull {
383 b3994ec5 2003-12-11 devnull Fcall t;
384 b3994ec5 2003-12-11 devnull int c, i, j, id;
385 b3994ec5 2003-12-11 devnull Qid q;
386 b3994ec5 2003-12-11 devnull uchar type;
387 b3994ec5 2003-12-11 devnull ulong path;
388 b3994ec5 2003-12-11 devnull Fid *nf;
389 b3994ec5 2003-12-11 devnull Dirtab *d, *dir;
390 b3994ec5 2003-12-11 devnull Window *w;
391 b3994ec5 2003-12-11 devnull char *err;
392 b3994ec5 2003-12-11 devnull
393 b3994ec5 2003-12-11 devnull nf = nil;
394 b3994ec5 2003-12-11 devnull w = nil;
395 b3994ec5 2003-12-11 devnull if(f->open)
396 b3994ec5 2003-12-11 devnull return respond(x, &t, "walk of open file");
397 b3994ec5 2003-12-11 devnull if(x->fcall.fid != x->fcall.newfid){
398 b3994ec5 2003-12-11 devnull nf = newfid(x->fcall.newfid);
399 b3994ec5 2003-12-11 devnull if(nf->busy)
400 b3994ec5 2003-12-11 devnull return respond(x, &t, "newfid already in use");
401 b3994ec5 2003-12-11 devnull nf->busy = TRUE;
402 b3994ec5 2003-12-11 devnull nf->open = FALSE;
403 b3994ec5 2003-12-11 devnull nf->mntdir = f->mntdir;
404 b3994ec5 2003-12-11 devnull if(f->mntdir)
405 b3994ec5 2003-12-11 devnull f->mntdir->ref++;
406 b3994ec5 2003-12-11 devnull nf->dir = f->dir;
407 b3994ec5 2003-12-11 devnull nf->qid = f->qid;
408 b3994ec5 2003-12-11 devnull nf->w = f->w;
409 b3994ec5 2003-12-11 devnull nf->nrpart = 0; /* not open, so must be zero */
410 b3994ec5 2003-12-11 devnull if(nf->w)
411 b3994ec5 2003-12-11 devnull incref(&nf->w->ref);
412 b3994ec5 2003-12-11 devnull f = nf; /* walk f */
413 b3994ec5 2003-12-11 devnull }
414 b3994ec5 2003-12-11 devnull
415 b3994ec5 2003-12-11 devnull t.nwqid = 0;
416 b3994ec5 2003-12-11 devnull err = nil;
417 b3994ec5 2003-12-11 devnull dir = nil;
418 b3994ec5 2003-12-11 devnull id = WIN(f->qid);
419 b3994ec5 2003-12-11 devnull q = f->qid;
420 b3994ec5 2003-12-11 devnull
421 b3994ec5 2003-12-11 devnull if(x->fcall.nwname > 0){
422 b3994ec5 2003-12-11 devnull for(i=0; i<x->fcall.nwname; i++){
423 b3994ec5 2003-12-11 devnull if((q.type & QTDIR) == 0){
424 b3994ec5 2003-12-11 devnull err = Enotdir;
425 b3994ec5 2003-12-11 devnull break;
426 b3994ec5 2003-12-11 devnull }
427 b3994ec5 2003-12-11 devnull
428 b3994ec5 2003-12-11 devnull if(strcmp(x->fcall.wname[i], "..") == 0){
429 b3994ec5 2003-12-11 devnull type = QTDIR;
430 b3994ec5 2003-12-11 devnull path = Qdir;
431 b3994ec5 2003-12-11 devnull id = 0;
432 b3994ec5 2003-12-11 devnull if(w){
433 b3994ec5 2003-12-11 devnull winclose(w);
434 b3994ec5 2003-12-11 devnull w = nil;
435 b3994ec5 2003-12-11 devnull }
436 b3994ec5 2003-12-11 devnull Accept:
437 b3994ec5 2003-12-11 devnull if(i == MAXWELEM){
438 b3994ec5 2003-12-11 devnull err = "name too long";
439 b3994ec5 2003-12-11 devnull break;
440 b3994ec5 2003-12-11 devnull }
441 b3994ec5 2003-12-11 devnull q.type = type;
442 b3994ec5 2003-12-11 devnull q.vers = 0;
443 b3994ec5 2003-12-11 devnull q.path = QID(id, path);
444 b3994ec5 2003-12-11 devnull t.wqid[t.nwqid++] = q;
445 b3994ec5 2003-12-11 devnull continue;
446 b3994ec5 2003-12-11 devnull }
447 b3994ec5 2003-12-11 devnull
448 b3994ec5 2003-12-11 devnull /* is it a numeric name? */
449 b3994ec5 2003-12-11 devnull for(j=0; (c=x->fcall.wname[i][j]); j++)
450 b3994ec5 2003-12-11 devnull if(c<'0' || '9'<c)
451 b3994ec5 2003-12-11 devnull goto Regular;
452 b3994ec5 2003-12-11 devnull /* yes: it's a directory */
453 b3994ec5 2003-12-11 devnull if(w) /* name has form 27/23; get out before losing w */
454 b3994ec5 2003-12-11 devnull break;
455 b3994ec5 2003-12-11 devnull id = atoi(x->fcall.wname[i]);
456 b3994ec5 2003-12-11 devnull qlock(&row.lk);
457 b3994ec5 2003-12-11 devnull w = lookid(id, FALSE);
458 b3994ec5 2003-12-11 devnull if(w == nil){
459 b3994ec5 2003-12-11 devnull qunlock(&row.lk);
460 b3994ec5 2003-12-11 devnull break;
461 b3994ec5 2003-12-11 devnull }
462 b3994ec5 2003-12-11 devnull incref(&w->ref); /* we'll drop reference at end if there's an error */
463 b3994ec5 2003-12-11 devnull path = Qdir;
464 b3994ec5 2003-12-11 devnull type = QTDIR;
465 b3994ec5 2003-12-11 devnull qunlock(&row.lk);
466 b3994ec5 2003-12-11 devnull dir = dirtabw;
467 b3994ec5 2003-12-11 devnull goto Accept;
468 b3994ec5 2003-12-11 devnull
469 b3994ec5 2003-12-11 devnull Regular:
470 b3994ec5 2003-12-11 devnull // if(FILE(f->qid) == Qacme) /* empty directory */
471 b3994ec5 2003-12-11 devnull // break;
472 b3994ec5 2003-12-11 devnull if(strcmp(x->fcall.wname[i], "new") == 0){
473 b3994ec5 2003-12-11 devnull if(w)
474 b3994ec5 2003-12-11 devnull error("w set in walk to new");
475 b3994ec5 2003-12-11 devnull sendp(cnewwindow, nil); /* signal newwindowthread */
476 b3994ec5 2003-12-11 devnull w = recvp(cnewwindow); /* receive new window */
477 b3994ec5 2003-12-11 devnull incref(&w->ref);
478 b3994ec5 2003-12-11 devnull type = QTDIR;
479 b3994ec5 2003-12-11 devnull path = QID(w->id, Qdir);
480 b3994ec5 2003-12-11 devnull id = w->id;
481 b3994ec5 2003-12-11 devnull dir = dirtabw;
482 b3994ec5 2003-12-11 devnull goto Accept;
483 b3994ec5 2003-12-11 devnull }
484 b3994ec5 2003-12-11 devnull
485 b3994ec5 2003-12-11 devnull if(id == 0)
486 b3994ec5 2003-12-11 devnull d = dirtab;
487 b3994ec5 2003-12-11 devnull else
488 b3994ec5 2003-12-11 devnull d = dirtabw;
489 b3994ec5 2003-12-11 devnull d++; /* skip '.' */
490 b3994ec5 2003-12-11 devnull for(; d->name; d++)
491 b3994ec5 2003-12-11 devnull if(strcmp(x->fcall.wname[i], d->name) == 0){
492 b3994ec5 2003-12-11 devnull path = d->qid;
493 b3994ec5 2003-12-11 devnull type = d->type;
494 b3994ec5 2003-12-11 devnull dir = d;
495 b3994ec5 2003-12-11 devnull goto Accept;
496 b3994ec5 2003-12-11 devnull }
497 b3994ec5 2003-12-11 devnull
498 b3994ec5 2003-12-11 devnull break; /* file not found */
499 b3994ec5 2003-12-11 devnull }
500 b3994ec5 2003-12-11 devnull
501 b3994ec5 2003-12-11 devnull if(i==0 && err == nil)
502 b3994ec5 2003-12-11 devnull err = Eexist;
503 b3994ec5 2003-12-11 devnull }
504 b3994ec5 2003-12-11 devnull
505 b3994ec5 2003-12-11 devnull if(err!=nil || t.nwqid<x->fcall.nwname){
506 b3994ec5 2003-12-11 devnull if(nf){
507 b3994ec5 2003-12-11 devnull nf->busy = FALSE;
508 b3994ec5 2003-12-11 devnull fsysdelid(nf->mntdir);
509 b3994ec5 2003-12-11 devnull }
510 b3994ec5 2003-12-11 devnull }else if(t.nwqid == x->fcall.nwname){
511 b3994ec5 2003-12-11 devnull if(w){
512 b3994ec5 2003-12-11 devnull f->w = w;
513 b3994ec5 2003-12-11 devnull w = nil; /* don't drop the reference */
514 b3994ec5 2003-12-11 devnull }
515 b3994ec5 2003-12-11 devnull if(dir)
516 b3994ec5 2003-12-11 devnull f->dir = dir;
517 b3994ec5 2003-12-11 devnull f->qid = q;
518 b3994ec5 2003-12-11 devnull }
519 b3994ec5 2003-12-11 devnull
520 b3994ec5 2003-12-11 devnull if(w != nil)
521 b3994ec5 2003-12-11 devnull winclose(w);
522 b3994ec5 2003-12-11 devnull
523 b3994ec5 2003-12-11 devnull return respond(x, &t, err);
524 b3994ec5 2003-12-11 devnull }
525 b3994ec5 2003-12-11 devnull
526 b3994ec5 2003-12-11 devnull static
527 b3994ec5 2003-12-11 devnull Xfid*
528 b3994ec5 2003-12-11 devnull fsysopen(Xfid *x, Fid *f)
529 b3994ec5 2003-12-11 devnull {
530 b3994ec5 2003-12-11 devnull Fcall t;
531 b3994ec5 2003-12-11 devnull int m;
532 b3994ec5 2003-12-11 devnull
533 b3994ec5 2003-12-11 devnull /* can't truncate anything, so just disregard */
534 b3994ec5 2003-12-11 devnull x->fcall.mode &= ~(OTRUNC|OCEXEC);
535 b3994ec5 2003-12-11 devnull /* can't execute or remove anything */
536 b3994ec5 2003-12-11 devnull if(x->fcall.mode==OEXEC || (x->fcall.mode&ORCLOSE))
537 b3994ec5 2003-12-11 devnull goto Deny;
538 b3994ec5 2003-12-11 devnull switch(x->fcall.mode){
539 b3994ec5 2003-12-11 devnull default:
540 b3994ec5 2003-12-11 devnull goto Deny;
541 b3994ec5 2003-12-11 devnull case OREAD:
542 b3994ec5 2003-12-11 devnull m = 0400;
543 b3994ec5 2003-12-11 devnull break;
544 b3994ec5 2003-12-11 devnull case OWRITE:
545 b3994ec5 2003-12-11 devnull m = 0200;
546 b3994ec5 2003-12-11 devnull break;
547 b3994ec5 2003-12-11 devnull case ORDWR:
548 b3994ec5 2003-12-11 devnull m = 0600;
549 b3994ec5 2003-12-11 devnull break;
550 b3994ec5 2003-12-11 devnull }
551 b3994ec5 2003-12-11 devnull if(((f->dir->perm&~(DMDIR|DMAPPEND))&m) != m)
552 b3994ec5 2003-12-11 devnull goto Deny;
553 b3994ec5 2003-12-11 devnull
554 be22ae2d 2004-03-26 devnull sendp(x->c, (void*)xfidopen);
555 b3994ec5 2003-12-11 devnull return nil;
556 b3994ec5 2003-12-11 devnull
557 b3994ec5 2003-12-11 devnull Deny:
558 b3994ec5 2003-12-11 devnull return respond(x, &t, Eperm);
559 b3994ec5 2003-12-11 devnull }
560 b3994ec5 2003-12-11 devnull
561 b3994ec5 2003-12-11 devnull static
562 b3994ec5 2003-12-11 devnull Xfid*
563 b3994ec5 2003-12-11 devnull fsyscreate(Xfid *x, Fid *f)
564 b3994ec5 2003-12-11 devnull {
565 b3994ec5 2003-12-11 devnull Fcall t;
566 b3994ec5 2003-12-11 devnull
567 b3994ec5 2003-12-11 devnull USED(f);
568 b3994ec5 2003-12-11 devnull return respond(x, &t, Eperm);
569 b3994ec5 2003-12-11 devnull }
570 b3994ec5 2003-12-11 devnull
571 b3994ec5 2003-12-11 devnull static
572 b3994ec5 2003-12-11 devnull int
573 b3994ec5 2003-12-11 devnull idcmp(const void *a, const void *b)
574 b3994ec5 2003-12-11 devnull {
575 b3994ec5 2003-12-11 devnull return *(int*)a - *(int*)b;
576 b3994ec5 2003-12-11 devnull }
577 b3994ec5 2003-12-11 devnull
578 b3994ec5 2003-12-11 devnull static
579 b3994ec5 2003-12-11 devnull Xfid*
580 b3994ec5 2003-12-11 devnull fsysread(Xfid *x, Fid *f)
581 b3994ec5 2003-12-11 devnull {
582 b3994ec5 2003-12-11 devnull Fcall t;
583 b3994ec5 2003-12-11 devnull uchar *b;
584 b3994ec5 2003-12-11 devnull int i, id, n, o, e, j, k, *ids, nids;
585 b3994ec5 2003-12-11 devnull Dirtab *d, dt;
586 b3994ec5 2003-12-11 devnull Column *c;
587 b3994ec5 2003-12-11 devnull uint clock, len;
588 b3994ec5 2003-12-11 devnull char buf[16];
589 b3994ec5 2003-12-11 devnull
590 b3994ec5 2003-12-11 devnull if(f->qid.type & QTDIR){
591 b3994ec5 2003-12-11 devnull if(FILE(f->qid) == Qacme){ /* empty dir */
592 b3994ec5 2003-12-11 devnull t.data = nil;
593 b3994ec5 2003-12-11 devnull t.count = 0;
594 b3994ec5 2003-12-11 devnull respond(x, &t, nil);
595 b3994ec5 2003-12-11 devnull return x;
596 b3994ec5 2003-12-11 devnull }
597 b3994ec5 2003-12-11 devnull o = x->fcall.offset;
598 b3994ec5 2003-12-11 devnull e = x->fcall.offset+x->fcall.count;
599 b3994ec5 2003-12-11 devnull clock = getclock();
600 b3994ec5 2003-12-11 devnull b = emalloc(messagesize);
601 b3994ec5 2003-12-11 devnull id = WIN(f->qid);
602 b3994ec5 2003-12-11 devnull n = 0;
603 b3994ec5 2003-12-11 devnull if(id > 0)
604 b3994ec5 2003-12-11 devnull d = dirtabw;
605 b3994ec5 2003-12-11 devnull else
606 b3994ec5 2003-12-11 devnull d = dirtab;
607 b3994ec5 2003-12-11 devnull d++; /* first entry is '.' */
608 b3994ec5 2003-12-11 devnull for(i=0; d->name!=nil && i<e; i+=len){
609 b3994ec5 2003-12-11 devnull len = dostat(WIN(x->f->qid), d, b+n, x->fcall.count-n, clock);
610 b3994ec5 2003-12-11 devnull if(len <= BIT16SZ)
611 b3994ec5 2003-12-11 devnull break;
612 b3994ec5 2003-12-11 devnull if(i >= o)
613 b3994ec5 2003-12-11 devnull n += len;
614 b3994ec5 2003-12-11 devnull d++;
615 b3994ec5 2003-12-11 devnull }
616 b3994ec5 2003-12-11 devnull if(id == 0){
617 b3994ec5 2003-12-11 devnull qlock(&row.lk);
618 b3994ec5 2003-12-11 devnull nids = 0;
619 b3994ec5 2003-12-11 devnull ids = nil;
620 b3994ec5 2003-12-11 devnull for(j=0; j<row.ncol; j++){
621 b3994ec5 2003-12-11 devnull c = row.col[j];
622 b3994ec5 2003-12-11 devnull for(k=0; k<c->nw; k++){
623 b3994ec5 2003-12-11 devnull ids = realloc(ids, (nids+1)*sizeof(int));
624 b3994ec5 2003-12-11 devnull ids[nids++] = c->w[k]->id;
625 b3994ec5 2003-12-11 devnull }
626 b3994ec5 2003-12-11 devnull }
627 b3994ec5 2003-12-11 devnull qunlock(&row.lk);
628 b3994ec5 2003-12-11 devnull qsort(ids, nids, sizeof ids[0], idcmp);
629 b3994ec5 2003-12-11 devnull j = 0;
630 b3994ec5 2003-12-11 devnull dt.name = buf;
631 b3994ec5 2003-12-11 devnull for(; j<nids && i<e; i+=len){
632 b3994ec5 2003-12-11 devnull k = ids[j];
633 b3994ec5 2003-12-11 devnull sprint(dt.name, "%d", k);
634 b3994ec5 2003-12-11 devnull dt.qid = QID(k, Qdir);
635 b3994ec5 2003-12-11 devnull dt.type = QTDIR;
636 b3994ec5 2003-12-11 devnull dt.perm = DMDIR|0700;
637 b3994ec5 2003-12-11 devnull len = dostat(k, &dt, b+n, x->fcall.count-n, clock);
638 b3994ec5 2003-12-11 devnull if(len == 0)
639 b3994ec5 2003-12-11 devnull break;
640 b3994ec5 2003-12-11 devnull if(i >= o)
641 b3994ec5 2003-12-11 devnull n += len;
642 b3994ec5 2003-12-11 devnull j++;
643 b3994ec5 2003-12-11 devnull }
644 b3994ec5 2003-12-11 devnull free(ids);
645 b3994ec5 2003-12-11 devnull }
646 b3994ec5 2003-12-11 devnull t.data = (char*)b;
647 b3994ec5 2003-12-11 devnull t.count = n;
648 b3994ec5 2003-12-11 devnull respond(x, &t, nil);
649 b3994ec5 2003-12-11 devnull free(b);
650 b3994ec5 2003-12-11 devnull return x;
651 b3994ec5 2003-12-11 devnull }
652 be22ae2d 2004-03-26 devnull sendp(x->c, (void*)xfidread);
653 b3994ec5 2003-12-11 devnull return nil;
654 b3994ec5 2003-12-11 devnull }
655 b3994ec5 2003-12-11 devnull
656 b3994ec5 2003-12-11 devnull static
657 b3994ec5 2003-12-11 devnull Xfid*
658 b3994ec5 2003-12-11 devnull fsyswrite(Xfid *x, Fid *f)
659 b3994ec5 2003-12-11 devnull {
660 b3994ec5 2003-12-11 devnull USED(f);
661 be22ae2d 2004-03-26 devnull sendp(x->c, (void*)xfidwrite);
662 b3994ec5 2003-12-11 devnull return nil;
663 b3994ec5 2003-12-11 devnull }
664 b3994ec5 2003-12-11 devnull
665 b3994ec5 2003-12-11 devnull static
666 b3994ec5 2003-12-11 devnull Xfid*
667 b3994ec5 2003-12-11 devnull fsysclunk(Xfid *x, Fid *f)
668 b3994ec5 2003-12-11 devnull {
669 b3994ec5 2003-12-11 devnull fsysdelid(f->mntdir);
670 be22ae2d 2004-03-26 devnull sendp(x->c, (void*)xfidclose);
671 b3994ec5 2003-12-11 devnull return nil;
672 b3994ec5 2003-12-11 devnull }
673 b3994ec5 2003-12-11 devnull
674 b3994ec5 2003-12-11 devnull static
675 b3994ec5 2003-12-11 devnull Xfid*
676 b3994ec5 2003-12-11 devnull fsysremove(Xfid *x, Fid *f)
677 b3994ec5 2003-12-11 devnull {
678 b3994ec5 2003-12-11 devnull Fcall t;
679 b3994ec5 2003-12-11 devnull
680 b3994ec5 2003-12-11 devnull USED(f);
681 b3994ec5 2003-12-11 devnull return respond(x, &t, Eperm);
682 b3994ec5 2003-12-11 devnull }
683 b3994ec5 2003-12-11 devnull
684 b3994ec5 2003-12-11 devnull static
685 b3994ec5 2003-12-11 devnull Xfid*
686 b3994ec5 2003-12-11 devnull fsysstat(Xfid *x, Fid *f)
687 b3994ec5 2003-12-11 devnull {
688 b3994ec5 2003-12-11 devnull Fcall t;
689 b3994ec5 2003-12-11 devnull
690 b3994ec5 2003-12-11 devnull t.stat = emalloc(messagesize-IOHDRSZ);
691 b3994ec5 2003-12-11 devnull t.nstat = dostat(WIN(x->f->qid), f->dir, t.stat, messagesize-IOHDRSZ, getclock());
692 b3994ec5 2003-12-11 devnull x = respond(x, &t, nil);
693 b3994ec5 2003-12-11 devnull free(t.stat);
694 b3994ec5 2003-12-11 devnull return x;
695 b3994ec5 2003-12-11 devnull }
696 b3994ec5 2003-12-11 devnull
697 b3994ec5 2003-12-11 devnull static
698 b3994ec5 2003-12-11 devnull Xfid*
699 b3994ec5 2003-12-11 devnull fsyswstat(Xfid *x, Fid *f)
700 b3994ec5 2003-12-11 devnull {
701 b3994ec5 2003-12-11 devnull Fcall t;
702 b3994ec5 2003-12-11 devnull
703 b3994ec5 2003-12-11 devnull USED(f);
704 b3994ec5 2003-12-11 devnull return respond(x, &t, Eperm);
705 b3994ec5 2003-12-11 devnull }
706 b3994ec5 2003-12-11 devnull
707 b3994ec5 2003-12-11 devnull Fid*
708 b3994ec5 2003-12-11 devnull newfid(int fid)
709 b3994ec5 2003-12-11 devnull {
710 b3994ec5 2003-12-11 devnull Fid *f, *ff, **fh;
711 b3994ec5 2003-12-11 devnull
712 b3994ec5 2003-12-11 devnull ff = nil;
713 b3994ec5 2003-12-11 devnull fh = &fids[fid&(Nhash-1)];
714 b3994ec5 2003-12-11 devnull for(f=*fh; f; f=f->next)
715 b3994ec5 2003-12-11 devnull if(f->fid == fid)
716 b3994ec5 2003-12-11 devnull return f;
717 b3994ec5 2003-12-11 devnull else if(ff==nil && f->busy==FALSE)
718 b3994ec5 2003-12-11 devnull ff = f;
719 b3994ec5 2003-12-11 devnull if(ff){
720 b3994ec5 2003-12-11 devnull ff->fid = fid;
721 b3994ec5 2003-12-11 devnull return ff;
722 b3994ec5 2003-12-11 devnull }
723 b3994ec5 2003-12-11 devnull f = emalloc(sizeof *f);
724 b3994ec5 2003-12-11 devnull f->fid = fid;
725 b3994ec5 2003-12-11 devnull f->next = *fh;
726 b3994ec5 2003-12-11 devnull *fh = f;
727 b3994ec5 2003-12-11 devnull return f;
728 b3994ec5 2003-12-11 devnull }
729 b3994ec5 2003-12-11 devnull
730 b3994ec5 2003-12-11 devnull uint
731 b3994ec5 2003-12-11 devnull getclock(void)
732 b3994ec5 2003-12-11 devnull {
733 b3994ec5 2003-12-11 devnull /*
734 b3994ec5 2003-12-11 devnull char buf[32];
735 b3994ec5 2003-12-11 devnull
736 b3994ec5 2003-12-11 devnull buf[0] = '\0';
737 b3994ec5 2003-12-11 devnull pread(clockfd, buf, sizeof buf, 0);
738 b3994ec5 2003-12-11 devnull return atoi(buf);
739 b3994ec5 2003-12-11 devnull */
740 b3994ec5 2003-12-11 devnull return time(0);
741 b3994ec5 2003-12-11 devnull }
742 b3994ec5 2003-12-11 devnull
743 b3994ec5 2003-12-11 devnull int
744 b3994ec5 2003-12-11 devnull dostat(int id, Dirtab *dir, uchar *buf, int nbuf, uint clock)
745 b3994ec5 2003-12-11 devnull {
746 b3994ec5 2003-12-11 devnull Dir d;
747 b3994ec5 2003-12-11 devnull
748 b3994ec5 2003-12-11 devnull d.qid.path = QID(id, dir->qid);
749 b3994ec5 2003-12-11 devnull d.qid.vers = 0;
750 b3994ec5 2003-12-11 devnull d.qid.type = dir->type;
751 b3994ec5 2003-12-11 devnull d.mode = dir->perm;
752 b3994ec5 2003-12-11 devnull d.length = 0; /* would be nice to do better */
753 b3994ec5 2003-12-11 devnull d.name = dir->name;
754 b3994ec5 2003-12-11 devnull d.uid = user;
755 b3994ec5 2003-12-11 devnull d.gid = user;
756 b3994ec5 2003-12-11 devnull d.muid = user;
757 b3994ec5 2003-12-11 devnull d.atime = clock;
758 b3994ec5 2003-12-11 devnull d.mtime = clock;
759 b3994ec5 2003-12-11 devnull return convD2M(&d, buf, nbuf);
760 b3994ec5 2003-12-11 devnull }