示例#1
0
static int
remov(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;
}
示例#2
0
文件: 9p.c 项目: 99years/plan9
int
clunkfid(Session *s, Fid *f)
{
	putfid(s, f);
	if(s == 0 || f == 0)
		return 0;
	s->f.fid = f - s->fids;
	return xmesg(s, Tclunk);
}
示例#3
0
static int
dowrite(Session *s, Fid *f, void *buf, int n)
{
	s->f.fid = f - s->fids;
	s->f.offset = 0;
	s->f.count = n;
	s->f.data = (char *)buf;
	if(xmesg(s, Twrite) < 0)
		return -1;
	return n;
}
示例#4
0
static int
doread(Session *s, Fid *f, void *buf, int n)
{
	s->f.fid = f - s->fids;
	s->f.offset = 0;
	s->f.count = n;
	if(xmesg(s, Tread) < 0)
		return -1;
	n = s->f.count;
	memmove(buf, s->f.data, n);
	return n;
}
示例#5
0
static int
nfsread(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;
}
示例#6
0
文件: 9p.c 项目: 99years/plan9
Fid *
newfid(Session *s)
{
	Fid *f, *fN;

	chat("newfid..");
	if(s->list.prev == 0){
		chat("init..");
		s->list.prev = &s->list;
		s->list.next = &s->list;
		s->free = s->fids;
		if(0 && chatty)
			fN = &s->fids[25];
		else
			fN = &s->fids[nelem(s->fids)];
		for(f=s->fids; f<fN; f++){
			f->owner = 0;
			f->prev = 0;
			f->next = f+1;
		}
		(f-1)->next = 0;
	}
	if(s->free){
		f = s->free;
		s->free = f->next;
		LINK(&s->list, f);
	}else{
		for(f=s->list.prev; f!=&s->list; f=f->prev)
			if(f->owner)
				break;
		if(f == &s->list){
			clog("fid leak");
			return 0;
		}
		setfid(s, f);
		if(xmesg(s, Tclunk) < 0){
			clog("clunk failed, no fids?");
			/*return 0;*/
		}
		*(f->owner) = 0;
		f->owner = 0;
	}
	chat("%ld...", f - s->fids);
	f->tstale = nfstime + staletime;
	return f;
}
示例#7
0
int
xfstat(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;
}
示例#8
0
static int
nfswrite(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)
		return error(reply, NFSERR_IO);
	PLONG(NFS_OK);
	dataptr += dir2fattr(cmd->up, &dir, dataptr);
	chat("OK\n");
	return dataptr - (uchar *)reply->results;
}
示例#9
0
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;
}
示例#10
0
int
xfwstat(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;
}
示例#11
0
/* returns 0 if auth succeeded (or unneeded), -1 otherwise */
int
authhostowner(Session *s)
{
	Fid *af, *f;
	int rv = -1;
	int afd;
	AuthInfo *ai;
	AuthRpc *rpc;

	/* get a fid to authenticate over */
	f = nil;
	af = newfid(s);
	s->f.afid = af - s->fids;
	s->f.uname = getuser();
	s->f.aname = s->spec;
	if(xmesg(s, Tauth)){
		/* not needed */
		rv = 0;
		goto out;
	}

	quotefmtinstall();	/* just in case */

	afd = open("/mnt/factotum/rpc", ORDWR);
	if(afd < 0){
		werrstr("opening /mnt/factotum/rpc: %r");
		goto out;
	}

	rpc = auth_allocrpc(afd);
	if(rpc == nil)
		goto out;

	ai = authproto(s, af, rpc, auth_getkey, "proto=p9any role=client");
	if(ai != nil){
		rv = 0;
		auth_freeAI(ai);
	}
	auth_freerpc(rpc);
	close(afd);

	/* try attaching with the afid */
	chat("attaching as hostowner...");
	f = newfid(s);
	s->f.fid = f - s->fids;
	s->f.afid = af - s->fids;;
	s->f.uname = getuser();
	s->f.aname = s->spec;
	if(xmesg(s, Tattach) == 0)
		rv = 0;
out:
	if(af != nil){
		putfid(s, af);
		s->f.fid = af - s->fids;
		xmesg(s, Tclunk);
	}
	if(f != nil){
		putfid(s, f);
		s->f.fid = f - s->fids;
		xmesg(s, Tclunk);
	}

	return rv;
}
示例#12
0
文件: nfsmount.c 项目: 99years/plan9
void
srvinit(int fd, char *file, char *addr)
{
	char fdservice[16], *naddr;
	Session *s;
	Xfile *xp;
	Xfid *xf;
	Fid *f;

	s = calloc(1, sizeof(Session));
	s->spec = "";
	s->fd = -1;
	if(fd >= 0){
		s->fd = fd;
		sprint(fdservice, "/fd/%d", s->fd);
		s->service = strstore(fdservice);
		chat("fd = %d\n", s->fd);
	}else if(file){
		chat("file = \"%s\"\n", file);
		s->service = file;
		s->fd = open(file, ORDWR);
		if(s->fd < 0){
			clog("can't open %s: %r\n", file);
			goto error;
		}
	}else if(addr){
		chat("addr = \"%s\"\n", addr);
		naddr = netmkaddr(addr, 0, "9fs");
		s->service = addr;
		s->fd = dial(naddr, 0, 0, 0);
		if(s->fd < 0){
			clog("can't dial %s: %r\n", naddr);
			goto error;
		}
	}

	chat("version...");
	s->tag = NOTAG-1;
	s->f.msize = Maxfdata+IOHDRSZ;
	s->f.version = "9P2000";
	xmesg(s, Tversion);
	messagesize = IOHDRSZ+s->f.msize;
	chat("version spec %s size %d\n", s->f.version, s->f.msize);

	s->tag = 0;

	chat("authenticate...");
	if(authhostowner(s) < 0){
		clog("auth failed %r\n");
		goto error;
	}

	chat("attach as none...");
	f = newfid(s);
	s->f.fid = f - s->fids;
	s->f.afid = ~0x0UL;
	s->f.uname = "none";
	s->f.aname = s->spec;
	if(xmesg(s, Tattach)){
		clog("attach failed\n");
		goto error;
	}

	xp = xfile(&s->f.qid, s, 1);
	s->root = xp;
	xp->parent = xp;
	xp->name = "/";
	xf = xfid("none", xp, 1);
	xf->urfid = f;
	clog("service=%s uid=%s fid=%ld\n",
		s->service, xf->uid, xf->urfid - s->fids);
	if(tail)
		tail->next = s;
	else
		head = s;
	tail = s;
	return;

error:
	if(s->fd >= 0)
		close(s->fd);
	free(s);
}
示例#13
0
static int
nfsreaddir(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;
}