summaryrefslogtreecommitdiffstats
path: root/src/cmd/factotum/fs.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-02-13 05:58:45 +0000
committerrsc <devnull@localhost>2005-02-13 05:58:45 +0000
commit0f8ec41b0ae522b73085fa1662461e6351ba7e54 (patch)
tree2d54cfd8208bdd903273ccc7df889677cf7fe8d5 /src/cmd/factotum/fs.c
parent7637c81af02c49ef508b946dfdec39f757a658d4 (diff)
downloadplan9port-0f8ec41b0ae522b73085fa1662461e6351ba7e54.tar.gz
plan9port-0f8ec41b0ae522b73085fa1662461e6351ba7e54.zip
moving to auth
Diffstat (limited to 'src/cmd/factotum/fs.c')
-rw-r--r--src/cmd/factotum/fs.c531
1 files changed, 0 insertions, 531 deletions
diff --git a/src/cmd/factotum/fs.c b/src/cmd/factotum/fs.c
deleted file mode 100644
index f9ad785b..00000000
--- a/src/cmd/factotum/fs.c
+++ /dev/null
@@ -1,531 +0,0 @@
-#include "std.h"
-#include "dat.h"
-
-enum
-{
- Qroot,
- Qfactotum,
- Qrpc,
- Qkeylist,
- Qprotolist,
- Qconfirm,
- Qlog,
- Qctl,
- Qneedkey,
- Qconv,
-};
-
-static int qtop;
-
-Qid
-mkqid(int type, int path)
-{
- Qid q;
-
- q.type = type;
- q.path = path;
- q.vers = 0;
- return q;
-}
-
-static struct
-{
- char *name;
- int qidpath;
- ulong perm;
-} dirtab[] = {
- /* positions of confirm and needkey known below */
- "confirm", Qconfirm, 0600|DMEXCL,
- "needkey", Qneedkey, 0600|DMEXCL,
- "ctl", Qctl, 0600,
- "rpc", Qrpc, 0666,
- "proto", Qprotolist, 0444,
- "log", Qlog, 0600|DMEXCL,
- "conv", Qconv, 0400,
-};
-
-static void
-fillstat(Dir *dir, char *name, int type, int path, ulong perm)
-{
- dir->name = estrdup(name);
- dir->uid = estrdup(owner);
- dir->gid = estrdup(owner);
- dir->mode = perm;
- dir->length = 0;
- dir->qid = mkqid(type, path);
- dir->atime = time(0);
- dir->mtime = time(0);
- dir->muid = estrdup("");
-}
-
-static int
-rootdirgen(int n, Dir *dir, void *v)
-{
- USED(v);
-
- if(n > 0)
- return -1;
-
- fillstat(dir, factname, QTDIR, Qfactotum, DMDIR|0555);
- return 0;
-}
-
-static int
-fsdirgen(int n, Dir *dir, void *v)
-{
- USED(v);
-
- if(n >= nelem(dirtab))
- return -1;
- fillstat(dir, dirtab[n].name, 0, dirtab[n].qidpath, dirtab[n].perm);
- return 0;
-}
-
-static char*
-fswalk1(Fid *fid, char *name, Qid *qid)
-{
- int i;
-
- switch((int)fid->qid.path){
- default:
- return "fswalk1: cannot happen";
- case Qroot:
- if(strcmp(name, factname) == 0){
- *qid = mkqid(QTDIR, Qfactotum);
- fid->qid = *qid;
- return nil;
- }
- if(strcmp(name, "..") == 0){
- *qid = fid->qid;
- return nil;
- }
- return "not found";
- case Qfactotum:
- for(i=0; i<nelem(dirtab); i++)
- if(strcmp(name, dirtab[i].name) == 0){
- *qid = mkqid(0, dirtab[i].qidpath);
- fid->qid = *qid;
- return nil;
- }
- if(strcmp(name, "..") == 0){
- *qid = mkqid(QTDIR, qtop);
- fid->qid = *qid;
- return nil;
- }
- return "not found";
- }
-}
-
-static void
-fsstat(Req *r)
-{
- int i, path;
-
- path = r->fid->qid.path;
- switch(path){
- case Qroot:
- fillstat(&r->d, "/", QTDIR, Qroot, 0555|DMDIR);
- break;
- case Qfactotum:
- fillstat(&r->d, "factotum", QTDIR, Qfactotum, 0555|DMDIR);
- break;
- default:
- for(i=0; i<nelem(dirtab); i++)
- if(dirtab[i].qidpath == path){
- fillstat(&r->d, dirtab[i].name, 0, dirtab[i].qidpath, dirtab[i].perm);
- goto Break2;
- }
- respond(r, "file not found");
- break;
- }
- Break2:
- respond(r, nil);
-}
-
-static int
-readlist(int off, int (*gen)(int, char*, uint), Req *r)
-{
- char *a, *ea;
- int n;
-
- a = r->ofcall.data;
- ea = a+r->ifcall.count;
- for(;;){
- n = (*gen)(off, a, ea-a);
- if(n == 0){
- r->ofcall.count = a - (char*)r->ofcall.data;
- return off;
- }
- a += n;
- off++;
- }
- return -1; /* not reached */
-}
-
-static int
-keylist(int i, char *a, uint nn)
-{
- int n;
- char buf[512];
- Key *k;
-
- if(i >= ring.nkey)
- return 0;
-
- k = ring.key[i];
- k->attr = sortattr(k->attr);
- n = snprint(buf, sizeof buf, "key %A %N\n", k->attr, k->privattr);
- if(n >= sizeof(buf)-5)
- strcpy(buf+sizeof(buf)-5, "...\n");
- n = strlen(buf);
- if(n > nn)
- return 0;
- memmove(a, buf, n);
- return n;
-}
-
-static int
-protolist(int i, char *a, uint n)
-{
- if(prototab[i] == nil)
- return 0;
- if(strlen(prototab[i]->name)+1 > n)
- return 0;
- n = strlen(prototab[i]->name)+1;
- memmove(a, prototab[i]->name, n-1);
- a[n-1] = '\n';
- return n;
-}
-
-/* BUG this is O(n^2) to fill in the list */
-static int
-convlist(int i, char *a, uint nn)
-{
- Conv *c;
- char buf[512];
- int n;
-
- for(c=conv; c && i-- > 0; c=c->next)
- ;
-
- if(c == nil)
- return 0;
-
- if(c->state)
- n = snprint(buf, sizeof buf, "conv state=%q %A\n", c->state, c->attr);
- else
- n = snprint(buf, sizeof buf, "conv state=closed err=%q\n", c->err);
-
- if(n >= sizeof(buf)-5)
- strcpy(buf+sizeof(buf)-5, "...\n");
- n = strlen(buf);
- if(n > nn)
- return 0;
- memmove(a, buf, n);
- return n;
-}
-
-static void
-fskickreply(Conv *c)
-{
- Req *r;
-
- if(c->hangup){
- if(c->req){
- respond(c->req, "hangup");
- c->req = nil;
- }
- return;
- }
-
- if(!c->req || !c->nreply)
- return;
-
- r = c->req;
- r->ofcall.count = c->nreply;
- r->ofcall.data = c->reply;
- if(r->ofcall.count > r->ifcall.count)
- r->ofcall.count = r->ifcall.count;
- respond(r, nil);
- c->req = nil;
- c->nreply = 0;
-}
-
-/*
- * Some of the file system work happens in the fs proc, but
- * fsopen, fsread, fswrite, fsdestroyfid, and fsflush happen in
- * the main proc so that they can access the various shared
- * data structures without worrying about locking.
- */
-static int inuse[nelem(dirtab)];
-int *confirminuse = &inuse[0];
-int *needkeyinuse = &inuse[1];
-static void
-fsopen(Req *r)
-{
- int i, *inusep, perm;
- static int need[4] = { 4, 2, 6, 1 };
- Conv *c;
-
- inusep = nil;
- perm = 5; /* directory */
- for(i=0; i<nelem(dirtab); i++)
- if(dirtab[i].qidpath == r->fid->qid.path){
- if(dirtab[i].perm & DMEXCL)
- inusep = &inuse[i];
- if(strcmp(r->fid->uid, owner) == 0)
- perm = dirtab[i].perm>>6;
- else
- perm = dirtab[i].perm;
- break;
- }
-
- if((r->ifcall.mode&~(OMASK|OTRUNC))
- || (need[r->ifcall.mode&3] & ~perm)){
- respond(r, "permission denied");
- return;
- }
-
- if(inusep){
- if(*inusep){
- respond(r, "file in use");
- return;
- }
- *inusep = 1;
- }
-
- if(r->fid->qid.path == Qrpc){
- if((c = convalloc(r->fid->uid)) == nil){
- char e[ERRMAX];
-
- rerrstr(e, sizeof e);
- respond(r, e);
- return;
- }
- c->kickreply = fskickreply;
- r->fid->aux = c;
- }
-
- respond(r, nil);
-}
-
-static void
-fsread(Req *r)
-{
- Conv *c;
-
- switch((int)r->fid->qid.path){
- default:
- respond(r, "fsread: cannot happen");
- break;
- case Qroot:
- dirread9p(r, rootdirgen, nil);
- respond(r, nil);
- break;
- case Qfactotum:
- dirread9p(r, fsdirgen, nil);
- respond(r, nil);
- break;
- case Qrpc:
- c = r->fid->aux;
- if(c->rpc.op == RpcUnknown){
- respond(r, "no rpc pending");
- break;
- }
- if(c->req){
- respond(r, "read already pending");
- break;
- }
- c->req = r;
- if(c->nreply)
- (*c->kickreply)(c);
- else
- rpcexec(c);
- break;
- case Qconfirm:
- confirmread(r);
- break;
- case Qlog:
- logread(r);
- break;
- case Qctl:
- r->fid->aux = (void*)readlist((int)r->fid->aux, keylist, r);
- respond(r, nil);
- break;
- case Qneedkey:
- needkeyread(r);
- break;
- case Qprotolist:
- r->fid->aux = (void*)readlist((int)r->fid->aux, protolist, r);
- respond(r, nil);
- break;
- case Qconv:
- r->fid->aux = (void*)readlist((int)r->fid->aux, convlist, r);
- respond(r, nil);
- break;
- }
-}
-
-static void
-fswrite(Req *r)
-{
- int ret;
- char err[ERRMAX], *s;
- int (*strfn)(char*);
-
- switch((int)r->fid->qid.path){
- default:
- respond(r, "fswrite: cannot happen");
- break;
- case Qrpc:
- if(rpcwrite(r->fid->aux, r->ifcall.data, r->ifcall.count) < 0){
- rerrstr(err, sizeof err);
- respond(r, err);
- }else{
- r->ofcall.count = r->ifcall.count;
- respond(r, nil);
- }
- break;
- case Qneedkey:
- strfn = needkeywrite;
- goto string;
- case Qctl:
- strfn = ctlwrite;
- goto string;
- case Qconfirm:
- strfn = confirmwrite;
- string:
- s = emalloc(r->ifcall.count+1);
- memmove(s, r->ifcall.data, r->ifcall.count);
- s[r->ifcall.count] = '\0';
- ret = (*strfn)(s);
- free(s);
- if(ret < 0){
- rerrstr(err, sizeof err);
- respond(r, err);
- }else{
- r->ofcall.count = r->ifcall.count;
- respond(r, nil);
- }
- break;
- }
-}
-
-static void
-fsflush(Req *r)
-{
- confirmflush(r);
- logflush(r);
-}
-
-static void
-fsdestroyfid(Fid *fid)
-{
- if(fid->qid.path == Qrpc && fid->aux){
- convhangup(fid->aux);
- convclose(fid->aux);
- }
-}
-
-static Channel *creq;
-static Channel *cfid, *cfidr;
-
-static void
-fsreqthread(void *v)
-{
- Req *r;
-
- USED(v);
-
- while((r = recvp(creq)) != nil){
- switch(r->ifcall.type){
- default:
- respond(r, "bug in fsreqthread");
- break;
- case Topen:
- fsopen(r);
- break;
- case Tread:
- fsread(r);
- break;
- case Twrite:
- fswrite(r);
- break;
- case Tflush:
- fsflush(r);
- break;
- }
- }
-}
-
-static void
-fsclunkthread(void *v)
-{
- Fid *f;
-
- USED(v);
-
- while((f = recvp(cfid)) != nil){
- fsdestroyfid(f);
- sendp(cfidr, 0);
- }
-}
-
-static void
-fsproc(void *v)
-{
- USED(v);
-
- threadcreate(fsreqthread, nil, STACK);
- threadcreate(fsclunkthread, nil, STACK);
- threadexits(nil);
-}
-
-static void
-fsattach(Req *r)
-{
- r->fid->qid = mkqid(QTDIR, qtop);
- r->ofcall.qid = r->fid->qid;
- respond(r, nil);
-}
-
-static void
-fssend(Req *r)
-{
- sendp(creq, r);
-}
-
-static void
-fssendclunk(Fid *f)
-{
- sendp(cfid, f);
- recvp(cfidr);
-}
-
-void
-fsstart(Srv *s)
-{
- USED(s);
-
- if(extrafactotumdir)
- qtop = Qroot;
- else
- qtop = Qfactotum;
- creq = chancreate(sizeof(Req*), 0);
- cfid = chancreate(sizeof(Fid*), 0);
- cfidr = chancreate(sizeof(Fid*), 0);
- proccreate(fsproc, nil, STACK);
-}
-
-Srv fs = {
-.attach= fsattach,
-.walk1= fswalk1,
-.open= fssend,
-.read= fssend,
-.write= fssend,
-.stat= fsstat,
-.flush= fssend,
-.destroyfid= fssendclunk,
-.start= fsstart,
-};
-