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