Blame


1 7763a61a 2003-11-23 devnull #include "stdinc.h"
2 7763a61a 2003-11-23 devnull #include <auth.h>
3 7763a61a 2003-11-23 devnull #include <fcall.h>
4 a20a1468 2005-01-16 devnull #include <thread.h>
5 7763a61a 2003-11-23 devnull #include "vac.h"
6 7763a61a 2003-11-23 devnull
7 7763a61a 2003-11-23 devnull typedef struct Fid Fid;
8 7763a61a 2003-11-23 devnull typedef struct DirBuf DirBuf;
9 7763a61a 2003-11-23 devnull
10 7763a61a 2003-11-23 devnull enum
11 7763a61a 2003-11-23 devnull {
12 7763a61a 2003-11-23 devnull OPERM = 0x3, /* mask of all permission types in open mode */
13 7763a61a 2003-11-23 devnull };
14 7763a61a 2003-11-23 devnull
15 7763a61a 2003-11-23 devnull enum
16 7763a61a 2003-11-23 devnull {
17 7763a61a 2003-11-23 devnull DirBufSize = 20,
18 7763a61a 2003-11-23 devnull };
19 7763a61a 2003-11-23 devnull
20 7763a61a 2003-11-23 devnull struct Fid
21 7763a61a 2003-11-23 devnull {
22 7763a61a 2003-11-23 devnull short busy;
23 7763a61a 2003-11-23 devnull short open;
24 7763a61a 2003-11-23 devnull int fid;
25 7763a61a 2003-11-23 devnull char *user;
26 7763a61a 2003-11-23 devnull Qid qid;
27 7763a61a 2003-11-23 devnull VacFile *file;
28 7763a61a 2003-11-23 devnull
29 7763a61a 2003-11-23 devnull DirBuf *db;
30 7763a61a 2003-11-23 devnull
31 7763a61a 2003-11-23 devnull Fid *next;
32 7763a61a 2003-11-23 devnull };
33 7763a61a 2003-11-23 devnull
34 7763a61a 2003-11-23 devnull struct DirBuf
35 7763a61a 2003-11-23 devnull {
36 7763a61a 2003-11-23 devnull VacDirEnum *vde;
37 7763a61a 2003-11-23 devnull VacDir buf[DirBufSize];
38 7763a61a 2003-11-23 devnull int i, n;
39 7763a61a 2003-11-23 devnull int eof;
40 7763a61a 2003-11-23 devnull };
41 7763a61a 2003-11-23 devnull
42 7763a61a 2003-11-23 devnull enum
43 7763a61a 2003-11-23 devnull {
44 7763a61a 2003-11-23 devnull Pexec = 1,
45 7763a61a 2003-11-23 devnull Pwrite = 2,
46 7763a61a 2003-11-23 devnull Pread = 4,
47 7763a61a 2003-11-23 devnull Pother = 1,
48 7763a61a 2003-11-23 devnull Pgroup = 8,
49 7763a61a 2003-11-23 devnull Powner = 64,
50 7763a61a 2003-11-23 devnull };
51 7763a61a 2003-11-23 devnull
52 7763a61a 2003-11-23 devnull Fid *fids;
53 7763a61a 2003-11-23 devnull uchar *data;
54 7763a61a 2003-11-23 devnull int mfd[2];
55 7763a61a 2003-11-23 devnull char *user;
56 7763a61a 2003-11-23 devnull uchar mdata[8192+IOHDRSZ];
57 7763a61a 2003-11-23 devnull int messagesize = sizeof mdata;
58 7763a61a 2003-11-23 devnull Fcall rhdr;
59 7763a61a 2003-11-23 devnull Fcall thdr;
60 a20a1468 2005-01-16 devnull VacFs *fs;
61 a20a1468 2005-01-16 devnull VtConn *conn;
62 a20a1468 2005-01-16 devnull // VtSession *session;
63 7763a61a 2003-11-23 devnull int noperm;
64 7763a61a 2003-11-23 devnull
65 7763a61a 2003-11-23 devnull Fid * newfid(int);
66 7763a61a 2003-11-23 devnull void error(char*);
67 7763a61a 2003-11-23 devnull void io(void);
68 7763a61a 2003-11-23 devnull void shutdown(void);
69 7763a61a 2003-11-23 devnull void usage(void);
70 7763a61a 2003-11-23 devnull int perm(Fid*, int);
71 7763a61a 2003-11-23 devnull int permf(VacFile*, char*, int);
72 7763a61a 2003-11-23 devnull ulong getl(void *p);
73 7763a61a 2003-11-23 devnull void init(char*, char*, long, int);
74 7763a61a 2003-11-23 devnull DirBuf *dirBufAlloc(VacFile*);
75 7763a61a 2003-11-23 devnull VacDir *dirBufGet(DirBuf*);
76 7763a61a 2003-11-23 devnull int dirBufUnget(DirBuf*);
77 7763a61a 2003-11-23 devnull void dirBufFree(DirBuf*);
78 7763a61a 2003-11-23 devnull int vacdirread(Fid *f, char *p, long off, long cnt);
79 7763a61a 2003-11-23 devnull int vdStat(VacDir *vd, uchar *p, int np);
80 a20a1468 2005-01-16 devnull void srv(void* a);
81 7763a61a 2003-11-23 devnull
82 a20a1468 2005-01-16 devnull
83 7763a61a 2003-11-23 devnull char *rflush(Fid*), *rversion(Fid*),
84 7763a61a 2003-11-23 devnull *rauth(Fid*), *rattach(Fid*), *rwalk(Fid*),
85 7763a61a 2003-11-23 devnull *ropen(Fid*), *rcreate(Fid*),
86 7763a61a 2003-11-23 devnull *rread(Fid*), *rwrite(Fid*), *rclunk(Fid*),
87 7763a61a 2003-11-23 devnull *rremove(Fid*), *rstat(Fid*), *rwstat(Fid*);
88 7763a61a 2003-11-23 devnull
89 7763a61a 2003-11-23 devnull char *(*fcalls[])(Fid*) = {
90 7763a61a 2003-11-23 devnull [Tflush] rflush,
91 7763a61a 2003-11-23 devnull [Tversion] rversion,
92 7763a61a 2003-11-23 devnull [Tattach] rattach,
93 7763a61a 2003-11-23 devnull [Tauth] rauth,
94 7763a61a 2003-11-23 devnull [Twalk] rwalk,
95 7763a61a 2003-11-23 devnull [Topen] ropen,
96 7763a61a 2003-11-23 devnull [Tcreate] rcreate,
97 7763a61a 2003-11-23 devnull [Tread] rread,
98 7763a61a 2003-11-23 devnull [Twrite] rwrite,
99 7763a61a 2003-11-23 devnull [Tclunk] rclunk,
100 7763a61a 2003-11-23 devnull [Tremove] rremove,
101 7763a61a 2003-11-23 devnull [Tstat] rstat,
102 7763a61a 2003-11-23 devnull [Twstat] rwstat,
103 7763a61a 2003-11-23 devnull };
104 7763a61a 2003-11-23 devnull
105 7763a61a 2003-11-23 devnull char Eperm[] = "permission denied";
106 7763a61a 2003-11-23 devnull char Enotdir[] = "not a directory";
107 7763a61a 2003-11-23 devnull char Enotexist[] = "file does not exist";
108 7763a61a 2003-11-23 devnull char Einuse[] = "file in use";
109 7763a61a 2003-11-23 devnull char Eexist[] = "file exists";
110 7763a61a 2003-11-23 devnull char Enotowner[] = "not owner";
111 7763a61a 2003-11-23 devnull char Eisopen[] = "file already open for I/O";
112 7763a61a 2003-11-23 devnull char Excl[] = "exclusive use file already open";
113 7763a61a 2003-11-23 devnull char Ename[] = "illegal name";
114 7763a61a 2003-11-23 devnull char Erdonly[] = "read only file system";
115 7763a61a 2003-11-23 devnull char Eio[] = "i/o error";
116 7763a61a 2003-11-23 devnull char Eempty[] = "directory is not empty";
117 7763a61a 2003-11-23 devnull char Emode[] = "illegal mode";
118 7763a61a 2003-11-23 devnull
119 7763a61a 2003-11-23 devnull int dflag;
120 7763a61a 2003-11-23 devnull
121 7763a61a 2003-11-23 devnull void
122 7763a61a 2003-11-23 devnull notifyf(void *a, char *s)
123 7763a61a 2003-11-23 devnull {
124 7763a61a 2003-11-23 devnull USED(a);
125 7763a61a 2003-11-23 devnull if(strncmp(s, "interrupt", 9) == 0)
126 7763a61a 2003-11-23 devnull noted(NCONT);
127 7763a61a 2003-11-23 devnull noted(NDFLT);
128 7763a61a 2003-11-23 devnull }
129 7763a61a 2003-11-23 devnull
130 7763a61a 2003-11-23 devnull void
131 a20a1468 2005-01-16 devnull threadmain(int argc, char *argv[])
132 7763a61a 2003-11-23 devnull {
133 91124c1b 2005-01-16 devnull char *defsrv, *q;
134 91124c1b 2005-01-16 devnull int p[2], l;
135 7763a61a 2003-11-23 devnull int stdio = 0;
136 7763a61a 2003-11-23 devnull char *host = nil;
137 7763a61a 2003-11-23 devnull long ncache = 1000;
138 7763a61a 2003-11-23 devnull int readOnly = 1;
139 7763a61a 2003-11-23 devnull
140 91124c1b 2005-01-16 devnull defsrv = nil;
141 7763a61a 2003-11-23 devnull ARGBEGIN{
142 7763a61a 2003-11-23 devnull case 'd':
143 7763a61a 2003-11-23 devnull fmtinstall('F', fcallfmt);
144 7763a61a 2003-11-23 devnull dflag = 1;
145 7763a61a 2003-11-23 devnull break;
146 7763a61a 2003-11-23 devnull case 'c':
147 32053cdf 2005-01-16 devnull ncache = atoi(EARGF(usage()));
148 7763a61a 2003-11-23 devnull break;
149 7763a61a 2003-11-23 devnull case 'i':
150 7763a61a 2003-11-23 devnull stdio = 1;
151 7763a61a 2003-11-23 devnull mfd[0] = 0;
152 7763a61a 2003-11-23 devnull mfd[1] = 1;
153 7763a61a 2003-11-23 devnull break;
154 7763a61a 2003-11-23 devnull case 'h':
155 32053cdf 2005-01-16 devnull host = EARGF(usage());
156 7763a61a 2003-11-23 devnull break;
157 7763a61a 2003-11-23 devnull case 's':
158 32053cdf 2005-01-16 devnull defsrv = EARGF(usage());
159 7763a61a 2003-11-23 devnull break;
160 7763a61a 2003-11-23 devnull case 'p':
161 7763a61a 2003-11-23 devnull noperm = 1;
162 7763a61a 2003-11-23 devnull break;
163 7763a61a 2003-11-23 devnull default:
164 7763a61a 2003-11-23 devnull usage();
165 7763a61a 2003-11-23 devnull }ARGEND
166 7763a61a 2003-11-23 devnull
167 7763a61a 2003-11-23 devnull if(argc != 1)
168 7763a61a 2003-11-23 devnull usage();
169 7763a61a 2003-11-23 devnull
170 7763a61a 2003-11-23 devnull init(argv[0], host, ncache, readOnly);
171 7763a61a 2003-11-23 devnull
172 7763a61a 2003-11-23 devnull if(pipe(p) < 0)
173 7763a61a 2003-11-23 devnull sysfatal("pipe failed: %r");
174 7763a61a 2003-11-23 devnull
175 a20a1468 2005-01-16 devnull mfd[0] = p[0];
176 a20a1468 2005-01-16 devnull mfd[1] = p[0];
177 a20a1468 2005-01-16 devnull proccreate(srv, 0, 32 * 1024);
178 a20a1468 2005-01-16 devnull
179 91124c1b 2005-01-16 devnull if(defsrv == nil){
180 91124c1b 2005-01-16 devnull q = strrchr(argv[0], '/');
181 91124c1b 2005-01-16 devnull if(q)
182 91124c1b 2005-01-16 devnull q++;
183 91124c1b 2005-01-16 devnull else
184 91124c1b 2005-01-16 devnull q = argv[0];
185 91124c1b 2005-01-16 devnull defsrv = vtmalloc(6+strlen(q)+1);
186 91124c1b 2005-01-16 devnull strcpy(defsrv, "vacfs.");
187 91124c1b 2005-01-16 devnull strcat(defsrv, q);
188 91124c1b 2005-01-16 devnull l = strlen(defsrv);
189 91124c1b 2005-01-16 devnull if(strcmp(defsrv+l-4, ".vac") == 0)
190 91124c1b 2005-01-16 devnull defsrv[l-4] = 0;
191 91124c1b 2005-01-16 devnull }
192 91124c1b 2005-01-16 devnull
193 91124c1b 2005-01-16 devnull if(post9pservice(p[1], defsrv) != 0)
194 a20a1468 2005-01-16 devnull sysfatal("post9pservice");
195 a20a1468 2005-01-16 devnull
196 a20a1468 2005-01-16 devnull
197 a20a1468 2005-01-16 devnull threadexits(0);
198 7763a61a 2003-11-23 devnull }
199 7763a61a 2003-11-23 devnull
200 a20a1468 2005-01-16 devnull void srv(void* a) {
201 a20a1468 2005-01-16 devnull io();
202 a20a1468 2005-01-16 devnull shutdown();
203 a20a1468 2005-01-16 devnull }
204 a20a1468 2005-01-16 devnull
205 7763a61a 2003-11-23 devnull void
206 7763a61a 2003-11-23 devnull usage(void)
207 7763a61a 2003-11-23 devnull {
208 7763a61a 2003-11-23 devnull fprint(2, "usage: %s [-sd] [-h host] [-c ncache] [-m mountpoint] vacfile\n", argv0);
209 7763a61a 2003-11-23 devnull exits("usage");
210 7763a61a 2003-11-23 devnull }
211 7763a61a 2003-11-23 devnull
212 7763a61a 2003-11-23 devnull char*
213 7763a61a 2003-11-23 devnull rversion(Fid *unused)
214 7763a61a 2003-11-23 devnull {
215 7763a61a 2003-11-23 devnull Fid *f;
216 7763a61a 2003-11-23 devnull
217 7763a61a 2003-11-23 devnull USED(unused);
218 7763a61a 2003-11-23 devnull
219 7763a61a 2003-11-23 devnull for(f = fids; f; f = f->next)
220 7763a61a 2003-11-23 devnull if(f->busy)
221 7763a61a 2003-11-23 devnull rclunk(f);
222 7763a61a 2003-11-23 devnull
223 7763a61a 2003-11-23 devnull if(rhdr.msize < 256)
224 a20a1468 2005-01-16 devnull return vtstrdup("version: message size too small");
225 7763a61a 2003-11-23 devnull messagesize = rhdr.msize;
226 7763a61a 2003-11-23 devnull if(messagesize > sizeof mdata)
227 7763a61a 2003-11-23 devnull messagesize = sizeof mdata;
228 7763a61a 2003-11-23 devnull thdr.msize = messagesize;
229 7763a61a 2003-11-23 devnull if(strncmp(rhdr.version, "9P2000", 6) != 0)
230 a20a1468 2005-01-16 devnull return vtstrdup("unrecognized 9P version");
231 7763a61a 2003-11-23 devnull thdr.version = "9P2000";
232 7763a61a 2003-11-23 devnull return nil;
233 7763a61a 2003-11-23 devnull }
234 7763a61a 2003-11-23 devnull
235 7763a61a 2003-11-23 devnull char*
236 7763a61a 2003-11-23 devnull rflush(Fid *f)
237 7763a61a 2003-11-23 devnull {
238 7763a61a 2003-11-23 devnull USED(f);
239 7763a61a 2003-11-23 devnull return 0;
240 7763a61a 2003-11-23 devnull }
241 7763a61a 2003-11-23 devnull
242 7763a61a 2003-11-23 devnull char*
243 7763a61a 2003-11-23 devnull rauth(Fid *f)
244 7763a61a 2003-11-23 devnull {
245 7763a61a 2003-11-23 devnull USED(f);
246 a20a1468 2005-01-16 devnull return vtstrdup("vacfs: authentication not required");
247 7763a61a 2003-11-23 devnull }
248 7763a61a 2003-11-23 devnull
249 7763a61a 2003-11-23 devnull char*
250 7763a61a 2003-11-23 devnull rattach(Fid *f)
251 7763a61a 2003-11-23 devnull {
252 7763a61a 2003-11-23 devnull /* no authentication for the momment */
253 7763a61a 2003-11-23 devnull VacFile *file;
254 a20a1468 2005-01-16 devnull char err[80];
255 7763a61a 2003-11-23 devnull
256 a20a1468 2005-01-16 devnull file = vacfsgetroot(fs);
257 a20a1468 2005-01-16 devnull if(file == nil) {
258 a20a1468 2005-01-16 devnull rerrstr(err, sizeof err);
259 a20a1468 2005-01-16 devnull return vtstrdup(err);
260 a20a1468 2005-01-16 devnull }
261 a20a1468 2005-01-16 devnull
262 7763a61a 2003-11-23 devnull f->busy = 1;
263 7763a61a 2003-11-23 devnull f->file = file;
264 a20a1468 2005-01-16 devnull f->qid = (Qid){vacfilegetid(f->file), 0, QTDIR};
265 7763a61a 2003-11-23 devnull thdr.qid = f->qid;
266 7763a61a 2003-11-23 devnull if(rhdr.uname[0])
267 a20a1468 2005-01-16 devnull f->user = vtstrdup(rhdr.uname);
268 7763a61a 2003-11-23 devnull else
269 7763a61a 2003-11-23 devnull f->user = "none";
270 7763a61a 2003-11-23 devnull return 0;
271 7763a61a 2003-11-23 devnull }
272 7763a61a 2003-11-23 devnull
273 7763a61a 2003-11-23 devnull VacFile*
274 7763a61a 2003-11-23 devnull _vfWalk(VacFile *file, char *name)
275 7763a61a 2003-11-23 devnull {
276 7763a61a 2003-11-23 devnull VacFile *n;
277 7763a61a 2003-11-23 devnull
278 a20a1468 2005-01-16 devnull n = vacfilewalk(file, name);
279 7763a61a 2003-11-23 devnull if(n)
280 7763a61a 2003-11-23 devnull return n;
281 7763a61a 2003-11-23 devnull if(strcmp(name, "SLASH") == 0)
282 a20a1468 2005-01-16 devnull return vacfilewalk(file, "/");
283 7763a61a 2003-11-23 devnull return nil;
284 7763a61a 2003-11-23 devnull }
285 7763a61a 2003-11-23 devnull
286 7763a61a 2003-11-23 devnull char*
287 7763a61a 2003-11-23 devnull rwalk(Fid *f)
288 7763a61a 2003-11-23 devnull {
289 7763a61a 2003-11-23 devnull VacFile *file, *nfile;
290 7763a61a 2003-11-23 devnull Fid *nf;
291 7763a61a 2003-11-23 devnull int nqid, nwname;
292 7763a61a 2003-11-23 devnull Qid qid;
293 a20a1468 2005-01-16 devnull char *err = nil;
294 7763a61a 2003-11-23 devnull
295 7763a61a 2003-11-23 devnull if(f->busy == 0)
296 7763a61a 2003-11-23 devnull return Enotexist;
297 7763a61a 2003-11-23 devnull nf = nil;
298 7763a61a 2003-11-23 devnull if(rhdr.fid != rhdr.newfid){
299 7763a61a 2003-11-23 devnull if(f->open)
300 a20a1468 2005-01-16 devnull return vtstrdup(Eisopen);
301 7763a61a 2003-11-23 devnull if(f->busy == 0)
302 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
303 7763a61a 2003-11-23 devnull nf = newfid(rhdr.newfid);
304 7763a61a 2003-11-23 devnull if(nf->busy)
305 a20a1468 2005-01-16 devnull return vtstrdup(Eisopen);
306 7763a61a 2003-11-23 devnull nf->busy = 1;
307 7763a61a 2003-11-23 devnull nf->open = 0;
308 7763a61a 2003-11-23 devnull nf->qid = f->qid;
309 a20a1468 2005-01-16 devnull nf->file = vacfileincref(f->file);
310 a20a1468 2005-01-16 devnull nf->user = vtstrdup(f->user);
311 7763a61a 2003-11-23 devnull f = nf;
312 7763a61a 2003-11-23 devnull }
313 7763a61a 2003-11-23 devnull
314 7763a61a 2003-11-23 devnull nwname = rhdr.nwname;
315 7763a61a 2003-11-23 devnull
316 7763a61a 2003-11-23 devnull /* easy case */
317 7763a61a 2003-11-23 devnull if(nwname == 0) {
318 7763a61a 2003-11-23 devnull thdr.nwqid = 0;
319 7763a61a 2003-11-23 devnull return 0;
320 7763a61a 2003-11-23 devnull }
321 7763a61a 2003-11-23 devnull
322 7763a61a 2003-11-23 devnull file = f->file;
323 a20a1468 2005-01-16 devnull vacfileincref(file);
324 7763a61a 2003-11-23 devnull qid = f->qid;
325 7763a61a 2003-11-23 devnull
326 7763a61a 2003-11-23 devnull for(nqid = 0; nqid < nwname; nqid++){
327 7763a61a 2003-11-23 devnull if((qid.type & QTDIR) == 0){
328 a20a1468 2005-01-16 devnull err = Enotdir;
329 7763a61a 2003-11-23 devnull break;
330 7763a61a 2003-11-23 devnull }
331 7763a61a 2003-11-23 devnull if(!permf(file, f->user, Pexec)) {
332 a20a1468 2005-01-16 devnull err = Eperm;
333 7763a61a 2003-11-23 devnull break;
334 7763a61a 2003-11-23 devnull }
335 7763a61a 2003-11-23 devnull nfile = _vfWalk(file, rhdr.wname[nqid]);
336 7763a61a 2003-11-23 devnull if(nfile == nil)
337 7763a61a 2003-11-23 devnull break;
338 a20a1468 2005-01-16 devnull vacfiledecref(file);
339 7763a61a 2003-11-23 devnull file = nfile;
340 7763a61a 2003-11-23 devnull qid.type = QTFILE;
341 a20a1468 2005-01-16 devnull if(vacfileisdir(file))
342 7763a61a 2003-11-23 devnull qid.type = QTDIR;
343 a20a1468 2005-01-16 devnull qid.vers = vacfilegetmcount(file);
344 a20a1468 2005-01-16 devnull qid.path = vacfilegetid(file);
345 7763a61a 2003-11-23 devnull thdr.wqid[nqid] = qid;
346 7763a61a 2003-11-23 devnull }
347 7763a61a 2003-11-23 devnull
348 7763a61a 2003-11-23 devnull thdr.nwqid = nqid;
349 7763a61a 2003-11-23 devnull
350 7763a61a 2003-11-23 devnull if(nqid == nwname){
351 7763a61a 2003-11-23 devnull /* success */
352 7763a61a 2003-11-23 devnull f->qid = thdr.wqid[nqid-1];
353 a20a1468 2005-01-16 devnull vacfiledecref(f->file);
354 7763a61a 2003-11-23 devnull f->file = file;
355 7763a61a 2003-11-23 devnull return 0;
356 7763a61a 2003-11-23 devnull }
357 7763a61a 2003-11-23 devnull
358 a20a1468 2005-01-16 devnull vacfiledecref(file);
359 7763a61a 2003-11-23 devnull if(nf != nil)
360 7763a61a 2003-11-23 devnull rclunk(nf);
361 7763a61a 2003-11-23 devnull
362 7763a61a 2003-11-23 devnull /* only error on the first element */
363 7763a61a 2003-11-23 devnull if(nqid == 0)
364 a20a1468 2005-01-16 devnull return vtstrdup(err);
365 7763a61a 2003-11-23 devnull
366 7763a61a 2003-11-23 devnull return 0;
367 7763a61a 2003-11-23 devnull }
368 7763a61a 2003-11-23 devnull
369 7763a61a 2003-11-23 devnull char *
370 7763a61a 2003-11-23 devnull ropen(Fid *f)
371 7763a61a 2003-11-23 devnull {
372 7763a61a 2003-11-23 devnull int mode, trunc;
373 7763a61a 2003-11-23 devnull
374 7763a61a 2003-11-23 devnull if(f->open)
375 a20a1468 2005-01-16 devnull return vtstrdup(Eisopen);
376 7763a61a 2003-11-23 devnull if(!f->busy)
377 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
378 a20a1468 2005-01-16 devnull
379 7763a61a 2003-11-23 devnull mode = rhdr.mode;
380 7763a61a 2003-11-23 devnull thdr.iounit = messagesize - IOHDRSZ;
381 7763a61a 2003-11-23 devnull if(f->qid.type & QTDIR){
382 7763a61a 2003-11-23 devnull if(mode != OREAD)
383 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
384 7763a61a 2003-11-23 devnull if(!perm(f, Pread))
385 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
386 7763a61a 2003-11-23 devnull thdr.qid = f->qid;
387 7763a61a 2003-11-23 devnull f->db = nil;
388 7763a61a 2003-11-23 devnull f->open = 1;
389 7763a61a 2003-11-23 devnull return 0;
390 7763a61a 2003-11-23 devnull }
391 7763a61a 2003-11-23 devnull if(mode & ORCLOSE)
392 a20a1468 2005-01-16 devnull return vtstrdup(Erdonly);
393 7763a61a 2003-11-23 devnull trunc = mode & OTRUNC;
394 7763a61a 2003-11-23 devnull mode &= OPERM;
395 7763a61a 2003-11-23 devnull if(mode==OWRITE || mode==ORDWR || trunc)
396 7763a61a 2003-11-23 devnull if(!perm(f, Pwrite))
397 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
398 7763a61a 2003-11-23 devnull if(mode==OREAD || mode==ORDWR)
399 7763a61a 2003-11-23 devnull if(!perm(f, Pread))
400 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
401 7763a61a 2003-11-23 devnull if(mode==OEXEC)
402 7763a61a 2003-11-23 devnull if(!perm(f, Pexec))
403 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
404 7763a61a 2003-11-23 devnull thdr.qid = f->qid;
405 7763a61a 2003-11-23 devnull thdr.iounit = messagesize - IOHDRSZ;
406 7763a61a 2003-11-23 devnull f->open = 1;
407 7763a61a 2003-11-23 devnull return 0;
408 7763a61a 2003-11-23 devnull }
409 7763a61a 2003-11-23 devnull
410 7763a61a 2003-11-23 devnull char*
411 7763a61a 2003-11-23 devnull rcreate(Fid* fid)
412 7763a61a 2003-11-23 devnull {
413 7763a61a 2003-11-23 devnull VacFile *vf;
414 7763a61a 2003-11-23 devnull ulong mode;
415 7763a61a 2003-11-23 devnull
416 7763a61a 2003-11-23 devnull if(fid->open)
417 a20a1468 2005-01-16 devnull return vtstrdup(Eisopen);
418 7763a61a 2003-11-23 devnull if(!fid->busy)
419 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
420 a20a1468 2005-01-16 devnull if(fs->mode & ModeSnapshot)
421 a20a1468 2005-01-16 devnull return vtstrdup(Erdonly);
422 7763a61a 2003-11-23 devnull vf = fid->file;
423 a20a1468 2005-01-16 devnull if(!vacfileisdir(vf))
424 a20a1468 2005-01-16 devnull return vtstrdup(Enotdir);
425 7763a61a 2003-11-23 devnull if(!permf(vf, fid->user, Pwrite))
426 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
427 7763a61a 2003-11-23 devnull
428 7763a61a 2003-11-23 devnull mode = rhdr.perm & 0777;
429 7763a61a 2003-11-23 devnull
430 7763a61a 2003-11-23 devnull if(rhdr.perm & DMDIR){
431 7763a61a 2003-11-23 devnull if((rhdr.mode & OTRUNC) || (rhdr.perm & DMAPPEND))
432 a20a1468 2005-01-16 devnull return vtstrdup(Emode);
433 7763a61a 2003-11-23 devnull switch(rhdr.mode & OPERM){
434 7763a61a 2003-11-23 devnull default:
435 a20a1468 2005-01-16 devnull return vtstrdup(Emode);
436 7763a61a 2003-11-23 devnull case OEXEC:
437 7763a61a 2003-11-23 devnull case OREAD:
438 7763a61a 2003-11-23 devnull break;
439 7763a61a 2003-11-23 devnull case OWRITE:
440 7763a61a 2003-11-23 devnull case ORDWR:
441 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
442 7763a61a 2003-11-23 devnull }
443 7763a61a 2003-11-23 devnull mode |= ModeDir;
444 7763a61a 2003-11-23 devnull }
445 a20a1468 2005-01-16 devnull vf = vacfilecreate(vf, rhdr.name, mode, "none");
446 a20a1468 2005-01-16 devnull if(vf == nil) {
447 a20a1468 2005-01-16 devnull char err[80];
448 a20a1468 2005-01-16 devnull rerrstr(err, sizeof err);
449 7763a61a 2003-11-23 devnull
450 a20a1468 2005-01-16 devnull return vtstrdup(err);
451 a20a1468 2005-01-16 devnull }
452 a20a1468 2005-01-16 devnull
453 a20a1468 2005-01-16 devnull vacfiledecref(fid->file);
454 a20a1468 2005-01-16 devnull
455 7763a61a 2003-11-23 devnull fid->file = vf;
456 7763a61a 2003-11-23 devnull fid->qid.type = QTFILE;
457 a20a1468 2005-01-16 devnull if(vacfileisdir(vf))
458 7763a61a 2003-11-23 devnull fid->qid.type = QTDIR;
459 a20a1468 2005-01-16 devnull fid->qid.vers = vacfilegetmcount(vf);
460 a20a1468 2005-01-16 devnull fid->qid.path = vacfilegetid(vf);
461 7763a61a 2003-11-23 devnull
462 7763a61a 2003-11-23 devnull thdr.qid = fid->qid;
463 7763a61a 2003-11-23 devnull thdr.iounit = messagesize - IOHDRSZ;
464 7763a61a 2003-11-23 devnull
465 7763a61a 2003-11-23 devnull return 0;
466 7763a61a 2003-11-23 devnull }
467 7763a61a 2003-11-23 devnull
468 7763a61a 2003-11-23 devnull char*
469 7763a61a 2003-11-23 devnull rread(Fid *f)
470 7763a61a 2003-11-23 devnull {
471 7763a61a 2003-11-23 devnull char *buf;
472 7763a61a 2003-11-23 devnull vlong off;
473 7763a61a 2003-11-23 devnull int cnt;
474 7763a61a 2003-11-23 devnull VacFile *vf;
475 a20a1468 2005-01-16 devnull char err[80];
476 7763a61a 2003-11-23 devnull int n;
477 7763a61a 2003-11-23 devnull
478 7763a61a 2003-11-23 devnull if(!f->busy)
479 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
480 7763a61a 2003-11-23 devnull vf = f->file;
481 7763a61a 2003-11-23 devnull thdr.count = 0;
482 7763a61a 2003-11-23 devnull off = rhdr.offset;
483 7763a61a 2003-11-23 devnull buf = thdr.data;
484 7763a61a 2003-11-23 devnull cnt = rhdr.count;
485 7763a61a 2003-11-23 devnull if(f->qid.type & QTDIR)
486 7763a61a 2003-11-23 devnull n = vacdirread(f, buf, off, cnt);
487 7763a61a 2003-11-23 devnull else
488 a20a1468 2005-01-16 devnull n = vacfileread(vf, buf, cnt, off);
489 7763a61a 2003-11-23 devnull if(n < 0) {
490 a20a1468 2005-01-16 devnull rerrstr(err, sizeof err);
491 a20a1468 2005-01-16 devnull return vtstrdup(err);
492 7763a61a 2003-11-23 devnull }
493 7763a61a 2003-11-23 devnull thdr.count = n;
494 7763a61a 2003-11-23 devnull return 0;
495 7763a61a 2003-11-23 devnull }
496 7763a61a 2003-11-23 devnull
497 7763a61a 2003-11-23 devnull char*
498 7763a61a 2003-11-23 devnull rwrite(Fid *f)
499 7763a61a 2003-11-23 devnull {
500 7763a61a 2003-11-23 devnull char *buf;
501 7763a61a 2003-11-23 devnull vlong off;
502 7763a61a 2003-11-23 devnull int cnt;
503 7763a61a 2003-11-23 devnull VacFile *vf;
504 7763a61a 2003-11-23 devnull
505 7763a61a 2003-11-23 devnull if(!f->busy)
506 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
507 7763a61a 2003-11-23 devnull vf = f->file;
508 7763a61a 2003-11-23 devnull thdr.count = 0;
509 7763a61a 2003-11-23 devnull off = rhdr.offset;
510 7763a61a 2003-11-23 devnull buf = rhdr.data;
511 7763a61a 2003-11-23 devnull cnt = rhdr.count;
512 7763a61a 2003-11-23 devnull if(f->qid.type & QTDIR)
513 7763a61a 2003-11-23 devnull return "file is a directory";
514 a20a1468 2005-01-16 devnull thdr.count = vacfilewrite(vf, buf, cnt, off, "none");
515 7763a61a 2003-11-23 devnull if(thdr.count < 0) {
516 a20a1468 2005-01-16 devnull char err[80];
517 a20a1468 2005-01-16 devnull
518 a20a1468 2005-01-16 devnull rerrstr(err, sizeof err);
519 a20a1468 2005-01-16 devnull fprint(2, "write failed: %s\n", err);
520 a20a1468 2005-01-16 devnull return vtstrdup(err);
521 7763a61a 2003-11-23 devnull }
522 7763a61a 2003-11-23 devnull return 0;
523 7763a61a 2003-11-23 devnull }
524 7763a61a 2003-11-23 devnull
525 7763a61a 2003-11-23 devnull char *
526 7763a61a 2003-11-23 devnull rclunk(Fid *f)
527 7763a61a 2003-11-23 devnull {
528 7763a61a 2003-11-23 devnull f->busy = 0;
529 7763a61a 2003-11-23 devnull f->open = 0;
530 a20a1468 2005-01-16 devnull vtfree(f->user);
531 7763a61a 2003-11-23 devnull f->user = nil;
532 a20a1468 2005-01-16 devnull vacfiledecref(f->file);
533 7763a61a 2003-11-23 devnull f->file = nil;
534 7763a61a 2003-11-23 devnull dirBufFree(f->db);
535 7763a61a 2003-11-23 devnull f->db = nil;
536 7763a61a 2003-11-23 devnull return 0;
537 7763a61a 2003-11-23 devnull }
538 7763a61a 2003-11-23 devnull
539 7763a61a 2003-11-23 devnull char *
540 7763a61a 2003-11-23 devnull rremove(Fid *f)
541 7763a61a 2003-11-23 devnull {
542 7763a61a 2003-11-23 devnull VacFile *vf, *vfp;
543 a20a1468 2005-01-16 devnull char errbuf[80];
544 7763a61a 2003-11-23 devnull char *err = nil;
545 7763a61a 2003-11-23 devnull
546 7763a61a 2003-11-23 devnull if(!f->busy)
547 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
548 7763a61a 2003-11-23 devnull vf = f->file;
549 a20a1468 2005-01-16 devnull vfp = vacfilegetparent(vf);
550 7763a61a 2003-11-23 devnull
551 7763a61a 2003-11-23 devnull if(!permf(vfp, f->user, Pwrite)) {
552 7763a61a 2003-11-23 devnull err = Eperm;
553 7763a61a 2003-11-23 devnull goto Exit;
554 7763a61a 2003-11-23 devnull }
555 7763a61a 2003-11-23 devnull
556 a20a1468 2005-01-16 devnull if(!vacfileremove(vf, "none")) {
557 a20a1468 2005-01-16 devnull rerrstr(errbuf, sizeof errbuf);
558 a20a1468 2005-01-16 devnull print("vfRemove failed: %s\n", errbuf);
559 a20a1468 2005-01-16 devnull
560 a20a1468 2005-01-16 devnull err = errbuf;
561 7763a61a 2003-11-23 devnull }
562 7763a61a 2003-11-23 devnull
563 7763a61a 2003-11-23 devnull Exit:
564 a20a1468 2005-01-16 devnull vacfiledecref(vfp);
565 7763a61a 2003-11-23 devnull rclunk(f);
566 a20a1468 2005-01-16 devnull return vtstrdup(err);
567 7763a61a 2003-11-23 devnull }
568 7763a61a 2003-11-23 devnull
569 7763a61a 2003-11-23 devnull char *
570 7763a61a 2003-11-23 devnull rstat(Fid *f)
571 7763a61a 2003-11-23 devnull {
572 7763a61a 2003-11-23 devnull VacDir dir;
573 7763a61a 2003-11-23 devnull static uchar statbuf[1024];
574 7763a61a 2003-11-23 devnull
575 7763a61a 2003-11-23 devnull if(!f->busy)
576 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
577 a20a1468 2005-01-16 devnull vacfilegetdir(f->file, &dir);
578 7763a61a 2003-11-23 devnull thdr.stat = statbuf;
579 7763a61a 2003-11-23 devnull thdr.nstat = vdStat(&dir, thdr.stat, sizeof statbuf);
580 a20a1468 2005-01-16 devnull vdcleanup(&dir);
581 7763a61a 2003-11-23 devnull return 0;
582 7763a61a 2003-11-23 devnull }
583 7763a61a 2003-11-23 devnull
584 7763a61a 2003-11-23 devnull char *
585 7763a61a 2003-11-23 devnull rwstat(Fid *f)
586 7763a61a 2003-11-23 devnull {
587 7763a61a 2003-11-23 devnull if(!f->busy)
588 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
589 a20a1468 2005-01-16 devnull return vtstrdup(Erdonly);
590 7763a61a 2003-11-23 devnull }
591 7763a61a 2003-11-23 devnull
592 7763a61a 2003-11-23 devnull int
593 7763a61a 2003-11-23 devnull vdStat(VacDir *vd, uchar *p, int np)
594 7763a61a 2003-11-23 devnull {
595 7763a61a 2003-11-23 devnull Dir dir;
596 7763a61a 2003-11-23 devnull
597 7763a61a 2003-11-23 devnull memset(&dir, 0, sizeof(dir));
598 7763a61a 2003-11-23 devnull
599 7763a61a 2003-11-23 devnull /*
600 7763a61a 2003-11-23 devnull * Where do path and version come from
601 7763a61a 2003-11-23 devnull */
602 7763a61a 2003-11-23 devnull dir.qid.path = vd->qid;
603 7763a61a 2003-11-23 devnull dir.qid.vers = vd->mcount;
604 7763a61a 2003-11-23 devnull dir.mode = vd->mode & 0777;
605 7763a61a 2003-11-23 devnull if(vd->mode & ModeAppend){
606 7763a61a 2003-11-23 devnull dir.qid.type |= QTAPPEND;
607 7763a61a 2003-11-23 devnull dir.mode |= DMAPPEND;
608 7763a61a 2003-11-23 devnull }
609 7763a61a 2003-11-23 devnull if(vd->mode & ModeExclusive){
610 7763a61a 2003-11-23 devnull dir.qid.type |= QTEXCL;
611 7763a61a 2003-11-23 devnull dir.mode |= DMEXCL;
612 7763a61a 2003-11-23 devnull }
613 7763a61a 2003-11-23 devnull if(vd->mode & ModeDir){
614 7763a61a 2003-11-23 devnull dir.qid.type |= QTDIR;
615 7763a61a 2003-11-23 devnull dir.mode |= DMDIR;
616 7763a61a 2003-11-23 devnull }
617 7763a61a 2003-11-23 devnull
618 7763a61a 2003-11-23 devnull dir.atime = vd->atime;
619 7763a61a 2003-11-23 devnull dir.mtime = vd->mtime;
620 7763a61a 2003-11-23 devnull dir.length = vd->size;
621 7763a61a 2003-11-23 devnull
622 7763a61a 2003-11-23 devnull dir.name = vd->elem;
623 7763a61a 2003-11-23 devnull dir.uid = vd->uid;
624 7763a61a 2003-11-23 devnull dir.gid = vd->gid;
625 7763a61a 2003-11-23 devnull dir.muid = vd->mid;
626 7763a61a 2003-11-23 devnull
627 7763a61a 2003-11-23 devnull return convD2M(&dir, p, np);
628 7763a61a 2003-11-23 devnull }
629 7763a61a 2003-11-23 devnull
630 7763a61a 2003-11-23 devnull DirBuf*
631 7763a61a 2003-11-23 devnull dirBufAlloc(VacFile *vf)
632 7763a61a 2003-11-23 devnull {
633 7763a61a 2003-11-23 devnull DirBuf *db;
634 7763a61a 2003-11-23 devnull
635 a20a1468 2005-01-16 devnull db = vtmallocz(sizeof(DirBuf));
636 a20a1468 2005-01-16 devnull db->vde = vdeopen(vf);
637 7763a61a 2003-11-23 devnull return db;
638 7763a61a 2003-11-23 devnull }
639 7763a61a 2003-11-23 devnull
640 7763a61a 2003-11-23 devnull VacDir *
641 7763a61a 2003-11-23 devnull dirBufGet(DirBuf *db)
642 7763a61a 2003-11-23 devnull {
643 7763a61a 2003-11-23 devnull VacDir *vd;
644 7763a61a 2003-11-23 devnull int n;
645 7763a61a 2003-11-23 devnull
646 7763a61a 2003-11-23 devnull if(db->eof)
647 7763a61a 2003-11-23 devnull return nil;
648 7763a61a 2003-11-23 devnull
649 7763a61a 2003-11-23 devnull if(db->i >= db->n) {
650 a20a1468 2005-01-16 devnull n = vderead(db->vde, db->buf);
651 7763a61a 2003-11-23 devnull if(n < 0)
652 7763a61a 2003-11-23 devnull return nil;
653 7763a61a 2003-11-23 devnull db->i = 0;
654 7763a61a 2003-11-23 devnull db->n = n;
655 7763a61a 2003-11-23 devnull if(n == 0) {
656 7763a61a 2003-11-23 devnull db->eof = 1;
657 7763a61a 2003-11-23 devnull return nil;
658 7763a61a 2003-11-23 devnull }
659 7763a61a 2003-11-23 devnull }
660 7763a61a 2003-11-23 devnull
661 7763a61a 2003-11-23 devnull vd = db->buf + db->i;
662 7763a61a 2003-11-23 devnull db->i++;
663 7763a61a 2003-11-23 devnull
664 7763a61a 2003-11-23 devnull return vd;
665 7763a61a 2003-11-23 devnull }
666 7763a61a 2003-11-23 devnull
667 7763a61a 2003-11-23 devnull int
668 7763a61a 2003-11-23 devnull dirBufUnget(DirBuf *db)
669 7763a61a 2003-11-23 devnull {
670 7763a61a 2003-11-23 devnull assert(db->i > 0);
671 7763a61a 2003-11-23 devnull db->i--;
672 7763a61a 2003-11-23 devnull return 1;
673 7763a61a 2003-11-23 devnull }
674 7763a61a 2003-11-23 devnull
675 7763a61a 2003-11-23 devnull void
676 7763a61a 2003-11-23 devnull dirBufFree(DirBuf *db)
677 7763a61a 2003-11-23 devnull {
678 7763a61a 2003-11-23 devnull int i;
679 7763a61a 2003-11-23 devnull
680 7763a61a 2003-11-23 devnull if(db == nil)
681 7763a61a 2003-11-23 devnull return;
682 7763a61a 2003-11-23 devnull
683 7763a61a 2003-11-23 devnull for(i=db->i; i<db->n; i++)
684 a20a1468 2005-01-16 devnull vdcleanup(db->buf + i);
685 a20a1468 2005-01-16 devnull vdeclose(db->vde);
686 a20a1468 2005-01-16 devnull vtfree(db);
687 7763a61a 2003-11-23 devnull }
688 7763a61a 2003-11-23 devnull
689 7763a61a 2003-11-23 devnull int
690 7763a61a 2003-11-23 devnull vacdirread(Fid *f, char *p, long off, long cnt)
691 7763a61a 2003-11-23 devnull {
692 7763a61a 2003-11-23 devnull int n, nb;
693 7763a61a 2003-11-23 devnull VacDir *vd;
694 7763a61a 2003-11-23 devnull
695 7763a61a 2003-11-23 devnull /*
696 7763a61a 2003-11-23 devnull * special case of rewinding a directory
697 7763a61a 2003-11-23 devnull * otherwise ignore the offset
698 7763a61a 2003-11-23 devnull */
699 7763a61a 2003-11-23 devnull if(off == 0 && f->db) {
700 7763a61a 2003-11-23 devnull dirBufFree(f->db);
701 7763a61a 2003-11-23 devnull f->db = nil;
702 7763a61a 2003-11-23 devnull }
703 7763a61a 2003-11-23 devnull
704 7763a61a 2003-11-23 devnull if(f->db == nil)
705 7763a61a 2003-11-23 devnull f->db = dirBufAlloc(f->file);
706 7763a61a 2003-11-23 devnull
707 7763a61a 2003-11-23 devnull for(nb = 0; nb < cnt; nb += n) {
708 7763a61a 2003-11-23 devnull vd = dirBufGet(f->db);
709 7763a61a 2003-11-23 devnull if(vd == nil) {
710 7763a61a 2003-11-23 devnull if(!f->db->eof)
711 7763a61a 2003-11-23 devnull return -1;
712 7763a61a 2003-11-23 devnull break;
713 7763a61a 2003-11-23 devnull }
714 7763a61a 2003-11-23 devnull n = vdStat(vd, (uchar*)p, cnt-nb);
715 7763a61a 2003-11-23 devnull if(n <= BIT16SZ) {
716 7763a61a 2003-11-23 devnull dirBufUnget(f->db);
717 7763a61a 2003-11-23 devnull break;
718 7763a61a 2003-11-23 devnull }
719 a20a1468 2005-01-16 devnull vdcleanup(vd);
720 7763a61a 2003-11-23 devnull p += n;
721 7763a61a 2003-11-23 devnull }
722 7763a61a 2003-11-23 devnull return nb;
723 7763a61a 2003-11-23 devnull }
724 7763a61a 2003-11-23 devnull
725 7763a61a 2003-11-23 devnull Fid *
726 7763a61a 2003-11-23 devnull newfid(int fid)
727 7763a61a 2003-11-23 devnull {
728 7763a61a 2003-11-23 devnull Fid *f, *ff;
729 7763a61a 2003-11-23 devnull
730 7763a61a 2003-11-23 devnull ff = 0;
731 7763a61a 2003-11-23 devnull for(f = fids; f; f = f->next)
732 7763a61a 2003-11-23 devnull if(f->fid == fid)
733 7763a61a 2003-11-23 devnull return f;
734 7763a61a 2003-11-23 devnull else if(!ff && !f->busy)
735 7763a61a 2003-11-23 devnull ff = f;
736 7763a61a 2003-11-23 devnull if(ff){
737 7763a61a 2003-11-23 devnull ff->fid = fid;
738 7763a61a 2003-11-23 devnull return ff;
739 7763a61a 2003-11-23 devnull }
740 a20a1468 2005-01-16 devnull f = vtmallocz(sizeof *f);
741 7763a61a 2003-11-23 devnull f->fid = fid;
742 7763a61a 2003-11-23 devnull f->next = fids;
743 7763a61a 2003-11-23 devnull fids = f;
744 7763a61a 2003-11-23 devnull return f;
745 7763a61a 2003-11-23 devnull }
746 7763a61a 2003-11-23 devnull
747 7763a61a 2003-11-23 devnull void
748 7763a61a 2003-11-23 devnull io(void)
749 7763a61a 2003-11-23 devnull {
750 7763a61a 2003-11-23 devnull char *err;
751 7763a61a 2003-11-23 devnull int n;
752 7763a61a 2003-11-23 devnull
753 7763a61a 2003-11-23 devnull for(;;){
754 7763a61a 2003-11-23 devnull /*
755 7763a61a 2003-11-23 devnull * reading from a pipe or a network device
756 7763a61a 2003-11-23 devnull * will give an error after a few eof reads
757 7763a61a 2003-11-23 devnull * however, we cannot tell the difference
758 7763a61a 2003-11-23 devnull * between a zero-length read and an interrupt
759 7763a61a 2003-11-23 devnull * on the processes writing to us,
760 7763a61a 2003-11-23 devnull * so we wait for the error
761 7763a61a 2003-11-23 devnull */
762 7763a61a 2003-11-23 devnull n = read9pmsg(mfd[0], mdata, sizeof mdata);
763 7763a61a 2003-11-23 devnull if(n == 0)
764 7763a61a 2003-11-23 devnull continue;
765 7763a61a 2003-11-23 devnull if(n < 0)
766 7763a61a 2003-11-23 devnull break;
767 7763a61a 2003-11-23 devnull if(convM2S(mdata, n, &rhdr) != n)
768 7763a61a 2003-11-23 devnull sysfatal("convM2S conversion error");
769 7763a61a 2003-11-23 devnull
770 7763a61a 2003-11-23 devnull if(dflag)
771 7763a61a 2003-11-23 devnull fprint(2, "vacfs:<-%F\n", &rhdr);
772 7763a61a 2003-11-23 devnull
773 7763a61a 2003-11-23 devnull thdr.data = (char*)mdata + IOHDRSZ;
774 7763a61a 2003-11-23 devnull if(!fcalls[rhdr.type])
775 7763a61a 2003-11-23 devnull err = "bad fcall type";
776 7763a61a 2003-11-23 devnull else
777 7763a61a 2003-11-23 devnull err = (*fcalls[rhdr.type])(newfid(rhdr.fid));
778 7763a61a 2003-11-23 devnull if(err){
779 7763a61a 2003-11-23 devnull thdr.type = Rerror;
780 7763a61a 2003-11-23 devnull thdr.ename = err;
781 7763a61a 2003-11-23 devnull }else{
782 7763a61a 2003-11-23 devnull thdr.type = rhdr.type + 1;
783 7763a61a 2003-11-23 devnull thdr.fid = rhdr.fid;
784 7763a61a 2003-11-23 devnull }
785 7763a61a 2003-11-23 devnull thdr.tag = rhdr.tag;
786 7763a61a 2003-11-23 devnull if(dflag)
787 7763a61a 2003-11-23 devnull fprint(2, "vacfs:->%F\n", &thdr);
788 7763a61a 2003-11-23 devnull n = convS2M(&thdr, mdata, messagesize);
789 a20a1468 2005-01-16 devnull if (err)
790 a20a1468 2005-01-16 devnull vtfree(err);
791 a20a1468 2005-01-16 devnull
792 7763a61a 2003-11-23 devnull if(write(mfd[1], mdata, n) != n)
793 7763a61a 2003-11-23 devnull sysfatal("mount write: %r");
794 7763a61a 2003-11-23 devnull }
795 7763a61a 2003-11-23 devnull }
796 7763a61a 2003-11-23 devnull
797 7763a61a 2003-11-23 devnull int
798 7763a61a 2003-11-23 devnull permf(VacFile *vf, char *user, int p)
799 7763a61a 2003-11-23 devnull {
800 7763a61a 2003-11-23 devnull VacDir dir;
801 7763a61a 2003-11-23 devnull ulong perm;
802 7763a61a 2003-11-23 devnull
803 a20a1468 2005-01-16 devnull if(vacfilegetdir(vf, &dir))
804 7763a61a 2003-11-23 devnull return 0;
805 7763a61a 2003-11-23 devnull perm = dir.mode & 0777;
806 a20a1468 2005-01-16 devnull
807 7763a61a 2003-11-23 devnull if(noperm)
808 7763a61a 2003-11-23 devnull goto Good;
809 7763a61a 2003-11-23 devnull if((p*Pother) & perm)
810 7763a61a 2003-11-23 devnull goto Good;
811 7763a61a 2003-11-23 devnull if(strcmp(user, dir.gid)==0 && ((p*Pgroup) & perm))
812 7763a61a 2003-11-23 devnull goto Good;
813 7763a61a 2003-11-23 devnull if(strcmp(user, dir.uid)==0 && ((p*Powner) & perm))
814 7763a61a 2003-11-23 devnull goto Good;
815 a20a1468 2005-01-16 devnull vdcleanup(&dir);
816 7763a61a 2003-11-23 devnull return 0;
817 7763a61a 2003-11-23 devnull Good:
818 a20a1468 2005-01-16 devnull vdcleanup(&dir);
819 7763a61a 2003-11-23 devnull return 1;
820 7763a61a 2003-11-23 devnull }
821 7763a61a 2003-11-23 devnull
822 7763a61a 2003-11-23 devnull int
823 7763a61a 2003-11-23 devnull perm(Fid *f, int p)
824 7763a61a 2003-11-23 devnull {
825 7763a61a 2003-11-23 devnull return permf(f->file, f->user, p);
826 7763a61a 2003-11-23 devnull }
827 7763a61a 2003-11-23 devnull
828 7763a61a 2003-11-23 devnull void
829 7763a61a 2003-11-23 devnull init(char *file, char *host, long ncache, int readOnly)
830 7763a61a 2003-11-23 devnull {
831 7763a61a 2003-11-23 devnull notify(notifyf);
832 7763a61a 2003-11-23 devnull user = getuser();
833 7763a61a 2003-11-23 devnull
834 a20a1468 2005-01-16 devnull fmtinstall('V', vtscorefmt);
835 a20a1468 2005-01-16 devnull // fmtinstall('R', vtErrFmt);
836 7763a61a 2003-11-23 devnull
837 a20a1468 2005-01-16 devnull conn = vtdial(host);
838 a20a1468 2005-01-16 devnull if(conn == nil)
839 a20a1468 2005-01-16 devnull sysfatal("could not connect to server: %r");
840 7763a61a 2003-11-23 devnull
841 a20a1468 2005-01-16 devnull if(vtconnect(conn) < 0)
842 a20a1468 2005-01-16 devnull sysfatal("vtconnect: %r");
843 7763a61a 2003-11-23 devnull
844 a20a1468 2005-01-16 devnull fs = vacfsopen(conn, file, /*readOnly ? ModeSnapshot :*/ VtOREAD, ncache);
845 7763a61a 2003-11-23 devnull if(fs == nil)
846 a20a1468 2005-01-16 devnull sysfatal("vfsOpen: %r");
847 7763a61a 2003-11-23 devnull }
848 7763a61a 2003-11-23 devnull
849 7763a61a 2003-11-23 devnull void
850 7763a61a 2003-11-23 devnull shutdown(void)
851 7763a61a 2003-11-23 devnull {
852 7763a61a 2003-11-23 devnull Fid *f;
853 7763a61a 2003-11-23 devnull
854 7763a61a 2003-11-23 devnull for(f = fids; f; f = f->next) {
855 7763a61a 2003-11-23 devnull if(!f->busy)
856 7763a61a 2003-11-23 devnull continue;
857 7763a61a 2003-11-23 devnull fprint(2, "open fid: %d\n", f->fid);
858 7763a61a 2003-11-23 devnull rclunk(f);
859 7763a61a 2003-11-23 devnull }
860 7763a61a 2003-11-23 devnull
861 a20a1468 2005-01-16 devnull vacfsclose(fs);
862 a20a1468 2005-01-16 devnull vthangup(conn);
863 7763a61a 2003-11-23 devnull }
864 7763a61a 2003-11-23 devnull