xref: /plan9/sys/src/cmd/9nfs/nfs.c (revision 4de34a7edde43207e841ec91ecd12e6cf5f5ebe7)
19a747e4fSDavid du Colombier #include "all.h"
29a747e4fSDavid du Colombier 
39a747e4fSDavid du Colombier extern uchar buf[];
49a747e4fSDavid du Colombier 
59a747e4fSDavid du Colombier Xfid *
rpc2xfid(Rpccall * cmd,Dir * dp)69a747e4fSDavid du Colombier rpc2xfid(Rpccall *cmd, Dir *dp)
79a747e4fSDavid du Colombier {
89a747e4fSDavid du Colombier 	char *argptr = cmd->args;
99a747e4fSDavid du Colombier 	Xfile *xp;
109a747e4fSDavid du Colombier 	Xfid *xf;
119a747e4fSDavid du Colombier 	Session *s;
129a747e4fSDavid du Colombier 	char *service;
139a747e4fSDavid du Colombier 	Authunix au;
149a747e4fSDavid du Colombier 	Qid qid;
159a747e4fSDavid du Colombier 	char client[256], *user;
169a747e4fSDavid du Colombier 	Unixidmap *m;
179a747e4fSDavid du Colombier 	int i;
189a747e4fSDavid du Colombier 	uvlong x1, x2;
199a747e4fSDavid du Colombier 
209a747e4fSDavid du Colombier 	chat("rpc2xfid %.8lux %.8lux %p %p\n", *((ulong*)argptr), *((ulong*)argptr+1), buf, argptr);
219a747e4fSDavid du Colombier 	if(argptr[0] == 0 && argptr[1] == 0){	/* root */
229a747e4fSDavid du Colombier 		chat("root...");
239a747e4fSDavid du Colombier 		xp = xfroot(&argptr[2], 0);
249a747e4fSDavid du Colombier 		s = xp ? xp->s : 0;
259a747e4fSDavid du Colombier 	}else{
269a747e4fSDavid du Colombier 		ulong ul;
279a747e4fSDavid du Colombier 		chat("noroot %.8lux...", *((ulong*)argptr));
289a747e4fSDavid du Colombier 		if((ul=GLONG()) != starttime){
299a747e4fSDavid du Colombier 			chat("bad tag %lux %lux...", ul, starttime);
309a747e4fSDavid du Colombier 			return 0;
319a747e4fSDavid du Colombier 		}
329a747e4fSDavid du Colombier 		s = (Session *)GLONG();
339a747e4fSDavid du Colombier 		x1 = GLONG();
349a747e4fSDavid du Colombier 		x2 = GLONG();
359a747e4fSDavid du Colombier 		qid.path = x1 | (x2<<32);
369a747e4fSDavid du Colombier 		qid.vers = 0;
379a747e4fSDavid du Colombier 		qid.type = GBYTE();
389a747e4fSDavid du Colombier 		xp = xfile(&qid, s, 0);
399a747e4fSDavid du Colombier 	}
409a747e4fSDavid du Colombier 	if(xp == 0){
419a747e4fSDavid du Colombier 		chat("no xfile...");
429a747e4fSDavid du Colombier 		return 0;
439a747e4fSDavid du Colombier 	}
449a747e4fSDavid du Colombier 	if(auth2unix(&cmd->cred, &au) != 0){
459a747e4fSDavid du Colombier 		chat("auth flavor=%ld, count=%ld\n",
469a747e4fSDavid du Colombier 			cmd->cred.flavor, cmd->cred.count);
479a747e4fSDavid du Colombier 		for(i=0; i<cmd->cred.count; i++)
489a747e4fSDavid du Colombier 			chat(" %.2ux", ((uchar *)cmd->cred.data)[i]);
499a747e4fSDavid du Colombier 		chat("...");
509a747e4fSDavid du Colombier 		return 0;
519a747e4fSDavid du Colombier 	}else{
529a747e4fSDavid du Colombier /*		chat("auth: %d %.*s u=%d g=%d",
539a747e4fSDavid du Colombier  *			au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid);
549a747e4fSDavid du Colombier  *		for(i=0; i<au.gidlen; i++)
559a747e4fSDavid du Colombier  *			chat(", %d", au.gids[i]);
569a747e4fSDavid du Colombier  *		chat("...");
579a747e4fSDavid du Colombier  */
589a747e4fSDavid du Colombier 		char *p = memchr(au.mach.s, '.', au.mach.n);
599a747e4fSDavid du Colombier 		chat("%ld@%.*s...", au.uid, utfnlen(au.mach.s, (p ? p-au.mach.s : au.mach.n)), au.mach.s);
609a747e4fSDavid du Colombier 	}
619a747e4fSDavid du Colombier 	if(au.mach.n >= sizeof client){
629a747e4fSDavid du Colombier 		chat("client name too long...");
639a747e4fSDavid du Colombier 		return 0;
649a747e4fSDavid du Colombier 	}
659a747e4fSDavid du Colombier 	memcpy(client, au.mach.s, au.mach.n);
669a747e4fSDavid du Colombier 	client[au.mach.n] = 0;
679a747e4fSDavid du Colombier 	service = xp->parent->s->service;
689a747e4fSDavid du Colombier 	cmd->up = m = pair2idmap(service, cmd->host);
699a747e4fSDavid du Colombier 	if(m == 0){
709a747e4fSDavid du Colombier 		chat("no map for pair (%s,%s)...", service, client);
719a747e4fSDavid du Colombier 		/*chat("getdom %d.%d.%d.%d", cmd->host&0xFF, (cmd->host>>8)&0xFF,
729a747e4fSDavid du Colombier 			(cmd->host>>16)&0xFF, (cmd->host>>24)&0xFF);/**/
739a747e4fSDavid du Colombier 		/*if(getdom(cmd->host, client, sizeof(client))<0)
749a747e4fSDavid du Colombier 			return 0;/**/
759a747e4fSDavid du Colombier 		return 0;
769a747e4fSDavid du Colombier 	}
779a747e4fSDavid du Colombier 	/*chat("map=(%s,%s)...", m->server, m->client);/**/
789a747e4fSDavid du Colombier 	cmd->user = user = id2name(&m->u.ids, au.uid);
799a747e4fSDavid du Colombier 	if(user == 0){
809a747e4fSDavid du Colombier 		chat("no user for id %ld...", au.uid);
819a747e4fSDavid du Colombier 		return 0;
829a747e4fSDavid du Colombier 	}
839a747e4fSDavid du Colombier 	chat("user=%s...", user);/**/
849a747e4fSDavid du Colombier 	xf = 0;
859a747e4fSDavid du Colombier 	if(s == xp->parent->s){
869a747e4fSDavid du Colombier 		if(!s->noauth)
879a747e4fSDavid du Colombier 			xf = setuser(xp, user);
889a747e4fSDavid du Colombier 		if(xf == 0)
899a747e4fSDavid du Colombier 			xf = setuser(xp, "none");
909a747e4fSDavid du Colombier 		if(xf == 0)
919a747e4fSDavid du Colombier 			chat("can't set user none...");
929a747e4fSDavid du Colombier 	}else
939a747e4fSDavid du Colombier 		xf = xp->users;
949a747e4fSDavid du Colombier 	if(xf)
959a747e4fSDavid du Colombier 		chat("uid=%s...", xf->uid);
969a747e4fSDavid du Colombier 	if(xf && dp && xfstat(xf, dp) < 0){
979a747e4fSDavid du Colombier 		chat("can't stat %s...", xp->name);
989a747e4fSDavid du Colombier 		return 0;
999a747e4fSDavid du Colombier 	}
1009a747e4fSDavid du Colombier 	return xf;
1019a747e4fSDavid du Colombier }
1029a747e4fSDavid du Colombier 
1039a747e4fSDavid du Colombier Xfid *
setuser(Xfile * xp,char * user)1049a747e4fSDavid du Colombier setuser(Xfile *xp, char *user)
1059a747e4fSDavid du Colombier {
1069a747e4fSDavid du Colombier 	Xfid *xf, *xpf;
1079a747e4fSDavid du Colombier 	Session *s;
1089a747e4fSDavid du Colombier 
1099a747e4fSDavid du Colombier 	xf = xfid(user, xp, 1);
1109a747e4fSDavid du Colombier 	if(xf->urfid)
1119a747e4fSDavid du Colombier 		return xf;
1129a747e4fSDavid du Colombier 	if(xp->parent==xp || !(xpf = setuser(xp->parent, user))) /* assign = */
1139a747e4fSDavid du Colombier 		return xfid(user, xp, -1);
1149a747e4fSDavid du Colombier 	s = xp->s;
1159a747e4fSDavid du Colombier 	xf->urfid = newfid(s);
1169a747e4fSDavid du Colombier 	xf->urfid->owner = &xf->urfid;
1179a747e4fSDavid du Colombier 	setfid(s, xpf->urfid);
1189a747e4fSDavid du Colombier 	s->f.newfid = xf->urfid - s->fids;
1199a747e4fSDavid du Colombier 	s->f.nwname = 1;
1209a747e4fSDavid du Colombier 	s->f.wname[0] = xp->name;
1219a747e4fSDavid du Colombier 	if(xmesg(s, Twalk) || s->f.nwqid != 1)
1229a747e4fSDavid du Colombier 		return xfid(user, xp, -1);
1239a747e4fSDavid du Colombier 	return xf;
1249a747e4fSDavid du Colombier }
1259a747e4fSDavid du Colombier 
1269a747e4fSDavid du Colombier int
xfstat(Xfid * xf,Dir * dp)1279a747e4fSDavid du Colombier xfstat(Xfid *xf, Dir *dp)
1289a747e4fSDavid du Colombier {
1299a747e4fSDavid du Colombier 	Xfile *xp;
1309a747e4fSDavid du Colombier 	Session *s;
1319a747e4fSDavid du Colombier 	char buf[128];
1329a747e4fSDavid du Colombier 
1339a747e4fSDavid du Colombier 	xp = xf->xp;
1349a747e4fSDavid du Colombier 	s = xp->s;
1359a747e4fSDavid du Colombier 	if(s != xp->parent->s){
1369a747e4fSDavid du Colombier 		seprint(buf, buf+sizeof buf, "#%s", xf->uid);
1379a747e4fSDavid du Colombier 		dp->name = strstore(buf);
1389a747e4fSDavid du Colombier 		dp->uid = xf->uid;
1399a747e4fSDavid du Colombier 		dp->gid = xf->uid;
1409a747e4fSDavid du Colombier 		dp->muid = xf->uid;
1415e91980fSDavid du Colombier 		dp->qid.path = (uvlong)xf->uid;
1429a747e4fSDavid du Colombier 		dp->qid.type = QTFILE;
1439a747e4fSDavid du Colombier 		dp->qid.vers = 0;
1449a747e4fSDavid du Colombier 		dp->mode = 0666;
1459a747e4fSDavid du Colombier 		dp->atime = time(0);
1469a747e4fSDavid du Colombier 		dp->mtime = dp->atime;
1479a747e4fSDavid du Colombier 		dp->length = NETCHLEN;
1489a747e4fSDavid du Colombier 		dp->type = 0;
1499a747e4fSDavid du Colombier 		dp->type = 0;
1509a747e4fSDavid du Colombier 		return 0;
1519a747e4fSDavid du Colombier 	}
1529a747e4fSDavid du Colombier 	setfid(s, xf->urfid);
1539a747e4fSDavid du Colombier 	if(xmesg(s, Tstat) == 0){
1549a747e4fSDavid du Colombier 		convM2D(s->f.stat, s->f.nstat, dp, (char*)s->statbuf);
1559a747e4fSDavid du Colombier 		if(xp->qid.path == dp->qid.path){
1569a747e4fSDavid du Colombier 			xp->name = strstore(dp->name);
1579a747e4fSDavid du Colombier 			return 0;
1589a747e4fSDavid du Colombier 		}
1599a747e4fSDavid du Colombier 		/* not reached ? */
1609a747e4fSDavid du Colombier 		chat("xp->qid.path=0x%.16llux, dp->qid.path=0x%.16llux name=%s...",
1619a747e4fSDavid du Colombier 			xp->qid.path, dp->qid.path, dp->name);
1629a747e4fSDavid du Colombier 	}
1639a747e4fSDavid du Colombier 	if(xp != xp->parent)
1649a747e4fSDavid du Colombier 		xpclear(xp);
1659a747e4fSDavid du Colombier 	else
1669a747e4fSDavid du Colombier 		clog("can't stat root: %s",
1679a747e4fSDavid du Colombier 			s->f.type == Rerror ? s->f.ename : "??");
1689a747e4fSDavid du Colombier 	return -1;
1699a747e4fSDavid du Colombier }
1709a747e4fSDavid du Colombier 
1719a747e4fSDavid du Colombier int
xfwstat(Xfid * xf,Dir * dp)1729a747e4fSDavid du Colombier xfwstat(Xfid *xf, Dir *dp)
1739a747e4fSDavid du Colombier {
1749a747e4fSDavid du Colombier 	Xfile *xp;
1759a747e4fSDavid du Colombier 	Session *s;
1769a747e4fSDavid du Colombier 
1779a747e4fSDavid du Colombier 	xp = xf->xp;
1789a747e4fSDavid du Colombier 	s = xp->s;
1799a747e4fSDavid du Colombier 
1809a747e4fSDavid du Colombier 	/*
1819a747e4fSDavid du Colombier 	 * xf->urfid can be zero because some DOS NFS clients
1829a747e4fSDavid du Colombier 	 * try to do wstat on the #user authentication files on close.
1839a747e4fSDavid du Colombier 	 */
1849a747e4fSDavid du Colombier 	if(s == 0 || xf->urfid == 0)
1859a747e4fSDavid du Colombier 		return -1;
1869a747e4fSDavid du Colombier 	setfid(s, xf->urfid);
1879a747e4fSDavid du Colombier 	s->f.stat = s->statbuf;
1889a747e4fSDavid du Colombier 	convD2M(dp, s->f.stat, Maxstatdata);
1899a747e4fSDavid du Colombier 	if(xmesg(s, Twstat))
1909a747e4fSDavid du Colombier 		return -1;
1919a747e4fSDavid du Colombier 	xp->name = strstore(dp->name);
1929a747e4fSDavid du Colombier 	return 0;
1939a747e4fSDavid du Colombier }
1949a747e4fSDavid du Colombier 
1959a747e4fSDavid du Colombier int
xfopen(Xfid * xf,int flag)1969a747e4fSDavid du Colombier xfopen(Xfid *xf, int flag)
1979a747e4fSDavid du Colombier {
1989a747e4fSDavid du Colombier 	static int modes[] = {
1999a747e4fSDavid du Colombier 		[Oread] OREAD, [Owrite] OWRITE, [Oread|Owrite] ORDWR,
2009a747e4fSDavid du Colombier 	};
2019a747e4fSDavid du Colombier 	Xfile *xp;
2029a747e4fSDavid du Colombier 	Session *s;
2039a747e4fSDavid du Colombier 	Fid *opfid;
2049a747e4fSDavid du Colombier 	int omode;
2059a747e4fSDavid du Colombier 
2069a747e4fSDavid du Colombier 	if(xf->opfid && (xf->mode & flag & Open) == flag)
2079a747e4fSDavid du Colombier 		return 0;
2089a747e4fSDavid du Colombier 	omode = modes[(xf->mode|flag) & Open];
2099a747e4fSDavid du Colombier 	if(flag & Trunc)
2109a747e4fSDavid du Colombier 		omode |= OTRUNC;
2119a747e4fSDavid du Colombier 	xp = xf->xp;
2129a747e4fSDavid du Colombier 	chat("open(\"%s\", %d)...", xp->name, omode);
2139a747e4fSDavid du Colombier 	s = xp->s;
2149a747e4fSDavid du Colombier 	opfid = newfid(s);
2159a747e4fSDavid du Colombier 	setfid(s, xf->urfid);
2169a747e4fSDavid du Colombier 	s->f.newfid = opfid - s->fids;
2179a747e4fSDavid du Colombier 	s->f.nwname = 0;
2189a747e4fSDavid du Colombier 	if(xmesg(s, Twalk)){
2199a747e4fSDavid du Colombier 		putfid(s, opfid);
2209a747e4fSDavid du Colombier 		return -1;
2219a747e4fSDavid du Colombier 	}
2229a747e4fSDavid du Colombier 	setfid(s, opfid);
2239a747e4fSDavid du Colombier 	s->f.mode = omode;
2249a747e4fSDavid du Colombier 	if(xmesg(s, Topen)){
2259a747e4fSDavid du Colombier 		clunkfid(s, opfid);
2269a747e4fSDavid du Colombier 		return -1;
2279a747e4fSDavid du Colombier 	}
2289a747e4fSDavid du Colombier 	if(xf->opfid)
2299a747e4fSDavid du Colombier 		clunkfid(s, xf->opfid);
2309a747e4fSDavid du Colombier 	xf->mode |= flag & Open;
2319a747e4fSDavid du Colombier 	xf->opfid = opfid;
2329a747e4fSDavid du Colombier 	opfid->owner = &xf->opfid;
2339a747e4fSDavid du Colombier 	xf->offset = 0;
2349a747e4fSDavid du Colombier 	return 0;
2359a747e4fSDavid du Colombier }
2369a747e4fSDavid du Colombier 
2379a747e4fSDavid du Colombier void
xfclose(Xfid * xf)2389a747e4fSDavid du Colombier xfclose(Xfid *xf)
2399a747e4fSDavid du Colombier {
2409a747e4fSDavid du Colombier 	Xfile *xp;
2419a747e4fSDavid du Colombier 
2429a747e4fSDavid du Colombier 	if(xf->mode & Open){
2439a747e4fSDavid du Colombier 		xp = xf->xp;
2449a747e4fSDavid du Colombier 		chat("close(\"%s\")...", xp->name);
2459a747e4fSDavid du Colombier 		if(xf->opfid)
2469a747e4fSDavid du Colombier 			clunkfid(xp->s, xf->opfid);
2479a747e4fSDavid du Colombier 		xf->mode &= ~Open;
2489a747e4fSDavid du Colombier 		xf->opfid = 0;
2499a747e4fSDavid du Colombier 	}
2509a747e4fSDavid du Colombier }
2519a747e4fSDavid du Colombier 
2529a747e4fSDavid du Colombier void
xfclear(Xfid * xf)2539a747e4fSDavid du Colombier xfclear(Xfid *xf)
2549a747e4fSDavid du Colombier {
2559a747e4fSDavid du Colombier 	Xfile *xp = xf->xp;
2569a747e4fSDavid du Colombier 
2579a747e4fSDavid du Colombier 	if(xf->opfid){
2589a747e4fSDavid du Colombier 		clunkfid(xp->s, xf->opfid);
2599a747e4fSDavid du Colombier 		xf->opfid = 0;
2609a747e4fSDavid du Colombier 	}
2619a747e4fSDavid du Colombier 	if(xf->urfid){
2629a747e4fSDavid du Colombier 		clunkfid(xp->s, xf->urfid);
2639a747e4fSDavid du Colombier 		xf->urfid = 0;
2649a747e4fSDavid du Colombier 	}
2659a747e4fSDavid du Colombier 	xfid(xf->uid, xp, -1);
2669a747e4fSDavid du Colombier }
2679a747e4fSDavid du Colombier 
2689a747e4fSDavid du Colombier Xfid *
xfwalkcr(int type,Xfid * xf,String * elem,long perm)2699a747e4fSDavid du Colombier xfwalkcr(int type, Xfid *xf, String *elem, long perm)
2709a747e4fSDavid du Colombier {
2719a747e4fSDavid du Colombier 	Session *s;
2729a747e4fSDavid du Colombier 	Xfile *xp, *newxp;
2739a747e4fSDavid du Colombier 	Xfid *newxf;
2749a747e4fSDavid du Colombier 	Fid *nfid;
2759a747e4fSDavid du Colombier 
2769a747e4fSDavid du Colombier 	chat("xf%s(\"%s\")...", type==Tcreate ? "create" : "walk", elem->s);
2779a747e4fSDavid du Colombier 	xp = xf->xp;
2789a747e4fSDavid du Colombier 	s = xp->s;
2799a747e4fSDavid du Colombier 	nfid = newfid(s);
2809a747e4fSDavid du Colombier 	setfid(s, xf->urfid);
2819a747e4fSDavid du Colombier 	s->f.newfid = nfid - s->fids;
2829a747e4fSDavid du Colombier 	if(type == Tcreate){
2839a747e4fSDavid du Colombier 		s->f.nwname = 0;
2849a747e4fSDavid du Colombier 		if(xmesg(s, Twalk)){
2859a747e4fSDavid du Colombier 			putfid(s, nfid);
2869a747e4fSDavid du Colombier 			return 0;
2879a747e4fSDavid du Colombier 		}
2889a747e4fSDavid du Colombier 		s->f.fid = nfid - s->fids;
2899a747e4fSDavid du Colombier 	}
2909a747e4fSDavid du Colombier 	if(type == Tcreate){
2919a747e4fSDavid du Colombier 		s->f.name = elem->s;
2929a747e4fSDavid du Colombier 		s->f.perm = perm;
2939a747e4fSDavid du Colombier 		s->f.mode = (perm&DMDIR) ? OREAD : ORDWR;
2949a747e4fSDavid du Colombier 		if(xmesg(s, type)){
2959a747e4fSDavid du Colombier 			clunkfid(s, nfid);
2969a747e4fSDavid du Colombier 			return 0;
2979a747e4fSDavid du Colombier 		}
2989a747e4fSDavid du Colombier 	}else{	/* Twalk */
2999a747e4fSDavid du Colombier 		s->f.nwname = 1;
3009a747e4fSDavid du Colombier 		s->f.wname[0] = elem->s;
3019a747e4fSDavid du Colombier 		if(xmesg(s, type) || s->f.nwqid!=1){
3029a747e4fSDavid du Colombier 			putfid(s, nfid);
3039a747e4fSDavid du Colombier 			return 0;
3049a747e4fSDavid du Colombier 		}
3059a747e4fSDavid du Colombier 		s->f.qid = s->f.wqid[0];	/* only one element */
3069a747e4fSDavid du Colombier 	}
3079a747e4fSDavid du Colombier 	chat("fid=%d,qid=0x%llux,%ld,%.2ux...", s->f.fid, s->f.qid.path, s->f.qid.vers, s->f.qid.type);
3089a747e4fSDavid du Colombier 	newxp = xfile(&s->f.qid, s, 1);
3099a747e4fSDavid du Colombier 	if(newxp->parent == 0){
3109a747e4fSDavid du Colombier 		chat("new xfile...");
3119a747e4fSDavid du Colombier 		newxp->parent = xp;
3129a747e4fSDavid du Colombier 		newxp->sib = xp->child;
3139a747e4fSDavid du Colombier 		xp->child = newxp;
3149a747e4fSDavid du Colombier 	}
3159a747e4fSDavid du Colombier 	newxf = xfid(xf->uid, newxp, 1);
3169a747e4fSDavid du Colombier 	if(type == Tcreate){
3179a747e4fSDavid du Colombier 		newxf->mode = (perm&DMDIR) ? Oread : (Oread|Owrite);
3189a747e4fSDavid du Colombier 		newxf->opfid = nfid;
3199a747e4fSDavid du Colombier 		nfid->owner = &newxf->opfid;
3209a747e4fSDavid du Colombier 		nfid = newfid(s);
3219a747e4fSDavid du Colombier 		setfid(s, xf->urfid);
3229a747e4fSDavid du Colombier 		s->f.newfid = nfid - s->fids;
3239a747e4fSDavid du Colombier 		s->f.nwname = 1;
3249a747e4fSDavid du Colombier 		s->f.wname[0] = elem->s;
3259a747e4fSDavid du Colombier 		if(xmesg(s, Twalk) || s->f.nwqid!=1){
3269a747e4fSDavid du Colombier 			putfid(s, nfid);
3279a747e4fSDavid du Colombier 			xpclear(newxp);
3289a747e4fSDavid du Colombier 			return 0;
3299a747e4fSDavid du Colombier 		}
3309a747e4fSDavid du Colombier 		newxf->urfid = nfid;
3319a747e4fSDavid du Colombier 		nfid->owner = &newxf->urfid;
3329a747e4fSDavid du Colombier 	}else if(newxf->urfid){
3339a747e4fSDavid du Colombier 		chat("old xfid %ld...", newxf->urfid-s->fids);
3349a747e4fSDavid du Colombier 		clunkfid(s, nfid);
3359a747e4fSDavid du Colombier 	}else{
3369a747e4fSDavid du Colombier 		newxf->urfid = nfid;
3379a747e4fSDavid du Colombier 		nfid->owner = &newxf->urfid;
3389a747e4fSDavid du Colombier 	}
3399a747e4fSDavid du Colombier 	newxp->name = strstore(elem->s);
3409a747e4fSDavid du Colombier 	return newxf;
3419a747e4fSDavid du Colombier }
3429a747e4fSDavid du Colombier 
3439a747e4fSDavid du Colombier void
xpclear(Xfile * xp)3449a747e4fSDavid du Colombier xpclear(Xfile *xp)
3459a747e4fSDavid du Colombier {
3469a747e4fSDavid du Colombier 	Session *s;
3479a747e4fSDavid du Colombier 	Xfid *xf;
3489a747e4fSDavid du Colombier 	Xfile *xnp;
3499a747e4fSDavid du Colombier 
3509a747e4fSDavid du Colombier 	s = xp->s;
3519a747e4fSDavid du Colombier 	while(xf = xp->users)	/* assign = */
3529a747e4fSDavid du Colombier 		xfclear(xf);
3539a747e4fSDavid du Colombier 	while(xnp = xp->child){	/* assign = */
3549a747e4fSDavid du Colombier 		xp->child = xnp->sib;
3559a747e4fSDavid du Colombier 		xnp->parent = 0;
3569a747e4fSDavid du Colombier 		xpclear(xnp);
3579a747e4fSDavid du Colombier 		xfile(&xnp->qid, s, -1);
3589a747e4fSDavid du Colombier 	}
3599a747e4fSDavid du Colombier 	if(xnp = xp->parent){	/* assign = */
3609a747e4fSDavid du Colombier 		if(xnp->child == xp)
3619a747e4fSDavid du Colombier 			xnp->child = xp->sib;
3629a747e4fSDavid du Colombier 		else{
3639a747e4fSDavid du Colombier 			xnp = xnp->child;
3649a747e4fSDavid du Colombier 			while(xnp->sib != xp)
3659a747e4fSDavid du Colombier 				xnp = xnp->sib;
3669a747e4fSDavid du Colombier 			xnp->sib = xp->sib;
3679a747e4fSDavid du Colombier 		}
3689a747e4fSDavid du Colombier 		xfile(&xp->qid, s, -1);
3699a747e4fSDavid du Colombier 	}
3709a747e4fSDavid du Colombier }
3719a747e4fSDavid du Colombier 
3729a747e4fSDavid du Colombier int
xp2fhandle(Xfile * xp,Fhandle fh)3739a747e4fSDavid du Colombier xp2fhandle(Xfile *xp, Fhandle fh)
3749a747e4fSDavid du Colombier {
3759a747e4fSDavid du Colombier 	uchar *dataptr = fh;
3769a747e4fSDavid du Colombier 	ulong x;
3779a747e4fSDavid du Colombier 	int n;
3789a747e4fSDavid du Colombier 
3799a747e4fSDavid du Colombier 	memset(fh, 0, FHSIZE);
3809a747e4fSDavid du Colombier 	if(xp == xp->parent){	/* root */
3819a747e4fSDavid du Colombier 		dataptr[0] = 0;
3829a747e4fSDavid du Colombier 		dataptr[1] = 0;
3839a747e4fSDavid du Colombier 		n = strlen(xp->s->service);
3849a747e4fSDavid du Colombier 		if(n > FHSIZE-3)
3859a747e4fSDavid du Colombier 			n = FHSIZE-3;
3869a747e4fSDavid du Colombier 		memmove(&dataptr[2], xp->s->service, n);
3879a747e4fSDavid du Colombier 		dataptr[2+n] = 0;
3889a747e4fSDavid du Colombier 	}else{
3899a747e4fSDavid du Colombier 		PLONG(starttime);
390*4de34a7eSDavid du Colombier 		PLONG((u32int)(uintptr)xp->s);
3919a747e4fSDavid du Colombier 		x = xp->qid.path;
3929a747e4fSDavid du Colombier 		PLONG(x);
3939a747e4fSDavid du Colombier 		x = xp->qid.path>>32;
3949a747e4fSDavid du Colombier 		PLONG(x);
3959a747e4fSDavid du Colombier 		PBYTE(xp->qid.type);
3969a747e4fSDavid du Colombier 		USED(dataptr);
3979a747e4fSDavid du Colombier 	}
3989a747e4fSDavid du Colombier 	return FHSIZE;
3999a747e4fSDavid du Colombier }
4009a747e4fSDavid du Colombier 
4019a747e4fSDavid du Colombier int
dir2fattr(Unixidmap * up,Dir * dp,void * mp)4029a747e4fSDavid du Colombier dir2fattr(Unixidmap *up, Dir *dp, void *mp)
4039a747e4fSDavid du Colombier {
4049a747e4fSDavid du Colombier 	uchar *dataptr = mp;
4059a747e4fSDavid du Colombier 	long length;
4069a747e4fSDavid du Colombier 	int r;
4079a747e4fSDavid du Colombier 
4089a747e4fSDavid du Colombier 	r = dp->mode & 0777;
4099a747e4fSDavid du Colombier 	if (dp->mode & DMDIR)
4109a747e4fSDavid du Colombier 		length = 1024;
4119a747e4fSDavid du Colombier 	else
4129a747e4fSDavid du Colombier 		length = dp->length;
4139a747e4fSDavid du Colombier 	if((dp->mode & DMDIR) && dp->type == '/' && dp->dev == 0)
4149a747e4fSDavid du Colombier 		r |= 0555;
4159a747e4fSDavid du Colombier 	if(dp->mode & DMDIR){
4169a747e4fSDavid du Colombier 		PLONG(NFDIR);	/* type */
4179a747e4fSDavid du Colombier 		r |= S_IFDIR;
4189a747e4fSDavid du Colombier 		PLONG(r);	/* mode */
4199a747e4fSDavid du Colombier 		PLONG(3);	/* nlink */
4209a747e4fSDavid du Colombier 	}else{
4219a747e4fSDavid du Colombier 		PLONG(NFREG);	/* type */
4229a747e4fSDavid du Colombier 		r |= S_IFREG;
4239a747e4fSDavid du Colombier 		PLONG(r);	/* mode */
4249a747e4fSDavid du Colombier 		PLONG(1);	/* nlink */
4259a747e4fSDavid du Colombier 	}
4269a747e4fSDavid du Colombier 	r = name2id(&up->u.ids, dp->uid);
4279a747e4fSDavid du Colombier 	if(r < 0){
4289a747e4fSDavid du Colombier 		r = name2id(&up->u.ids, "daemon");
4299a747e4fSDavid du Colombier 		if(r < 0)
4309a747e4fSDavid du Colombier 			r = 1;
4319a747e4fSDavid du Colombier 	}
4329a747e4fSDavid du Colombier 	PLONG(r);		/* uid */
4339a747e4fSDavid du Colombier 	r = name2id(&up->g.ids, dp->gid);
4349a747e4fSDavid du Colombier 	if(r < 0){
4359a747e4fSDavid du Colombier 		r = name2id(&up->g.ids, "user");
4369a747e4fSDavid du Colombier 		if(r < 0)
4379a747e4fSDavid du Colombier 			r = 1;
4389a747e4fSDavid du Colombier 	}
4399a747e4fSDavid du Colombier 	PLONG(r);		/* gid */
4409a747e4fSDavid du Colombier 	PLONG(length);		/* size */
4419a747e4fSDavid du Colombier 	PLONG(2048);		/* blocksize */
4429a747e4fSDavid du Colombier 	PLONG(0);		/* rdev */
4439a747e4fSDavid du Colombier 	r = (length+2047)/2048;
4449a747e4fSDavid du Colombier 	PLONG(r);		/* blocks */
4459a747e4fSDavid du Colombier 	r = (dp->type<<16) | dp->dev;
4469a747e4fSDavid du Colombier 	PLONG(r);		/* fsid */
4479a747e4fSDavid du Colombier 	PLONG(dp->qid.path);	/* fileid */
4489a747e4fSDavid du Colombier 	PLONG(dp->atime);	/* atime */
4499a747e4fSDavid du Colombier 	PLONG(0);
4509a747e4fSDavid du Colombier 	PLONG(dp->mtime);	/* mtime */
4519a747e4fSDavid du Colombier 	PLONG(0);
4529a747e4fSDavid du Colombier 	PLONG(dp->mtime);	/* ctime */
4539a747e4fSDavid du Colombier 	PLONG(0);
4549a747e4fSDavid du Colombier 	return dataptr - (uchar *)mp;
4559a747e4fSDavid du Colombier }
4569a747e4fSDavid du Colombier 
4579a747e4fSDavid du Colombier int
convM2sattr(void * mp,Sattr * sp)4589a747e4fSDavid du Colombier convM2sattr(void *mp, Sattr *sp)
4599a747e4fSDavid du Colombier {
4609a747e4fSDavid du Colombier 	uchar *argptr = mp;
4619a747e4fSDavid du Colombier 
4629a747e4fSDavid du Colombier 	sp->mode = GLONG();
4639a747e4fSDavid du Colombier 	sp->uid = GLONG();
4649a747e4fSDavid du Colombier 	sp->gid = GLONG();
4659a747e4fSDavid du Colombier 	sp->size = GLONG();
4669a747e4fSDavid du Colombier 	sp->atime = GLONG();
4679a747e4fSDavid du Colombier 	sp->ausec = GLONG();
4689a747e4fSDavid du Colombier 	sp->mtime = GLONG();
4699a747e4fSDavid du Colombier 	sp->musec = GLONG();
4709a747e4fSDavid du Colombier 	return argptr - (uchar *)mp;
4719a747e4fSDavid du Colombier }
472