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

📄 nfsserver.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
		return error(reply, NFSERR_IO);	PLONG(NFS_OK);	dataptr += dir2fattr(cmd->up, &dir, dataptr);	chat("OK\n");	return dataptr - (uchar *)reply->results;}static intcreat(int n, Rpccall *cmd, Rpccall *reply, int chdir){	Xfid *xf, *newxf;	Xfile *xp;	String elem;	Dir dir; Sattr sattr;	uchar *argptr = cmd->args;	uchar *dataptr = reply->results;	int trunced;	if(n <= FHSIZE)		return garbage(reply, "count too small");	xf = rpc2xfid(cmd, 0);	argptr += FHSIZE;	argptr += string2S(argptr, &elem);	argptr += convM2sattr(argptr, &sattr);	if(argptr != &((uchar *)cmd->args)[n])		return garbage(reply, "bad count");	if(xf == 0)		return error(reply, NFSERR_STALE);	xp = xf->xp;	if(!(xp->qid.type & QTDIR))		return error(reply, NFSERR_NOTDIR);	chat("%s/%.*s...", xp->name, utfnlen(elem.s, elem.n), elem.s);	trunced = 0;	if(xp->parent == xp && elem.s[0] == '#'){		newxf = xfauth(xp, &elem);		if(newxf == 0)			return error(reply, NFSERR_PERM);		if(xfauthremove(newxf, cmd->user) < 0)			return error(reply, NFSERR_PERM);		trunced = 1;	}else		newxf = xfwalkcr(Twalk, xf, &elem, 0);	if(newxf == 0){		newxf = xfwalkcr(Tcreate, xf, &elem, chdir|(sattr.mode&0777));		if(newxf)			trunced = 1;		else			newxf = xfwalkcr(Twalk, xf, &elem, 0);	}	if(newxf == 0)		return error(reply, NFSERR_PERM);	if(!trunced && chdir)		return error(reply, NFSERR_EXIST);	if(!trunced && xfopen(newxf, Trunc|Oread|Owrite) < 0)		return error(reply, NFSERR_PERM);	if(xfstat(newxf, &dir) < 0)		return error(reply, NFSERR_IO);	PLONG(NFS_OK);	dataptr += xp2fhandle(newxf->xp, dataptr);	dataptr += dir2fattr(cmd->up, &dir, dataptr);	chat("OK\n");	return dataptr - (uchar *)reply->results;}static intnfscreate(int n, Rpccall *cmd, Rpccall *reply){	chat("create...");	return creat(n, cmd, reply, 0);}static intremov(int n, Rpccall *cmd, Rpccall *reply){	Session *s;	Xfile *xp;	Xfid *xf, *newxf;	String elem;	Fid *nfid;	uchar *argptr = cmd->args;	uchar *dataptr = reply->results;	if(n <= FHSIZE)		return garbage(reply, "count too small");	xf = rpc2xfid(cmd, 0);	argptr += FHSIZE;	argptr += string2S(argptr, &elem);	if(argptr != &((uchar *)cmd->args)[n])		return garbage(reply, "bad count");	if(xf == 0)		return error(reply, NFSERR_STALE);	xp = xf->xp;	if(!(xp->qid.type & QTDIR))		return error(reply, NFSERR_NOTDIR);	chat("%s/%.*s...", xp->name, utfnlen(elem.s, elem.n), elem.s);	if(xp->s->noauth == 0 && xp->parent == xp && elem.s[0] == '#')		return error(reply, NFSERR_PERM);	newxf = xfwalkcr(Twalk, xf, &elem, 0);	if(newxf == 0)		return error(reply, NFSERR_NOENT);	s = xp->s;	nfid = newfid(s);	setfid(s, newxf->urfid);	s->f.newfid = nfid - s->fids;	s->f.nwname = 0;	if(xmesg(s, Twalk) < 0){		putfid(s, nfid);		return error(reply, NFSERR_IO);	}	s->f.fid = nfid - s->fids;	if(xmesg(s, Tremove) < 0){		putfid(s, nfid);		return error(reply, NFSERR_PERM);	}	putfid(s, nfid);	xpclear(newxf->xp);	PLONG(NFS_OK);	chat("OK\n");	return dataptr - (uchar *)reply->results;}static intnfsremove(int n, Rpccall *cmd, Rpccall *reply){	chat("remove...");	return remov(n, cmd, reply);}static intnfsrename(int n, Rpccall *cmd, Rpccall *reply){	Xfid *xf, *newxf;	Xfile *xp;	uchar *fromdir, *todir;	String fromelem, toelem;	Dir dir;	uchar *argptr = cmd->args;	uchar *dataptr = reply->results;	chat("rename...");	if(n <= FHSIZE)		return garbage(reply, "count too small");	xf = rpc2xfid(cmd, 0);	fromdir = argptr;	argptr += FHSIZE;	argptr += string2S(argptr, &fromelem);	todir = argptr;	argptr += FHSIZE;	argptr += string2S(argptr, &toelem);	if(argptr != &((uchar *)cmd->args)[n])		return garbage(reply, "bad count");	if(xf == 0)		return error(reply, NFSERR_STALE);	xp = xf->xp;	if(!(xp->qid.type & QTDIR))		return error(reply, NFSERR_NOTDIR);	if(memcmp(fromdir, todir, FHSIZE) != 0)		return error(reply, NFSERR_NXIO);	newxf = xfwalkcr(Twalk, xf, &fromelem, 0);	if(newxf == 0)		return error(reply, NFSERR_NOENT);	if(xfstat(newxf, &dir) < 0)		return error(reply, NFSERR_IO);	if(xp->parent == xp && toelem.s[0] == '#')		return error(reply, NFSERR_PERM);	nulldir(&dir);	dir.name = toelem.s;	if(xfwstat(newxf, &dir) < 0)		return error(reply, NFSERR_PERM);	PLONG(NFS_OK);	chat("OK\n");	return dataptr - (uchar *)reply->results;}static intnfslink(int n, Rpccall *cmd, Rpccall *reply){	USED(n, reply);	chat("link...");	showauth(&cmd->cred);	return error(reply, NFSERR_NOENT);}static intnfssymlink(int n, Rpccall *cmd, Rpccall *reply){	USED(n, reply);	chat("symlink...");	showauth(&cmd->cred);	return error(reply, NFSERR_NOENT);}static intnfsmkdir(int n, Rpccall *cmd, Rpccall *reply){	chat("mkdir...");	return creat(n, cmd, reply, DMDIR);}static intnfsrmdir(int n, Rpccall *cmd, Rpccall *reply){	chat("rmdir...");	return remov(n, cmd, reply);}static intnfsreaddir(int n, Rpccall *cmd, Rpccall *reply){	Session *s;	Xfid *xf;	Dir dir;	char *rdata;	int k, offset, count, sfcount, entries, dsize;	uchar *argptr = cmd->args;	uchar *dataptr = reply->results;	chat("readdir...");	if(n != FHSIZE+8)		return garbage(reply, "bad count");	xf = rpc2xfid(cmd, 0);	argptr += FHSIZE;	offset = GLONG();	count = GLONG();	if(xf == 0)		return error(reply, NFSERR_STALE);	chat("%s (%ld) %d %d...", xf->xp->name, xf->offset, offset, count);	s = xf->xp->s;	if((xf->mode & Open) && xf->offset > offset)		xfclose(xf);	if(xfopen(xf, Oread) < 0)		return error(reply, NFSERR_PERM);	while(xf->offset < offset){	/* if we reopened, xf->offset will be zero */		sfcount = offset - xf->offset;		if(sfcount > messagesize-IOHDRSZ)			sfcount = messagesize-IOHDRSZ;		setfid(s, xf->opfid);		s->f.offset = xf->offset;		s->f.count = sfcount;		if(xmesg(s, Tread) < 0){			xfclose(xf);			return error(reply, NFSERR_IO);		}		if(s->f.count <= BIT16SZ)			break;		xf->offset += s->f.count;	}	if(count > messagesize-IOHDRSZ)		count = messagesize-IOHDRSZ;	PLONG(NFS_OK);	entries = 0;	while(count > 16){	/* at least 16 bytes required; we don't know size of name */chat("top of loop\n");		setfid(s, xf->opfid);		s->f.offset = xf->offset;		s->f.count = count;	/* as good a guess as any */		if(xmesg(s, Tread) < 0){			xfclose(xf);			return error(reply, NFSERR_IO);		}		sfcount = s->f.count;		if(sfcount <= BIT16SZ)			break;		xf->offset += sfcount;chat("count %d data 0x%p\n", s->f.count, s->f.data);		rdata = s->f.data;		/* now have a buffer of Plan 9 directories; unpack into NFS thingies */		while(sfcount >= 0){			dsize = convM2D((uchar*)rdata, sfcount, &dir, (char*)s->statbuf);			if(dsize <= BIT16SZ){				count = 0;	/* force break from outer loop */				break;			}			offset += dsize;			k = strlen(dir.name);			if(count < 16+ROUNDUP(k)){				count = 0;	/* force break from outer loop */				break;			}			PLONG(TRUE);			PLONG(dir.qid.path);			PLONG(k);			PPTR(dir.name, k);			PLONG(offset);			count -= 16+ROUNDUP(k);			rdata += dsize;			sfcount -= dsize;		}	}	PLONG(FALSE);	if(s->f.count <= 0){		xfclose(xf);		chat("eof...");		PLONG(TRUE);	}else		PLONG(FALSE);	chat("%d OK\n", entries);	return dataptr - (uchar *)reply->results;}static intnfsstatfs(int n, Rpccall *cmd, Rpccall *reply){	uchar *dataptr = reply->results;	enum {		Xfersize = 2048,		Maxlong = (long)((1ULL<<31) - 1),		Maxfreeblks = Maxlong / Xfersize,	};	chat("statfs...");	showauth(&cmd->cred);	if(n != FHSIZE)		return garbage(reply, "bad count");	PLONG(NFS_OK);	PLONG(4096);		/* tsize (fs block size) */	PLONG(Xfersize);	/* bsize (optimal transfer size) */	PLONG(Maxfreeblks);	/* blocks in fs */	PLONG(Maxfreeblks);	/* bfree to root*/	PLONG(Maxfreeblks);	/* bavail (free to mortals) */	chat("OK\n");	/*conftime = 0;	readunixidmaps(config);*/	return dataptr - (uchar *)reply->results;}

⌨️ 快捷键说明

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