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