📄 nfsserver.c
字号:
#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 + -