Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/src/cmd/9nfs/nfs.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "all.h"
2
 
3
extern uchar buf[];
4
 
5
Xfid *
6
rpc2xfid(Rpccall *cmd, Dir *dp)
7
{
8
	char *argptr = cmd->args;
9
	Xfile *xp;
10
	Xfid *xf;
11
	Session *s;
12
	char *service;
13
	Authunix au;
14
	Qid qid;
15
	char client[256], *user;
16
	Unixidmap *m;
17
	int i;
18
	uvlong x1, x2;
19
 
20
	chat("rpc2xfid %.8lux %.8lux %p %p\n", *((ulong*)argptr), *((ulong*)argptr+1), buf, argptr);
21
	if(argptr[0] == 0 && argptr[1] == 0){	/* root */
22
		chat("root...");
23
		xp = xfroot(&argptr[2], 0);
24
		s = xp ? xp->s : 0;
25
	}else{
26
		ulong ul;
27
		chat("noroot %.8lux...", *((ulong*)argptr));
28
		if((ul=GLONG()) != starttime){
29
			chat("bad tag %lux %lux...", ul, starttime);
30
			return 0;
31
		}
32
		s = (Session *)GLONG();
33
		x1 = GLONG();
34
		x2 = GLONG();
35
		qid.path = x1 | (x2<<32);
36
		qid.vers = 0;
37
		qid.type = GBYTE();
38
		xp = xfile(&qid, s, 0);
39
	}
40
	if(xp == 0){
41
		chat("no xfile...");
42
		return 0;
43
	}
44
	if(auth2unix(&cmd->cred, &au) != 0){
45
		chat("auth flavor=%ld, count=%ld\n",
46
			cmd->cred.flavor, cmd->cred.count);
47
		for(i=0; i<cmd->cred.count; i++)
48
			chat(" %.2ux", ((uchar *)cmd->cred.data)[i]);
49
		chat("...");
50
		return 0;
51
	}else{
52
/*		chat("auth: %d %.*s u=%d g=%d",
53
 *			au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid);
54
 *		for(i=0; i<au.gidlen; i++)
55
 *			chat(", %d", au.gids[i]);
56
 *		chat("...");
57
 */
58
		char *p = memchr(au.mach.s, '.', au.mach.n);
59
		chat("%ld@%.*s...", au.uid, utfnlen(au.mach.s, (p ? p-au.mach.s : au.mach.n)), au.mach.s);
60
	}
61
	if(au.mach.n >= sizeof client){
62
		chat("client name too long...");
63
		return 0;
64
	}
65
	memcpy(client, au.mach.s, au.mach.n);
66
	client[au.mach.n] = 0;
67
	service = xp->parent->s->service;
68
	cmd->up = m = pair2idmap(service, cmd->host);
69
	if(m == 0){
70
		chat("no map for pair (%s,%s)...", service, client);
71
		/*chat("getdom %d.%d.%d.%d", cmd->host&0xFF, (cmd->host>>8)&0xFF,
72
			(cmd->host>>16)&0xFF, (cmd->host>>24)&0xFF);/**/
73
		/*if(getdom(cmd->host, client, sizeof(client))<0)
74
			return 0;/**/
75
		return 0;
76
	}
77
	/*chat("map=(%s,%s)...", m->server, m->client);/**/
78
	cmd->user = user = id2name(&m->u.ids, au.uid);
79
	if(user == 0){
80
		chat("no user for id %ld...", au.uid);
81
		return 0;
82
	}
83
	chat("user=%s...", user);/**/
84
	xf = 0;
85
	if(s == xp->parent->s){
86
		if(!s->noauth)
87
			xf = setuser(xp, user);
88
		if(xf == 0)
89
			xf = setuser(xp, "none");
90
		if(xf == 0)
91
			chat("can't set user none...");
92
	}else
93
		xf = xp->users;
94
	if(xf)
95
		chat("uid=%s...", xf->uid);
96
	if(xf && dp && xfstat(xf, dp) < 0){
97
		chat("can't stat %s...", xp->name);
98
		return 0;
99
	}
100
	return xf;
101
}
102
 
103
Xfid *
104
setuser(Xfile *xp, char *user)
105
{
106
	Xfid *xf, *xpf;
107
	Session *s;
108
 
109
	xf = xfid(user, xp, 1);
110
	if(xf->urfid)
111
		return xf;
112
	if(xp->parent==xp || !(xpf = setuser(xp->parent, user))) /* assign = */
113
		return xfid(user, xp, -1);
114
	s = xp->s;
115
	xf->urfid = newfid(s);
116
	xf->urfid->owner = &xf->urfid;
117
	setfid(s, xpf->urfid);
118
	s->f.newfid = xf->urfid - s->fids;
119
	s->f.nwname = 1;
120
	s->f.wname[0] = xp->name;
121
	if(xmesg(s, Twalk) || s->f.nwqid != 1)
122
		return xfid(user, xp, -1);
123
	return xf;
124
}
125
 
126
int
127
xfstat(Xfid *xf, Dir *dp)
128
{
129
	Xfile *xp;
130
	Session *s;
131
	char buf[128];
132
 
133
	xp = xf->xp;
134
	s = xp->s;
135
	if(s != xp->parent->s){
136
		seprint(buf, buf+sizeof buf, "#%s", xf->uid);
137
		dp->name = strstore(buf);
138
		dp->uid = xf->uid;
139
		dp->gid = xf->uid;
140
		dp->muid = xf->uid;
141
		dp->qid.path = (uvlong)xf->uid;
142
		dp->qid.type = QTFILE;
143
		dp->qid.vers = 0;
144
		dp->mode = 0666;
145
		dp->atime = time(0);
146
		dp->mtime = dp->atime;
147
		dp->length = NETCHLEN;
148
		dp->type = 0;
149
		dp->type = 0;
150
		return 0;
151
	}
152
	setfid(s, xf->urfid);
153
	if(xmesg(s, Tstat) == 0){
154
		convM2D(s->f.stat, s->f.nstat, dp, (char*)s->statbuf);
155
		if(xp->qid.path == dp->qid.path){
156
			xp->name = strstore(dp->name);
157
			return 0;
158
		}
159
		/* not reached ? */
160
		chat("xp->qid.path=0x%.16llux, dp->qid.path=0x%.16llux name=%s...",
161
			xp->qid.path, dp->qid.path, dp->name);
162
	}
163
	if(xp != xp->parent)
164
		xpclear(xp);
165
	else
166
		clog("can't stat root: %s",
167
			s->f.type == Rerror ? s->f.ename : "??");
168
	return -1;
169
}
170
 
171
int
172
xfwstat(Xfid *xf, Dir *dp)
173
{
174
	Xfile *xp;
175
	Session *s;
176
 
177
	xp = xf->xp;
178
	s = xp->s;
179
 
180
	/*
181
	 * xf->urfid can be zero because some DOS NFS clients
182
	 * try to do wstat on the #user authentication files on close.
183
	 */
184
	if(s == 0 || xf->urfid == 0)
185
		return -1;
186
	setfid(s, xf->urfid);
187
	s->f.stat = s->statbuf;
188
	convD2M(dp, s->f.stat, Maxstatdata);
189
	if(xmesg(s, Twstat))
190
		return -1;
191
	xp->name = strstore(dp->name);
192
	return 0;
193
}
194
 
195
int
196
xfopen(Xfid *xf, int flag)
197
{
198
	static int modes[] = {
199
		[Oread] OREAD, [Owrite] OWRITE, [Oread|Owrite] ORDWR,
200
	};
201
	Xfile *xp;
202
	Session *s;
203
	Fid *opfid;
204
	int omode;
205
 
206
	if(xf->opfid && (xf->mode & flag & Open) == flag)
207
		return 0;
208
	omode = modes[(xf->mode|flag) & Open];
209
	if(flag & Trunc)
210
		omode |= OTRUNC;
211
	xp = xf->xp;
212
	chat("open(\"%s\", %d)...", xp->name, omode);
213
	s = xp->s;
214
	opfid = newfid(s);
215
	setfid(s, xf->urfid);
216
	s->f.newfid = opfid - s->fids;
217
	s->f.nwname = 0;
218
	if(xmesg(s, Twalk)){
219
		putfid(s, opfid);
220
		return -1;
221
	}
222
	setfid(s, opfid);
223
	s->f.mode = omode;
224
	if(xmesg(s, Topen)){
225
		clunkfid(s, opfid);
226
		return -1;
227
	}
228
	if(xf->opfid)
229
		clunkfid(s, xf->opfid);
230
	xf->mode |= flag & Open;
231
	xf->opfid = opfid;
232
	opfid->owner = &xf->opfid;
233
	xf->offset = 0;
234
	return 0;
235
}
236
 
237
void
238
xfclose(Xfid *xf)
239
{
240
	Xfile *xp;
241
 
242
	if(xf->mode & Open){
243
		xp = xf->xp;
244
		chat("close(\"%s\")...", xp->name);
245
		if(xf->opfid)
246
			clunkfid(xp->s, xf->opfid);
247
		xf->mode &= ~Open;
248
		xf->opfid = 0;
249
	}
250
}
251
 
252
void
253
xfclear(Xfid *xf)
254
{
255
	Xfile *xp = xf->xp;
256
 
257
	if(xf->opfid){
258
		clunkfid(xp->s, xf->opfid);
259
		xf->opfid = 0;
260
	}
261
	if(xf->urfid){
262
		clunkfid(xp->s, xf->urfid);
263
		xf->urfid = 0;
264
	}
265
	xfid(xf->uid, xp, -1);
266
}
267
 
268
Xfid *
269
xfwalkcr(int type, Xfid *xf, String *elem, long perm)
270
{
271
	Session *s;
272
	Xfile *xp, *newxp;
273
	Xfid *newxf;
274
	Fid *nfid;
275
 
276
	chat("xf%s(\"%s\")...", type==Tcreate ? "create" : "walk", elem->s);
277
	xp = xf->xp;
278
	s = xp->s;
279
	nfid = newfid(s);
280
	setfid(s, xf->urfid);
281
	s->f.newfid = nfid - s->fids;
282
	if(type == Tcreate){
283
		s->f.nwname = 0;
284
		if(xmesg(s, Twalk)){
285
			putfid(s, nfid);
286
			return 0;
287
		}
288
		s->f.fid = nfid - s->fids;
289
	}
290
	if(type == Tcreate){
291
		s->f.name = elem->s;
292
		s->f.perm = perm;
293
		s->f.mode = (perm&DMDIR) ? OREAD : ORDWR;
294
		if(xmesg(s, type)){
295
			clunkfid(s, nfid);
296
			return 0;
297
		}
298
	}else{	/* Twalk */
299
		s->f.nwname = 1;
300
		s->f.wname[0] = elem->s;
301
		if(xmesg(s, type) || s->f.nwqid!=1){
302
			putfid(s, nfid);
303
			return 0;
304
		}
305
		s->f.qid = s->f.wqid[0];	/* only one element */
306
	}
307
	chat("fid=%d,qid=0x%llux,%ld,%.2ux...", s->f.fid, s->f.qid.path, s->f.qid.vers, s->f.qid.type);
308
	newxp = xfile(&s->f.qid, s, 1);
309
	if(newxp->parent == 0){
310
		chat("new xfile...");
311
		newxp->parent = xp;
312
		newxp->sib = xp->child;
313
		xp->child = newxp;
314
	}
315
	newxf = xfid(xf->uid, newxp, 1);
316
	if(type == Tcreate){
317
		newxf->mode = (perm&DMDIR) ? Oread : (Oread|Owrite);
318
		newxf->opfid = nfid;
319
		nfid->owner = &newxf->opfid;
320
		nfid = newfid(s);
321
		setfid(s, xf->urfid);
322
		s->f.newfid = nfid - s->fids;
323
		s->f.nwname = 1;
324
		s->f.wname[0] = elem->s;
325
		if(xmesg(s, Twalk) || s->f.nwqid!=1){
326
			putfid(s, nfid);
327
			xpclear(newxp);
328
			return 0;
329
		}
330
		newxf->urfid = nfid;
331
		nfid->owner = &newxf->urfid;
332
	}else if(newxf->urfid){
333
		chat("old xfid %ld...", newxf->urfid-s->fids);
334
		clunkfid(s, nfid);
335
	}else{
336
		newxf->urfid = nfid;
337
		nfid->owner = &newxf->urfid;
338
	}
339
	newxp->name = strstore(elem->s);
340
	return newxf;
341
}
342
 
343
void
344
xpclear(Xfile *xp)
345
{
346
	Session *s;
347
	Xfid *xf;
348
	Xfile *xnp;
349
 
350
	s = xp->s;
351
	while(xf = xp->users)	/* assign = */
352
		xfclear(xf);
353
	while(xnp = xp->child){	/* assign = */
354
		xp->child = xnp->sib;
355
		xnp->parent = 0;
356
		xpclear(xnp);
357
		xfile(&xnp->qid, s, -1);
358
	}
359
	if(xnp = xp->parent){	/* assign = */
360
		if(xnp->child == xp)
361
			xnp->child = xp->sib;
362
		else{
363
			xnp = xnp->child;
364
			while(xnp->sib != xp)
365
				xnp = xnp->sib;
366
			xnp->sib = xp->sib;
367
		}
368
		xfile(&xp->qid, s, -1);
369
	}
370
}
371
 
372
int
373
xp2fhandle(Xfile *xp, Fhandle fh)
374
{
375
	uchar *dataptr = fh;
376
	ulong x;
377
	int n;
378
 
379
	memset(fh, 0, FHSIZE);
380
	if(xp == xp->parent){	/* root */
381
		dataptr[0] = 0;
382
		dataptr[1] = 0;
383
		n = strlen(xp->s->service);
384
		if(n > FHSIZE-3)
385
			n = FHSIZE-3;
386
		memmove(&dataptr[2], xp->s->service, n);
387
		dataptr[2+n] = 0;
388
	}else{
389
		PLONG(starttime);
390
		PLONG((u32int)(uintptr)xp->s);
391
		x = xp->qid.path;
392
		PLONG(x);
393
		x = xp->qid.path>>32;
394
		PLONG(x);
395
		PBYTE(xp->qid.type);
396
		USED(dataptr);
397
	}
398
	return FHSIZE;
399
}
400
 
401
int
402
dir2fattr(Unixidmap *up, Dir *dp, void *mp)
403
{
404
	uchar *dataptr = mp;
405
	long length;
406
	int r;
407
 
408
	r = dp->mode & 0777;
409
	if (dp->mode & DMDIR)
410
		length = 1024;
411
	else
412
		length = dp->length;
413
	if((dp->mode & DMDIR) && dp->type == '/' && dp->dev == 0)
414
		r |= 0555;
415
	if(dp->mode & DMDIR){
416
		PLONG(NFDIR);	/* type */
417
		r |= S_IFDIR;
418
		PLONG(r);	/* mode */
419
		PLONG(3);	/* nlink */
420
	}else{
421
		PLONG(NFREG);	/* type */
422
		r |= S_IFREG;
423
		PLONG(r);	/* mode */
424
		PLONG(1);	/* nlink */
425
	}
426
	r = name2id(&up->u.ids, dp->uid);
427
	if(r < 0){
428
		r = name2id(&up->u.ids, "daemon");
429
		if(r < 0)
430
			r = 1;
431
	}
432
	PLONG(r);		/* uid */
433
	r = name2id(&up->g.ids, dp->gid);
434
	if(r < 0){
435
		r = name2id(&up->g.ids, "user");
436
		if(r < 0)
437
			r = 1;
438
	}
439
	PLONG(r);		/* gid */
440
	PLONG(length);		/* size */
441
	PLONG(2048);		/* blocksize */
442
	PLONG(0);		/* rdev */
443
	r = (length+2047)/2048;
444
	PLONG(r);		/* blocks */
445
	r = (dp->type<<16) | dp->dev;
446
	PLONG(r);		/* fsid */
447
	PLONG(dp->qid.path);	/* fileid */
448
	PLONG(dp->atime);	/* atime */
449
	PLONG(0);
450
	PLONG(dp->mtime);	/* mtime */
451
	PLONG(0);
452
	PLONG(dp->mtime);	/* ctime */
453
	PLONG(0);
454
	return dataptr - (uchar *)mp;
455
}
456
 
457
int
458
convM2sattr(void *mp, Sattr *sp)
459
{
460
	uchar *argptr = mp;
461
 
462
	sp->mode = GLONG();
463
	sp->uid = GLONG();
464
	sp->gid = GLONG();
465
	sp->size = GLONG();
466
	sp->atime = GLONG();
467
	sp->ausec = GLONG();
468
	sp->mtime = GLONG();
469
	sp->musec = GLONG();
470
	return argptr - (uchar *)mp;
471
}