Blame


1 57ccfb9e 2003-12-11 devnull #include <u.h>
2 57ccfb9e 2003-12-11 devnull #include <libc.h>
3 57ccfb9e 2003-12-11 devnull #include <fcall.h>
4 57ccfb9e 2003-12-11 devnull
5 57ccfb9e 2003-12-11 devnull /*
6 57ccfb9e 2003-12-11 devnull * Rather than reading /adm/users, which is a lot of work for
7 57ccfb9e 2003-12-11 devnull * a toy program, we assume all groups have the form
8 57ccfb9e 2003-12-11 devnull * NNN:user:user:
9 57ccfb9e 2003-12-11 devnull * meaning that each user is the leader of his own group.
10 57ccfb9e 2003-12-11 devnull */
11 57ccfb9e 2003-12-11 devnull
12 57ccfb9e 2003-12-11 devnull enum
13 57ccfb9e 2003-12-11 devnull {
14 57ccfb9e 2003-12-11 devnull OPERM = 0x3, /* mask of all permission types in open mode */
15 57ccfb9e 2003-12-11 devnull Nram = 2048,
16 57ccfb9e 2003-12-11 devnull Maxsize = 512*1024*1024,
17 cbeb0b26 2006-04-01 devnull Maxfdata = 8192
18 57ccfb9e 2003-12-11 devnull };
19 57ccfb9e 2003-12-11 devnull
20 57ccfb9e 2003-12-11 devnull typedef struct Fid Fid;
21 57ccfb9e 2003-12-11 devnull typedef struct Ram Ram;
22 57ccfb9e 2003-12-11 devnull
23 57ccfb9e 2003-12-11 devnull struct Fid
24 57ccfb9e 2003-12-11 devnull {
25 57ccfb9e 2003-12-11 devnull short busy;
26 57ccfb9e 2003-12-11 devnull short open;
27 57ccfb9e 2003-12-11 devnull short rclose;
28 57ccfb9e 2003-12-11 devnull int fid;
29 57ccfb9e 2003-12-11 devnull Fid *next;
30 57ccfb9e 2003-12-11 devnull char *user;
31 57ccfb9e 2003-12-11 devnull Ram *ram;
32 57ccfb9e 2003-12-11 devnull };
33 57ccfb9e 2003-12-11 devnull
34 57ccfb9e 2003-12-11 devnull struct Ram
35 57ccfb9e 2003-12-11 devnull {
36 57ccfb9e 2003-12-11 devnull short busy;
37 57ccfb9e 2003-12-11 devnull short open;
38 57ccfb9e 2003-12-11 devnull long parent; /* index in Ram array */
39 57ccfb9e 2003-12-11 devnull Qid qid;
40 57ccfb9e 2003-12-11 devnull long perm;
41 57ccfb9e 2003-12-11 devnull char *name;
42 57ccfb9e 2003-12-11 devnull ulong atime;
43 57ccfb9e 2003-12-11 devnull ulong mtime;
44 57ccfb9e 2003-12-11 devnull char *user;
45 57ccfb9e 2003-12-11 devnull char *group;
46 57ccfb9e 2003-12-11 devnull char *muid;
47 57ccfb9e 2003-12-11 devnull char *data;
48 57ccfb9e 2003-12-11 devnull long ndata;
49 57ccfb9e 2003-12-11 devnull };
50 57ccfb9e 2003-12-11 devnull
51 57ccfb9e 2003-12-11 devnull enum
52 57ccfb9e 2003-12-11 devnull {
53 57ccfb9e 2003-12-11 devnull Pexec = 1,
54 57ccfb9e 2003-12-11 devnull Pwrite = 2,
55 57ccfb9e 2003-12-11 devnull Pread = 4,
56 57ccfb9e 2003-12-11 devnull Pother = 1,
57 57ccfb9e 2003-12-11 devnull Pgroup = 8,
58 cbeb0b26 2006-04-01 devnull Powner = 64
59 57ccfb9e 2003-12-11 devnull };
60 57ccfb9e 2003-12-11 devnull
61 57ccfb9e 2003-12-11 devnull ulong path; /* incremented for each new file */
62 57ccfb9e 2003-12-11 devnull Fid *fids;
63 57ccfb9e 2003-12-11 devnull Ram ram[Nram];
64 57ccfb9e 2003-12-11 devnull int nram;
65 57ccfb9e 2003-12-11 devnull int mfd[2];
66 57ccfb9e 2003-12-11 devnull char *user;
67 57ccfb9e 2003-12-11 devnull uchar mdata[IOHDRSZ+Maxfdata];
68 57ccfb9e 2003-12-11 devnull uchar rdata[Maxfdata]; /* buffer for data in reply */
69 57ccfb9e 2003-12-11 devnull uchar statbuf[STATMAX];
70 57ccfb9e 2003-12-11 devnull Fcall thdr;
71 57ccfb9e 2003-12-11 devnull Fcall rhdr;
72 57ccfb9e 2003-12-11 devnull int messagesize = sizeof mdata;
73 57ccfb9e 2003-12-11 devnull
74 57ccfb9e 2003-12-11 devnull Fid * newfid(int);
75 57ccfb9e 2003-12-11 devnull uint ramstat(Ram*, uchar*, uint);
76 57ccfb9e 2003-12-11 devnull void error(char*);
77 57ccfb9e 2003-12-11 devnull void io(void);
78 57ccfb9e 2003-12-11 devnull void *erealloc(void*, ulong);
79 57ccfb9e 2003-12-11 devnull void *emalloc(ulong);
80 57ccfb9e 2003-12-11 devnull char *estrdup(char*);
81 57ccfb9e 2003-12-11 devnull void usage(void);
82 57ccfb9e 2003-12-11 devnull int perm(Fid*, Ram*, int);
83 57ccfb9e 2003-12-11 devnull
84 57ccfb9e 2003-12-11 devnull char *rflush(Fid*), *rversion(Fid*), *rauth(Fid*),
85 57ccfb9e 2003-12-11 devnull *rattach(Fid*), *rwalk(Fid*),
86 57ccfb9e 2003-12-11 devnull *ropen(Fid*), *rcreate(Fid*),
87 57ccfb9e 2003-12-11 devnull *rread(Fid*), *rwrite(Fid*), *rclunk(Fid*),
88 57ccfb9e 2003-12-11 devnull *rremove(Fid*), *rstat(Fid*), *rwstat(Fid*);
89 57ccfb9e 2003-12-11 devnull
90 be22ae2d 2004-03-26 devnull char *(*fcalls[Tmax])(Fid*);
91 57ccfb9e 2003-12-11 devnull
92 be22ae2d 2004-03-26 devnull static void
93 be22ae2d 2004-03-26 devnull initfcalls(void)
94 be22ae2d 2004-03-26 devnull {
95 be22ae2d 2004-03-26 devnull fcalls[Tversion]= rversion;
96 be22ae2d 2004-03-26 devnull fcalls[Tflush]= rflush;
97 be22ae2d 2004-03-26 devnull fcalls[Tauth]= rauth;
98 be22ae2d 2004-03-26 devnull fcalls[Tattach]= rattach;
99 be22ae2d 2004-03-26 devnull fcalls[Twalk]= rwalk;
100 be22ae2d 2004-03-26 devnull fcalls[Topen]= ropen;
101 be22ae2d 2004-03-26 devnull fcalls[Tcreate]= rcreate;
102 be22ae2d 2004-03-26 devnull fcalls[Tread]= rread;
103 be22ae2d 2004-03-26 devnull fcalls[Twrite]= rwrite;
104 be22ae2d 2004-03-26 devnull fcalls[Tclunk]= rclunk;
105 be22ae2d 2004-03-26 devnull fcalls[Tremove]= rremove;
106 be22ae2d 2004-03-26 devnull fcalls[Tstat]= rstat;
107 be22ae2d 2004-03-26 devnull fcalls[Twstat]= rwstat;
108 be22ae2d 2004-03-26 devnull }
109 be22ae2d 2004-03-26 devnull
110 57ccfb9e 2003-12-11 devnull char Eperm[] = "permission denied";
111 57ccfb9e 2003-12-11 devnull char Enotdir[] = "not a directory";
112 57ccfb9e 2003-12-11 devnull char Enoauth[] = "ramfs: authentication not required";
113 57ccfb9e 2003-12-11 devnull char Enotexist[] = "file does not exist";
114 57ccfb9e 2003-12-11 devnull char Einuse[] = "file in use";
115 57ccfb9e 2003-12-11 devnull char Eexist[] = "file exists";
116 57ccfb9e 2003-12-11 devnull char Eisdir[] = "file is a directory";
117 57ccfb9e 2003-12-11 devnull char Enotowner[] = "not owner";
118 57ccfb9e 2003-12-11 devnull char Eisopen[] = "file already open for I/O";
119 57ccfb9e 2003-12-11 devnull char Excl[] = "exclusive use file already open";
120 57ccfb9e 2003-12-11 devnull char Ename[] = "illegal name";
121 57ccfb9e 2003-12-11 devnull char Eversion[] = "unknown 9P version";
122 57ccfb9e 2003-12-11 devnull char Enotempty[] = "directory not empty";
123 57ccfb9e 2003-12-11 devnull char Ebadfid[] = "bad fid";
124 57ccfb9e 2003-12-11 devnull
125 57ccfb9e 2003-12-11 devnull int debug;
126 57ccfb9e 2003-12-11 devnull int private;
127 57ccfb9e 2003-12-11 devnull
128 57ccfb9e 2003-12-11 devnull void
129 57ccfb9e 2003-12-11 devnull notifyf(void *a, char *s)
130 57ccfb9e 2003-12-11 devnull {
131 57ccfb9e 2003-12-11 devnull USED(a);
132 57ccfb9e 2003-12-11 devnull if(strncmp(s, "interrupt", 9) == 0)
133 57ccfb9e 2003-12-11 devnull noted(NCONT);
134 57ccfb9e 2003-12-11 devnull noted(NDFLT);
135 57ccfb9e 2003-12-11 devnull }
136 57ccfb9e 2003-12-11 devnull
137 57ccfb9e 2003-12-11 devnull void
138 57ccfb9e 2003-12-11 devnull main(int argc, char *argv[])
139 57ccfb9e 2003-12-11 devnull {
140 57ccfb9e 2003-12-11 devnull Ram *r;
141 57ccfb9e 2003-12-11 devnull char *defmnt;
142 57ccfb9e 2003-12-11 devnull int p[2];
143 57ccfb9e 2003-12-11 devnull int stdio = 0;
144 57ccfb9e 2003-12-11 devnull char *service;
145 57ccfb9e 2003-12-11 devnull
146 be22ae2d 2004-03-26 devnull initfcalls();
147 57ccfb9e 2003-12-11 devnull service = "ramfs";
148 f583e2b1 2005-01-04 devnull defmnt = nil;
149 57ccfb9e 2003-12-11 devnull ARGBEGIN{
150 57ccfb9e 2003-12-11 devnull case 'D':
151 57ccfb9e 2003-12-11 devnull debug = 1;
152 57ccfb9e 2003-12-11 devnull break;
153 57ccfb9e 2003-12-11 devnull case 'i':
154 57ccfb9e 2003-12-11 devnull defmnt = 0;
155 57ccfb9e 2003-12-11 devnull stdio = 1;
156 57ccfb9e 2003-12-11 devnull mfd[0] = 0;
157 57ccfb9e 2003-12-11 devnull mfd[1] = 1;
158 57ccfb9e 2003-12-11 devnull break;
159 57ccfb9e 2003-12-11 devnull case 's':
160 f583e2b1 2005-01-04 devnull defmnt = nil;
161 57ccfb9e 2003-12-11 devnull break;
162 57ccfb9e 2003-12-11 devnull case 'm':
163 57ccfb9e 2003-12-11 devnull defmnt = ARGF();
164 57ccfb9e 2003-12-11 devnull break;
165 57ccfb9e 2003-12-11 devnull case 'p':
166 57ccfb9e 2003-12-11 devnull private++;
167 57ccfb9e 2003-12-11 devnull break;
168 57ccfb9e 2003-12-11 devnull case 'S':
169 57ccfb9e 2003-12-11 devnull defmnt = 0;
170 57ccfb9e 2003-12-11 devnull service = EARGF(usage());
171 57ccfb9e 2003-12-11 devnull break;
172 57ccfb9e 2003-12-11 devnull default:
173 57ccfb9e 2003-12-11 devnull usage();
174 57ccfb9e 2003-12-11 devnull }ARGEND
175 c5bfba48 2012-10-21 rsc USED(defmnt);
176 57ccfb9e 2003-12-11 devnull
177 57ccfb9e 2003-12-11 devnull if(pipe(p) < 0)
178 57ccfb9e 2003-12-11 devnull error("pipe failed");
179 57ccfb9e 2003-12-11 devnull if(!stdio){
180 57ccfb9e 2003-12-11 devnull mfd[0] = p[0];
181 57ccfb9e 2003-12-11 devnull mfd[1] = p[0];
182 a2660887 2008-05-07 rsc if(post9pservice(p[1], service, nil) < 0)
183 57ccfb9e 2003-12-11 devnull sysfatal("post9pservice %s: %r", service);
184 57ccfb9e 2003-12-11 devnull }
185 57ccfb9e 2003-12-11 devnull
186 57ccfb9e 2003-12-11 devnull user = getuser();
187 57ccfb9e 2003-12-11 devnull notify(notifyf);
188 57ccfb9e 2003-12-11 devnull nram = 2;
189 57ccfb9e 2003-12-11 devnull r = &ram[0];
190 57ccfb9e 2003-12-11 devnull r->busy = 1;
191 57ccfb9e 2003-12-11 devnull r->data = 0;
192 57ccfb9e 2003-12-11 devnull r->ndata = 0;
193 57ccfb9e 2003-12-11 devnull r->perm = DMDIR | 0775;
194 57ccfb9e 2003-12-11 devnull r->qid.type = QTDIR;
195 57ccfb9e 2003-12-11 devnull r->qid.path = 0;
196 57ccfb9e 2003-12-11 devnull r->qid.vers = 0;
197 57ccfb9e 2003-12-11 devnull r->parent = 0;
198 57ccfb9e 2003-12-11 devnull r->user = user;
199 57ccfb9e 2003-12-11 devnull r->group = user;
200 57ccfb9e 2003-12-11 devnull r->muid = user;
201 57ccfb9e 2003-12-11 devnull r->atime = time(0);
202 57ccfb9e 2003-12-11 devnull r->mtime = r->atime;
203 57ccfb9e 2003-12-11 devnull r->name = estrdup(".");
204 57ccfb9e 2003-12-11 devnull
205 57ccfb9e 2003-12-11 devnull r = &ram[1];
206 57ccfb9e 2003-12-11 devnull r->busy = 1;
207 57ccfb9e 2003-12-11 devnull r->data = 0;
208 57ccfb9e 2003-12-11 devnull r->ndata = 0;
209 57ccfb9e 2003-12-11 devnull r->perm = 0666;
210 57ccfb9e 2003-12-11 devnull r->qid.type = 0;
211 57ccfb9e 2003-12-11 devnull r->qid.path = 1;
212 57ccfb9e 2003-12-11 devnull r->qid.vers = 0;
213 57ccfb9e 2003-12-11 devnull r->parent = 0;
214 57ccfb9e 2003-12-11 devnull r->user = user;
215 57ccfb9e 2003-12-11 devnull r->group = user;
216 57ccfb9e 2003-12-11 devnull r->muid = user;
217 57ccfb9e 2003-12-11 devnull r->atime = time(0);
218 57ccfb9e 2003-12-11 devnull r->mtime = r->atime;
219 57ccfb9e 2003-12-11 devnull r->name = estrdup("file");
220 57ccfb9e 2003-12-11 devnull
221 57ccfb9e 2003-12-11 devnull if(debug)
222 57ccfb9e 2003-12-11 devnull fmtinstall('F', fcallfmt);
223 57ccfb9e 2003-12-11 devnull switch(rfork(RFFDG|RFPROC|RFNAMEG|RFNOTEG)){
224 57ccfb9e 2003-12-11 devnull case -1:
225 57ccfb9e 2003-12-11 devnull error("fork");
226 57ccfb9e 2003-12-11 devnull case 0:
227 57ccfb9e 2003-12-11 devnull close(p[1]);
228 57ccfb9e 2003-12-11 devnull io();
229 57ccfb9e 2003-12-11 devnull break;
230 57ccfb9e 2003-12-11 devnull default:
231 57ccfb9e 2003-12-11 devnull close(p[0]); /* don't deadlock if child fails */
232 57ccfb9e 2003-12-11 devnull }
233 57ccfb9e 2003-12-11 devnull exits(0);
234 57ccfb9e 2003-12-11 devnull }
235 57ccfb9e 2003-12-11 devnull
236 57ccfb9e 2003-12-11 devnull char*
237 57ccfb9e 2003-12-11 devnull rversion(Fid *x)
238 57ccfb9e 2003-12-11 devnull {
239 57ccfb9e 2003-12-11 devnull Fid *f;
240 57ccfb9e 2003-12-11 devnull
241 57ccfb9e 2003-12-11 devnull USED(x);
242 57ccfb9e 2003-12-11 devnull for(f = fids; f; f = f->next)
243 57ccfb9e 2003-12-11 devnull if(f->busy)
244 57ccfb9e 2003-12-11 devnull rclunk(f);
245 57ccfb9e 2003-12-11 devnull if(thdr.msize > sizeof mdata)
246 57ccfb9e 2003-12-11 devnull rhdr.msize = sizeof mdata;
247 57ccfb9e 2003-12-11 devnull else
248 57ccfb9e 2003-12-11 devnull rhdr.msize = thdr.msize;
249 57ccfb9e 2003-12-11 devnull messagesize = rhdr.msize;
250 57ccfb9e 2003-12-11 devnull if(strncmp(thdr.version, "9P2000", 6) != 0)
251 57ccfb9e 2003-12-11 devnull return Eversion;
252 57ccfb9e 2003-12-11 devnull rhdr.version = "9P2000";
253 57ccfb9e 2003-12-11 devnull return 0;
254 57ccfb9e 2003-12-11 devnull }
255 57ccfb9e 2003-12-11 devnull
256 57ccfb9e 2003-12-11 devnull char*
257 57ccfb9e 2003-12-11 devnull rauth(Fid *x)
258 57ccfb9e 2003-12-11 devnull {
259 57ccfb9e 2003-12-11 devnull if(x->busy)
260 57ccfb9e 2003-12-11 devnull return Ebadfid;
261 57ccfb9e 2003-12-11 devnull return "ramfs: no authentication required";
262 57ccfb9e 2003-12-11 devnull }
263 57ccfb9e 2003-12-11 devnull
264 57ccfb9e 2003-12-11 devnull char*
265 57ccfb9e 2003-12-11 devnull rflush(Fid *f)
266 57ccfb9e 2003-12-11 devnull {
267 57ccfb9e 2003-12-11 devnull USED(f);
268 57ccfb9e 2003-12-11 devnull return 0;
269 57ccfb9e 2003-12-11 devnull }
270 57ccfb9e 2003-12-11 devnull
271 57ccfb9e 2003-12-11 devnull char*
272 57ccfb9e 2003-12-11 devnull rattach(Fid *f)
273 57ccfb9e 2003-12-11 devnull {
274 57ccfb9e 2003-12-11 devnull /* no authentication! */
275 57ccfb9e 2003-12-11 devnull if(f->busy)
276 57ccfb9e 2003-12-11 devnull return Ebadfid;
277 57ccfb9e 2003-12-11 devnull f->busy = 1;
278 57ccfb9e 2003-12-11 devnull f->rclose = 0;
279 57ccfb9e 2003-12-11 devnull f->ram = &ram[0];
280 57ccfb9e 2003-12-11 devnull rhdr.qid = f->ram->qid;
281 57ccfb9e 2003-12-11 devnull if(thdr.uname[0])
282 57ccfb9e 2003-12-11 devnull f->user = estrdup(thdr.uname);
283 57ccfb9e 2003-12-11 devnull else
284 57ccfb9e 2003-12-11 devnull f->user = "none";
285 57ccfb9e 2003-12-11 devnull if(strcmp(user, "none") == 0)
286 57ccfb9e 2003-12-11 devnull user = f->user;
287 57ccfb9e 2003-12-11 devnull return 0;
288 57ccfb9e 2003-12-11 devnull }
289 57ccfb9e 2003-12-11 devnull
290 57ccfb9e 2003-12-11 devnull char*
291 0a839b83 2004-12-27 devnull xclone(Fid *f, Fid **nf)
292 57ccfb9e 2003-12-11 devnull {
293 57ccfb9e 2003-12-11 devnull if(!f->busy)
294 57ccfb9e 2003-12-11 devnull return Ebadfid;
295 57ccfb9e 2003-12-11 devnull if(f->open)
296 57ccfb9e 2003-12-11 devnull return Eisopen;
297 57ccfb9e 2003-12-11 devnull if(f->ram->busy == 0)
298 57ccfb9e 2003-12-11 devnull return Enotexist;
299 57ccfb9e 2003-12-11 devnull *nf = newfid(thdr.newfid);
300 57ccfb9e 2003-12-11 devnull (*nf)->busy = 1;
301 57ccfb9e 2003-12-11 devnull (*nf)->open = 0;
302 57ccfb9e 2003-12-11 devnull (*nf)->rclose = 0;
303 57ccfb9e 2003-12-11 devnull (*nf)->ram = f->ram;
304 57ccfb9e 2003-12-11 devnull (*nf)->user = f->user; /* no ref count; the leakage is minor */
305 57ccfb9e 2003-12-11 devnull return 0;
306 57ccfb9e 2003-12-11 devnull }
307 57ccfb9e 2003-12-11 devnull
308 57ccfb9e 2003-12-11 devnull char*
309 57ccfb9e 2003-12-11 devnull rwalk(Fid *f)
310 57ccfb9e 2003-12-11 devnull {
311 57ccfb9e 2003-12-11 devnull Ram *r, *fram;
312 57ccfb9e 2003-12-11 devnull char *name;
313 57ccfb9e 2003-12-11 devnull Ram *parent;
314 57ccfb9e 2003-12-11 devnull Fid *nf;
315 57ccfb9e 2003-12-11 devnull char *err;
316 57ccfb9e 2003-12-11 devnull ulong t;
317 57ccfb9e 2003-12-11 devnull int i;
318 57ccfb9e 2003-12-11 devnull
319 57ccfb9e 2003-12-11 devnull if(!f->busy)
320 57ccfb9e 2003-12-11 devnull return Ebadfid;
321 57ccfb9e 2003-12-11 devnull err = nil;
322 57ccfb9e 2003-12-11 devnull nf = nil;
323 57ccfb9e 2003-12-11 devnull rhdr.nwqid = 0;
324 57ccfb9e 2003-12-11 devnull if(thdr.newfid != thdr.fid){
325 0a839b83 2004-12-27 devnull err = xclone(f, &nf);
326 57ccfb9e 2003-12-11 devnull if(err)
327 57ccfb9e 2003-12-11 devnull return err;
328 57ccfb9e 2003-12-11 devnull f = nf; /* walk the new fid */
329 57ccfb9e 2003-12-11 devnull }
330 57ccfb9e 2003-12-11 devnull fram = f->ram;
331 57ccfb9e 2003-12-11 devnull if(thdr.nwname > 0){
332 57ccfb9e 2003-12-11 devnull t = time(0);
333 57ccfb9e 2003-12-11 devnull for(i=0; i<thdr.nwname && i<MAXWELEM; i++){
334 57ccfb9e 2003-12-11 devnull if((fram->qid.type & QTDIR) == 0){
335 57ccfb9e 2003-12-11 devnull err = Enotdir;
336 57ccfb9e 2003-12-11 devnull break;
337 57ccfb9e 2003-12-11 devnull }
338 57ccfb9e 2003-12-11 devnull if(fram->busy == 0){
339 57ccfb9e 2003-12-11 devnull err = Enotexist;
340 57ccfb9e 2003-12-11 devnull break;
341 57ccfb9e 2003-12-11 devnull }
342 57ccfb9e 2003-12-11 devnull fram->atime = t;
343 57ccfb9e 2003-12-11 devnull name = thdr.wname[i];
344 57ccfb9e 2003-12-11 devnull if(strcmp(name, ".") == 0){
345 57ccfb9e 2003-12-11 devnull Found:
346 57ccfb9e 2003-12-11 devnull rhdr.nwqid++;
347 57ccfb9e 2003-12-11 devnull rhdr.wqid[i] = fram->qid;
348 57ccfb9e 2003-12-11 devnull continue;
349 57ccfb9e 2003-12-11 devnull }
350 57ccfb9e 2003-12-11 devnull parent = &ram[fram->parent];
351 57ccfb9e 2003-12-11 devnull if(!perm(f, parent, Pexec)){
352 57ccfb9e 2003-12-11 devnull err = Eperm;
353 57ccfb9e 2003-12-11 devnull break;
354 57ccfb9e 2003-12-11 devnull }
355 57ccfb9e 2003-12-11 devnull if(strcmp(name, "..") == 0){
356 57ccfb9e 2003-12-11 devnull fram = parent;
357 57ccfb9e 2003-12-11 devnull goto Found;
358 57ccfb9e 2003-12-11 devnull }
359 57ccfb9e 2003-12-11 devnull for(r=ram; r < &ram[nram]; r++)
360 57ccfb9e 2003-12-11 devnull if(r->busy && r->parent==fram-ram && strcmp(name, r->name)==0){
361 57ccfb9e 2003-12-11 devnull fram = r;
362 57ccfb9e 2003-12-11 devnull goto Found;
363 57ccfb9e 2003-12-11 devnull }
364 57ccfb9e 2003-12-11 devnull break;
365 57ccfb9e 2003-12-11 devnull }
366 57ccfb9e 2003-12-11 devnull if(i==0 && err == nil)
367 57ccfb9e 2003-12-11 devnull err = Enotexist;
368 57ccfb9e 2003-12-11 devnull }
369 57ccfb9e 2003-12-11 devnull if(nf != nil && (err!=nil || rhdr.nwqid<thdr.nwname)){
370 57ccfb9e 2003-12-11 devnull /* clunk the new fid, which is the one we walked */
371 57ccfb9e 2003-12-11 devnull fprint(2, "f %d zero busy\n", f->fid);
372 57ccfb9e 2003-12-11 devnull f->busy = 0;
373 57ccfb9e 2003-12-11 devnull f->ram = nil;
374 57ccfb9e 2003-12-11 devnull }
375 57ccfb9e 2003-12-11 devnull if(rhdr.nwqid == thdr.nwname) /* update the fid after a successful walk */
376 57ccfb9e 2003-12-11 devnull f->ram = fram;
377 57ccfb9e 2003-12-11 devnull assert(f->busy);
378 57ccfb9e 2003-12-11 devnull return err;
379 57ccfb9e 2003-12-11 devnull }
380 57ccfb9e 2003-12-11 devnull
381 57ccfb9e 2003-12-11 devnull char *
382 57ccfb9e 2003-12-11 devnull ropen(Fid *f)
383 57ccfb9e 2003-12-11 devnull {
384 57ccfb9e 2003-12-11 devnull Ram *r;
385 57ccfb9e 2003-12-11 devnull int mode, trunc;
386 57ccfb9e 2003-12-11 devnull
387 57ccfb9e 2003-12-11 devnull if(!f->busy)
388 57ccfb9e 2003-12-11 devnull return Ebadfid;
389 57ccfb9e 2003-12-11 devnull if(f->open)
390 57ccfb9e 2003-12-11 devnull return Eisopen;
391 57ccfb9e 2003-12-11 devnull r = f->ram;
392 57ccfb9e 2003-12-11 devnull if(r->busy == 0)
393 57ccfb9e 2003-12-11 devnull return Enotexist;
394 57ccfb9e 2003-12-11 devnull if(r->perm & DMEXCL)
395 57ccfb9e 2003-12-11 devnull if(r->open)
396 57ccfb9e 2003-12-11 devnull return Excl;
397 57ccfb9e 2003-12-11 devnull mode = thdr.mode;
398 57ccfb9e 2003-12-11 devnull if(r->qid.type & QTDIR){
399 57ccfb9e 2003-12-11 devnull if(mode != OREAD)
400 57ccfb9e 2003-12-11 devnull return Eperm;
401 57ccfb9e 2003-12-11 devnull rhdr.qid = r->qid;
402 57ccfb9e 2003-12-11 devnull return 0;
403 57ccfb9e 2003-12-11 devnull }
404 57ccfb9e 2003-12-11 devnull if(mode & ORCLOSE){
405 57ccfb9e 2003-12-11 devnull /* can't remove root; must be able to write parent */
406 57ccfb9e 2003-12-11 devnull if(r->qid.path==0 || !perm(f, &ram[r->parent], Pwrite))
407 57ccfb9e 2003-12-11 devnull return Eperm;
408 57ccfb9e 2003-12-11 devnull f->rclose = 1;
409 57ccfb9e 2003-12-11 devnull }
410 57ccfb9e 2003-12-11 devnull trunc = mode & OTRUNC;
411 57ccfb9e 2003-12-11 devnull mode &= OPERM;
412 57ccfb9e 2003-12-11 devnull if(mode==OWRITE || mode==ORDWR || trunc)
413 57ccfb9e 2003-12-11 devnull if(!perm(f, r, Pwrite))
414 57ccfb9e 2003-12-11 devnull return Eperm;
415 57ccfb9e 2003-12-11 devnull if(mode==OREAD || mode==ORDWR)
416 57ccfb9e 2003-12-11 devnull if(!perm(f, r, Pread))
417 57ccfb9e 2003-12-11 devnull return Eperm;
418 57ccfb9e 2003-12-11 devnull if(mode==OEXEC)
419 57ccfb9e 2003-12-11 devnull if(!perm(f, r, Pexec))
420 57ccfb9e 2003-12-11 devnull return Eperm;
421 57ccfb9e 2003-12-11 devnull if(trunc && (r->perm&DMAPPEND)==0){
422 57ccfb9e 2003-12-11 devnull r->ndata = 0;
423 57ccfb9e 2003-12-11 devnull if(r->data)
424 57ccfb9e 2003-12-11 devnull free(r->data);
425 57ccfb9e 2003-12-11 devnull r->data = 0;
426 57ccfb9e 2003-12-11 devnull r->qid.vers++;
427 57ccfb9e 2003-12-11 devnull }
428 57ccfb9e 2003-12-11 devnull rhdr.qid = r->qid;
429 57ccfb9e 2003-12-11 devnull rhdr.iounit = messagesize-IOHDRSZ;
430 57ccfb9e 2003-12-11 devnull f->open = 1;
431 57ccfb9e 2003-12-11 devnull r->open++;
432 57ccfb9e 2003-12-11 devnull return 0;
433 57ccfb9e 2003-12-11 devnull }
434 57ccfb9e 2003-12-11 devnull
435 57ccfb9e 2003-12-11 devnull char *
436 57ccfb9e 2003-12-11 devnull rcreate(Fid *f)
437 57ccfb9e 2003-12-11 devnull {
438 57ccfb9e 2003-12-11 devnull Ram *r;
439 57ccfb9e 2003-12-11 devnull char *name;
440 57ccfb9e 2003-12-11 devnull long parent, prm;
441 57ccfb9e 2003-12-11 devnull
442 57ccfb9e 2003-12-11 devnull if(!f->busy)
443 57ccfb9e 2003-12-11 devnull return Ebadfid;
444 57ccfb9e 2003-12-11 devnull if(f->open)
445 57ccfb9e 2003-12-11 devnull return Eisopen;
446 57ccfb9e 2003-12-11 devnull if(f->ram->busy == 0)
447 57ccfb9e 2003-12-11 devnull return Enotexist;
448 57ccfb9e 2003-12-11 devnull parent = f->ram - ram;
449 57ccfb9e 2003-12-11 devnull if((f->ram->qid.type&QTDIR) == 0)
450 57ccfb9e 2003-12-11 devnull return Enotdir;
451 57ccfb9e 2003-12-11 devnull /* must be able to write parent */
452 57ccfb9e 2003-12-11 devnull if(!perm(f, f->ram, Pwrite))
453 57ccfb9e 2003-12-11 devnull return Eperm;
454 57ccfb9e 2003-12-11 devnull prm = thdr.perm;
455 57ccfb9e 2003-12-11 devnull name = thdr.name;
456 57ccfb9e 2003-12-11 devnull if(strcmp(name, ".")==0 || strcmp(name, "..")==0)
457 57ccfb9e 2003-12-11 devnull return Ename;
458 57ccfb9e 2003-12-11 devnull for(r=ram; r<&ram[nram]; r++)
459 57ccfb9e 2003-12-11 devnull if(r->busy && parent==r->parent)
460 57ccfb9e 2003-12-11 devnull if(strcmp((char*)name, r->name)==0)
461 57ccfb9e 2003-12-11 devnull return Einuse;
462 57ccfb9e 2003-12-11 devnull for(r=ram; r->busy; r++)
463 57ccfb9e 2003-12-11 devnull if(r == &ram[Nram-1])
464 57ccfb9e 2003-12-11 devnull return "no free ram resources";
465 57ccfb9e 2003-12-11 devnull r->busy = 1;
466 57ccfb9e 2003-12-11 devnull r->qid.path = ++path;
467 57ccfb9e 2003-12-11 devnull r->qid.vers = 0;
468 57ccfb9e 2003-12-11 devnull if(prm & DMDIR)
469 57ccfb9e 2003-12-11 devnull r->qid.type |= QTDIR;
470 57ccfb9e 2003-12-11 devnull r->parent = parent;
471 57ccfb9e 2003-12-11 devnull free(r->name);
472 57ccfb9e 2003-12-11 devnull r->name = estrdup(name);
473 57ccfb9e 2003-12-11 devnull r->user = f->user;
474 57ccfb9e 2003-12-11 devnull r->group = f->ram->group;
475 57ccfb9e 2003-12-11 devnull r->muid = f->ram->muid;
476 57ccfb9e 2003-12-11 devnull if(prm & DMDIR)
477 57ccfb9e 2003-12-11 devnull prm = (prm&~0777) | (f->ram->perm&prm&0777);
478 57ccfb9e 2003-12-11 devnull else
479 57ccfb9e 2003-12-11 devnull prm = (prm&(~0777|0111)) | (f->ram->perm&prm&0666);
480 57ccfb9e 2003-12-11 devnull r->perm = prm;
481 57ccfb9e 2003-12-11 devnull r->ndata = 0;
482 57ccfb9e 2003-12-11 devnull if(r-ram >= nram)
483 57ccfb9e 2003-12-11 devnull nram = r - ram + 1;
484 57ccfb9e 2003-12-11 devnull r->atime = time(0);
485 57ccfb9e 2003-12-11 devnull r->mtime = r->atime;
486 57ccfb9e 2003-12-11 devnull f->ram->mtime = r->atime;
487 57ccfb9e 2003-12-11 devnull f->ram = r;
488 57ccfb9e 2003-12-11 devnull rhdr.qid = r->qid;
489 57ccfb9e 2003-12-11 devnull rhdr.iounit = messagesize-IOHDRSZ;
490 57ccfb9e 2003-12-11 devnull f->open = 1;
491 57ccfb9e 2003-12-11 devnull if(thdr.mode & ORCLOSE)
492 57ccfb9e 2003-12-11 devnull f->rclose = 1;
493 57ccfb9e 2003-12-11 devnull r->open++;
494 57ccfb9e 2003-12-11 devnull return 0;
495 57ccfb9e 2003-12-11 devnull }
496 57ccfb9e 2003-12-11 devnull
497 57ccfb9e 2003-12-11 devnull char*
498 57ccfb9e 2003-12-11 devnull rread(Fid *f)
499 57ccfb9e 2003-12-11 devnull {
500 57ccfb9e 2003-12-11 devnull Ram *r;
501 57ccfb9e 2003-12-11 devnull uchar *buf;
502 57ccfb9e 2003-12-11 devnull long off;
503 57ccfb9e 2003-12-11 devnull int n, m, cnt;
504 57ccfb9e 2003-12-11 devnull
505 57ccfb9e 2003-12-11 devnull if(!f->busy)
506 57ccfb9e 2003-12-11 devnull return Ebadfid;
507 57ccfb9e 2003-12-11 devnull if(f->ram->busy == 0)
508 57ccfb9e 2003-12-11 devnull return Enotexist;
509 57ccfb9e 2003-12-11 devnull n = 0;
510 57ccfb9e 2003-12-11 devnull rhdr.count = 0;
511 57ccfb9e 2003-12-11 devnull off = thdr.offset;
512 57ccfb9e 2003-12-11 devnull buf = rdata;
513 57ccfb9e 2003-12-11 devnull cnt = thdr.count;
514 57ccfb9e 2003-12-11 devnull if(cnt > messagesize) /* shouldn't happen, anyway */
515 57ccfb9e 2003-12-11 devnull cnt = messagesize;
516 57ccfb9e 2003-12-11 devnull if(f->ram->qid.type & QTDIR){
517 57ccfb9e 2003-12-11 devnull for(r=ram+1; off > 0; r++){
518 57ccfb9e 2003-12-11 devnull if(r->busy && r->parent==f->ram-ram)
519 57ccfb9e 2003-12-11 devnull off -= ramstat(r, statbuf, sizeof statbuf);
520 57ccfb9e 2003-12-11 devnull if(r == &ram[nram-1])
521 57ccfb9e 2003-12-11 devnull return 0;
522 57ccfb9e 2003-12-11 devnull }
523 57ccfb9e 2003-12-11 devnull for(; r<&ram[nram] && n < cnt; r++){
524 57ccfb9e 2003-12-11 devnull if(!r->busy || r->parent!=f->ram-ram)
525 57ccfb9e 2003-12-11 devnull continue;
526 57ccfb9e 2003-12-11 devnull m = ramstat(r, buf+n, cnt-n);
527 57ccfb9e 2003-12-11 devnull if(m == 0)
528 57ccfb9e 2003-12-11 devnull break;
529 57ccfb9e 2003-12-11 devnull n += m;
530 57ccfb9e 2003-12-11 devnull }
531 57ccfb9e 2003-12-11 devnull rhdr.data = (char*)rdata;
532 57ccfb9e 2003-12-11 devnull rhdr.count = n;
533 57ccfb9e 2003-12-11 devnull return 0;
534 57ccfb9e 2003-12-11 devnull }
535 57ccfb9e 2003-12-11 devnull r = f->ram;
536 57ccfb9e 2003-12-11 devnull if(off >= r->ndata)
537 57ccfb9e 2003-12-11 devnull return 0;
538 57ccfb9e 2003-12-11 devnull r->atime = time(0);
539 57ccfb9e 2003-12-11 devnull n = cnt;
540 57ccfb9e 2003-12-11 devnull if(off+n > r->ndata)
541 57ccfb9e 2003-12-11 devnull n = r->ndata - off;
542 57ccfb9e 2003-12-11 devnull rhdr.data = r->data+off;
543 57ccfb9e 2003-12-11 devnull rhdr.count = n;
544 57ccfb9e 2003-12-11 devnull return 0;
545 57ccfb9e 2003-12-11 devnull }
546 57ccfb9e 2003-12-11 devnull
547 57ccfb9e 2003-12-11 devnull char*
548 57ccfb9e 2003-12-11 devnull rwrite(Fid *f)
549 57ccfb9e 2003-12-11 devnull {
550 57ccfb9e 2003-12-11 devnull Ram *r;
551 57ccfb9e 2003-12-11 devnull ulong off;
552 57ccfb9e 2003-12-11 devnull int cnt;
553 57ccfb9e 2003-12-11 devnull
554 57ccfb9e 2003-12-11 devnull r = f->ram;
555 57ccfb9e 2003-12-11 devnull if(!f->busy)
556 57ccfb9e 2003-12-11 devnull return Ebadfid;
557 57ccfb9e 2003-12-11 devnull if(r->busy == 0)
558 57ccfb9e 2003-12-11 devnull return Enotexist;
559 57ccfb9e 2003-12-11 devnull off = thdr.offset;
560 57ccfb9e 2003-12-11 devnull if(r->perm & DMAPPEND)
561 57ccfb9e 2003-12-11 devnull off = r->ndata;
562 57ccfb9e 2003-12-11 devnull cnt = thdr.count;
563 57ccfb9e 2003-12-11 devnull if(r->qid.type & QTDIR)
564 57ccfb9e 2003-12-11 devnull return Eisdir;
565 57ccfb9e 2003-12-11 devnull if(off+cnt >= Maxsize) /* sanity check */
566 57ccfb9e 2003-12-11 devnull return "write too big";
567 57ccfb9e 2003-12-11 devnull if(off+cnt > r->ndata)
568 57ccfb9e 2003-12-11 devnull r->data = erealloc(r->data, off+cnt);
569 57ccfb9e 2003-12-11 devnull if(off > r->ndata)
570 57ccfb9e 2003-12-11 devnull memset(r->data+r->ndata, 0, off-r->ndata);
571 57ccfb9e 2003-12-11 devnull if(off+cnt > r->ndata)
572 57ccfb9e 2003-12-11 devnull r->ndata = off+cnt;
573 57ccfb9e 2003-12-11 devnull memmove(r->data+off, thdr.data, cnt);
574 57ccfb9e 2003-12-11 devnull r->qid.vers++;
575 57ccfb9e 2003-12-11 devnull r->mtime = time(0);
576 57ccfb9e 2003-12-11 devnull rhdr.count = cnt;
577 57ccfb9e 2003-12-11 devnull return 0;
578 57ccfb9e 2003-12-11 devnull }
579 57ccfb9e 2003-12-11 devnull
580 57ccfb9e 2003-12-11 devnull static int
581 57ccfb9e 2003-12-11 devnull emptydir(Ram *dr)
582 57ccfb9e 2003-12-11 devnull {
583 57ccfb9e 2003-12-11 devnull long didx = dr - ram;
584 57ccfb9e 2003-12-11 devnull Ram *r;
585 57ccfb9e 2003-12-11 devnull
586 57ccfb9e 2003-12-11 devnull for(r=ram; r<&ram[nram]; r++)
587 57ccfb9e 2003-12-11 devnull if(r->busy && didx==r->parent)
588 57ccfb9e 2003-12-11 devnull return 0;
589 57ccfb9e 2003-12-11 devnull return 1;
590 57ccfb9e 2003-12-11 devnull }
591 57ccfb9e 2003-12-11 devnull
592 57ccfb9e 2003-12-11 devnull char *
593 57ccfb9e 2003-12-11 devnull realremove(Ram *r)
594 57ccfb9e 2003-12-11 devnull {
595 57ccfb9e 2003-12-11 devnull if(r->qid.type & QTDIR && !emptydir(r))
596 57ccfb9e 2003-12-11 devnull return Enotempty;
597 57ccfb9e 2003-12-11 devnull r->ndata = 0;
598 57ccfb9e 2003-12-11 devnull if(r->data)
599 57ccfb9e 2003-12-11 devnull free(r->data);
600 57ccfb9e 2003-12-11 devnull r->data = 0;
601 57ccfb9e 2003-12-11 devnull r->parent = 0;
602 57ccfb9e 2003-12-11 devnull memset(&r->qid, 0, sizeof r->qid);
603 57ccfb9e 2003-12-11 devnull free(r->name);
604 57ccfb9e 2003-12-11 devnull r->name = nil;
605 57ccfb9e 2003-12-11 devnull r->busy = 0;
606 57ccfb9e 2003-12-11 devnull return nil;
607 57ccfb9e 2003-12-11 devnull }
608 57ccfb9e 2003-12-11 devnull
609 57ccfb9e 2003-12-11 devnull char *
610 57ccfb9e 2003-12-11 devnull rclunk(Fid *f)
611 57ccfb9e 2003-12-11 devnull {
612 57ccfb9e 2003-12-11 devnull char *e = nil;
613 57ccfb9e 2003-12-11 devnull
614 57ccfb9e 2003-12-11 devnull if(f->open)
615 57ccfb9e 2003-12-11 devnull f->ram->open--;
616 57ccfb9e 2003-12-11 devnull if(f->rclose)
617 57ccfb9e 2003-12-11 devnull e = realremove(f->ram);
618 57ccfb9e 2003-12-11 devnull fprint(2, "clunk fid %d busy=%d\n", f->fid, f->busy);
619 57ccfb9e 2003-12-11 devnull fprint(2, "f %d zero busy\n", f->fid);
620 57ccfb9e 2003-12-11 devnull f->busy = 0;
621 57ccfb9e 2003-12-11 devnull f->open = 0;
622 57ccfb9e 2003-12-11 devnull f->ram = 0;
623 57ccfb9e 2003-12-11 devnull return e;
624 57ccfb9e 2003-12-11 devnull }
625 57ccfb9e 2003-12-11 devnull
626 57ccfb9e 2003-12-11 devnull char *
627 57ccfb9e 2003-12-11 devnull rremove(Fid *f)
628 57ccfb9e 2003-12-11 devnull {
629 57ccfb9e 2003-12-11 devnull Ram *r;
630 57ccfb9e 2003-12-11 devnull
631 57ccfb9e 2003-12-11 devnull if(f->open)
632 57ccfb9e 2003-12-11 devnull f->ram->open--;
633 57ccfb9e 2003-12-11 devnull fprint(2, "f %d zero busy\n", f->fid);
634 57ccfb9e 2003-12-11 devnull f->busy = 0;
635 57ccfb9e 2003-12-11 devnull f->open = 0;
636 57ccfb9e 2003-12-11 devnull r = f->ram;
637 57ccfb9e 2003-12-11 devnull f->ram = 0;
638 57ccfb9e 2003-12-11 devnull if(r->qid.path == 0 || !perm(f, &ram[r->parent], Pwrite))
639 57ccfb9e 2003-12-11 devnull return Eperm;
640 57ccfb9e 2003-12-11 devnull ram[r->parent].mtime = time(0);
641 57ccfb9e 2003-12-11 devnull return realremove(r);
642 57ccfb9e 2003-12-11 devnull }
643 57ccfb9e 2003-12-11 devnull
644 57ccfb9e 2003-12-11 devnull char *
645 57ccfb9e 2003-12-11 devnull rstat(Fid *f)
646 57ccfb9e 2003-12-11 devnull {
647 57ccfb9e 2003-12-11 devnull if(!f->busy)
648 57ccfb9e 2003-12-11 devnull return Ebadfid;
649 57ccfb9e 2003-12-11 devnull if(f->ram->busy == 0)
650 57ccfb9e 2003-12-11 devnull return Enotexist;
651 57ccfb9e 2003-12-11 devnull rhdr.nstat = ramstat(f->ram, statbuf, sizeof statbuf);
652 57ccfb9e 2003-12-11 devnull rhdr.stat = statbuf;
653 57ccfb9e 2003-12-11 devnull return 0;
654 57ccfb9e 2003-12-11 devnull }
655 57ccfb9e 2003-12-11 devnull
656 57ccfb9e 2003-12-11 devnull char *
657 57ccfb9e 2003-12-11 devnull rwstat(Fid *f)
658 57ccfb9e 2003-12-11 devnull {
659 57ccfb9e 2003-12-11 devnull Ram *r, *s;
660 57ccfb9e 2003-12-11 devnull Dir dir;
661 57ccfb9e 2003-12-11 devnull
662 57ccfb9e 2003-12-11 devnull if(!f->busy)
663 57ccfb9e 2003-12-11 devnull return Ebadfid;
664 57ccfb9e 2003-12-11 devnull if(f->ram->busy == 0)
665 57ccfb9e 2003-12-11 devnull return Enotexist;
666 57ccfb9e 2003-12-11 devnull convM2D(thdr.stat, thdr.nstat, &dir, (char*)statbuf);
667 57ccfb9e 2003-12-11 devnull r = f->ram;
668 57ccfb9e 2003-12-11 devnull
669 57ccfb9e 2003-12-11 devnull /*
670 57ccfb9e 2003-12-11 devnull * To change length, must have write permission on file.
671 57ccfb9e 2003-12-11 devnull */
672 57ccfb9e 2003-12-11 devnull if(dir.length!=~0 && dir.length!=r->ndata){
673 57ccfb9e 2003-12-11 devnull if(!perm(f, r, Pwrite))
674 57ccfb9e 2003-12-11 devnull return Eperm;
675 57ccfb9e 2003-12-11 devnull }
676 57ccfb9e 2003-12-11 devnull
677 57ccfb9e 2003-12-11 devnull /*
678 57ccfb9e 2003-12-11 devnull * To change name, must have write permission in parent
679 57ccfb9e 2003-12-11 devnull * and name must be unique.
680 57ccfb9e 2003-12-11 devnull */
681 57ccfb9e 2003-12-11 devnull if(dir.name[0]!='\0' && strcmp(dir.name, r->name)!=0){
682 57ccfb9e 2003-12-11 devnull if(!perm(f, &ram[r->parent], Pwrite))
683 57ccfb9e 2003-12-11 devnull return Eperm;
684 57ccfb9e 2003-12-11 devnull for(s=ram; s<&ram[nram]; s++)
685 57ccfb9e 2003-12-11 devnull if(s->busy && s->parent==r->parent)
686 57ccfb9e 2003-12-11 devnull if(strcmp(dir.name, s->name)==0)
687 57ccfb9e 2003-12-11 devnull return Eexist;
688 57ccfb9e 2003-12-11 devnull }
689 57ccfb9e 2003-12-11 devnull
690 57ccfb9e 2003-12-11 devnull /*
691 57ccfb9e 2003-12-11 devnull * To change mode, must be owner or group leader.
692 57ccfb9e 2003-12-11 devnull * Because of lack of users file, leader=>group itself.
693 57ccfb9e 2003-12-11 devnull */
694 57ccfb9e 2003-12-11 devnull if(dir.mode!=~0 && r->perm!=dir.mode){
695 57ccfb9e 2003-12-11 devnull if(strcmp(f->user, r->user) != 0)
696 57ccfb9e 2003-12-11 devnull if(strcmp(f->user, r->group) != 0)
697 57ccfb9e 2003-12-11 devnull return Enotowner;
698 57ccfb9e 2003-12-11 devnull }
699 57ccfb9e 2003-12-11 devnull
700 57ccfb9e 2003-12-11 devnull /*
701 57ccfb9e 2003-12-11 devnull * To change group, must be owner and member of new group,
702 57ccfb9e 2003-12-11 devnull * or leader of current group and leader of new group.
703 57ccfb9e 2003-12-11 devnull * Second case cannot happen, but we check anyway.
704 57ccfb9e 2003-12-11 devnull */
705 57ccfb9e 2003-12-11 devnull if(dir.gid[0]!='\0' && strcmp(r->group, dir.gid)!=0){
706 57ccfb9e 2003-12-11 devnull if(strcmp(f->user, r->user) == 0)
707 cbeb0b26 2006-04-01 devnull /* if(strcmp(f->user, dir.gid) == 0) */
708 57ccfb9e 2003-12-11 devnull goto ok;
709 57ccfb9e 2003-12-11 devnull if(strcmp(f->user, r->group) == 0)
710 57ccfb9e 2003-12-11 devnull if(strcmp(f->user, dir.gid) == 0)
711 57ccfb9e 2003-12-11 devnull goto ok;
712 57ccfb9e 2003-12-11 devnull return Enotowner;
713 57ccfb9e 2003-12-11 devnull ok:;
714 57ccfb9e 2003-12-11 devnull }
715 57ccfb9e 2003-12-11 devnull
716 57ccfb9e 2003-12-11 devnull /* all ok; do it */
717 57ccfb9e 2003-12-11 devnull if(dir.mode != ~0){
718 57ccfb9e 2003-12-11 devnull dir.mode &= ~DMDIR; /* cannot change dir bit */
719 57ccfb9e 2003-12-11 devnull dir.mode |= r->perm&DMDIR;
720 57ccfb9e 2003-12-11 devnull r->perm = dir.mode;
721 57ccfb9e 2003-12-11 devnull }
722 57ccfb9e 2003-12-11 devnull if(dir.name[0] != '\0'){
723 57ccfb9e 2003-12-11 devnull free(r->name);
724 57ccfb9e 2003-12-11 devnull r->name = estrdup(dir.name);
725 57ccfb9e 2003-12-11 devnull }
726 57ccfb9e 2003-12-11 devnull if(dir.gid[0] != '\0')
727 57ccfb9e 2003-12-11 devnull r->group = estrdup(dir.gid);
728 57ccfb9e 2003-12-11 devnull if(dir.length!=~0 && dir.length!=r->ndata){
729 57ccfb9e 2003-12-11 devnull r->data = erealloc(r->data, dir.length);
730 57ccfb9e 2003-12-11 devnull if(r->ndata < dir.length)
731 57ccfb9e 2003-12-11 devnull memset(r->data+r->ndata, 0, dir.length-r->ndata);
732 57ccfb9e 2003-12-11 devnull r->ndata = dir.length;
733 57ccfb9e 2003-12-11 devnull }
734 57ccfb9e 2003-12-11 devnull ram[r->parent].mtime = time(0);
735 57ccfb9e 2003-12-11 devnull return 0;
736 57ccfb9e 2003-12-11 devnull }
737 57ccfb9e 2003-12-11 devnull
738 57ccfb9e 2003-12-11 devnull uint
739 57ccfb9e 2003-12-11 devnull ramstat(Ram *r, uchar *buf, uint nbuf)
740 57ccfb9e 2003-12-11 devnull {
741 57ccfb9e 2003-12-11 devnull int n;
742 57ccfb9e 2003-12-11 devnull Dir dir;
743 57ccfb9e 2003-12-11 devnull
744 57ccfb9e 2003-12-11 devnull dir.name = r->name;
745 57ccfb9e 2003-12-11 devnull dir.qid = r->qid;
746 57ccfb9e 2003-12-11 devnull dir.mode = r->perm;
747 57ccfb9e 2003-12-11 devnull dir.length = r->ndata;
748 57ccfb9e 2003-12-11 devnull dir.uid = r->user;
749 57ccfb9e 2003-12-11 devnull dir.gid = r->group;
750 57ccfb9e 2003-12-11 devnull dir.muid = r->muid;
751 57ccfb9e 2003-12-11 devnull dir.atime = r->atime;
752 57ccfb9e 2003-12-11 devnull dir.mtime = r->mtime;
753 57ccfb9e 2003-12-11 devnull n = convD2M(&dir, buf, nbuf);
754 57ccfb9e 2003-12-11 devnull if(n > 2)
755 57ccfb9e 2003-12-11 devnull return n;
756 57ccfb9e 2003-12-11 devnull return 0;
757 57ccfb9e 2003-12-11 devnull }
758 57ccfb9e 2003-12-11 devnull
759 57ccfb9e 2003-12-11 devnull Fid *
760 57ccfb9e 2003-12-11 devnull newfid(int fid)
761 57ccfb9e 2003-12-11 devnull {
762 57ccfb9e 2003-12-11 devnull Fid *f, *ff;
763 57ccfb9e 2003-12-11 devnull
764 57ccfb9e 2003-12-11 devnull ff = 0;
765 57ccfb9e 2003-12-11 devnull for(f = fids; f; f = f->next)
766 001dc170 2007-06-05 devnull if(f->fid == fid)
767 57ccfb9e 2003-12-11 devnull return f;
768 57ccfb9e 2003-12-11 devnull else if(!ff && !f->busy)
769 57ccfb9e 2003-12-11 devnull ff = f;
770 57ccfb9e 2003-12-11 devnull if(ff){
771 57ccfb9e 2003-12-11 devnull ff->fid = fid;
772 57ccfb9e 2003-12-11 devnull return ff;
773 57ccfb9e 2003-12-11 devnull }
774 57ccfb9e 2003-12-11 devnull f = emalloc(sizeof *f);
775 57ccfb9e 2003-12-11 devnull f->ram = nil;
776 57ccfb9e 2003-12-11 devnull f->fid = fid;
777 57ccfb9e 2003-12-11 devnull f->next = fids;
778 57ccfb9e 2003-12-11 devnull fids = f;
779 57ccfb9e 2003-12-11 devnull return f;
780 57ccfb9e 2003-12-11 devnull }
781 57ccfb9e 2003-12-11 devnull
782 57ccfb9e 2003-12-11 devnull void
783 57ccfb9e 2003-12-11 devnull io(void)
784 57ccfb9e 2003-12-11 devnull {
785 57ccfb9e 2003-12-11 devnull char *err, buf[20];
786 57ccfb9e 2003-12-11 devnull int n, pid, ctl;
787 57ccfb9e 2003-12-11 devnull
788 57ccfb9e 2003-12-11 devnull pid = getpid();
789 57ccfb9e 2003-12-11 devnull if(private){
790 57ccfb9e 2003-12-11 devnull snprint(buf, sizeof buf, "/proc/%d/ctl", pid);
791 57ccfb9e 2003-12-11 devnull ctl = open(buf, OWRITE);
792 57ccfb9e 2003-12-11 devnull if(ctl < 0){
793 57ccfb9e 2003-12-11 devnull fprint(2, "can't protect ramfs\n");
794 57ccfb9e 2003-12-11 devnull }else{
795 57ccfb9e 2003-12-11 devnull fprint(ctl, "noswap\n");
796 57ccfb9e 2003-12-11 devnull fprint(ctl, "private\n");
797 57ccfb9e 2003-12-11 devnull close(ctl);
798 57ccfb9e 2003-12-11 devnull }
799 57ccfb9e 2003-12-11 devnull }
800 57ccfb9e 2003-12-11 devnull
801 57ccfb9e 2003-12-11 devnull for(;;){
802 57ccfb9e 2003-12-11 devnull /*
803 57ccfb9e 2003-12-11 devnull * reading from a pipe or a network device
804 57ccfb9e 2003-12-11 devnull * will give an error after a few eof reads.
805 57ccfb9e 2003-12-11 devnull * however, we cannot tell the difference
806 57ccfb9e 2003-12-11 devnull * between a zero-length read and an interrupt
807 57ccfb9e 2003-12-11 devnull * on the processes writing to us,
808 57ccfb9e 2003-12-11 devnull * so we wait for the error.
809 57ccfb9e 2003-12-11 devnull */
810 57ccfb9e 2003-12-11 devnull n = read9pmsg(mfd[0], mdata, messagesize);
811 57ccfb9e 2003-12-11 devnull if(n < 0)
812 57ccfb9e 2003-12-11 devnull error("mount read");
813 57ccfb9e 2003-12-11 devnull if(n == 0)
814 57ccfb9e 2003-12-11 devnull error("mount eof");
815 57ccfb9e 2003-12-11 devnull if(convM2S(mdata, n, &thdr) == 0)
816 57ccfb9e 2003-12-11 devnull continue;
817 57ccfb9e 2003-12-11 devnull
818 57ccfb9e 2003-12-11 devnull if(debug)
819 57ccfb9e 2003-12-11 devnull fprint(2, "ramfs %d:<-%F\n", pid, &thdr);
820 57ccfb9e 2003-12-11 devnull
821 57ccfb9e 2003-12-11 devnull if(!fcalls[thdr.type])
822 57ccfb9e 2003-12-11 devnull err = "bad fcall type";
823 57ccfb9e 2003-12-11 devnull else
824 57ccfb9e 2003-12-11 devnull err = (*fcalls[thdr.type])(newfid(thdr.fid));
825 57ccfb9e 2003-12-11 devnull if(err){
826 57ccfb9e 2003-12-11 devnull rhdr.type = Rerror;
827 57ccfb9e 2003-12-11 devnull rhdr.ename = err;
828 57ccfb9e 2003-12-11 devnull }else{
829 57ccfb9e 2003-12-11 devnull rhdr.type = thdr.type + 1;
830 57ccfb9e 2003-12-11 devnull rhdr.fid = thdr.fid;
831 57ccfb9e 2003-12-11 devnull }
832 57ccfb9e 2003-12-11 devnull rhdr.tag = thdr.tag;
833 57ccfb9e 2003-12-11 devnull if(debug)
834 57ccfb9e 2003-12-11 devnull fprint(2, "ramfs %d:->%F\n", pid, &rhdr);/**/
835 57ccfb9e 2003-12-11 devnull n = convS2M(&rhdr, mdata, messagesize);
836 57ccfb9e 2003-12-11 devnull if(n == 0)
837 57ccfb9e 2003-12-11 devnull error("convS2M error on write");
838 57ccfb9e 2003-12-11 devnull if(write(mfd[1], mdata, n) != n)
839 57ccfb9e 2003-12-11 devnull error("mount write");
840 57ccfb9e 2003-12-11 devnull }
841 57ccfb9e 2003-12-11 devnull }
842 57ccfb9e 2003-12-11 devnull
843 57ccfb9e 2003-12-11 devnull int
844 57ccfb9e 2003-12-11 devnull perm(Fid *f, Ram *r, int p)
845 57ccfb9e 2003-12-11 devnull {
846 57ccfb9e 2003-12-11 devnull if((p*Pother) & r->perm)
847 57ccfb9e 2003-12-11 devnull return 1;
848 57ccfb9e 2003-12-11 devnull if(strcmp(f->user, r->group)==0 && ((p*Pgroup) & r->perm))
849 57ccfb9e 2003-12-11 devnull return 1;
850 57ccfb9e 2003-12-11 devnull if(strcmp(f->user, r->user)==0 && ((p*Powner) & r->perm))
851 57ccfb9e 2003-12-11 devnull return 1;
852 57ccfb9e 2003-12-11 devnull return 0;
853 57ccfb9e 2003-12-11 devnull }
854 57ccfb9e 2003-12-11 devnull
855 57ccfb9e 2003-12-11 devnull void
856 57ccfb9e 2003-12-11 devnull error(char *s)
857 57ccfb9e 2003-12-11 devnull {
858 57ccfb9e 2003-12-11 devnull fprint(2, "%s: %s: %r\n", argv0, s);
859 57ccfb9e 2003-12-11 devnull exits(s);
860 57ccfb9e 2003-12-11 devnull }
861 57ccfb9e 2003-12-11 devnull
862 57ccfb9e 2003-12-11 devnull void *
863 57ccfb9e 2003-12-11 devnull emalloc(ulong n)
864 57ccfb9e 2003-12-11 devnull {
865 57ccfb9e 2003-12-11 devnull void *p;
866 57ccfb9e 2003-12-11 devnull
867 57ccfb9e 2003-12-11 devnull p = malloc(n);
868 57ccfb9e 2003-12-11 devnull if(!p)
869 57ccfb9e 2003-12-11 devnull error("out of memory");
870 57ccfb9e 2003-12-11 devnull memset(p, 0, n);
871 57ccfb9e 2003-12-11 devnull return p;
872 57ccfb9e 2003-12-11 devnull }
873 57ccfb9e 2003-12-11 devnull
874 57ccfb9e 2003-12-11 devnull void *
875 57ccfb9e 2003-12-11 devnull erealloc(void *p, ulong n)
876 57ccfb9e 2003-12-11 devnull {
877 57ccfb9e 2003-12-11 devnull p = realloc(p, n);
878 57ccfb9e 2003-12-11 devnull if(!p)
879 57ccfb9e 2003-12-11 devnull error("out of memory");
880 57ccfb9e 2003-12-11 devnull return p;
881 57ccfb9e 2003-12-11 devnull }
882 57ccfb9e 2003-12-11 devnull
883 57ccfb9e 2003-12-11 devnull char *
884 57ccfb9e 2003-12-11 devnull estrdup(char *q)
885 57ccfb9e 2003-12-11 devnull {
886 57ccfb9e 2003-12-11 devnull char *p;
887 57ccfb9e 2003-12-11 devnull int n;
888 57ccfb9e 2003-12-11 devnull
889 57ccfb9e 2003-12-11 devnull n = strlen(q)+1;
890 57ccfb9e 2003-12-11 devnull p = malloc(n);
891 57ccfb9e 2003-12-11 devnull if(!p)
892 57ccfb9e 2003-12-11 devnull error("out of memory");
893 57ccfb9e 2003-12-11 devnull memmove(p, q, n);
894 57ccfb9e 2003-12-11 devnull return p;
895 57ccfb9e 2003-12-11 devnull }
896 57ccfb9e 2003-12-11 devnull
897 57ccfb9e 2003-12-11 devnull void
898 57ccfb9e 2003-12-11 devnull usage(void)
899 57ccfb9e 2003-12-11 devnull {
900 57ccfb9e 2003-12-11 devnull fprint(2, "usage: %s [-is] [-m mountpoint]\n", argv0);
901 57ccfb9e 2003-12-11 devnull exits("usage");
902 57ccfb9e 2003-12-11 devnull }