/* * 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);}
/*
* 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;
void
fsattach(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;
}
void
fsstat(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);
}
int
dirgen(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;
}
void
fsread(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;
}
}
void
fswrite(Req *r)
{
respond(r, "no writing");
}
void
fsopen(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,
};
void
usage(void)
{
fprint(2, "usage: aux/stub [-Dd] path/name\n");
exits("usage");
}
void
main(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);
}