1 #include "all.h"
2 #include "9p1.h"
3
4 void
fcall9p1(Chan * cp,Oldfcall * in,Oldfcall * ou)5 fcall9p1(Chan *cp, Oldfcall *in, Oldfcall *ou)
6 {
7 int t;
8
9 rlock(&mainlock);
10 t = in->type;
11 if(t < 0 || t >= MAXSYSCALL || (t&1) || !call9p1[t]) {
12 print("bad message type %d\n", t);
13 panic("");
14 }
15 ou->type = t+1;
16 ou->err = 0;
17
18 rlock(&cp->reflock);
19 (*call9p1[t])(cp, in, ou);
20 runlock(&cp->reflock);
21
22 if(ou->err)
23 if(CHAT(cp))
24 print(" error: %s\n", errstring[ou->err]);
25 cons.work.count++;
26 runlock(&mainlock);
27 }
28
29 int
con_session(void)30 con_session(void)
31 {
32 Oldfcall in, ou;
33
34 in.type = Tsession9p1;
35 fcall9p1(cons.chan, &in, &ou);
36 return ou.err;
37 }
38
39 int
con_attach(int fid,char * uid,char * arg)40 con_attach(int fid, char *uid, char *arg)
41 {
42 Oldfcall in, ou;
43
44 in.type = Tattach9p1;
45 in.fid = fid;
46 strncpy(in.uname, uid, NAMELEN);
47 strncpy(in.aname, arg, NAMELEN);
48 fcall9p1(cons.chan, &in, &ou);
49 return ou.err;
50 }
51
52 int
con_clone(int fid1,int fid2)53 con_clone(int fid1, int fid2)
54 {
55 Oldfcall in, ou;
56
57 in.type = Tclone9p1;
58 in.fid = fid1;
59 in.newfid = fid2;
60 fcall9p1(cons.chan, &in, &ou);
61 return ou.err;
62 }
63
64 int
con_path(int fid,char * path)65 con_path(int fid, char *path)
66 {
67 Oldfcall in, ou;
68 char *p;
69
70 in.type = Twalk9p1;
71 in.fid = fid;
72
73 loop:
74 if(*path == 0)
75 return 0;
76 strncpy(in.name, path, NAMELEN);
77 if(p = strchr(path, '/')) {
78 path = p+1;
79 if(p = strchr(in.name, '/'))
80 *p = 0;
81 } else
82 path = strchr(path, 0);
83 if(in.name[0]) {
84 fcall9p1(cons.chan, &in, &ou);
85 if(ou.err)
86 return ou.err;
87 }
88 goto loop;
89 }
90
91 int
con_walk(int fid,char * name)92 con_walk(int fid, char *name)
93 {
94 Oldfcall in, ou;
95
96 in.type = Twalk9p1;
97 in.fid = fid;
98 strncpy(in.name, name, NAMELEN);
99 fcall9p1(cons.chan, &in, &ou);
100 return ou.err;
101 }
102
103 int
con_stat(int fid,char * data)104 con_stat(int fid, char *data)
105 {
106 Oldfcall in, ou;
107
108 in.type = Tstat9p1;
109 in.fid = fid;
110 fcall9p1(cons.chan, &in, &ou);
111 if(ou.err == 0)
112 memmove(data, ou.stat, sizeof ou.stat);
113 return ou.err;
114 }
115
116 int
con_wstat(int fid,char * data)117 con_wstat(int fid, char *data)
118 {
119 Oldfcall in, ou;
120
121 in.type = Twstat9p1;
122 in.fid = fid;
123 memmove(in.stat, data, sizeof in.stat);
124 fcall9p1(cons.chan, &in, &ou);
125 return ou.err;
126 }
127
128 int
con_open(int fid,int mode)129 con_open(int fid, int mode)
130 {
131 Oldfcall in, ou;
132
133 in.type = Topen9p1;
134 in.fid = fid;
135 in.mode = mode;
136 fcall9p1(cons.chan, &in, &ou);
137 return ou.err;
138 }
139
140 int
con_read(int fid,char * data,long offset,int count)141 con_read(int fid, char *data, long offset, int count)
142 {
143 Oldfcall in, ou;
144
145 in.type = Tread9p1;
146 in.fid = fid;
147 in.offset = offset;
148 in.count = count;
149 ou.data = data;
150 fcall9p1(cons.chan, &in, &ou);
151 if(ou.err)
152 return 0;
153 return ou.count;
154 }
155
156 int
con_write(int fid,char * data,long offset,int count)157 con_write(int fid, char *data, long offset, int count)
158 {
159 Oldfcall in, ou;
160
161 in.type = Twrite9p1;
162 in.fid = fid;
163 in.data = data;
164 in.offset = offset;
165 in.count = count;
166 fcall9p1(cons.chan, &in, &ou);
167 if(ou.err)
168 return 0;
169 return ou.count;
170 }
171
172 int
con_remove(int fid)173 con_remove(int fid)
174 {
175 Oldfcall in, ou;
176
177 in.type = Tremove9p1;
178 in.fid = fid;
179 fcall9p1(cons.chan, &in, &ou);
180 return ou.err;
181 }
182
183 int
con_create(int fid,char * name,int uid,int gid,long perm,int mode)184 con_create(int fid, char *name, int uid, int gid, long perm, int mode)
185 {
186 Oldfcall in, ou;
187
188 in.type = Tcreate9p1;
189 in.fid = fid;
190 strncpy(in.name, name, NAMELEN);
191 in.perm = perm;
192 in.mode = mode;
193 cons.uid = uid; /* beyond ugly */
194 cons.gid = gid;
195 fcall9p1(cons.chan, &in, &ou);
196 return ou.err;
197 }
198
199 int
doclri(File * f)200 doclri(File *f)
201 {
202 Iobuf *p, *p1;
203 Dentry *d, *d1;
204 int err;
205
206 err = 0;
207 p = 0;
208 p1 = 0;
209 if(isro(f->fs->dev)) {
210 err = Eronly;
211 goto out;
212 }
213 /*
214 * check on parent directory of file to be deleted
215 */
216 if(f->wpath == 0 || f->wpath->addr == f->addr) {
217 err = Ephase;
218 goto out;
219 }
220 p1 = getbuf(f->fs->dev, f->wpath->addr, Bread);
221 d1 = getdir(p1, f->wpath->slot);
222 if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
223 err = Ephase;
224 goto out;
225 }
226
227 accessdir(p1, d1, FWRITE);
228 putbuf(p1);
229 p1 = 0;
230
231 /*
232 * check on file to be deleted
233 */
234 p = getbuf(f->fs->dev, f->addr, Bread);
235 d = getdir(p, f->slot);
236
237
238 /*
239 * do it
240 */
241 memset(d, 0, sizeof(Dentry));
242 settag(p, Tdir, QPNONE);
243 freewp(f->wpath);
244 freefp(f);
245
246 out:
247 if(p1)
248 putbuf(p1);
249 if(p)
250 putbuf(p);
251 return err;
252 }
253
254 void
f_clri(Chan * cp,Oldfcall * in,Oldfcall * ou)255 f_clri(Chan *cp, Oldfcall *in, Oldfcall *ou)
256 {
257 File *f;
258
259 if(CHAT(cp)) {
260 print("c_clri %d\n", cp->chan);
261 print(" fid = %d\n", in->fid);
262 }
263
264 f = filep(cp, in->fid, 0);
265 if(!f) {
266 ou->err = Efid;
267 goto out;
268 }
269 ou->err = doclri(f);
270
271 out:
272 ou->fid = in->fid;
273 if(f)
274 qunlock(f);
275 }
276
277 int
con_clri(int fid)278 con_clri(int fid)
279 {
280 Oldfcall in, ou;
281 Chan *cp;
282
283 in.type = Tremove9p1;
284 in.fid = fid;
285 cp = cons.chan;
286
287 rlock(&mainlock);
288 ou.type = Tremove9p1+1;
289 ou.err = 0;
290
291 rlock(&cp->reflock);
292
293 f_clri(cp, &in, &ou);
294
295 runlock(&cp->reflock);
296
297 cons.work.count++;
298 runlock(&mainlock);
299 return ou.err;
300 }
301
302 int
con_swap(int fid1,int fid2)303 con_swap(int fid1, int fid2)
304 {
305 int err;
306 Iobuf *p1, *p2;
307 File *f1, *f2;
308 Dentry *d1, *d2;
309 Dentry dt1, dt2;
310 Chan *cp;
311
312 cp = cons.chan;
313 err = 0;
314 rlock(&mainlock);
315 rlock(&cp->reflock);
316
317 f2 = nil;
318 p1 = p2 = nil;
319 f1 = filep(cp, fid1, 0);
320 if(!f1){
321 err = Efid;
322 goto out;
323 }
324 p1 = getbuf(f1->fs->dev, f1->addr, Bread|Bmod);
325 d1 = getdir(p1, f1->slot);
326 if(!d1 || !(d1->mode&DALLOC)){
327 err = Ealloc;
328 goto out;
329 }
330
331 f2 = filep(cp, fid2, 0);
332 if(!f2){
333 err = Efid;
334 goto out;
335 }
336 if(memcmp(&f1->fs->dev, &f2->fs->dev, 4)==0
337 && f2->addr == f1->addr)
338 p2 = p1;
339 else
340 p2 = getbuf(f2->fs->dev, f2->addr, Bread|Bmod);
341 d2 = getdir(p2, f2->slot);
342 if(!d2 || !(d2->mode&DALLOC)){
343 err = Ealloc;
344 goto out;
345 }
346
347 dt1 = *d1;
348 dt2 = *d2;
349 *d1 = dt2;
350 *d2 = dt1;
351 memmove(d1->name, dt1.name, NAMELEN);
352 memmove(d2->name, dt2.name, NAMELEN);
353
354 mkqid(&f1->qid, d1, 1);
355 mkqid(&f2->qid, d2, 1);
356 out:
357 if(f1)
358 qunlock(f1);
359 if(f2)
360 qunlock(f2);
361 if(p1)
362 putbuf(p1);
363 if(p2 && p2!=p1)
364 putbuf(p2);
365
366 runlock(&cp->reflock);
367 cons.work.count++;
368 runlock(&mainlock);
369
370 return err;
371 }
372