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