207 lines · 3.2 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <fcall.h>#include <thread.h>#include <9p.h> uint time0; enum{	Qroot = 0,	Qkid,}; char *kidname;uint kidmode; voidfsattach(Req *r){	char *spec; 	spec = r->ifcall.aname;	if(spec && spec[0]){		respond(r, "invalid attach specifier");		return;	}	r->ofcall.qid = (Qid){Qroot, 0, QTDIR};	r->fid->qid = r->ofcall.qid;	respond(r, nil);} char*fswalk1(Fid *fid, char *name, Qid *qid){	switch((int)fid->qid.path){	default:		return "path not found";	case Qroot:		if(strcmp(name, "..") == 0)			break;		if(strcmp(name, kidname) == 0){			fid->qid = (Qid){Qkid, 0, kidmode>>24};			break;		}		return "path not found";	case Qkid:		if(strcmp(name, "..") == 0){			fid->qid = (Qid){Qroot, 0, QTDIR};			break;		}		return "path not found";	}	*qid = fid->qid;	return nil;} voidfsstat(Req *r){	int q;	Dir *d; 	d = &r->d;	memset(d, 0, sizeof *d);	q = r->fid->qid.path;	d->qid = r->fid->qid;	switch(q){	case Qroot:		d->name = estrdup9p("/");		d->mode = DMDIR|0777;		break; 	case Qkid:		d->name = estrdup9p(kidname);		d->mode = kidmode;		break;	} 	d->atime = d->mtime = time0;	d->uid = estrdup9p("stub");	d->gid = estrdup9p("stub");	d->muid = estrdup9p("");	respond(r, nil);} intdirgen(int off, Dir *d, void*){	if(off != 0)		return -1; 	memset(d, 0, sizeof *d);	d->atime = d->mtime = time0;	d->name = estrdup9p(kidname);	d->mode = kidmode;	d->qid = (Qid){Qkid, 0, kidmode>>24};	d->qid.type = d->mode>>24;	d->uid = estrdup9p("stub");	d->gid = estrdup9p("stub");	d->muid = estrdup9p("");	return 0;} voidfsread(Req *r){	int q; 	q = r->fid->qid.path;	switch(q){	default:		respond(r, "bug");		return; 	case Qroot:		dirread9p(r, dirgen, nil);		respond(r, nil);		return;	}} voidfswrite(Req *r){	respond(r, "no writing");} voidfsopen(Req *r){	if(r->fid->qid.path != Qroot){		respond(r, "permission denied");		return;	} 	if(r->ifcall.mode != OREAD)		respond(r, "permission denied");	else		respond(r, nil);} Srv fs = {	.attach=	fsattach,	.open=	fsopen,	.read=	fsread,	.write=	fswrite,	.stat=	fsstat,	.walk1=	fswalk1,}; voidusage(void){	fprint(2, "usage: aux/stub [-Dd] path/name\n");	exits("usage");} voidmain(int argc, char **argv){	char *p, *mtpt; 	quotefmtinstall(); 	time0 = time(0);	ARGBEGIN{	case 'D':		chatty9p++;		break;	case 'd':		kidmode = DMDIR;		break;	default:		usage();	}ARGEND 	if(argc != 1)		usage(); 	if((p = strrchr(argv[0], '/')) == 0){		mtpt = ".";		kidname = argv[0];	}else if(p == argv[0]){		mtpt = "/";		kidname = argv[0]+1;	}else{		mtpt = argv[0];		*p++ = '\0';		kidname = p;	}	/* don't leave standard descriptors open to confuse mk */	close(0);	close(1);	close(2);	postmountsrv(&fs, nil, mtpt, MBEFORE);	exits(nil);}