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