xref: /plan9/sys/src/cmd/disk/kfs/console.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include	"all.h"
2 
3 void
4 p9fcall(Chan *cp, Fcall *in, Fcall *ou)
5 {
6 	int t;
7 
8 	rlock(&mainlock);
9 	t = in->type;
10 	if(t < 0 || t >= MAXSYSCALL || (t&1) || !p9call[t]) {
11 		print("bad message type %d\n", t);
12 		panic("");
13 	}
14 	ou->type = t+1;
15 	ou->err = 0;
16 
17 	rlock(&cp->reflock);
18 
19 	(*p9call[t])(cp, in, ou);
20 
21 	runlock(&cp->reflock);
22 
23 	cons.work.count++;
24 	runlock(&mainlock);
25 }
26 
27 int
28 con_session(void)
29 {
30 	Fcall in, ou;
31 
32 	in.type = Tsession;
33 	p9fcall(cons.chan, &in, &ou);
34 	return ou.err;
35 }
36 
37 int
38 con_attach(int fid, char *uid, char *arg)
39 {
40 	Fcall in, ou;
41 
42 	in.type = Tattach;
43 	in.fid = fid;
44 	strncpy(in.uname, uid, NAMELEN);
45 	strncpy(in.aname, arg, NAMELEN);
46 	p9fcall(cons.chan, &in, &ou);
47 	return ou.err;
48 }
49 
50 int
51 con_clone(int fid1, int fid2)
52 {
53 	Fcall in, ou;
54 
55 	in.type = Tclone;
56 	in.fid = fid1;
57 	in.newfid = fid2;
58 	p9fcall(cons.chan, &in, &ou);
59 	return ou.err;
60 }
61 
62 int
63 con_path(int fid, char *path)
64 {
65 	Fcall in, ou;
66 	char *p;
67 
68 	in.type = Twalk;
69 	in.fid = fid;
70 
71 loop:
72 	if(*path == 0)
73 		return 0;
74 	strncpy(in.name, path, NAMELEN);
75 	if(p = strchr(path, '/')) {
76 		path = p+1;
77 		if(p = strchr(in.name, '/'))
78 			*p = 0;
79 	} else
80 		path = strchr(path, 0);
81 	if(in.name[0]) {
82 		p9fcall(cons.chan, &in, &ou);
83 		if(ou.err)
84 			return ou.err;
85 	}
86 	goto loop;
87 }
88 
89 int
90 con_walk(int fid, char *name)
91 {
92 	Fcall in, ou;
93 
94 	in.type = Twalk;
95 	in.fid = fid;
96 	strncpy(in.name, name, NAMELEN);
97 	p9fcall(cons.chan, &in, &ou);
98 	return ou.err;
99 }
100 
101 int
102 con_stat(int fid, char *data)
103 {
104 	Fcall in, ou;
105 
106 	in.type = Tstat;
107 	in.fid = fid;
108 	p9fcall(cons.chan, &in, &ou);
109 	if(ou.err == 0)
110 		memmove(data, ou.stat, sizeof ou.stat);
111 	return ou.err;
112 }
113 
114 int
115 con_wstat(int fid, char *data)
116 {
117 	Fcall in, ou;
118 
119 	in.type = Twstat;
120 	in.fid = fid;
121 	memmove(in.stat, data, sizeof in.stat);
122 	p9fcall(cons.chan, &in, &ou);
123 	return ou.err;
124 }
125 
126 int
127 con_open(int fid, int mode)
128 {
129 	Fcall in, ou;
130 
131 	in.type = Topen;
132 	in.fid = fid;
133 	in.mode = mode;
134 	p9fcall(cons.chan, &in, &ou);
135 	return ou.err;
136 }
137 
138 int
139 con_read(int fid, char *data, long offset, int count)
140 {
141 	Fcall in, ou;
142 
143 	in.type = Tread;
144 	in.fid = fid;
145 	in.offset = offset;
146 	in.count = count;
147 	ou.data = data;
148 	p9fcall(cons.chan, &in, &ou);
149 	if(ou.err)
150 		return 0;
151 	return ou.count;
152 }
153 
154 int
155 con_write(int fid, char *data, long offset, int count)
156 {
157 	Fcall in, ou;
158 
159 	in.type = Twrite;
160 	in.fid = fid;
161 	in.data = data;
162 	in.offset = offset;
163 	in.count = count;
164 	p9fcall(cons.chan, &in, &ou);
165 	if(ou.err)
166 		return 0;
167 	return ou.count;
168 }
169 
170 int
171 con_remove(int fid)
172 {
173 	Fcall in, ou;
174 
175 	in.type = Tremove;
176 	in.fid = fid;
177 	p9fcall(cons.chan, &in, &ou);
178 	return ou.err;
179 }
180 
181 int
182 con_create(int fid, char *name, int uid, int gid, long perm, int mode)
183 {
184 	Fcall in, ou;
185 
186 	in.type = Tcreate;
187 	in.fid = fid;
188 	strncpy(in.name, name, NAMELEN);
189 	in.perm = perm;
190 	in.mode = mode;
191 	cons.uid = uid;			/* beyond ugly */
192 	cons.gid = gid;
193 	p9fcall(cons.chan, &in, &ou);
194 	return ou.err;
195 }
196 
197 int
198 doclri(File *f)
199 {
200 	Iobuf *p, *p1;
201 	Dentry *d, *d1;
202 	int err;
203 
204 	err = 0;
205 	p = 0;
206 	p1 = 0;
207 	if(isro(f->fs->dev)) {
208 		err = Eronly;
209 		goto out;
210 	}
211 	/*
212 	 * check on parent directory of file to be deleted
213 	 */
214 	if(f->wpath == 0 || f->wpath->addr == f->addr) {
215 		err = Ephase;
216 		goto out;
217 	}
218 	p1 = getbuf(f->fs->dev, f->wpath->addr, Bread);
219 	d1 = getdir(p1, f->wpath->slot);
220 	if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
221 		err = Ephase;
222 		goto out;
223 	}
224 
225 	accessdir(p1, d1, FWRITE);
226 	putbuf(p1);
227 	p1 = 0;
228 
229 	/*
230 	 * check on file to be deleted
231 	 */
232 	p = getbuf(f->fs->dev, f->addr, Bread);
233 	d = getdir(p, f->slot);
234 
235 
236 	/*
237 	 * do it
238 	 */
239 	memset(d, 0, sizeof(Dentry));
240 	settag(p, Tdir, QPNONE);
241 	freewp(f->wpath);
242 	freefp(f);
243 
244 out:
245 	if(p1)
246 		putbuf(p1);
247 	if(p)
248 		putbuf(p);
249 	return err;
250 }
251 
252 void
253 f_clri(Chan *cp, Fcall *in, Fcall *ou)
254 {
255 	File *f;
256 
257 	if(CHAT(cp)) {
258 		print("c_clri %d\n", cp->chan);
259 		print("	fid = %d\n", in->fid);
260 	}
261 
262 	f = filep(cp, in->fid, 0);
263 	if(!f) {
264 		ou->err = Efid;
265 		goto out;
266 	}
267 	ou->err = doclri(f);
268 
269 out:
270 	ou->fid = in->fid;
271 	if(f)
272 		qunlock(f);
273 }
274 
275 int
276 con_clri(int fid)
277 {
278 	Fcall in, ou;
279 	Chan *cp;
280 
281 	in.type = Tremove;
282 	in.fid = fid;
283 	cp = cons.chan;
284 
285 	rlock(&mainlock);
286 	ou.type = Tremove+1;
287 	ou.err = 0;
288 
289 	rlock(&cp->reflock);
290 
291 	f_clri(cp, &in, &ou);
292 
293 	runlock(&cp->reflock);
294 
295 	cons.work.count++;
296 	runlock(&mainlock);
297 	return ou.err;
298 }
299