⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nfs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "all.h"extern uchar buf[];Xfid *rpc2xfid(Rpccall *cmd, Dir *dp){	char *argptr = cmd->args;	Xfile *xp;	Xfid *xf;	Session *s;	char *service;	Authunix au;	Qid qid;	char client[256], *user;	Unixidmap *m;	int i;	uvlong x1, x2;	chat("rpc2xfid %.8lux %.8lux %p %p\n", *((ulong*)argptr), *((ulong*)argptr+1), buf, argptr);	if(argptr[0] == 0 && argptr[1] == 0){	/* root */		chat("root...");		xp = xfroot(&argptr[2], 0);		s = xp ? xp->s : 0;	}else{		ulong ul;		chat("noroot %.8lux...", *((ulong*)argptr));		if((ul=GLONG()) != starttime){			chat("bad tag %lux %lux...", ul, starttime);			return 0;		}		s = (Session *)GLONG();		x1 = GLONG();		x2 = GLONG();		qid.path = x1 | (x2<<32);		qid.vers = 0;		qid.type = GBYTE();		xp = xfile(&qid, s, 0);	}	if(xp == 0){		chat("no xfile...");		return 0;	}	if(auth2unix(&cmd->cred, &au) != 0){		chat("auth flavor=%ld, count=%ld\n",			cmd->cred.flavor, cmd->cred.count);		for(i=0; i<cmd->cred.count; i++)			chat(" %.2ux", ((uchar *)cmd->cred.data)[i]);		chat("...");		return 0;	}else{/*		chat("auth: %d %.*s u=%d g=%d", *			au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid); *		for(i=0; i<au.gidlen; i++) *			chat(", %d", au.gids[i]); *		chat("..."); */		char *p = memchr(au.mach.s, '.', au.mach.n);		chat("%ld@%.*s...", au.uid, utfnlen(au.mach.s, (p ? p-au.mach.s : au.mach.n)), au.mach.s);	}	if(au.mach.n >= sizeof client){		chat("client name too long...");		return 0;	}	memcpy(client, au.mach.s, au.mach.n);	client[au.mach.n] = 0;	service = xp->parent->s->service;	cmd->up = m = pair2idmap(service, cmd->host);	if(m == 0){		chat("no map for pair (%s,%s)...", service, client);		/*chat("getdom %d.%d.%d.%d", cmd->host&0xFF, (cmd->host>>8)&0xFF,			(cmd->host>>16)&0xFF, (cmd->host>>24)&0xFF);/**/		/*if(getdom(cmd->host, client, sizeof(client))<0)			return 0;/**/		return 0;	}	/*chat("map=(%s,%s)...", m->server, m->client);/**/	cmd->user = user = id2name(&m->u.ids, au.uid);	if(user == 0){		chat("no user for id %ld...", au.uid);		return 0;	}	chat("user=%s...", user);/**/	xf = 0;	if(s == xp->parent->s){		if(!s->noauth)			xf = setuser(xp, user);		if(xf == 0)			xf = setuser(xp, "none");		if(xf == 0)			chat("can't set user none...");	}else		xf = xp->users;	if(xf)		chat("uid=%s...", xf->uid);	if(xf && dp && xfstat(xf, dp) < 0){		chat("can't stat %s...", xp->name);		return 0;	}	return xf;}Xfid *setuser(Xfile *xp, char *user){	Xfid *xf, *xpf;	Session *s;	xf = xfid(user, xp, 1);	if(xf->urfid)		return xf;	if(xp->parent==xp || !(xpf = setuser(xp->parent, user))) /* assign = */		return xfid(user, xp, -1);	s = xp->s;	xf->urfid = newfid(s);	xf->urfid->owner = &xf->urfid;	setfid(s, xpf->urfid);	s->f.newfid = xf->urfid - s->fids;	s->f.nwname = 1;	s->f.wname[0] = xp->name;	if(xmesg(s, Twalk) || s->f.nwqid != 1)		return xfid(user, xp, -1);	return xf;}intxfstat(Xfid *xf, Dir *dp){	Xfile *xp;	Session *s;	char buf[128];	xp = xf->xp;	s = xp->s;	if(s != xp->parent->s){		seprint(buf, buf+sizeof buf, "#%s", xf->uid);		dp->name = strstore(buf);		dp->uid = xf->uid;		dp->gid = xf->uid;		dp->muid = xf->uid;		dp->qid.path = (uvlong)xf->uid;		dp->qid.type = QTFILE;		dp->qid.vers = 0;		dp->mode = 0666;		dp->atime = time(0);		dp->mtime = dp->atime;		dp->length = NETCHLEN;		dp->type = 0;		dp->type = 0;		return 0;	}	setfid(s, xf->urfid);	if(xmesg(s, Tstat) == 0){		convM2D(s->f.stat, s->f.nstat, dp, (char*)s->statbuf);		if(xp->qid.path == dp->qid.path){			xp->name = strstore(dp->name);			return 0;		}		/* not reached ? */		chat("xp->qid.path=0x%.16llux, dp->qid.path=0x%.16llux name=%s...",			xp->qid.path, dp->qid.path, dp->name);	}	if(xp != xp->parent)		xpclear(xp);	else		clog("can't stat root: %s",			s->f.type == Rerror ? s->f.ename : "??");	return -1;}intxfwstat(Xfid *xf, Dir *dp){	Xfile *xp;	Session *s;	xp = xf->xp;	s = xp->s;	/*	 * xf->urfid can be zero because some DOS NFS clients	 * try to do wstat on the #user authentication files on close.	 */	if(s == 0 || xf->urfid == 0)		return -1;	setfid(s, xf->urfid);	s->f.stat = s->statbuf;	convD2M(dp, s->f.stat, Maxstatdata);	if(xmesg(s, Twstat))		return -1;	xp->name = strstore(dp->name);	return 0;}intxfopen(Xfid *xf, int flag){	static int modes[] = {		[Oread] OREAD, [Owrite] OWRITE, [Oread|Owrite] ORDWR,	};	Xfile *xp;	Session *s;	Fid *opfid;	int omode;	if(xf->opfid && (xf->mode & flag & Open) == flag)		return 0;	omode = modes[(xf->mode|flag) & Open];	if(flag & Trunc)		omode |= OTRUNC;	xp = xf->xp;	chat("open(\"%s\", %d)...", xp->name, omode);	s = xp->s;	opfid = newfid(s);	setfid(s, xf->urfid);	s->f.newfid = opfid - s->fids;	s->f.nwname = 0;	if(xmesg(s, Twalk)){		putfid(s, opfid);		return -1;	}	setfid(s, opfid);	s->f.mode = omode;	if(xmesg(s, Topen)){		clunkfid(s, opfid);		return -1;	}	if(xf->opfid)		clunkfid(s, xf->opfid);	xf->mode |= flag & Open;	xf->opfid = opfid;	opfid->owner = &xf->opfid;	xf->offset = 0;	return 0;}voidxfclose(Xfid *xf){	Xfile *xp;	if(xf->mode & Open){		xp = xf->xp;		chat("close(\"%s\")...", xp->name);		if(xf->opfid)			clunkfid(xp->s, xf->opfid);		xf->mode &= ~Open;		xf->opfid = 0;	}}voidxfclear(Xfid *xf){	Xfile *xp = xf->xp;	if(xf->opfid){		clunkfid(xp->s, xf->opfid);		xf->opfid = 0;	}	if(xf->urfid){		clunkfid(xp->s, xf->urfid);		xf->urfid = 0;	}	xfid(xf->uid, xp, -1);}Xfid *xfwalkcr(int type, Xfid *xf, String *elem, long perm){	Session *s;	Xfile *xp, *newxp;	Xfid *newxf;	Fid *nfid;	chat("xf%s(\"%s\")...", type==Tcreate ? "create" : "walk", elem->s);	xp = xf->xp;	s = xp->s;	nfid = newfid(s);	setfid(s, xf->urfid);	s->f.newfid = nfid - s->fids;	if(type == Tcreate){		s->f.nwname = 0;		if(xmesg(s, Twalk)){			putfid(s, nfid);			return 0;		}		s->f.fid = nfid - s->fids;	}	if(type == Tcreate){		s->f.name = elem->s;		s->f.perm = perm;		s->f.mode = (perm&DMDIR) ? OREAD : ORDWR;		if(xmesg(s, type)){			clunkfid(s, nfid);			return 0;		}	}else{	/* Twalk */		s->f.nwname = 1;		s->f.wname[0] = elem->s;		if(xmesg(s, type) || s->f.nwqid!=1){			putfid(s, nfid);			return 0;		}		s->f.qid = s->f.wqid[0];	/* only one element */	}	chat("fid=%d,qid=0x%llux,%ld,%.2ux...", s->f.fid, s->f.qid.path, s->f.qid.vers, s->f.qid.type);	newxp = xfile(&s->f.qid, s, 1);	if(newxp->parent == 0){		chat("new xfile...");		newxp->parent = xp;		newxp->sib = xp->child;		xp->child = newxp;	}	newxf = xfid(xf->uid, newxp, 1);	if(type == Tcreate){		newxf->mode = (perm&DMDIR) ? Oread : (Oread|Owrite);		newxf->opfid = nfid;		nfid->owner = &newxf->opfid;		nfid = newfid(s);		setfid(s, xf->urfid);		s->f.newfid = nfid - s->fids;		s->f.nwname = 1;		s->f.wname[0] = elem->s;		if(xmesg(s, Twalk) || s->f.nwqid!=1){			putfid(s, nfid);			xpclear(newxp);			return 0;		}		newxf->urfid = nfid;		nfid->owner = &newxf->urfid;	}else if(newxf->urfid){		chat("old xfid %ld...", newxf->urfid-s->fids);		clunkfid(s, nfid);	}else{		newxf->urfid = nfid;		nfid->owner = &newxf->urfid;	}	newxp->name = strstore(elem->s);	return newxf;}voidxpclear(Xfile *xp){	Session *s;	Xfid *xf;	Xfile *xnp;	s = xp->s;	while(xf = xp->users)	/* assign = */		xfclear(xf);	while(xnp = xp->child){	/* assign = */		xp->child = xnp->sib;		xnp->parent = 0;		xpclear(xnp);		xfile(&xnp->qid, s, -1);	}	if(xnp = xp->parent){	/* assign = */		if(xnp->child == xp)			xnp->child = xp->sib;		else{			xnp = xnp->child;			while(xnp->sib != xp)				xnp = xnp->sib;			xnp->sib = xp->sib;		}		xfile(&xp->qid, s, -1);	}}intxp2fhandle(Xfile *xp, Fhandle fh){	uchar *dataptr = fh;	ulong x;	int n;	memset(fh, 0, FHSIZE);	if(xp == xp->parent){	/* root */		dataptr[0] = 0;		dataptr[1] = 0;		n = strlen(xp->s->service);		if(n > FHSIZE-3)			n = FHSIZE-3;		memmove(&dataptr[2], xp->s->service, n);		dataptr[2+n] = 0;	}else{		PLONG(starttime);		PLONG((u32int)(uintptr)xp->s);		x = xp->qid.path;		PLONG(x);		x = xp->qid.path>>32;		PLONG(x);		PBYTE(xp->qid.type);		USED(dataptr);	}	return FHSIZE;}intdir2fattr(Unixidmap *up, Dir *dp, void *mp){	uchar *dataptr = mp;	long length;	int r;	r = dp->mode & 0777;	if (dp->mode & DMDIR)		length = 1024;	else		length = dp->length;	if((dp->mode & DMDIR) && dp->type == '/' && dp->dev == 0)		r |= 0555;	if(dp->mode & DMDIR){		PLONG(NFDIR);	/* type */		r |= S_IFDIR;		PLONG(r);	/* mode */		PLONG(3);	/* nlink */	}else{		PLONG(NFREG);	/* type */		r |= S_IFREG;		PLONG(r);	/* mode */		PLONG(1);	/* nlink */	}	r = name2id(&up->u.ids, dp->uid);	if(r < 0){		r = name2id(&up->u.ids, "daemon");		if(r < 0)			r = 1;	}	PLONG(r);		/* uid */	r = name2id(&up->g.ids, dp->gid);	if(r < 0){		r = name2id(&up->g.ids, "user");		if(r < 0)			r = 1;	}	PLONG(r);		/* gid */	PLONG(length);		/* size */	PLONG(2048);		/* blocksize */	PLONG(0);		/* rdev */	r = (length+2047)/2048;	PLONG(r);		/* blocks */	r = (dp->type<<16) | dp->dev;	PLONG(r);		/* fsid */	PLONG(dp->qid.path);	/* fileid */	PLONG(dp->atime);	/* atime */	PLONG(0);	PLONG(dp->mtime);	/* mtime */	PLONG(0);	PLONG(dp->mtime);	/* ctime */	PLONG(0);	return dataptr - (uchar *)mp;}intconvM2sattr(void *mp, Sattr *sp){	uchar *argptr = mp;	sp->mode = GLONG();	sp->uid = GLONG();	sp->gid = GLONG();	sp->size = GLONG();	sp->atime = GLONG();	sp->ausec = GLONG();	sp->mtime = GLONG();	sp->musec = GLONG();	return argptr - (uchar *)mp;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -