Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"all.h"
2
#include	"9p1.h"
3
 
4
void
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
}