xref: /plan9/sys/src/cmd/disk/kfs/console.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
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