From e5888a1ffdae813d7575f5fb02275c6bb07e5199 Mon Sep 17 00:00:00 2001 From: Taru Karttunen Date: Wed, 30 Mar 2011 15:46:40 +0300 Subject: Import sources from 2011-03-30 iso image --- sys/src/cmd/mntgen.c | 242 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100755 sys/src/cmd/mntgen.c (limited to 'sys/src/cmd/mntgen.c') diff --git a/sys/src/cmd/mntgen.c b/sys/src/cmd/mntgen.c new file mode 100755 index 000000000..2e6a0a442 --- /dev/null +++ b/sys/src/cmd/mntgen.c @@ -0,0 +1,242 @@ +#include +#include +#include +#include +#include <9p.h> +#include +#include + +static void +usage(void) +{ + fprint(2, "mntgen [-s srvname] [mtpt]\n"); + exits("usage"); +} + +ulong time0; + +typedef struct Tab Tab; +struct Tab +{ + char *name; + vlong qid; + ulong time; + int ref; +}; + +Tab *tab; +int ntab; +int mtab; + +static Tab* +findtab(vlong path) +{ + int i; + + for(i=0; iifcall.mode != OREAD) + respond(r, "permission denied"); + else + respond(r, nil); +} + +static int +dirgen(int i, Dir *d, void*) +{ + if(i >= ntab) + return -1; + memset(d, 0, sizeof *d); + d->qid.type = QTDIR; + d->uid = estrdup9p("sys"); + d->gid = estrdup9p("sys"); + d->mode = DMDIR|0555; + d->length = 0; + if(i == -1){ + d->name = estrdup9p("/"); + d->atime = d->mtime = time0; + }else{ + d->qid.path = tab[i].qid; + d->name = estrdup9p(tab[i].name); + d->atime = d->mtime = tab[i].time; + } + return 0; +} + +static void +fsread(Req *r) +{ + if(r->fid->qid.path == 0) + dirread9p(r, dirgen, nil); + else + r->ofcall.count = 0; + respond(r, nil); +} + +static void +fsstat(Req *r) +{ + Tab *t; + vlong qid; + + qid = r->fid->qid.path; + if(qid == 0) + dirgen(-1, &r->d, nil); + else{ + if((t = findtab(qid)) == nil){ + respond(r, "path not found (???)"); + return; + } + dirgen(t-tab, &r->d, nil); + } + respond(r, nil); +} + +static char* +fswalk1(Fid *fid, char *name, void*) +{ + int i; + Tab *t; + vlong h; + + if(fid->qid.path != 0){ + /* nothing in child directory */ + if(strcmp(name, "..") == 0){ + if((t = findtab(fid->qid.path)) != nil) + t->ref--; + fid->qid.path = 0; + return nil; + } + return "path not found"; + } + /* root */ + if(strcmp(name, "..") == 0) + return nil; + for(i=0; iqid.path = tab[i].qid; + return nil; + } + h = hash(name); + if(findtab(h) != nil) + return "hash collision"; + + /* create it */ + if(ntab == mtab){ + if(mtab == 0) + mtab = 16; + else + mtab *= 2; + tab = erealloc9p(tab, sizeof(tab[0])*mtab); + } + tab[ntab].qid = h; + fid->qid.path = tab[ntab].qid; + tab[ntab].name = estrdup9p(name); + tab[ntab].time = time(0); + tab[ntab].ref = 1; + ntab++; + + return nil; +} + +static char* +fsclone(Fid *fid, Fid*, void*) +{ + Tab *t; + + if((t = findtab(fid->qid.path)) != nil) + t->ref++; + return nil; +} + +static void +fswalk(Req *r) +{ + walkandclone(r, fswalk1, fsclone, nil); +} + +static void +fsclunk(Fid *fid) +{ + Tab *t; + vlong qid; + + qid = fid->qid.path; + if(qid == 0) + return; + if((t = findtab(qid)) == nil){ + fprint(2, "warning: cannot find %llux\n", qid); + return; + } + if(--t->ref == 0){ + free(t->name); + tab[t-tab] = tab[--ntab]; + }else if(t->ref < 0) + fprint(2, "warning: negative ref count for %s\n", t->name); +} + +static void +fsattach(Req *r) +{ + char *spec; + + spec = r->ifcall.aname; + if(spec && spec[0]){ + respond(r, "invalid attach specifier"); + return; + } + + r->ofcall.qid = (Qid){0, 0, QTDIR}; + r->fid->qid = r->ofcall.qid; + respond(r, nil); +} + +Srv fs= +{ +.attach= fsattach, +.open= fsopen, +.read= fsread, +.stat= fsstat, +.walk= fswalk, +.destroyfid= fsclunk +}; + +void +main(int argc, char **argv) +{ + char *service; + + time0 = time(0); + service = nil; + ARGBEGIN{ + case 'D': + chatty9p++; + break; + case 's': + service = EARGF(usage()); + break; + default: + usage(); + }ARGEND + + if(argc > 1) + usage(); + postmountsrv(&fs, service, argc ? argv[0] : "/n", MAFTER); + exits(nil); +} -- cgit v1.2.3