1 7763a61a 2003-11-23 devnull #include "stdinc.h"
2 7763a61a 2003-11-23 devnull #include <fcall.h>
3 7763a61a 2003-11-23 devnull #include "vac.h"
5 ada3d479 2008-06-15 rsc #ifndef PLAN9PORT
6 ada3d479 2008-06-15 rsc #define convM2Su(a, b, c, d) convM2S(a, b, c)
7 ada3d479 2008-06-15 rsc #define convS2Mu(a, b, c, d) convS2M(a, b, c)
8 ada3d479 2008-06-15 rsc #define convM2Du(a, b, c, d) convM2D(a, b, c)
9 ada3d479 2008-06-15 rsc #define convD2Mu(a, b, c, d) convD2M(a, b, c)
12 7763a61a 2003-11-23 devnull typedef struct Fid Fid;
16 cbeb0b26 2006-04-01 devnull OPERM = 0x3 /* mask of all permission types in open mode */
19 7763a61a 2003-11-23 devnull struct Fid
21 7763a61a 2003-11-23 devnull short busy;
22 7763a61a 2003-11-23 devnull short open;
24 7763a61a 2003-11-23 devnull char *user;
26 7763a61a 2003-11-23 devnull VacFile *file;
27 64f9764e 2008-06-14 rsc VacDirEnum *vde;
28 7763a61a 2003-11-23 devnull Fid *next;
33 7763a61a 2003-11-23 devnull Pexec = 1,
34 7763a61a 2003-11-23 devnull Pwrite = 2,
35 7763a61a 2003-11-23 devnull Pread = 4,
36 7763a61a 2003-11-23 devnull Pother = 1,
37 7763a61a 2003-11-23 devnull Pgroup = 8,
38 cbeb0b26 2006-04-01 devnull Powner = 64
41 7763a61a 2003-11-23 devnull Fid *fids;
42 7763a61a 2003-11-23 devnull uchar *data;
43 7763a61a 2003-11-23 devnull int mfd[2];
44 ada3d479 2008-06-15 rsc int srvfd = -1;
45 7763a61a 2003-11-23 devnull char *user;
46 7763a61a 2003-11-23 devnull uchar mdata[8192+IOHDRSZ];
47 7763a61a 2003-11-23 devnull int messagesize = sizeof mdata;
48 7763a61a 2003-11-23 devnull Fcall rhdr;
49 7763a61a 2003-11-23 devnull Fcall thdr;
50 a20a1468 2005-01-16 devnull VacFs *fs;
51 a20a1468 2005-01-16 devnull VtConn *conn;
52 7763a61a 2003-11-23 devnull int noperm;
53 bbfdd7a6 2005-09-13 devnull int dotu;
54 be3e3514 2008-04-17 rsc char *defmnt;
56 7763a61a 2003-11-23 devnull Fid * newfid(int);
57 7763a61a 2003-11-23 devnull void error(char*);
58 7763a61a 2003-11-23 devnull void io(void);
59 a331ac4c 2005-01-19 devnull void vacshutdown(void);
60 7763a61a 2003-11-23 devnull void usage(void);
61 7763a61a 2003-11-23 devnull int perm(Fid*, int);
62 7763a61a 2003-11-23 devnull int permf(VacFile*, char*, int);
63 7763a61a 2003-11-23 devnull ulong getl(void *p);
64 7763a61a 2003-11-23 devnull void init(char*, char*, long, int);
65 7763a61a 2003-11-23 devnull int vacdirread(Fid *f, char *p, long off, long cnt);
66 64f9764e 2008-06-14 rsc int vacstat(VacFile *parent, VacDir *vd, uchar *p, int np);
67 a20a1468 2005-01-16 devnull void srv(void* a);
70 7763a61a 2003-11-23 devnull char *rflush(Fid*), *rversion(Fid*),
71 7763a61a 2003-11-23 devnull *rauth(Fid*), *rattach(Fid*), *rwalk(Fid*),
72 7763a61a 2003-11-23 devnull *ropen(Fid*), *rcreate(Fid*),
73 7763a61a 2003-11-23 devnull *rread(Fid*), *rwrite(Fid*), *rclunk(Fid*),
74 7763a61a 2003-11-23 devnull *rremove(Fid*), *rstat(Fid*), *rwstat(Fid*);
76 9b3d503b 2005-01-19 devnull char *(*fcalls[Tmax])(Fid*);
79 9b3d503b 2005-01-19 devnull initfcalls(void)
81 9b3d503b 2005-01-19 devnull fcalls[Tflush]= rflush;
82 9b3d503b 2005-01-19 devnull fcalls[Tversion]= rversion;
83 9b3d503b 2005-01-19 devnull fcalls[Tattach]= rattach;
84 9b3d503b 2005-01-19 devnull fcalls[Tauth]= rauth;
85 9b3d503b 2005-01-19 devnull fcalls[Twalk]= rwalk;
86 9b3d503b 2005-01-19 devnull fcalls[Topen]= ropen;
87 9b3d503b 2005-01-19 devnull fcalls[Tcreate]= rcreate;
88 9b3d503b 2005-01-19 devnull fcalls[Tread]= rread;
89 9b3d503b 2005-01-19 devnull fcalls[Twrite]= rwrite;
90 9b3d503b 2005-01-19 devnull fcalls[Tclunk]= rclunk;
91 9b3d503b 2005-01-19 devnull fcalls[Tremove]= rremove;
92 9b3d503b 2005-01-19 devnull fcalls[Tstat]= rstat;
93 9b3d503b 2005-01-19 devnull fcalls[Twstat]= rwstat;
96 7763a61a 2003-11-23 devnull char Eperm[] = "permission denied";
97 7763a61a 2003-11-23 devnull char Enotdir[] = "not a directory";
98 7763a61a 2003-11-23 devnull char Enotexist[] = "file does not exist";
99 7763a61a 2003-11-23 devnull char Einuse[] = "file in use";
100 7763a61a 2003-11-23 devnull char Eexist[] = "file exists";
101 7763a61a 2003-11-23 devnull char Enotowner[] = "not owner";
102 7763a61a 2003-11-23 devnull char Eisopen[] = "file already open for I/O";
103 7763a61a 2003-11-23 devnull char Excl[] = "exclusive use file already open";
104 7763a61a 2003-11-23 devnull char Ename[] = "illegal name";
105 7763a61a 2003-11-23 devnull char Erdonly[] = "read only file system";
106 7763a61a 2003-11-23 devnull char Eio[] = "i/o error";
107 7763a61a 2003-11-23 devnull char Eempty[] = "directory is not empty";
108 7763a61a 2003-11-23 devnull char Emode[] = "illegal mode";
110 7763a61a 2003-11-23 devnull int dflag;
113 7763a61a 2003-11-23 devnull notifyf(void *a, char *s)
115 7763a61a 2003-11-23 devnull USED(a);
116 7763a61a 2003-11-23 devnull if(strncmp(s, "interrupt", 9) == 0)
117 7763a61a 2003-11-23 devnull noted(NCONT);
118 7763a61a 2003-11-23 devnull noted(NDFLT);
121 75d04888 2009-05-25 rsc #define TWID64 ~(u64int)0
122 75d04888 2009-05-25 rsc static u64int
123 75d04888 2009-05-25 rsc unittoull(char *s)
128 75d04888 2009-05-25 rsc if(s == nil)
129 75d04888 2009-05-25 rsc return TWID64;
130 75d04888 2009-05-25 rsc n = strtoul(s, &es, 0);
131 75d04888 2009-05-25 rsc if(*es == 'k' || *es == 'K'){
134 75d04888 2009-05-25 rsc }else if(*es == 'm' || *es == 'M'){
135 75d04888 2009-05-25 rsc n *= 1024*1024;
137 75d04888 2009-05-25 rsc }else if(*es == 'g' || *es == 'G'){
138 75d04888 2009-05-25 rsc n *= 1024*1024*1024;
141 75d04888 2009-05-25 rsc if(*es != '\0')
142 75d04888 2009-05-25 rsc return TWID64;
147 a20a1468 2005-01-16 devnull threadmain(int argc, char *argv[])
149 ada3d479 2008-06-15 rsc char *defsrv, *srvname;
150 ada3d479 2008-06-15 rsc int p[2], fd;
152 7763a61a 2003-11-23 devnull char *host = nil;
155 75d04888 2009-05-25 rsc mem = 16<<20;
157 23fb2edb 2005-07-24 devnull fmtinstall('H', encodefmt);
158 23fb2edb 2005-07-24 devnull fmtinstall('V', vtscorefmt);
159 23fb2edb 2005-07-24 devnull fmtinstall('F', vtfcallfmt);
161 ada3d479 2008-06-15 rsc defmnt = nil;
162 91124c1b 2005-01-16 devnull defsrv = nil;
163 7763a61a 2003-11-23 devnull ARGBEGIN{
164 7763a61a 2003-11-23 devnull case 'd':
165 7763a61a 2003-11-23 devnull fmtinstall('F', fcallfmt);
166 7763a61a 2003-11-23 devnull dflag = 1;
168 7763a61a 2003-11-23 devnull case 'i':
169 ada3d479 2008-06-15 rsc defmnt = nil;
170 7763a61a 2003-11-23 devnull stdio = 1;
171 7763a61a 2003-11-23 devnull mfd[0] = 0;
172 7763a61a 2003-11-23 devnull mfd[1] = 1;
174 7763a61a 2003-11-23 devnull case 'h':
175 32053cdf 2005-01-16 devnull host = EARGF(usage());
178 32053cdf 2005-01-16 devnull defsrv = EARGF(usage());
181 ada3d479 2008-06-15 rsc defsrv = "vacfs";
184 75d04888 2009-05-25 rsc mem = unittoull(EARGF(usage()));
187 be3e3514 2008-04-17 rsc defmnt = EARGF(usage());
189 7763a61a 2003-11-23 devnull case 'p':
190 7763a61a 2003-11-23 devnull noperm = 1;
192 23fb2edb 2005-07-24 devnull case 'V':
193 23fb2edb 2005-07-24 devnull chattyventi = 1;
195 7763a61a 2003-11-23 devnull default:
196 7763a61a 2003-11-23 devnull usage();
199 7763a61a 2003-11-23 devnull if(argc != 1)
200 7763a61a 2003-11-23 devnull usage();
202 ada3d479 2008-06-15 rsc #ifdef PLAN9PORT
203 ada3d479 2008-06-15 rsc if(defsrv == nil && defmnt == nil && !stdio){
204 ada3d479 2008-06-15 rsc srvname = strchr(argv[0], '/');
208 ada3d479 2008-06-15 rsc srvname = argv[0];
209 ada3d479 2008-06-15 rsc defsrv = vtmalloc(6+strlen(srvname)+1);
210 ada3d479 2008-06-15 rsc strcpy(defsrv, "vacfs.");
211 ada3d479 2008-06-15 rsc strcat(defsrv, srvname);
212 ada3d479 2008-06-15 rsc if(strcmp(defsrv+strlen(defsrv)-4, ".vac") == 0)
213 ada3d479 2008-06-15 rsc defsrv[strlen(defsrv)-4] = 0;
216 ada3d479 2008-06-15 rsc if(defsrv == nil && defmnt == nil && !stdio)
217 ada3d479 2008-06-15 rsc defmnt = "/n/vac";
219 ada3d479 2008-06-15 rsc if(stdio && defmnt)
220 ada3d479 2008-06-15 rsc sysfatal("cannot use -m with -i");
222 9b3d503b 2005-01-19 devnull initfcalls();
224 64f9764e 2008-06-14 rsc notify(notifyf);
225 64f9764e 2008-06-14 rsc user = getuser();
227 64f9764e 2008-06-14 rsc conn = vtdial(host);
228 64f9764e 2008-06-14 rsc if(conn == nil)
229 64f9764e 2008-06-14 rsc sysfatal("could not connect to server: %r");
231 64f9764e 2008-06-14 rsc if(vtconnect(conn) < 0)
232 64f9764e 2008-06-14 rsc sysfatal("vtconnect: %r");
234 75d04888 2009-05-25 rsc fs = vacfsopen(conn, argv[0], VtOREAD, mem);
235 64f9764e 2008-06-14 rsc if(fs == nil)
236 64f9764e 2008-06-14 rsc sysfatal("vacfsopen: %r");
239 ada3d479 2008-06-15 rsc if(pipe(p) < 0)
240 ada3d479 2008-06-15 rsc sysfatal("pipe failed: %r");
241 ada3d479 2008-06-15 rsc mfd[0] = p[0];
242 ada3d479 2008-06-15 rsc mfd[1] = p[0];
243 ada3d479 2008-06-15 rsc srvfd = p[1];
246 ada3d479 2008-06-15 rsc #ifdef PLAN9PORT
248 ada3d479 2008-06-15 rsc proccreate(srv, 0, 32 * 1024);
249 44c6e39c 2009-07-26 rsc if(!stdio && post9pservice(p[1], defsrv, defmnt) < 0)
250 a20a1468 2005-01-16 devnull sysfatal("post9pservice");
252 ada3d479 2008-06-15 rsc procrfork(srv, 0, 32 * 1024, RFFDG|RFNAMEG|RFNOTEG);
255 ada3d479 2008-06-15 rsc close(p[0]);
257 ada3d479 2008-06-15 rsc srvname = smprint("/srv/%s", defsrv);
258 ada3d479 2008-06-15 rsc fd = create(srvname, OWRITE|ORCLOSE, 0666);
260 ada3d479 2008-06-15 rsc sysfatal("create %s: %r", srvname);
261 ada3d479 2008-06-15 rsc if(fprint(fd, "%d", srvfd) < 0)
262 ada3d479 2008-06-15 rsc sysfatal("write %s: %r", srvname);
263 ada3d479 2008-06-15 rsc free(srvname);
266 ada3d479 2008-06-15 rsc if(mount(srvfd, -1, defmnt, MREPL|MCREATE, "") < 0)
267 ada3d479 2008-06-15 rsc sysfatal("mount %s: %r", defmnt);
271 a20a1468 2005-01-16 devnull threadexits(0);
275 a331ac4c 2005-01-19 devnull srv(void *a)
279 a331ac4c 2005-01-19 devnull vacshutdown();
283 7763a61a 2003-11-23 devnull usage(void)
285 7763a61a 2003-11-23 devnull fprint(2, "usage: %s [-sd] [-h host] [-c ncache] [-m mountpoint] vacfile\n", argv0);
286 38c10d1a 2005-01-17 devnull threadexitsall("usage");
290 7763a61a 2003-11-23 devnull rversion(Fid *unused)
294 7763a61a 2003-11-23 devnull USED(unused);
296 7763a61a 2003-11-23 devnull for(f = fids; f; f = f->next)
297 7763a61a 2003-11-23 devnull if(f->busy)
298 7763a61a 2003-11-23 devnull rclunk(f);
300 7763a61a 2003-11-23 devnull if(rhdr.msize < 256)
301 a20a1468 2005-01-16 devnull return vtstrdup("version: message size too small");
302 7763a61a 2003-11-23 devnull messagesize = rhdr.msize;
303 7763a61a 2003-11-23 devnull if(messagesize > sizeof mdata)
304 7763a61a 2003-11-23 devnull messagesize = sizeof mdata;
305 7763a61a 2003-11-23 devnull thdr.msize = messagesize;
306 7763a61a 2003-11-23 devnull if(strncmp(rhdr.version, "9P2000", 6) != 0)
307 a20a1468 2005-01-16 devnull return vtstrdup("unrecognized 9P version");
308 7763a61a 2003-11-23 devnull thdr.version = "9P2000";
309 bbfdd7a6 2005-09-13 devnull if(strncmp(rhdr.version, "9P2000.u", 8) == 0){
310 bbfdd7a6 2005-09-13 devnull dotu = 1;
311 bbfdd7a6 2005-09-13 devnull thdr.version = "9P2000.u";
313 7763a61a 2003-11-23 devnull return nil;
317 7763a61a 2003-11-23 devnull rflush(Fid *f)
319 7763a61a 2003-11-23 devnull USED(f);
320 7763a61a 2003-11-23 devnull return 0;
324 7763a61a 2003-11-23 devnull rauth(Fid *f)
326 7763a61a 2003-11-23 devnull USED(f);
327 a20a1468 2005-01-16 devnull return vtstrdup("vacfs: authentication not required");
331 7763a61a 2003-11-23 devnull rattach(Fid *f)
333 7763a61a 2003-11-23 devnull /* no authentication for the momment */
334 7763a61a 2003-11-23 devnull VacFile *file;
335 a20a1468 2005-01-16 devnull char err[80];
337 a20a1468 2005-01-16 devnull file = vacfsgetroot(fs);
338 a20a1468 2005-01-16 devnull if(file == nil) {
339 a20a1468 2005-01-16 devnull rerrstr(err, sizeof err);
340 a20a1468 2005-01-16 devnull return vtstrdup(err);
343 7763a61a 2003-11-23 devnull f->busy = 1;
344 7763a61a 2003-11-23 devnull f->file = file;
345 9b3d503b 2005-01-19 devnull f->qid.path = vacfilegetid(f->file);
346 9b3d503b 2005-01-19 devnull f->qid.vers = 0;
347 9b3d503b 2005-01-19 devnull f->qid.type = QTDIR;
348 7763a61a 2003-11-23 devnull thdr.qid = f->qid;
349 7763a61a 2003-11-23 devnull if(rhdr.uname[0])
350 a20a1468 2005-01-16 devnull f->user = vtstrdup(rhdr.uname);
352 7763a61a 2003-11-23 devnull f->user = "none";
353 7763a61a 2003-11-23 devnull return 0;
357 7763a61a 2003-11-23 devnull rwalk(Fid *f)
359 7763a61a 2003-11-23 devnull VacFile *file, *nfile;
360 7763a61a 2003-11-23 devnull Fid *nf;
361 7763a61a 2003-11-23 devnull int nqid, nwname;
362 7763a61a 2003-11-23 devnull Qid qid;
363 a20a1468 2005-01-16 devnull char *err = nil;
365 7763a61a 2003-11-23 devnull if(f->busy == 0)
366 7763a61a 2003-11-23 devnull return Enotexist;
367 7763a61a 2003-11-23 devnull nf = nil;
368 7763a61a 2003-11-23 devnull if(rhdr.fid != rhdr.newfid){
369 7763a61a 2003-11-23 devnull if(f->open)
370 a20a1468 2005-01-16 devnull return vtstrdup(Eisopen);
371 7763a61a 2003-11-23 devnull if(f->busy == 0)
372 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
373 7763a61a 2003-11-23 devnull nf = newfid(rhdr.newfid);
374 7763a61a 2003-11-23 devnull if(nf->busy)
375 a20a1468 2005-01-16 devnull return vtstrdup(Eisopen);
376 7763a61a 2003-11-23 devnull nf->busy = 1;
377 7763a61a 2003-11-23 devnull nf->open = 0;
378 7763a61a 2003-11-23 devnull nf->qid = f->qid;
379 a20a1468 2005-01-16 devnull nf->file = vacfileincref(f->file);
380 a20a1468 2005-01-16 devnull nf->user = vtstrdup(f->user);
384 7763a61a 2003-11-23 devnull nwname = rhdr.nwname;
386 7763a61a 2003-11-23 devnull /* easy case */
387 7763a61a 2003-11-23 devnull if(nwname == 0) {
388 7763a61a 2003-11-23 devnull thdr.nwqid = 0;
389 7763a61a 2003-11-23 devnull return 0;
392 7763a61a 2003-11-23 devnull file = f->file;
393 a20a1468 2005-01-16 devnull vacfileincref(file);
394 7763a61a 2003-11-23 devnull qid = f->qid;
396 7763a61a 2003-11-23 devnull for(nqid = 0; nqid < nwname; nqid++){
397 7763a61a 2003-11-23 devnull if((qid.type & QTDIR) == 0){
398 a20a1468 2005-01-16 devnull err = Enotdir;
401 7763a61a 2003-11-23 devnull if(!permf(file, f->user, Pexec)) {
402 a20a1468 2005-01-16 devnull err = Eperm;
405 64f9764e 2008-06-14 rsc nfile = vacfilewalk(file, rhdr.wname[nqid]);
406 7763a61a 2003-11-23 devnull if(nfile == nil)
408 a20a1468 2005-01-16 devnull vacfiledecref(file);
409 7763a61a 2003-11-23 devnull file = nfile;
410 7763a61a 2003-11-23 devnull qid.type = QTFILE;
411 a20a1468 2005-01-16 devnull if(vacfileisdir(file))
412 7763a61a 2003-11-23 devnull qid.type = QTDIR;
413 ada3d479 2008-06-15 rsc #ifdef PLAN9PORT
414 bbfdd7a6 2005-09-13 devnull if(vacfilegetmode(file)&ModeLink)
415 bbfdd7a6 2005-09-13 devnull qid.type = QTSYMLINK;
417 a20a1468 2005-01-16 devnull qid.vers = vacfilegetmcount(file);
418 a20a1468 2005-01-16 devnull qid.path = vacfilegetid(file);
419 7763a61a 2003-11-23 devnull thdr.wqid[nqid] = qid;
422 7763a61a 2003-11-23 devnull thdr.nwqid = nqid;
424 7763a61a 2003-11-23 devnull if(nqid == nwname){
425 7763a61a 2003-11-23 devnull /* success */
426 7763a61a 2003-11-23 devnull f->qid = thdr.wqid[nqid-1];
427 a20a1468 2005-01-16 devnull vacfiledecref(f->file);
428 7763a61a 2003-11-23 devnull f->file = file;
429 7763a61a 2003-11-23 devnull return 0;
432 a20a1468 2005-01-16 devnull vacfiledecref(file);
433 7763a61a 2003-11-23 devnull if(nf != nil)
434 7763a61a 2003-11-23 devnull rclunk(nf);
436 7763a61a 2003-11-23 devnull /* only error on the first element */
437 7763a61a 2003-11-23 devnull if(nqid == 0)
438 a20a1468 2005-01-16 devnull return vtstrdup(err);
440 7763a61a 2003-11-23 devnull return 0;
444 7763a61a 2003-11-23 devnull ropen(Fid *f)
446 7763a61a 2003-11-23 devnull int mode, trunc;
448 7763a61a 2003-11-23 devnull if(f->open)
449 a20a1468 2005-01-16 devnull return vtstrdup(Eisopen);
450 7763a61a 2003-11-23 devnull if(!f->busy)
451 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
453 7763a61a 2003-11-23 devnull mode = rhdr.mode;
454 7763a61a 2003-11-23 devnull thdr.iounit = messagesize - IOHDRSZ;
455 7763a61a 2003-11-23 devnull if(f->qid.type & QTDIR){
456 7763a61a 2003-11-23 devnull if(mode != OREAD)
457 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
458 7763a61a 2003-11-23 devnull if(!perm(f, Pread))
459 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
460 7763a61a 2003-11-23 devnull thdr.qid = f->qid;
461 64f9764e 2008-06-14 rsc f->vde = nil;
462 7763a61a 2003-11-23 devnull f->open = 1;
463 7763a61a 2003-11-23 devnull return 0;
465 7763a61a 2003-11-23 devnull if(mode & ORCLOSE)
466 a20a1468 2005-01-16 devnull return vtstrdup(Erdonly);
467 7763a61a 2003-11-23 devnull trunc = mode & OTRUNC;
468 7763a61a 2003-11-23 devnull mode &= OPERM;
469 7763a61a 2003-11-23 devnull if(mode==OWRITE || mode==ORDWR || trunc)
470 7763a61a 2003-11-23 devnull if(!perm(f, Pwrite))
471 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
472 7763a61a 2003-11-23 devnull if(mode==OREAD || mode==ORDWR)
473 7763a61a 2003-11-23 devnull if(!perm(f, Pread))
474 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
475 7763a61a 2003-11-23 devnull if(mode==OEXEC)
476 7763a61a 2003-11-23 devnull if(!perm(f, Pexec))
477 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
478 7763a61a 2003-11-23 devnull thdr.qid = f->qid;
479 7763a61a 2003-11-23 devnull thdr.iounit = messagesize - IOHDRSZ;
480 7763a61a 2003-11-23 devnull f->open = 1;
481 7763a61a 2003-11-23 devnull return 0;
485 7763a61a 2003-11-23 devnull rcreate(Fid* fid)
487 7763a61a 2003-11-23 devnull VacFile *vf;
488 7763a61a 2003-11-23 devnull ulong mode;
490 7763a61a 2003-11-23 devnull if(fid->open)
491 a20a1468 2005-01-16 devnull return vtstrdup(Eisopen);
492 7763a61a 2003-11-23 devnull if(!fid->busy)
493 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
494 a20a1468 2005-01-16 devnull if(fs->mode & ModeSnapshot)
495 a20a1468 2005-01-16 devnull return vtstrdup(Erdonly);
496 7763a61a 2003-11-23 devnull vf = fid->file;
497 a20a1468 2005-01-16 devnull if(!vacfileisdir(vf))
498 a20a1468 2005-01-16 devnull return vtstrdup(Enotdir);
499 7763a61a 2003-11-23 devnull if(!permf(vf, fid->user, Pwrite))
500 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
502 7763a61a 2003-11-23 devnull mode = rhdr.perm & 0777;
504 7763a61a 2003-11-23 devnull if(rhdr.perm & DMDIR){
505 7763a61a 2003-11-23 devnull if((rhdr.mode & OTRUNC) || (rhdr.perm & DMAPPEND))
506 a20a1468 2005-01-16 devnull return vtstrdup(Emode);
507 7763a61a 2003-11-23 devnull switch(rhdr.mode & OPERM){
508 7763a61a 2003-11-23 devnull default:
509 a20a1468 2005-01-16 devnull return vtstrdup(Emode);
510 7763a61a 2003-11-23 devnull case OEXEC:
511 7763a61a 2003-11-23 devnull case OREAD:
513 7763a61a 2003-11-23 devnull case OWRITE:
514 7763a61a 2003-11-23 devnull case ORDWR:
515 a20a1468 2005-01-16 devnull return vtstrdup(Eperm);
517 7763a61a 2003-11-23 devnull mode |= ModeDir;
519 ecc0a1b0 2008-06-15 rsc vf = vacfilecreate(vf, rhdr.name, mode);
520 a20a1468 2005-01-16 devnull if(vf == nil) {
521 a20a1468 2005-01-16 devnull char err[80];
522 a20a1468 2005-01-16 devnull rerrstr(err, sizeof err);
524 a20a1468 2005-01-16 devnull return vtstrdup(err);
527 a20a1468 2005-01-16 devnull vacfiledecref(fid->file);
529 7763a61a 2003-11-23 devnull fid->file = vf;
530 7763a61a 2003-11-23 devnull fid->qid.type = QTFILE;
531 a20a1468 2005-01-16 devnull if(vacfileisdir(vf))
532 7763a61a 2003-11-23 devnull fid->qid.type = QTDIR;
533 a20a1468 2005-01-16 devnull fid->qid.vers = vacfilegetmcount(vf);
534 a20a1468 2005-01-16 devnull fid->qid.path = vacfilegetid(vf);
536 7763a61a 2003-11-23 devnull thdr.qid = fid->qid;
537 7763a61a 2003-11-23 devnull thdr.iounit = messagesize - IOHDRSZ;
539 7763a61a 2003-11-23 devnull return 0;
543 7763a61a 2003-11-23 devnull rread(Fid *f)
545 7763a61a 2003-11-23 devnull char *buf;
546 7763a61a 2003-11-23 devnull vlong off;
547 7763a61a 2003-11-23 devnull int cnt;
548 7763a61a 2003-11-23 devnull VacFile *vf;
549 a20a1468 2005-01-16 devnull char err[80];
552 7763a61a 2003-11-23 devnull if(!f->busy)
553 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
554 7763a61a 2003-11-23 devnull vf = f->file;
555 7763a61a 2003-11-23 devnull thdr.count = 0;
556 7763a61a 2003-11-23 devnull off = rhdr.offset;
557 7763a61a 2003-11-23 devnull buf = thdr.data;
558 7763a61a 2003-11-23 devnull cnt = rhdr.count;
559 7763a61a 2003-11-23 devnull if(f->qid.type & QTDIR)
560 7763a61a 2003-11-23 devnull n = vacdirread(f, buf, off, cnt);
561 bbfdd7a6 2005-09-13 devnull else if(vacfilegetmode(f->file)&ModeDevice)
562 bbfdd7a6 2005-09-13 devnull return vtstrdup("device");
563 bbfdd7a6 2005-09-13 devnull else if(vacfilegetmode(f->file)&ModeLink)
564 bbfdd7a6 2005-09-13 devnull return vtstrdup("symbolic link");
565 bbfdd7a6 2005-09-13 devnull else if(vacfilegetmode(f->file)&ModeNamedPipe)
566 bbfdd7a6 2005-09-13 devnull return vtstrdup("named pipe");
568 a20a1468 2005-01-16 devnull n = vacfileread(vf, buf, cnt, off);
569 7763a61a 2003-11-23 devnull if(n < 0) {
570 a20a1468 2005-01-16 devnull rerrstr(err, sizeof err);
571 a20a1468 2005-01-16 devnull return vtstrdup(err);
573 7763a61a 2003-11-23 devnull thdr.count = n;
574 7763a61a 2003-11-23 devnull return 0;
578 7763a61a 2003-11-23 devnull rwrite(Fid *f)
581 c52cda30 2008-06-14 rsc return vtstrdup(Erdonly);
585 7763a61a 2003-11-23 devnull rclunk(Fid *f)
587 7763a61a 2003-11-23 devnull f->busy = 0;
588 7763a61a 2003-11-23 devnull f->open = 0;
589 a20a1468 2005-01-16 devnull vtfree(f->user);
590 7763a61a 2003-11-23 devnull f->user = nil;
591 9e2f1d9b 2005-11-21 devnull if(f->file)
592 9e2f1d9b 2005-11-21 devnull vacfiledecref(f->file);
593 7763a61a 2003-11-23 devnull f->file = nil;
594 64f9764e 2008-06-14 rsc vdeclose(f->vde);
595 64f9764e 2008-06-14 rsc f->vde = nil;
596 7763a61a 2003-11-23 devnull return 0;
600 7763a61a 2003-11-23 devnull rremove(Fid *f)
602 7763a61a 2003-11-23 devnull VacFile *vf, *vfp;
603 a20a1468 2005-01-16 devnull char errbuf[80];
604 7763a61a 2003-11-23 devnull char *err = nil;
606 7763a61a 2003-11-23 devnull if(!f->busy)
607 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
608 7763a61a 2003-11-23 devnull vf = f->file;
609 a20a1468 2005-01-16 devnull vfp = vacfilegetparent(vf);
611 7763a61a 2003-11-23 devnull if(!permf(vfp, f->user, Pwrite)) {
612 7763a61a 2003-11-23 devnull err = Eperm;
613 7763a61a 2003-11-23 devnull goto Exit;
616 ecc0a1b0 2008-06-15 rsc if(!vacfileremove(vf)) {
617 a20a1468 2005-01-16 devnull rerrstr(errbuf, sizeof errbuf);
618 a20a1468 2005-01-16 devnull err = errbuf;
622 a20a1468 2005-01-16 devnull vacfiledecref(vfp);
623 7763a61a 2003-11-23 devnull rclunk(f);
624 a20a1468 2005-01-16 devnull return vtstrdup(err);
628 7763a61a 2003-11-23 devnull rstat(Fid *f)
630 7763a61a 2003-11-23 devnull VacDir dir;
631 7763a61a 2003-11-23 devnull static uchar statbuf[1024];
632 bbfdd7a6 2005-09-13 devnull VacFile *parent;
634 7763a61a 2003-11-23 devnull if(!f->busy)
635 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
636 bbfdd7a6 2005-09-13 devnull parent = vacfilegetparent(f->file);
637 a20a1468 2005-01-16 devnull vacfilegetdir(f->file, &dir);
638 7763a61a 2003-11-23 devnull thdr.stat = statbuf;
639 64f9764e 2008-06-14 rsc thdr.nstat = vacstat(parent, &dir, thdr.stat, sizeof statbuf);
640 a20a1468 2005-01-16 devnull vdcleanup(&dir);
641 bbfdd7a6 2005-09-13 devnull vacfiledecref(parent);
642 7763a61a 2003-11-23 devnull return 0;
646 7763a61a 2003-11-23 devnull rwstat(Fid *f)
648 7763a61a 2003-11-23 devnull if(!f->busy)
649 a20a1468 2005-01-16 devnull return vtstrdup(Enotexist);
650 a20a1468 2005-01-16 devnull return vtstrdup(Erdonly);
654 64f9764e 2008-06-14 rsc vacstat(VacFile *parent, VacDir *vd, uchar *p, int np)
657 7763a61a 2003-11-23 devnull Dir dir;
658 ada3d479 2008-06-15 rsc #ifdef PLAN9PORT
660 bbfdd7a6 2005-09-13 devnull VacFile *vf;
661 ada3d479 2008-06-15 rsc uvlong size;
662 ada3d479 2008-06-15 rsc char *ext = nil;
665 7763a61a 2003-11-23 devnull memset(&dir, 0, sizeof(dir));
667 fa3c8da1 2008-06-15 rsc dir.qid.path = vd->qid + vacfilegetqidoffset(parent);
668 fa3c8da1 2008-06-15 rsc if(vd->qidspace)
669 fa3c8da1 2008-06-15 rsc dir.qid.path += vd->qidoffset;
670 7763a61a 2003-11-23 devnull dir.qid.vers = vd->mcount;
671 7763a61a 2003-11-23 devnull dir.mode = vd->mode & 0777;
672 7763a61a 2003-11-23 devnull if(vd->mode & ModeAppend){
673 7763a61a 2003-11-23 devnull dir.qid.type |= QTAPPEND;
674 7763a61a 2003-11-23 devnull dir.mode |= DMAPPEND;
676 7763a61a 2003-11-23 devnull if(vd->mode & ModeExclusive){
677 7763a61a 2003-11-23 devnull dir.qid.type |= QTEXCL;
678 7763a61a 2003-11-23 devnull dir.mode |= DMEXCL;
680 7763a61a 2003-11-23 devnull if(vd->mode & ModeDir){
681 7763a61a 2003-11-23 devnull dir.qid.type |= QTDIR;
682 7763a61a 2003-11-23 devnull dir.mode |= DMDIR;
685 ada3d479 2008-06-15 rsc #ifdef PLAN9PORT
686 bbfdd7a6 2005-09-13 devnull if(vd->mode & (ModeLink|ModeDevice|ModeNamedPipe)){
687 bbfdd7a6 2005-09-13 devnull vf = vacfilewalk(parent, vd->elem);
688 bbfdd7a6 2005-09-13 devnull if(vf == nil)
689 bbfdd7a6 2005-09-13 devnull return 0;
690 bbfdd7a6 2005-09-13 devnull vacfilegetsize(vf, &size);
691 bbfdd7a6 2005-09-13 devnull ext = malloc(size+1);
692 bbfdd7a6 2005-09-13 devnull if(ext == nil)
693 bbfdd7a6 2005-09-13 devnull return 0;
694 bbfdd7a6 2005-09-13 devnull n = vacfileread(vf, ext, size, 0);
695 bbfdd7a6 2005-09-13 devnull ext[size] = 0;
696 bbfdd7a6 2005-09-13 devnull vacfiledecref(vf);
697 bbfdd7a6 2005-09-13 devnull if(vd->mode & ModeLink){
698 bbfdd7a6 2005-09-13 devnull dir.qid.type |= QTSYMLINK;
699 bbfdd7a6 2005-09-13 devnull dir.mode |= DMSYMLINK;
701 bbfdd7a6 2005-09-13 devnull if(vd->mode & ModeDevice)
702 bbfdd7a6 2005-09-13 devnull dir.mode |= DMDEVICE;
703 bbfdd7a6 2005-09-13 devnull if(vd->mode & ModeNamedPipe)
704 bbfdd7a6 2005-09-13 devnull dir.mode |= DMNAMEDPIPE;
708 7763a61a 2003-11-23 devnull dir.atime = vd->atime;
709 7763a61a 2003-11-23 devnull dir.mtime = vd->mtime;
710 7763a61a 2003-11-23 devnull dir.length = vd->size;
712 7763a61a 2003-11-23 devnull dir.name = vd->elem;
713 7763a61a 2003-11-23 devnull dir.uid = vd->uid;
714 7763a61a 2003-11-23 devnull dir.gid = vd->gid;
715 7763a61a 2003-11-23 devnull dir.muid = vd->mid;
716 ada3d479 2008-06-15 rsc #ifdef PLAN9PORT
717 bbfdd7a6 2005-09-13 devnull dir.ext = ext;
718 2cb7bf88 2007-01-18 devnull dir.uidnum = atoi(vd->uid);
719 2cb7bf88 2007-01-18 devnull dir.gidnum = atoi(vd->gid);
722 bbfdd7a6 2005-09-13 devnull ret = convD2Mu(&dir, p, np, dotu);
723 ada3d479 2008-06-15 rsc #ifdef PLAN9PORT
724 bbfdd7a6 2005-09-13 devnull free(ext);
726 bbfdd7a6 2005-09-13 devnull return ret;
730 7763a61a 2003-11-23 devnull vacdirread(Fid *f, char *p, long off, long cnt)
732 64f9764e 2008-06-14 rsc int i, n, nb;
736 7763a61a 2003-11-23 devnull * special case of rewinding a directory
737 7763a61a 2003-11-23 devnull * otherwise ignore the offset
739 64f9764e 2008-06-14 rsc if(off == 0 && f->vde){
740 64f9764e 2008-06-14 rsc vdeclose(f->vde);
741 64f9764e 2008-06-14 rsc f->vde = nil;
744 64f9764e 2008-06-14 rsc if(f->vde == nil){
745 64f9764e 2008-06-14 rsc f->vde = vdeopen(f->file);
746 64f9764e 2008-06-14 rsc if(f->vde == nil)
750 7763a61a 2003-11-23 devnull for(nb = 0; nb < cnt; nb += n) {
751 64f9764e 2008-06-14 rsc i = vderead(f->vde, &vd);
756 64f9764e 2008-06-14 rsc n = vacstat(f->file, &vd, (uchar*)p, cnt-nb);
757 7763a61a 2003-11-23 devnull if(n <= BIT16SZ) {
758 64f9764e 2008-06-14 rsc vdeunread(f->vde);
761 64f9764e 2008-06-14 rsc vdcleanup(&vd);
764 7763a61a 2003-11-23 devnull return nb;
768 7763a61a 2003-11-23 devnull newfid(int fid)
770 7763a61a 2003-11-23 devnull Fid *f, *ff;
773 7763a61a 2003-11-23 devnull for(f = fids; f; f = f->next)
774 7763a61a 2003-11-23 devnull if(f->fid == fid)
775 7763a61a 2003-11-23 devnull return f;
776 7763a61a 2003-11-23 devnull else if(!ff && !f->busy)
779 7763a61a 2003-11-23 devnull ff->fid = fid;
780 7763a61a 2003-11-23 devnull return ff;
782 a20a1468 2005-01-16 devnull f = vtmallocz(sizeof *f);
783 7763a61a 2003-11-23 devnull f->fid = fid;
784 7763a61a 2003-11-23 devnull f->next = fids;
785 7763a61a 2003-11-23 devnull fids = f;
786 7763a61a 2003-11-23 devnull return f;
790 7763a61a 2003-11-23 devnull io(void)
792 7763a61a 2003-11-23 devnull char *err;
795 7763a61a 2003-11-23 devnull for(;;){
796 be3e3514 2008-04-17 rsc n = read9pmsg(mfd[0], mdata, sizeof mdata);
799 bbfdd7a6 2005-09-13 devnull if(convM2Su(mdata, n, &rhdr, dotu) != n)
800 7763a61a 2003-11-23 devnull sysfatal("convM2S conversion error");
802 7763a61a 2003-11-23 devnull if(dflag)
803 7763a61a 2003-11-23 devnull fprint(2, "vacfs:<-%F\n", &rhdr);
805 7763a61a 2003-11-23 devnull thdr.data = (char*)mdata + IOHDRSZ;
806 7763a61a 2003-11-23 devnull if(!fcalls[rhdr.type])
807 7763a61a 2003-11-23 devnull err = "bad fcall type";
809 7763a61a 2003-11-23 devnull err = (*fcalls[rhdr.type])(newfid(rhdr.fid));
810 7763a61a 2003-11-23 devnull if(err){
811 7763a61a 2003-11-23 devnull thdr.type = Rerror;
812 7763a61a 2003-11-23 devnull thdr.ename = err;
813 ada3d479 2008-06-15 rsc #ifdef PLAN9PORT
814 bbfdd7a6 2005-09-13 devnull thdr.errornum = 0;
817 7763a61a 2003-11-23 devnull thdr.type = rhdr.type + 1;
818 7763a61a 2003-11-23 devnull thdr.fid = rhdr.fid;
820 7763a61a 2003-11-23 devnull thdr.tag = rhdr.tag;
821 7763a61a 2003-11-23 devnull if(dflag)
822 7763a61a 2003-11-23 devnull fprint(2, "vacfs:->%F\n", &thdr);
823 bbfdd7a6 2005-09-13 devnull n = convS2Mu(&thdr, mdata, messagesize, dotu);
824 9e2f1d9b 2005-11-21 devnull if(n <= BIT16SZ)
825 9e2f1d9b 2005-11-21 devnull sysfatal("convS2Mu conversion error");
827 a20a1468 2005-01-16 devnull vtfree(err);
829 7763a61a 2003-11-23 devnull if(write(mfd[1], mdata, n) != n)
830 7763a61a 2003-11-23 devnull sysfatal("mount write: %r");
835 7763a61a 2003-11-23 devnull permf(VacFile *vf, char *user, int p)
837 7763a61a 2003-11-23 devnull VacDir dir;
838 7763a61a 2003-11-23 devnull ulong perm;
840 a20a1468 2005-01-16 devnull if(vacfilegetdir(vf, &dir))
841 7763a61a 2003-11-23 devnull return 0;
842 7763a61a 2003-11-23 devnull perm = dir.mode & 0777;
844 7763a61a 2003-11-23 devnull if(noperm)
845 7763a61a 2003-11-23 devnull goto Good;
846 7763a61a 2003-11-23 devnull if((p*Pother) & perm)
847 7763a61a 2003-11-23 devnull goto Good;
848 7763a61a 2003-11-23 devnull if(strcmp(user, dir.gid)==0 && ((p*Pgroup) & perm))
849 7763a61a 2003-11-23 devnull goto Good;
850 7763a61a 2003-11-23 devnull if(strcmp(user, dir.uid)==0 && ((p*Powner) & perm))
851 7763a61a 2003-11-23 devnull goto Good;
852 a20a1468 2005-01-16 devnull vdcleanup(&dir);
853 7763a61a 2003-11-23 devnull return 0;
855 a20a1468 2005-01-16 devnull vdcleanup(&dir);
856 7763a61a 2003-11-23 devnull return 1;
860 7763a61a 2003-11-23 devnull perm(Fid *f, int p)
862 7763a61a 2003-11-23 devnull return permf(f->file, f->user, p);
866 a331ac4c 2005-01-19 devnull vacshutdown(void)
870 7763a61a 2003-11-23 devnull for(f = fids; f; f = f->next) {
871 7763a61a 2003-11-23 devnull if(!f->busy)
872 7763a61a 2003-11-23 devnull continue;
873 7763a61a 2003-11-23 devnull rclunk(f);
876 a20a1468 2005-01-16 devnull vacfsclose(fs);
877 a20a1468 2005-01-16 devnull vthangup(conn);