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

📄 nfsserver.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "all.h"/* *	Cf. /lib/rfc/rfc1094 */static int	nfsnull(int, Rpccall*, Rpccall*);static int	nfsgetattr(int, Rpccall*, Rpccall*);static int	nfssetattr(int, Rpccall*, Rpccall*);static int	nfsroot(int, Rpccall*, Rpccall*);static int	nfslookup(int, Rpccall*, Rpccall*);static int	nfsreadlink(int, Rpccall*, Rpccall*);static int	nfsread(int, Rpccall*, Rpccall*);static int	nfswritecache(int, Rpccall*, Rpccall*);static int	nfswrite(int, Rpccall*, Rpccall*);static int	nfscreate(int, Rpccall*, Rpccall*);static int	nfsremove(int, Rpccall*, Rpccall*);static int	nfsrename(int, Rpccall*, Rpccall*);static int	nfslink(int, Rpccall*, Rpccall*);static int	nfssymlink(int, Rpccall*, Rpccall*);static int	nfsmkdir(int, Rpccall*, Rpccall*);static int	nfsrmdir(int, Rpccall*, Rpccall*);static int	nfsreaddir(int, Rpccall*, Rpccall*);static int	nfsstatfs(int, Rpccall*, Rpccall*);Procmap nfsproc[] = {	0, nfsnull,	/* void */	1, nfsgetattr,	/* Fhandle */	2, nfssetattr,	/* Fhandle, Sattr */	3, nfsroot,	/* void */	4, nfslookup,	/* Fhandle, String */	5, nfsreadlink,	/* Fhandle */	6, nfsread,	/* Fhandle, long, long, long */	7, nfswritecache,/* void */	8, nfswrite,	/* Fhandle, long, long, long, String */	9, nfscreate,	/* Fhandle, String, Sattr */	10, nfsremove,	/* Fhandle, String */	11, nfsrename,	/* Fhandle, String, Fhandle, String */	12, nfslink,	/* Fhandle, Fhandle, String */	13, nfssymlink,	/* Fhandle, String, String, Sattr */	14, nfsmkdir,	/* Fhandle, String, Sattr */	15, nfsrmdir,	/* Fhandle, String */	16, nfsreaddir,	/* Fhandle, long, long */	17, nfsstatfs,	/* Fhandle */	0, 0};void	nfsinit(int, char**);extern void	mntinit(int, char**);extern Procmap	mntproc[];Progmap progmap[] = {	100005, 1, mntinit, mntproc,	100003, 2, nfsinit, nfsproc,	0, 0, 0,};int	myport = 2049;long	nfstime;int	conftime;voidmain(int argc, char *argv[]){	server(argc, argv, myport, progmap);}static voiddoalarm(void){	nfstime = time(0);	mnttimer(nfstime);	if(conftime+5*60 < nfstime){		conftime = nfstime;		readunixidmaps(config);	}}voidnfsinit(int argc, char **argv){	/*	 * mntinit will have already parsed our options.	 */	USED(argc, argv);	clog("nfs file server init\n");	rpcalarm = doalarm;	nfstime = time(0);}static intnfsnull(int n, Rpccall *cmd, Rpccall *reply){	USED(n, reply);	chat("nfsnull...");	showauth(&cmd->cred);	chat("OK\n");	return 0;}static intnfsgetattr(int n, Rpccall *cmd, Rpccall *reply){	Xfid *xf;	Dir dir;	uchar *dataptr = reply->results;	chat("getattr...");	if(n != FHSIZE)		return garbage(reply, "bad count");	xf = rpc2xfid(cmd, &dir);	if(xf == 0)		return error(reply, NFSERR_STALE);	chat("%s...", xf->xp->name);	PLONG(NFS_OK);	dataptr += dir2fattr(cmd->up, &dir, dataptr);	chat("OK\n");	return dataptr - (uchar *)reply->results;}static intnfssetattr(int n, Rpccall *cmd, Rpccall *reply){	Xfid *xf;	Dir dir, nd;	Sattr sattr;	int r;	uchar *argptr = cmd->args;	uchar *dataptr = reply->results;	chat("setattr...");	if(n <= FHSIZE)		return garbage(reply, "count too small");	xf = rpc2xfid(cmd, &dir);	argptr += FHSIZE;	argptr += convM2sattr(argptr, &sattr);	if(argptr != &((uchar *)cmd->args)[n])		return garbage(reply, "bad count");	chat("mode=0%lo,u=%ld,g=%ld,size=%ld,atime=%ld,mtime=%ld...",		sattr.mode, sattr.uid, sattr.gid, sattr.size,		sattr.atime, sattr.mtime);	if(xf == 0)		return error(reply, NFSERR_STALE);	if(sattr.uid != NOATTR || sattr.gid != NOATTR)		return error(reply, NFSERR_PERM);	if(sattr.size == 0){		if(xf->xp->s != xf->xp->parent->s){			if(xfauthremove(xf, cmd->user) < 0)				return error(reply, NFSERR_PERM);		}else if(dir.length && xfopen(xf, Trunc|Oread|Owrite) < 0)			return error(reply, NFSERR_PERM);	}else if(sattr.size != NOATTR)		return error(reply, NFSERR_PERM);	r = 0;	nulldir(&nd);	if(sattr.mode != NOATTR)		++r, nd.mode = (dir.mode & ~0777) | (sattr.mode & 0777);	if(sattr.atime != NOATTR)		++r, nd.atime = sattr.atime;	if(sattr.mtime != NOATTR)		++r, nd.mtime = sattr.mtime;	chat("sattr.mode=%luo dir.mode=%luo nd.mode=%luo...", sattr.mode, dir.mode, nd.mode);	if(r){		r = xfwstat(xf, &nd);		if(r < 0)			return error(reply, NFSERR_PERM);	}	if(xfstat(xf, &dir) < 0)		return error(reply, NFSERR_STALE);	PLONG(NFS_OK);	dataptr += dir2fattr(cmd->up, &dir, dataptr);	chat("OK\n");	return dataptr - (uchar *)reply->results;}static intnfsroot(int n, Rpccall *cmd, Rpccall *reply){	USED(n, reply);	chat("nfsroot...");	showauth(&cmd->cred);	chat("OK\n");	return 0;}static intnfslookup(int n, Rpccall *cmd, Rpccall *reply){	Xfile *xp;	Xfid *xf, *newxf;	String elem;	Dir dir;	uchar *argptr = cmd->args;	uchar *dataptr = reply->results;	chat("lookup...");	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] == '#')		newxf = xfauth(xp, &elem);	else		newxf = xfwalkcr(Twalk, xf, &elem, 0);	if(newxf == 0)		return error(reply, NFSERR_NOENT);	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 intnfsreadlink(int n, Rpccall *cmd, Rpccall *reply){	USED(n, reply);	chat("readlink...");	showauth(&cmd->cred);	return error(reply, NFSERR_NOENT);}static intnfsread(int n, Rpccall *cmd, Rpccall *reply){	Session *s;	Xfid *xf;	Dir dir;	int offset, count;	uchar *argptr = cmd->args;	uchar *dataptr = reply->results;	uchar *readptr = dataptr + 4 + 17*4 + 4;	chat("read...");	if(n != FHSIZE+12)		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 %d %d...", xf->xp->name, offset, count);	if(xf->xp->s != xf->xp->parent->s){		count = xfauthread(xf, offset, readptr, count);	}else{		if(xfopen(xf, Oread) < 0)			return error(reply, NFSERR_PERM);		if(count > 8192)			count = 8192;		s = xf->xp->s;		setfid(s, xf->opfid);		xf->opfid->tstale = nfstime + 60;		s->f.offset = offset;		s->f.count = count;		if(xmesg(s, Tread) < 0)			return error(reply, NFSERR_IO);		count = s->f.count;		memmove(readptr, s->f.data, count);	}	if(xfstat(xf, &dir) < 0)		return error(reply, NFSERR_IO);	PLONG(NFS_OK);	dataptr += dir2fattr(cmd->up, &dir, dataptr);	PLONG(count);	dataptr += ROUNDUP(count);	chat("%d OK\n", count);	return dataptr - (uchar *)reply->results;}static intnfswritecache(int n, Rpccall *cmd, Rpccall *reply){	USED(n, reply);	chat("writecache...");	showauth(&cmd->cred);	chat("OK\n");	return 0;}static intnfswrite(int n, Rpccall *cmd, Rpccall *reply){	Session *s;	Xfid *xf;	Dir dir;	int offset, count;	uchar *argptr = cmd->args;	uchar *dataptr = reply->results;	chat("write...");	if(n < FHSIZE+16)		return garbage(reply, "count too small");	xf = rpc2xfid(cmd, 0);	argptr += FHSIZE + 4;	offset = GLONG();	argptr += 4;	count = GLONG();	if(xf == 0)		return error(reply, NFSERR_STALE);	chat("%s %d %d...", xf->xp->name, offset, count);	if(xf->xp->s != xf->xp->parent->s){		if(xfauthwrite(xf, offset, argptr, count) < 0)			return error(reply, NFSERR_IO);	}else{		if(xfopen(xf, Owrite) < 0)			return error(reply, NFSERR_PERM);		s = xf->xp->s;		setfid(s, xf->opfid);		xf->opfid->tstale = nfstime + 60;		s->f.offset = offset;		s->f.count = count;		s->f.data = (char *)argptr;		if(xmesg(s, Twrite) < 0)			return error(reply, NFSERR_IO);	}	if(xfstat(xf, &dir) < 0)

⌨️ 快捷键说明

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