diff options
| author | rsc <devnull@localhost> | 2005-02-13 05:58:45 +0000 |
|---|---|---|
| committer | rsc <devnull@localhost> | 2005-02-13 05:58:45 +0000 |
| commit | 0f8ec41b0ae522b73085fa1662461e6351ba7e54 (patch) | |
| tree | 2d54cfd8208bdd903273ccc7df889677cf7fe8d5 /src/cmd/factotum/fs.c | |
| parent | 7637c81af02c49ef508b946dfdec39f757a658d4 (diff) | |
| download | plan9port-0f8ec41b0ae522b73085fa1662461e6351ba7e54.tar.gz plan9port-0f8ec41b0ae522b73085fa1662461e6351ba7e54.zip | |
moving to auth
Diffstat (limited to 'src/cmd/factotum/fs.c')
| -rw-r--r-- | src/cmd/factotum/fs.c | 531 |
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, -}; - |
