ref: 77e279201d08529a662b3f31b8c2c65683a55ebe
parent: cb474632d3f23de10fea2d70a4b4c98d8f3a3755
author: cinap_lenrek <[email protected]>
date: Fri Aug 21 15:52:57 EDT 2015
remove kfs and kfscmd
--- a/sys/src/cmd/disk/kfs/9p1.c
+++ /dev/null
@@ -1,1446 +1,0 @@
-#include "all.h"
-#include "9p1.h"
-
-/*
- * buggery to give false qid for
- * the top 2 levels of the dump fs
- */
-void
-mkqid(Qid* qid, Dentry *d, int buggery)
-{
- int c;
-
- if(buggery && d->qid.path == QPROOT && (d->qid.path & QPDIR)){
- c = d->name[0];
- if(c >= '0' && c <= '9'){
- qid->path = 3;
- qid->vers = d->qid.version;
- qid->type = QTDIR;
-
- c = (c-'0')*10 + (d->name[1]-'0');
- if(c >= 1 && c <= 12)
- qid->path = 4;
- return;
- }
- }
-
- mkqid9p2(qid, &d->qid, d->mode);
-}
-
-int
-mkqidcmp(Qid* qid, Dentry *d)
-{
- Qid tmp;
-
- mkqid(&tmp, d, 1);
- if(qid->path==tmp.path && (qid->type&QTDIR)==(tmp.type&QTDIR))
- return 0;
- return Eqid;
-}
-
-void
-f_nop(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-
- USED(in);
- USED(ou);
- if(CHAT(cp))
- print("c_nop %d\n", cp->chan);
-}
-
-void
-f_flush(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-
- USED(in);
- USED(ou);
- if(CHAT(cp))
- print("c_flush %d\n", cp->chan);
- runlock(&cp->reflock);
- wlock(&cp->reflock);
- wunlock(&cp->reflock);
- rlock(&cp->reflock);
-}
-
-void
-f_session(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- if(CHAT(cp))
- print("c_session %d\n", cp->chan);
-
- memmove(cp->rchal, in->chal, sizeof(cp->rchal));
- if(wstatallow || cp == cons.srvchan){
- memset(ou->chal, 0, sizeof(ou->chal));
- memset(ou->authid, 0, sizeof(ou->authid));
- }else{
- mkchallenge(cp);
- memmove(ou->chal, cp->chal, sizeof(ou->chal));
- memmove(ou->authid, nvr.authid, sizeof(ou->authid));
- }
- sprint(ou->authdom, "%s.%s", service, nvr.authdom);
- fileinit(cp);
-}
-
-void
-f_attach(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- Iobuf *p;
- Dentry *d;
- File *f;
- int u;
- Filsys *fs;
- long raddr;
-
- if(CHAT(cp)) {
- print("c_attach %d\n", cp->chan);
- print(" fid = %d\n", in->fid);
- print(" uid = %s\n", in->uname);
- print(" arg = %s\n", in->aname);
- }
-
- ou->qid = QID9P1(0,0);
- ou->fid = in->fid;
- if(!in->aname[0]) /* default */
- strncpy(in->aname, filesys[0].name, sizeof(in->aname));
- p = 0;
- f = filep(cp, in->fid, 1);
- if(!f) {
- ou->err = Efid;
- goto out;
- }
- u = -1;
- if(cp != cons.chan){
- if(authorize(cp, in, ou) == 0 || strcmp(in->uname, "adm") == 0){
- ou->err = Eauth;
- goto out;
- }
- u = strtouid(in->uname);
- if(u < 0){
- ou->err = Ebadu;
- goto out;
- }
- }
-
- fs = fsstr(in->aname);
- if(fs == 0) {
- ou->err = Ebadspc;
- goto out;
- }
- raddr = getraddr(fs->dev);
- p = getbuf(fs->dev, raddr, Bread);
- d = getdir(p, 0);
- if(!d || checktag(p, Tdir, QPROOT) || !(d->mode & DALLOC)) {
- ou->err = Ealloc;
- goto out;
- }
- f->uid = u;
- if(iaccess(f, d, DREAD)) {
- ou->err = Eaccess;
- goto out;
- }
- accessdir(p, d, FREAD);
- mkqid(&f->qid, d, 1);
- f->fs = fs;
- f->addr = raddr;
- f->slot = 0;
- f->open = 0;
- freewp(f->wpath);
- f->wpath = 0;
-
- mkqid9p1(&ou->qid, &f->qid);
-
-out:
- if(p)
- putbuf(p);
- if(f) {
- qunlock(f);
- if(ou->err)
- freefp(f);
- }
-}
-
-void
-f_clone(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- File *f1, *f2;
- int fid, fid1;
-
- if(CHAT(cp)) {
- print("c_clone %d\n", cp->chan);
- print(" old fid = %d\n", in->fid);
- print(" new fid = %d\n", in->newfid);
- }
-
- fid = in->fid;
- fid1 = in->newfid;
-
- f1 = 0;
- f2 = 0;
- if(fid < fid1) {
- f1 = filep(cp, fid, 0);
- f2 = filep(cp, fid1, 1);
- } else
- if(fid1 < fid) {
- f2 = filep(cp, fid1, 1);
- f1 = filep(cp, fid, 0);
- }
- if(!f1 || !f2) {
- ou->err = Efid;
- goto out;
- }
-
-
- f2->fs = f1->fs;
- f2->addr = f1->addr;
- f2->open = f1->open & ~FREMOV;
- f2->uid = f1->uid;
- f2->slot = f1->slot;
- f2->qid = f1->qid;
-
- freewp(f2->wpath);
- f2->wpath = getwp(f1->wpath);
-
-out:
- ou->fid = fid;
- if(f1)
- qunlock(f1);
- if(f2)
- qunlock(f2);
-}
-
-void
-f_walk(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- Iobuf *p, *p1;
- Dentry *d, *d1;
- File *f;
- Wpath *w, *ow;
- int slot;
- long addr;
-
- if(CHAT(cp)) {
- print("c_walk %d\n", cp->chan);
- print(" fid = %d\n", in->fid);
- print(" name = %s\n", in->name);
- }
-
- ou->fid = in->fid;
- ou->qid = QID9P1(0,0);
- p = 0;
- f = filep(cp, in->fid, 0);
- if(!f) {
- ou->err = Efid;
- goto out;
- }
- p = getbuf(f->fs->dev, f->addr, Bread);
- d = getdir(p, f->slot);
- if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
- ou->err = Ealloc;
- goto out;
- }
- if(!(d->mode & DDIR)) {
- ou->err = Edir1;
- goto out;
- }
- if(ou->err = mkqidcmp(&f->qid, d))
- goto out;
- if(cp != cons.chan && iaccess(f, d, DEXEC)) {
- ou->err = Eaccess;
- goto out;
- }
- accessdir(p, d, FREAD);
- if(strcmp(in->name, ".") == 0)
- goto setdot;
- if(strcmp(in->name, "..") == 0) {
- if(f->wpath == 0)
- goto setdot;
- putbuf(p);
- p = 0;
- addr = f->wpath->addr;
- slot = f->wpath->slot;
- p1 = getbuf(f->fs->dev, addr, Bread);
- d1 = getdir(p1, slot);
- if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
- if(p1)
- putbuf(p1);
- ou->err = Ephase;
- goto out;
- }
- ow = f->wpath;
- f->wpath = ow->up;
- putwp(ow);
- goto found;
- }
- for(addr=0;; addr++) {
- p1 = dnodebuf(p, d, addr, 0);
- if(!p1 || checktag(p1, Tdir, d->qid.path) ) {
- if(p1)
- putbuf(p1);
- ou->err = Eentry;
- goto out;
- }
- for(slot=0; slot<DIRPERBUF; slot++) {
- d1 = getdir(p1, slot);
- if(!(d1->mode & DALLOC))
- continue;
- if(strncmp(in->name, d1->name, sizeof(in->name)))
- continue;
- /*
- * update walk path
- */
- w = newwp();
- if(!w) {
- ou->err = Ewalk;
- putbuf(p1);
- goto out;
- }
- w->addr = f->addr;
- w->slot = f->slot;
- w->up = f->wpath;
- f->wpath = w;
- slot += DIRPERBUF*addr;
- goto found;
- }
- putbuf(p1);
- }
-
-found:
- f->addr = p1->addr;
- mkqid(&f->qid, d1, 1);
- putbuf(p1);
- f->slot = slot;
-
-setdot:
- mkqid9p1(&ou->qid, &f->qid);
- f->open = 0;
-
-out:
- if(p)
- putbuf(p);
- if(f)
- qunlock(f);
-}
-
-void
-f_clunk(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- File *f;
- Tlock *t;
- long tim;
-
- if(CHAT(cp)) {
- print("c_clunk %d\n", cp->chan);
- print(" fid = %d\n", in->fid);
- }
-
- f = filep(cp, in->fid, 0);
- if(!f) {
- print("%p\n", f);
- ou->err = Efid;
- goto out;
- }
- if(t = f->tlock) {
- tim = time(0);
- if(t->time < tim || t->file != f)
- ou->err = Ebroken;
- t->time = 0; /* free the lock */
- f->tlock = 0;
- }
- if(f->open & FREMOV)
- ou->err = doremove(f, 0);
- f->open = 0;
- freewp(f->wpath);
- freefp(f);
-
-out:
- if(f)
- qunlock(f);
- ou->fid = in->fid;
-}
-
-void
-f_clwalk(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- int er, fid;
-
- if(CHAT(cp))
- print("c_clwalk macro\n");
-
- f_clone(cp, in, ou); /* sets tag, fid */
- if(ou->err)
- return;
- fid = in->fid;
- in->fid = in->newfid;
- f_walk(cp, in, ou); /* sets tag, fid, qid */
- er = ou->err;
- if(er == Eentry) {
- /*
- * if error is "no entry"
- * return non error and fid
- */
- ou->err = 0;
- f_clunk(cp, in, ou); /* sets tag, fid */
- ou->err = 0;
- ou->fid = fid;
- if(CHAT(cp))
- print(" error: %s\n", errstring[er]);
- return;
- }
- if(er) {
- /*
- * if any other error
- * return an error
- */
- ou->err = 0;
- f_clunk(cp, in, ou); /* sets tag, fid */
- ou->err = er;
- return;
- }
- /*
- * non error
- * return newfid
- */
-}
-
-void
-f_open(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- Iobuf *p;
- Dentry *d;
- File *f;
- Tlock *t;
- Qid qid;
- int ro, fmod;
-
- if(CHAT(cp)) {
- print("c_open %d\n", cp->chan);
- print(" fid = %d\n", in->fid);
- print(" mode = %o\n", in->mode);
- }
-
- p = 0;
- f = filep(cp, in->fid, 0);
- if(!f) {
- ou->err = Efid;
- goto out;
- }
-
- /*
- * if remove on close, check access here
- */
- ro = isro(f->fs->dev) || (cp != cons.chan && writegroup && !ingroup(f->uid, writegroup));
- if(in->mode & MRCLOSE) {
- if(ro) {
- ou->err = Eronly;
- goto out;
- }
- /*
- * check on parent directory of file to be deleted
- */
- if(f->wpath == 0 || f->wpath->addr == f->addr) {
- ou->err = Ephase;
- goto out;
- }
- p = getbuf(f->fs->dev, f->wpath->addr, Bread);
- d = getdir(p, f->wpath->slot);
- if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
- ou->err = Ephase;
- goto out;
- }
- if(iaccess(f, d, DWRITE)) {
- ou->err = Eaccess;
- goto out;
- }
- putbuf(p);
- }
- p = getbuf(f->fs->dev, f->addr, Bread);
- d = getdir(p, f->slot);
- if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
- ou->err = Ealloc;
- goto out;
- }
- if(ou->err = mkqidcmp(&f->qid, d))
- goto out;
- mkqid(&qid, d, 1);
- switch(in->mode & 7) {
-
- case MREAD:
- if(iaccess(f, d, DREAD) && !writeallow)
- goto badaccess;
- fmod = FREAD;
- break;
-
- case MWRITE:
- if((d->mode & DDIR) ||
- (iaccess(f, d, DWRITE) && !writeallow))
- goto badaccess;
- if(ro) {
- ou->err = Eronly;
- goto out;
- }
- fmod = FWRITE;
- break;
-
- case MBOTH:
- if((d->mode & DDIR) ||
- (iaccess(f, d, DREAD) && !writeallow) ||
- (iaccess(f, d, DWRITE) && !writeallow))
- goto badaccess;
- if(ro) {
- ou->err = Eronly;
- goto out;
- }
- fmod = FREAD+FWRITE;
- break;
-
- case MEXEC:
- if((d->mode & DDIR) ||
- iaccess(f, d, DEXEC))
- goto badaccess;
- fmod = FREAD;
- break;
-
- default:
- ou->err = Emode;
- goto out;
- }
- if(in->mode & MTRUNC) {
- if((d->mode & DDIR) ||
- (iaccess(f, d, DWRITE) && !writeallow))
- goto badaccess;
- if(ro) {
- ou->err = Eronly;
- goto out;
- }
- }
- t = 0;
- if(d->mode & DLOCK) {
- t = tlocked(p, d);
- if(t == 0) {
- ou->err = Elocked;
- goto out;
- }
- t->file = f;
- }
- if(in->mode & MRCLOSE)
- fmod |= FREMOV;
- f->open = fmod;
- if(in->mode & MTRUNC)
- if(!(d->mode & DAPND))
- dtrunc(p, d);
- f->tlock = t;
- f->lastra = 0;
- mkqid9p1(&ou->qid, &qid);
- goto out;
-
-badaccess:
- ou->err = Eaccess;
- f->open = 0;
-
-out:
- if(p)
- putbuf(p);
- if(f)
- qunlock(f);
- ou->fid = in->fid;
-}
-
-void
-f_create(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- Iobuf *p, *p1;
- Dentry *d, *d1;
- File *f;
- int slot, slot1, fmod;
- long addr, addr1, path;
- Qid qid;
- Tlock *t;
- Wpath *w;
-
- if(CHAT(cp)) {
- print("c_create %d\n", cp->chan);
- print(" fid = %d\n", in->fid);
- print(" name = %s\n", in->name);
- print(" perm = %lx+%lo\n", (in->perm>>28)&0xf,
- in->perm&0777);
- print(" mode = %d\n", in->mode);
- }
-
- p = 0;
- f = filep(cp, in->fid, 0);
- if(!f) {
- ou->err = Efid;
- goto out;
- }
- if(isro(f->fs->dev) || (cp != cons.chan && writegroup && !ingroup(f->uid, writegroup))) {
- ou->err = Eronly;
- goto out;
- }
-
- p = getbuf(f->fs->dev, f->addr, Bread);
- d = getdir(p, f->slot);
- if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
- ou->err = Ealloc;
- goto out;
- }
- if(ou->err = mkqidcmp(&f->qid, d))
- goto out;
- if(!(d->mode & DDIR)) {
- ou->err = Edir2;
- goto out;
- }
- if(cp != cons.chan && iaccess(f, d, DWRITE) && !writeallow) {
- ou->err = Eaccess;
- goto out;
- }
- accessdir(p, d, FREAD);
- if(!strncmp(in->name, ".", sizeof(in->name)) ||
- !strncmp(in->name, "..", sizeof(in->name))) {
- ou->err = Edot;
- goto out;
- }
- if(checkname(in->name)) {
- ou->err = Ename;
- goto out;
- }
- addr1 = 0;
- slot1 = 0; /* set */
- for(addr=0;; addr++) {
- p1 = dnodebuf(p, d, addr, 0);
- if(!p1) {
- if(addr1)
- break;
- p1 = dnodebuf(p, d, addr, Tdir);
- }
- if(p1 == 0) {
- ou->err = Efull;
- goto out;
- }
- if(checktag(p1, Tdir, d->qid.path)) {
- putbuf(p1);
- goto phase;
- }
- for(slot=0; slot<DIRPERBUF; slot++) {
- d1 = getdir(p1, slot);
- if(!(d1->mode & DALLOC)) {
- if(!addr1) {
- addr1 = p1->addr;
- slot1 = slot + addr*DIRPERBUF;
- }
- continue;
- }
- if(!strncmp(in->name, d1->name, sizeof(in->name))) {
- putbuf(p1);
- ou->err = Eexist;
- goto out;
- }
- }
- putbuf(p1);
- }
- switch(in->mode & 7) {
- case MEXEC:
- case MREAD: /* seems only useful to make directories */
- fmod = FREAD;
- break;
-
- case MWRITE:
- fmod = FWRITE;
- break;
-
- case MBOTH:
- fmod = FREAD+FWRITE;
- break;
-
- default:
- ou->err = Emode;
- goto out;
- }
- if(in->perm & PDIR)
- if((in->mode & MTRUNC) || (in->perm & PAPND) || (fmod & FWRITE))
- goto badaccess;
- /*
- * do it
- */
- path = qidpathgen(&f->fs->dev);
- p1 = getbuf(f->fs->dev, addr1, Bread|Bimm|Bmod);
- d1 = getdir(p1, slot1);
- if(!d1 || checktag(p1, Tdir, d->qid.path)) {
- if(p1)
- putbuf(p1);
- goto phase;
- }
- if(d1->mode & DALLOC) {
- putbuf(p1);
- goto phase;
- }
-
- strncpy(d1->name, in->name, sizeof(in->name));
- /*
- * bogus argument passing -- see console.c
- */
- if(cp == cons.chan) {
- d1->uid = cons.uid;
- d1->gid = cons.gid;
- } else {
- d1->uid = f->uid;
- d1->gid = d->gid;
- in->perm &= d->mode | ~0666;
- if(in->perm & PDIR)
- in->perm &= d->mode | ~0777;
- }
- d1->qid.path = path;
- d1->qid.version = 0;
- d1->mode = DALLOC | (in->perm & 0777);
- if(in->perm & PDIR) {
- d1->mode |= DDIR;
- d1->qid.path |= QPDIR;
- }
- if(in->perm & PAPND)
- d1->mode |= DAPND;
- t = 0;
- if(in->perm & PLOCK) {
- d1->mode |= DLOCK;
- t = tlocked(p1, d1);
- }
- accessdir(p1, d1, FWRITE);
- mkqid(&qid, d1, 0);
- putbuf(p1);
- accessdir(p, d, FWRITE);
-
- /*
- * do a walk to new directory entry
- */
- w = newwp();
- if(!w) {
- ou->err = Ewalk;
- goto out;
- }
- w->addr = f->addr;
- w->slot = f->slot;
- w->up = f->wpath;
- f->wpath = w;
- f->qid = qid;
- f->tlock = t;
- f->lastra = 0;
- if(in->mode & MRCLOSE)
- fmod |= FREMOV;
- f->open = fmod;
- f->addr = addr1;
- f->slot = slot1;
- if(t)
- t->file = f;
- mkqid9p1(&ou->qid, &qid);
- goto out;
-
-badaccess:
- ou->err = Eaccess;
- goto out;
-
-phase:
- ou->err = Ephase;
-
-out:
- if(p)
- putbuf(p);
- if(f)
- qunlock(f);
- ou->fid = in->fid;
-}
-
-void
-f_read(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- Iobuf *p, *p1;
- File *f;
- Dentry *d, *d1;
- Tlock *t;
- long addr, offset, tim;
- int nread, count, n, o, slot;
-
- if(CHAT(cp)) {
- print("c_read %d\n", cp->chan);
- print(" fid = %d\n", in->fid);
- print(" offset = %ld\n", in->offset);
- print(" count = %ld\n", in->count);
- }
-
- p = 0;
- count = in->count;
- offset = in->offset;
- nread = 0;
- f = filep(cp, in->fid, 0);
- if(!f) {
- ou->err = Efid;
- goto out;
- }
- if(!(f->open & FREAD)) {
- ou->err = Eopen;
- goto out;
- }
- if(count < 0 || count > MAXDAT) {
- ou->err = Ecount;
- goto out;
- }
- if(offset < 0) {
- ou->err = Eoffset;
- goto out;
- }
- p = getbuf(f->fs->dev, f->addr, Bread);
- d = getdir(p, f->slot);
- if(!d || !(d->mode & DALLOC)) {
- ou->err = Ealloc;
- goto out;
- }
- if(ou->err = mkqidcmp(&f->qid, d))
- goto out;
- if(t = f->tlock) {
- tim = time(0);
- if(t->time < tim || t->file != f) {
- ou->err = Ebroken;
- goto out;
- }
- /* renew the lock */
- t->time = tim + TLOCK;
- }
- accessdir(p, d, FREAD);
- if(d->mode & DDIR) {
- addr = 0;
- goto dread;
- }
- if(offset >= d->size)
- count = 0;
- else if(offset+count > d->size)
- count = d->size - offset;
- while(count > 0) {
- addr = offset / BUFSIZE;
- if(addr == f->lastra+1)
- dbufread(p, d, addr+1);
- f->lastra = addr;
- o = offset % BUFSIZE;
- n = BUFSIZE - o;
- if(n > count)
- n = count;
- p1 = dnodebuf(p, d, addr, 0);
- if(p1) {
- if(checktag(p1, Tfile, QPNONE)) {
- ou->err = Ephase;
- putbuf(p1);
- goto out;
- }
- memmove(ou->data+nread, p1->iobuf+o, n);
- putbuf(p1);
- } else
- memset(ou->data+nread, 0, n);
- count -= n;
- nread += n;
- offset += n;
- }
- goto out;
-
-dread:
- p1 = dnodebuf(p, d, addr, 0);
- if(!p1)
- goto out;
- if(checktag(p1, Tdir, QPNONE)) {
- ou->err = Ephase;
- putbuf(p1);
- goto out;
- }
- n = DIRREC;
- for(slot=0; slot<DIRPERBUF; slot++) {
- d1 = getdir(p1, slot);
- if(!(d1->mode & DALLOC))
- continue;
- if(offset >= n) {
- offset -= n;
- continue;
- }
- if(count < n) {
- putbuf(p1);
- goto out;
- }
- if(convD2M9p1(d1, ou->data+nread) != n)
- print("dirread convD2M\n");
- nread += n;
- count -= n;
- }
- putbuf(p1);
- addr++;
- goto dread;
-
-out:
- count = in->count - nread;
- if(count > 0)
- memset(ou->data+nread, 0, count);
- if(p)
- putbuf(p);
- if(f)
- qunlock(f);
- ou->fid = in->fid;
- ou->count = nread;
- if(CHAT(cp))
- print(" nread = %d\n", nread);
-}
-
-void
-f_write(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- Iobuf *p, *p1;
- Dentry *d;
- File *f;
- Tlock *t;
- long offset, addr, tim;
- int count, nwrite, o, n;
-
- if(CHAT(cp)) {
- print("c_write %d\n", cp->chan);
- print(" fid = %d\n", in->fid);
- print(" offset = %ld\n", in->offset);
- print(" count = %ld\n", in->count);
- }
-
- offset = in->offset;
- count = in->count;
- nwrite = 0;
- p = 0;
- f = filep(cp, in->fid, 0);
- if(!f) {
- ou->err = Efid;
- goto out;
- }
- if(!(f->open & FWRITE)) {
- ou->err = Eopen;
- goto out;
- }
- if(isro(f->fs->dev) || (cp != cons.chan && writegroup && !ingroup(f->uid, writegroup))) {
- ou->err = Eronly;
- goto out;
- }
- if(count < 0 || count > MAXDAT) {
- ou->err = Ecount;
- goto out;
- }
- if(offset < 0) {
- ou->err = Eoffset;
- goto out;
- }
- p = getbuf(f->fs->dev, f->addr, Bread|Bmod);
- d = getdir(p, f->slot);
- if(!d || !(d->mode & DALLOC)) {
- ou->err = Ealloc;
- goto out;
- }
- if(ou->err = mkqidcmp(&f->qid, d))
- goto out;
- if(t = f->tlock) {
- tim = time(0);
- if(t->time < tim || t->file != f) {
- ou->err = Ebroken;
- goto out;
- }
- /* renew the lock */
- t->time = tim + TLOCK;
- }
- accessdir(p, d, FWRITE);
- if(d->mode & DAPND)
- offset = d->size;
- if(offset+count > d->size)
- d->size = offset+count;
- while(count > 0) {
- addr = offset / BUFSIZE;
- o = offset % BUFSIZE;
- n = BUFSIZE - o;
- if(n > count)
- n = count;
- p1 = dnodebuf(p, d, addr, Tfile);
- if(p1 == 0) {
- ou->err = Efull;
- goto out;
- }
- if(checktag(p1, Tfile, d->qid.path)) {
- putbuf(p1);
- ou->err = Ephase;
- goto out;
- }
- memmove(p1->iobuf+o, in->data+nwrite, n);
- p1->flags |= Bmod;
- putbuf(p1);
- count -= n;
- nwrite += n;
- offset += n;
- }
- if(CHAT(cp))
- print(" nwrite = %d\n", nwrite);
-
-out:
- if(p)
- putbuf(p);
- if(f)
- qunlock(f);
- ou->fid = in->fid;
- ou->count = nwrite;
-}
-
-int
-doremove(File *f, int iscon)
-{
- Iobuf *p, *p1;
- Dentry *d, *d1;
- long addr;
- int slot, err;
-
- p = 0;
- p1 = 0;
- if(isro(f->fs->dev) || (f->cp != cons.chan && writegroup && !ingroup(f->uid, writegroup))) {
- err = Eronly;
- goto out;
- }
- /*
- * check on parent directory of file to be deleted
- */
- if(f->wpath == 0 || f->wpath->addr == f->addr) {
- err = Ephase;
- goto out;
- }
- p1 = getbuf(f->fs->dev, f->wpath->addr, Bread);
- d1 = getdir(p1, f->wpath->slot);
- if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
- err = Ephase;
- goto out;
- }
- if(!iscon && iaccess(f, d1, DWRITE)) {
- err = Eaccess;
- goto out;
- }
- accessdir(p1, d1, FWRITE);
- putbuf(p1);
- p1 = 0;
-
- /*
- * check on file to be deleted
- */
- p = getbuf(f->fs->dev, f->addr, Bread);
- d = getdir(p, f->slot);
- if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
- err = Ealloc;
- goto out;
- }
- if(err = mkqidcmp(&f->qid, d))
- goto out;
-
- /*
- * if deleting a directory, make sure it is empty
- */
- if((d->mode & DDIR))
- for(addr=0;; addr++) {
- p1 = dnodebuf(p, d, addr, 0);
- if(!p1)
- break;
- if(checktag(p1, Tdir, d->qid.path)) {
- err = Ephase;
- goto out;
- }
- for(slot=0; slot<DIRPERBUF; slot++) {
- d1 = getdir(p1, slot);
- if(!(d1->mode & DALLOC))
- continue;
- err = Eempty;
- goto out;
- }
- putbuf(p1);
- }
-
- /*
- * do it
- */
- dtrunc(p, d);
- memset(d, 0, sizeof(Dentry));
- settag(p, Tdir, QPNONE);
-
-out:
- if(p1)
- putbuf(p1);
- if(p)
- putbuf(p);
- return err;
-}
-
-void
-f_remove(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- File *f;
-
- if(CHAT(cp)) {
- print("c_remove %d\n", cp->chan);
- print(" fid = %d\n", in->fid);
- }
-
- f = filep(cp, in->fid, 0);
- if(!f) {
- ou->err = Efid;
- goto out;
- }
- ou->err = doremove(f, cp==cons.chan);
-
-out:
- ou->fid = in->fid;
- if(f)
- qunlock(f);
-}
-
-void
-f_stat(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- Iobuf *p;
- Dentry *d;
- File *f;
-
- if(CHAT(cp)) {
- print("c_stat %d\n", cp->chan);
- print(" fid = %d\n", in->fid);
- }
-
- p = 0;
- memset(ou->stat, 0, sizeof(ou->stat));
- f = filep(cp, in->fid, 0);
- if(!f) {
- ou->err = Efid;
- goto out;
- }
- p = getbuf(f->fs->dev, f->addr, Bread);
- d = getdir(p, f->slot);
- if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
- ou->err = Ealloc;
- goto out;
- }
- if(ou->err = mkqidcmp(&f->qid, d))
- goto out;
- if(d->qid.path == QPROOT) /* stat of root gives time */
- d->atime = time(0);
- if(convD2M9p1(d, ou->stat) != DIRREC)
- print("stat convD2M\n");
-
-out:
- if(p)
- putbuf(p);
- if(f)
- qunlock(f);
- ou->fid = in->fid;
-}
-
-void
-f_wstat(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- Iobuf *p, *p1;
- Dentry *d, *d1, xd;
- File *f;
- int slot;
- long addr;
-
- if(CHAT(cp)) {
- print("c_wstat %d\n", cp->chan);
- print(" fid = %d\n", in->fid);
- }
-
- p = 0;
- p1 = 0;
- d1 = 0;
- f = filep(cp, in->fid, 0);
- if(!f) {
- ou->err = Efid;
- goto out;
- }
- if(isro(f->fs->dev) || (cp != cons.chan && writegroup && !ingroup(f->uid, writegroup))) {
- ou->err = Eronly;
- goto out;
- }
-
- /*
- * first get parent
- */
- if(f->wpath) {
- p1 = getbuf(f->fs->dev, f->wpath->addr, Bread);
- d1 = getdir(p1, f->wpath->slot);
- if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
- ou->err = Ephase;
- goto out;
- }
- }
-
- p = getbuf(f->fs->dev, f->addr, Bread);
- d = getdir(p, f->slot);
- if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
- ou->err = Ealloc;
- goto out;
- }
- if(ou->err = mkqidcmp(&f->qid, d))
- goto out;
-
- convM2D9p1(in->stat, &xd);
- if(CHAT(cp)) {
- print(" d.name = %s\n", xd.name);
- print(" d.uid = %d\n", xd.uid);
- print(" d.gid = %d\n", xd.gid);
- print(" d.mode = %.4x\n", xd.mode);
- }
-
- /*
- * if chown,
- * must be god
- */
- while(xd.uid != d->uid) {
- if(wstatallow) /* set to allow chown during boot */
- break;
- ou->err = Enotu;
- goto out;
- }
-
- /*
- * if chgroup,
- * must be either
- * a) owner and in new group
- * b) leader of both groups
- */
- while(xd.gid != d->gid) {
- if(wstatallow || writeallow) /* set to allow chgrp during boot */
- break;
- if(d->uid == f->uid && ingroup(f->uid, xd.gid))
- break;
- if(leadgroup(f->uid, xd.gid))
- if(leadgroup(f->uid, d->gid))
- break;
- ou->err = Enotg;
- goto out;
- }
-
- /*
- * if rename,
- * must have write permission in parent
- */
- if(xd.name[0] == 0)
- strncpy(xd.name, d->name, sizeof(xd.name));
- while(strncmp(d->name, xd.name, sizeof(d->name)) != 0) {
- if(checkname(xd.name)) {
- ou->err = Ename;
- goto out;
- }
-
- if(strcmp(xd.name, ".") == 0 || strcmp(xd.name, "..") == 0) {
- ou->err = Ename;
- goto out;
- }
-
- /*
- * drop entry to prevent lock, then
- * check that destination name is unique,
- */
- putbuf(p);
- for(addr=0;; addr++) {
- p = dnodebuf(p1, d1, addr, 0);
- if(!p)
- break;
- if(checktag(p, Tdir, d1->qid.path)) {
- putbuf(p);
- continue;
- }
- for(slot=0; slot<DIRPERBUF; slot++) {
- d = getdir(p, slot);
- if(!(d->mode & DALLOC))
- continue;
- if(!strncmp(xd.name, d->name, sizeof(xd.name))) {
- ou->err = Eexist;
- goto out;
- }
- }
- putbuf(p);
- }
-
- /*
- * reacquire entry
- */
- p = getbuf(f->fs->dev, f->addr, Bread);
- d = getdir(p, f->slot);
- if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
- ou->err = Ephase;
- goto out;
- }
-
- if(wstatallow || writeallow) /* set to allow rename during boot */
- break;
- if(!d1 || iaccess(f, d1, DWRITE)) {
- ou->err = Eaccess;
- goto out;
- }
- break;
- }
-
- /*
- * if mode/time, either
- * a) owner
- * b) leader of either group
- */
- while(d->mtime != xd.mtime ||
- ((d->mode^xd.mode) & (DAPND|DLOCK|0777))) {
- if(wstatallow) /* set to allow chmod during boot */
- break;
- if(d->uid == f->uid)
- break;
- if(leadgroup(f->uid, xd.gid))
- break;
- if(leadgroup(f->uid, d->gid))
- break;
- ou->err = Enotu;
- goto out;
- }
- d->mtime = xd.mtime;
- d->uid = xd.uid;
- d->gid = xd.gid;
- d->mode = (xd.mode & (DAPND|DLOCK|0777)) | (d->mode & (DALLOC|DDIR));
-
- strncpy(d->name, xd.name, sizeof(d->name));
- if(wstatallow) {
- p->flags |= Bmod;
- if(xd.atime)
- d->atime = xd.atime;
- if(xd.mtime)
- d->mtime = xd.mtime;
- } else
- accessdir(p, d, FWSTAT);
-
-out:
- if(p)
- putbuf(p);
- if(p1)
- putbuf(p1);
- if(f)
- qunlock(f);
- ou->fid = in->fid;
-}
-
-void
-(*call9p1[MAXSYSCALL])(Chan*, Oldfcall*, Oldfcall*) =
-{
- [Tnop9p1] f_nop,
- [Tosession9p1] f_session,
- [Tsession9p1] f_session,
- [Tflush9p1] f_flush,
- [Toattach9p1] f_attach,
- [Tattach9p1] f_attach,
- [Tclone9p1] f_clone,
- [Twalk9p1] f_walk,
- [Topen9p1] f_open,
- [Tcreate9p1] f_create,
- [Tread9p1] f_read,
- [Twrite9p1] f_write,
- [Tclunk9p1] f_clunk,
- [Tremove9p1] f_remove,
- [Tstat9p1] f_stat,
- [Twstat9p1] f_wstat,
- [Tclwalk9p1] f_clwalk,
-};
-
-static void
-send(Chan *c, uchar *buf, int n)
-{
- int fd, m;
-
- fd = c->chan;
- m = write(fd, buf, n);
- if(m == n)
- return;
- panic("write failed");
-}
-
-void
-error9p1(Chan *c, uchar *buf)
-{
- buf[0] = Rnop9p1;
- buf[1] = ~0;
- buf[2] = ~0;
-
- send(c, buf, 3);
-}
-
-void
-serve9p1(Chan *chan, uchar *ib, int nib)
-{
- int n, t;
- uchar inbuf[MAXMSG+MAXDAT], outbuf[MAXMSG+MAXDAT];
- Oldfcall fi, fo;
-
- for(;;){
- if(nib){
- memmove(inbuf, ib, nib);
- n = nib;
- nib = 0;
- }else
- n = read(chan->chan, inbuf, sizeof inbuf);
- if(chat)
- print("read msg %d\n", n);
- if(n == 0 && (chan == cons.srvchan || chan == cons.chan))
- continue;
- if(n <= 0)
- return;
- if(convM2S9p1(inbuf, &fi, n) != n){
- error9p1(chan, outbuf);
- continue;
- }
-
- t = fi.type;
- if(t < 0 || t >= MAXSYSCALL || (t&1) || !call9p1[t]) {
- print("9p1: bad message type\n");
- error9p1(chan, outbuf);
- continue;
- }
-
- if(CHAT(chan))
- print("9p1: fi %O\n", &fi);
-
- /*
- * set up reply message
- */
- fo.err = 0;
- if(t == Tread9p1)
- fo.data = (char*)outbuf + 8;
-
- /*
- * call the file system
- */
- cons.work.count++;
- cons.rate.count += n;
-
- /*
- * call the file system
- */
- rlock(&mainlock);
- rlock(&chan->reflock);
-
- (*call9p1[t])(chan, &fi, &fo);
-
- runlock(&chan->reflock);
- runlock(&mainlock);
-
- fo.type = t+1;
- fo.tag = fi.tag;
-
- if(chat)
- print("9p1: fo %O\n", &fo);
-
- if(fo.err) {
- strcpy(fo.ename, errstring[fo.err]);
- if(CHAT(cp))
- print(" error: %s\n", fo.ename);
- fo.type = Terror9p1+1;
- }
-
- n = convS2M9p1(&fo, outbuf);
- if(n == 0) {
- print("9p1: bad S2M conversion\n");
- error9p1(chan, outbuf);
- continue;
- }
-
- cons.rate.count += n;
- send(chan, outbuf, n);
- }
-}
--- a/sys/src/cmd/disk/kfs/9p1.h
+++ /dev/null
@@ -1,113 +1,0 @@
-#define DIRREC 116 /* size of a directory ascii record */
-#define ERRREC 64 /* size of a error record */
-#define MAXMSG 160 /* max header sans data */
-
-typedef struct Oldfcall Oldfcall;
-
-struct Oldfcall
-{
- char type;
- ushort fid;
- short err;
- short tag;
- union
- {
- struct
- {
- short uid; /* T-Userstr */
- short oldtag; /* T-nFlush */
- Qid9p1 qid; /* R-Attach, R-Clwalk, R-Walk,
- * R-Open, R-Create */
- char rauth[AUTHENTLEN]; /* R-attach */
- };
- struct
- {
- char uname[NAMELEN]; /* T-nAttach */
- char aname[NAMELEN]; /* T-nAttach */
- char ticket[TICKETLEN]; /* T-attach */
- char auth[AUTHENTLEN]; /* T-attach */
- };
- struct
- {
- char ename[ERRREC]; /* R-nError */
- char chal[CHALLEN]; /* T-session, R-session */
- char authid[NAMELEN]; /* R-session */
- char authdom[DOMLEN]; /* R-session */
- };
- struct
- {
- char name[NAMELEN]; /* T-Walk, T-Clwalk, T-Create, T-Remove */
- long perm; /* T-Create */
- ushort newfid; /* T-Clone, T-Clwalk */
- char mode; /* T-Create, T-Open */
- };
- struct
- {
- long offset; /* T-Read, T-Write */
- long count; /* T-Read, T-Write, R-Read */
- char* data; /* T-Write, R-Read */
- };
- struct
- {
- char stat[DIRREC]; /* T-Wstat, R-Stat */
- };
- };
-};
-
-/*
- * P9 protocol message types
- */
-enum
-{
- Tnop9p1 = 50,
- Rnop9p1,
- Tosession9p1 = 52,
- Rosession9p1,
- Terror9p1 = 54, /* illegal */
- Rerror9p1,
- Tflush9p1 = 56,
- Rflush9p1,
- Toattach9p1 = 58,
- Roattach9p1,
- Tclone9p1 = 60,
- Rclone9p1,
- Twalk9p1 = 62,
- Rwalk9p1,
- Topen9p1 = 64,
- Ropen9p1,
- Tcreate9p1 = 66,
- Rcreate9p1,
- Tread9p1 = 68,
- Rread9p1,
- Twrite9p1 = 70,
- Rwrite9p1,
- Tclunk9p1 = 72,
- Rclunk9p1,
- Tremove9p1 = 74,
- Rremove9p1,
- Tstat9p1 = 76,
- Rstat9p1,
- Twstat9p1 = 78,
- Rwstat9p1,
- Tclwalk9p1 = 80,
- Rclwalk9p1,
- Tauth9p1 = 82, /* illegal */
- Rauth9p1, /* illegal */
- Tsession9p1 = 84,
- Rsession9p1,
- Tattach9p1 = 86,
- Rattach9p1,
-
- MAXSYSCALL
-};
-
-int convD2M9p1(Dentry*, char*);
-int convM2D9p1(char*, Dentry*);
-int convM2S9p1(uchar*, Oldfcall*, int);
-int convS2M9p1(Oldfcall*, uchar*);
-void fcall9p1(Chan*, Oldfcall*, Oldfcall*);
-int authorize(Chan*, Oldfcall*, Oldfcall*);
-
-void (*call9p1[MAXSYSCALL])(Chan*, Oldfcall*, Oldfcall*);
-
-extern Nvrsafe nvr;
--- a/sys/src/cmd/disk/kfs/9p12.c
+++ /dev/null
@@ -1,114 +1,0 @@
-#include "all.h"
-
-static int
-readmsg(Chan *c, void *abuf, int n, int *ninep)
-{
- int fd, len;
- uchar *buf;
-
- buf = abuf;
- fd = c->chan;
- qlock(&c->rlock);
- if(readn(fd, buf, 3) != 3){
- qunlock(&c->rlock);
- print("readn(3) fails: %r\n");
- return -1;
- }
- if((50 <= buf[0] && buf[0] <= 87 && (buf[0]&1)==0 && GBIT16(buf+1) == 0xFFFF)
- || buf[0] == 86 /* Tattach */){
- *ninep = 1;
- /* assume message boundaries */
- n = read(fd, buf+3, n-3);
- if(n < 0){
- qunlock(&c->rlock);
- return -1;
- }
- return n+3;
- }
-
- *ninep = 2;
- if(read(fd, buf+3, 1) != 1){
- qunlock(&c->rlock);
- print("read(1) fails: %r\n");
- return -1;
- }
- len = GBIT32(buf);
- if(len > n){
- print("msg too large\n");
- qunlock(&c->rlock);
- return -1;
- }
- if(readn(fd, buf+4, len-4) != len-4){
- print("readn(%d) fails: %r\n", len-4);
- qunlock(&c->rlock);
- return -1;
- }
- qunlock(&c->rlock);
- return len;
-}
-
-int
-startserveproc(void (*f)(Chan*, uchar*, int), char *name, Chan *c, uchar *b, int nb)
-{
- int pid;
-
- switch(pid = rfork(RFMEM|RFPROC)){
- case -1:
- panic("can't fork");
- case 0:
- break;
- default:
- return pid;
- }
- procname = name;
- f(c, b, nb);
- _exits(nil);
- return -1; /* can't happen */
-}
-
-void
-serve(Chan *chan)
-{
- int i, nin, p9, npid;
- uchar inbuf[1024];
- void (*s)(Chan*, uchar*, int);
- int *pid;
- Waitmsg *w;
-
- p9 = 0;
- if((nin = readmsg(chan, inbuf, sizeof inbuf, &p9)) < 0)
- return;
-
- switch(p9){
- default:
- print("unknown 9P type\n");
- return;
- case 1:
- s = serve9p1;
- break;
- case 2:
- s = serve9p2;
- break;
- }
-
- pid = malloc(sizeof(pid)*(conf.nserve-1));
- if(pid == nil)
- return;
- for(i=1; i<conf.nserve; i++)
- pid[i-1] = startserveproc(s, "srv", chan, nil, 0);
-
- (*s)(chan, inbuf, nin);
-
- /* wait till all other servers for this chan are done */
- for(npid = conf.nserve-1; npid > 0;){
- w = wait();
- if(w == 0)
- break;
- for(i = 0; i < conf.nserve-1; i++)
- if(pid[i] == w->pid)
- npid--;
- free(w);
- }
- free(pid);
-}
-
--- a/sys/src/cmd/disk/kfs/9p1lib.c
+++ /dev/null
@@ -1,461 +1,0 @@
-#include "all.h"
-#include "9p1.h"
-
-#define CHAR(x) *p++ = f->x
-#define SHORT(x) { ulong vvv = f->x; p[0] = vvv; p[1] = vvv>>8; p += 2; }
-#define VLONG(q) p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4
-#define LONG(x) { ulong vvv = f->x; VLONG(vvv); }
-#define BYTES(x,n) memmove(p, f->x, n); p += n
-#define STRING(x,n) strncpy((char*)p, f->x, n); p += n
-
-int
-convS2M9p1(Oldfcall *f, uchar *ap)
-{
- uchar *p;
- int t;
-
- p = ap;
- CHAR(type);
- t = f->type;
- SHORT(tag);
- switch(t)
- {
- default:
- print("convS2M9p1: bad type: %d\n", t);
- return 0;
-
- case Tnop9p1:
- case Tosession9p1:
- break;
-
- case Tsession9p1:
- BYTES(chal, sizeof(f->chal));
- break;
-
- case Tflush9p1:
- SHORT(oldtag);
- break;
-
- case Tattach9p1:
- SHORT(fid);
- STRING(uname, sizeof(f->uname));
- STRING(aname, sizeof(f->aname));
- BYTES(ticket, sizeof(f->ticket));
- BYTES(auth, sizeof(f->auth));
- break;
-
- case Toattach9p1:
- SHORT(fid);
- STRING(uname, sizeof(f->uname));
- STRING(aname, sizeof(f->aname));
- BYTES(ticket, NAMELEN);
- break;
-
- case Tclone9p1:
- SHORT(fid);
- SHORT(newfid);
- break;
-
- case Twalk9p1:
- SHORT(fid);
- STRING(name, sizeof(f->name));
- break;
-
- case Tclwalk9p1:
- SHORT(fid);
- SHORT(newfid);
- STRING(name, sizeof(f->name));
- break;
-
- case Topen9p1:
- SHORT(fid);
- CHAR(mode);
- break;
-
- case Tcreate9p1:
- SHORT(fid);
- STRING(name, sizeof(f->name));
- LONG(perm);
- CHAR(mode);
- break;
-
- case Tread9p1:
- SHORT(fid);
- LONG(offset); VLONG(0);
- SHORT(count);
- break;
-
- case Twrite9p1:
- SHORT(fid);
- LONG(offset); VLONG(0);
- SHORT(count);
- p++;
- if((uchar*)p == (uchar*)f->data) {
- p += f->count;
- break;
- }
- BYTES(data, f->count);
- break;
-
- case Tclunk9p1:
- case Tremove9p1:
- case Tstat9p1:
- SHORT(fid);
- break;
-
- case Twstat9p1:
- SHORT(fid);
- BYTES(stat, sizeof(f->stat));
- break;
-/*
- */
- case Rnop9p1:
- case Rosession9p1:
- case Rflush9p1:
- break;
-
- case Rsession9p1:
- BYTES(chal, sizeof(f->chal));
- BYTES(authid, sizeof(f->authid));
- BYTES(authdom, sizeof(f->authdom));
- break;
-
- case Rerror9p1:
- STRING(ename, sizeof(f->ename));
- break;
-
- case Rclone9p1:
- case Rclunk9p1:
- case Rremove9p1:
- case Rwstat9p1:
- SHORT(fid);
- break;
-
- case Rwalk9p1:
- case Ropen9p1:
- case Rcreate9p1:
- case Rclwalk9p1:
- SHORT(fid);
- LONG(qid.path);
- LONG(qid.version);
- break;
-
- case Rattach9p1:
- SHORT(fid);
- LONG(qid.path);
- LONG(qid.version);
- BYTES(rauth, sizeof(f->rauth));
- break;
-
- case Roattach9p1:
- SHORT(fid);
- LONG(qid.path);
- LONG(qid.version);
- break;
-
- case Rread9p1:
- SHORT(fid);
- SHORT(count);
- p++;
- if((uchar*)p == (uchar*)f->data) {
- p += f->count;
- break;
- }
- BYTES(data, f->count);
- break;
-
- case Rwrite9p1:
- SHORT(fid);
- SHORT(count);
- break;
-
- case Rstat9p1:
- SHORT(fid);
- BYTES(stat, sizeof(f->stat));
- break;
- }
- return p - (uchar*)ap;
-}
-
-/*
- * buggery to give false qid for
- * the top 2 levels of the dump fs
- */
-static ulong
-fakeqid9p1(Dentry *f)
-{
- ulong q;
- int c;
-
- q = f->qid.path;
- if(q == (QPROOT|QPDIR)) {
- c = f->name[0];
- if(c >= '0' && c <= '9') {
- q = 3|QPDIR;
- c = (c-'0')*10 + (f->name[1]-'0');
- if(c >= 1 && c <= 12)
- q = 4|QPDIR;
- }
- }
- return q;
-}
-
-int
-convD2M9p1(Dentry *f, char *ap)
-{
- uchar *p;
- ulong q;
-
- p = (uchar*)ap;
- STRING(name, sizeof(f->name));
-
- memset(p, 0, 2*NAMELEN);
- uidtostr((char*)p, f->uid);
- p += NAMELEN;
-
- uidtostr((char*)p, f->gid);
- p += NAMELEN;
-
- q = fakeqid9p1(f);
- VLONG(q);
- LONG(qid.version);
- {
- q = f->mode & 0x0fff;
- if(f->mode & DDIR)
- q |= PDIR;
- if(f->mode & DAPND)
- q |= PAPND;
- if(f->mode & DLOCK)
- q |= PLOCK;
- VLONG(q);
- }
- LONG(atime);
- LONG(mtime);
- LONG(size); VLONG(0);
- VLONG(0);
- return p - (uchar*)ap;
-}
-
-#undef CHAR
-#undef SHORT
-#undef LONG
-#undef VLONG
-#undef BYTES
-#undef STRING
-
-#define CHAR(x) f->x = *p++
-#define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2
-#define VLONG(q) q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4
-#define LONG(x) VLONG(f->x)
-#define BYTES(x,n) memmove(f->x, p, n); p += n
-#define STRING(x,n) memmove(f->x, p, n); p += n
-
-int
-convM2S9p1(uchar *ap, Oldfcall *f, int n)
-{
- uchar *p;
- int t;
-
- p = ap;
- CHAR(type);
- t = f->type;
- SHORT(tag);
- switch(t)
- {
- default:
- /*
- * only whine if it couldn't be a 9P2000 Tversion9p1.
- */
- if(t != 19 || ap[4] != 100)
- print("convM2S9p1: bad type: %d\n", f->type);
- return 0;
-
- case Tnop9p1:
- case Tosession9p1:
- break;
-
- case Tsession9p1:
- BYTES(chal, sizeof(f->chal));
- break;
-
- case Tflush9p1:
- SHORT(oldtag);
- break;
-
- case Tattach9p1:
- SHORT(fid);
- BYTES(uname, sizeof(f->uname));
- BYTES(aname, sizeof(f->aname));
- BYTES(ticket, sizeof(f->ticket));
- BYTES(auth, sizeof(f->auth));
- break;
-
- case Toattach9p1:
- SHORT(fid);
- BYTES(uname, sizeof(f->uname));
- BYTES(aname, sizeof(f->aname));
- BYTES(ticket, NAMELEN);
- break;
-
- case Tclone9p1:
- SHORT(fid);
- SHORT(newfid);
- break;
-
- case Twalk9p1:
- SHORT(fid);
- BYTES(name, sizeof(f->name));
- break;
-
- case Tclwalk9p1:
- SHORT(fid);
- SHORT(newfid);
- BYTES(name, sizeof(f->name));
- break;
-
- case Tremove9p1:
- SHORT(fid);
- break;
-
- case Topen9p1:
- SHORT(fid);
- CHAR(mode);
- break;
-
- case Tcreate9p1:
- SHORT(fid);
- BYTES(name, sizeof(f->name));
- LONG(perm);
- CHAR(mode);
- break;
-
- case Tread9p1:
- SHORT(fid);
- LONG(offset); p += 4;
- SHORT(count);
- break;
-
- case Twrite9p1:
- SHORT(fid);
- LONG(offset); p += 4;
- SHORT(count);
- p++;
- f->data = (char*)p; p += f->count;
- break;
-
- case Tclunk9p1:
- case Tstat9p1:
- SHORT(fid);
- break;
-
- case Twstat9p1:
- SHORT(fid);
- BYTES(stat, sizeof(f->stat));
- break;
-
-/*
- */
- case Rnop9p1:
- case Rosession9p1:
- break;
-
- case Rsession9p1:
- BYTES(chal, sizeof(f->chal));
- BYTES(authid, sizeof(f->authid));
- BYTES(authdom, sizeof(f->authdom));
- break;
-
- case Rerror9p1:
- BYTES(ename, sizeof(f->ename));
- break;
-
- case Rflush9p1:
- break;
-
- case Rclone9p1:
- case Rclunk9p1:
- case Rremove9p1:
- case Rwstat9p1:
- SHORT(fid);
- break;
-
- case Rwalk9p1:
- case Rclwalk9p1:
- case Ropen9p1:
- case Rcreate9p1:
- SHORT(fid);
- LONG(qid.path);
- LONG(qid.version);
- break;
-
- case Rattach9p1:
- SHORT(fid);
- LONG(qid.path);
- LONG(qid.version);
- BYTES(rauth, sizeof(f->rauth));
- break;
-
- case Roattach9p1:
- SHORT(fid);
- LONG(qid.path);
- LONG(qid.version);
- break;
-
- case Rread9p1:
- SHORT(fid);
- SHORT(count);
- p++;
- f->data = (char*)p; p += f->count;
- break;
-
- case Rwrite9p1:
- SHORT(fid);
- SHORT(count);
- break;
-
- case Rstat9p1:
- SHORT(fid);
- BYTES(stat, sizeof(f->stat));
- break;
- }
- if((uchar*)ap+n == p)
- return n;
- return 0;
-}
-
-int
-convM2D9p1(char *ap, Dentry *f)
-{
- uchar *p;
- char str[28];
-
- p = (uchar*)ap;
- BYTES(name, sizeof(f->name));
-
- memmove(str, p, NAMELEN);
- p += NAMELEN;
- f->uid = strtouid(str);
-
- memmove(str, p, NAMELEN);
- p += NAMELEN;
- f->gid = strtouid(str);
-
- LONG(qid.path);
- LONG(qid.version);
- {
- LONG(atime);
- f->mode = (f->atime & 0x0fff) | DALLOC;
- if(f->atime & PDIR)
- f->mode |= DDIR;
- if(f->atime & PAPND)
- f->mode |= DAPND;
- if(f->atime & PLOCK)
- f->mode |= DLOCK;
- }
- LONG(atime);
- LONG(mtime);
- LONG(size); p += 4;
- p += 4;
- return p - (uchar*)ap;
-}
-
--- a/sys/src/cmd/disk/kfs/9p2.c
+++ /dev/null
@@ -1,1870 +1,0 @@
-#include "all.h"
-
-#define MSIZE (MAXDAT+128)
-
-static void
-seterror(Fcall *ou, int err)
-{
-
- if(0 <= err && err < MAXERR)
- ou->ename = errstring[err];
- else
- ou->ename = "unknown error";
-}
-
-static int
-fsversion(Chan* chan, Fcall* f, Fcall* r)
-{
- if(f->msize < 256)
- return Econvert;
-
- if(f->msize < MSIZE)
- r->msize = f->msize;
- else
- r->msize = MSIZE;
- /*
- * Should check the '.' stuff here.
- * What happens if Tversion has already been seen?
- */
- if(strcmp(f->version, VERSION9P) == 0){
- r->version = VERSION9P;
- chan->msize = r->msize;
- }else
- r->version = "unknown";
-
- fileinit(chan);
- return 0;
-}
-
-char *keyspec = "proto=p9any role=server";
-
-static int
-fsauth(Chan *chan, Fcall *f, Fcall *r)
-{
- int err, fd;
- char *aname;
- File *file;
- int afd;
- AuthRpc *rpc;
-
- err = 0;
- if(chan == cons.srvchan)
- return Eauthmsg;
- file = filep(chan, f->afid, 1);
- if(file == nil)
- return Efidinuse;
-
- /* forget any previous authentication */
- file->cuid = 0;
-
- if(access("/mnt/factotum", 0) < 0)
- if((fd = open("/srv/factotum", ORDWR)) >= 0)
- mount(fd, -1, "/mnt", MBEFORE, "");
-
- afd = open("/mnt/factotum/rpc", ORDWR);
- if(afd < 0){
- err = Esystem;
- goto out;
- }
- rpc = auth_allocrpc(afd);
- if(rpc == nil){
- close(afd);
- err = Esystem;
- goto out;
- }
- file->rpc = rpc;
- if(auth_rpc(rpc, "start", keyspec, strlen(keyspec)) != ARok){
- err = Esystem;
- goto out;
- }
-
- aname = f->aname;
- if(!aname[0])
- aname = "main";
- file->fs = fsstr(aname);
- if(file->fs == nil){
- err = Ebadspc;
- goto out;
- }
- file->uid = strtouid(f->uname);
- if(file->uid < 0){
- err = Ebadu;
- goto out;
- }
- file->qid.path = 0;
- file->qid.vers = 0;
- file->qid.type = QTAUTH;
- r->qid = file->qid;
-
-out:
- if(file != nil){
- qunlock(file);
- if(err != 0)
- freefp(file);
- }
- return err;
-}
-
-int
-authread(File *file, uchar *data, int count)
-{
- AuthInfo *ai;
- AuthRpc *rpc;
- int rv;
-
- rpc = file->rpc;
- if(rpc == nil)
- return -1;
-
- rv = auth_rpc(rpc, "read", nil, 0);
- switch(rv){
- case ARdone:
- ai = auth_getinfo(rpc);
- if(ai == nil)
- return -1;
- if(chat)
- print("authread identifies user as %s\n", ai->cuid);
- file->cuid = strtouid(ai->cuid);
- auth_freeAI(ai);
- if(file->cuid == 0)
- return -1;
- if(chat)
- print("%s is a known user\n", ai->cuid);
- return 0;
- case ARok:
- if(count < rpc->narg)
- return -1;
- memmove(data, rpc->arg, rpc->narg);
- return rpc->narg;
- case ARphase:
- return -1;
- default:
- return -1;
- }
-}
-
-int
-authwrite(File *file, uchar *data, int count)
-{
- int ret;
-
- ret = auth_rpc(file->rpc, "write", data, count);
- if(ret != ARok)
- return -1;
- return count;
-}
-
-void
-mkqid9p1(Qid9p1* qid9p1, Qid* qid)
-{
- if(qid->path & 0xFFFFFFFF00000000LL)
- panic("mkqid9p1: path %lluX\n", qid->path);
- qid9p1->path = qid->path & 0xFFFFFFFF;
- if(qid->type & QTDIR)
- qid9p1->path |= QPDIR;
- qid9p1->version = qid->vers;
-}
-
-void
-authfree(File *fp)
-{
- if(fp->rpc != nil){
- close(fp->rpc->afd);
- free(fp->rpc);
- fp->rpc = nil;
- }
-}
-
-void
-mkqid9p2(Qid* qid, Qid9p1* qid9p1, int mode)
-{
- qid->path = (ulong)(qid9p1->path & ~QPDIR);
- qid->vers = qid9p1->version;
- qid->type = 0;
- if(mode & DDIR)
- qid->type |= QTDIR;
- if(mode & DAPND)
- qid->type |= QTAPPEND;
- if(mode & DLOCK)
- qid->type |= QTEXCL;
-}
-
-static int
-checkattach(Chan *chan, File *afile, File *file, Filsys *fs)
-{
- uchar buf[1];
-
- if(chan == cons.srvchan || chan == cons.chan)
- return 0;
-
- /* if no afile, this had better be none */
- if(afile == nil){
- if(file->uid == 0){
- if(!allownone && !chan->authed)
- return Eauth;
- return 0;
- }
- return Eauth;
- }
-
- /* otherwise, we'ld better have a usable cuid */
- if(!(afile->qid.type&QTAUTH))
- return Eauth;
- if(afile->uid != file->uid || afile->fs != fs)
- return Eauth;
- if(afile->cuid <= 0){
- if(authread(afile, buf, 0) != 0)
- return Eauth;
- if(afile->cuid <= 0)
- return Eauth;
- }
- file->uid = afile->cuid;
-
- /* once someone has authenticated on the channel, others can become none */
- chan->authed = 1;
-
- return 0;
-}
-
-static int
-fsattach(Chan* chan, Fcall* f, Fcall* r)
-{
- char *aname;
- Iobuf *p;
- Dentry *d;
- File *file;
- File *afile;
- Filsys *fs;
- long raddr;
- int error, u;
-
- aname = f->aname;
- if(!aname[0]) /* default */
- aname = "main";
- p = nil;
- afile = filep(chan, f->afid, 0);
- file = filep(chan, f->fid, 1);
- if(file == nil){
- error = Efidinuse;
- goto out;
- }
-
- u = -1;
- if(chan != cons.chan){
- if(strcmp(f->uname, "adm") == 0){
- error = Eauth;
- goto out;
- }
- u = strtouid(f->uname);
- if(u < 0){
- error = Ebadu;
- goto out;
- }
- }
- file->uid = u;
-
- fs = fsstr(aname);
- if(fs == nil){
- error = Ebadspc;
- goto out;
- }
-
- if(error = checkattach(chan, afile, file, fs))
- goto out;
-
- raddr = getraddr(fs->dev);
- p = getbuf(fs->dev, raddr, Bread);
- d = getdir(p, 0);
- if(d == nil || checktag(p, Tdir, QPROOT) || !(d->mode & DALLOC)){
- error = Ealloc;
- goto out;
- }
- if(iaccess(file, d, DEXEC)){
- error = Eaccess;
- goto out;
- }
- if(file->uid == 0 && isro(fs->dev)) {
- /*
- * 'none' not allowed on dump
- */
- error = Eaccess;
- goto out;
- }
- accessdir(p, d, FREAD);
- mkqid(&file->qid, d, 1);
- file->fs = fs;
- file->addr = raddr;
- file->slot = 0;
- file->open = 0;
- freewp(file->wpath);
- file->wpath = 0;
-
- r->qid = file->qid;
-
-// if(cons.flags & attachflag)
-// print("9p2: attach %s %T to \"%s\" C%d\n",
-// chan->whoname, chan->whotime, fs->name, chan->chan);
-
-out:
-// if((cons.flags & attachflag) && error)
-// print("9p2: attach %s %T SUCK EGGS --- %s\n",
-// f->uname, time(), errstr[error]);
- if(p != nil)
- putbuf(p);
- if(afile != nil)
- qunlock(afile);
- if(file != nil){
- qunlock(file);
- if(error)
- freefp(file);
- }
-
- return error;
-}
-
-static int
-fsflush(Chan* chan, Fcall*, Fcall*)
-{
- runlock(&chan->reflock);
- wlock(&chan->reflock);
- wunlock(&chan->reflock);
- rlock(&chan->reflock);
-
- return 0;
-}
-
-static void
-clone(File* nfile, File* file)
-{
- Wpath *wpath;
-
- nfile->qid = file->qid;
-
- lock(&wpathlock);
- nfile->wpath = file->wpath;
- for(wpath = nfile->wpath; wpath != nil; wpath = wpath->up)
- wpath->refs++;
- unlock(&wpathlock);
-
- nfile->fs = file->fs;
- nfile->addr = file->addr;
- nfile->slot = file->slot;
- nfile->uid = file->uid;
- nfile->cuid = 0;
- nfile->open = file->open & ~FREMOV;
-}
-
-static int
-walkname(File* file, char* wname, Qid* wqid)
-{
- Wpath *w;
- Iobuf *p, *p1;
- Dentry *d, *d1;
- int error, slot;
- long addr, qpath;
-
- p = p1 = nil;
-
- /*
- * File must not have been opened for I/O by an open
- * or create message and must represent a directory.
- */
- if(file->open != 0){
- error = Emode;
- goto out;
- }
-
- p = getbuf(file->fs->dev, file->addr, Bread);
- if(p == nil || checktag(p, Tdir, QPNONE)){
- error = Edir1;
- goto out;
- }
- if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
- error = Ealloc;
- goto out;
- }
- if(!(d->mode & DDIR)){
- error = Edir1;
- goto out;
- }
- if(error = mkqidcmp(&file->qid, d))
- goto out;
-
- /*
- * For walked elements the implied user must
- * have permission to search the directory.
- */
- if(file->cp != cons.chan && iaccess(file, d, DEXEC)){
- error = Eaccess;
- goto out;
- }
- accessdir(p, d, FREAD);
-
- if(strcmp(wname, ".") == 0){
-setdot:
- if(wqid != nil)
- *wqid = file->qid;
- goto out;
- }
- if(strcmp(wname, "..") == 0){
- if(file->wpath == 0)
- goto setdot;
- putbuf(p);
- p = nil;
- addr = file->wpath->addr;
- slot = file->wpath->slot;
- p1 = getbuf(file->fs->dev, addr, Bread);
- if(p1 == nil || checktag(p1, Tdir, QPNONE)){
- error = Edir1;
- goto out;
- }
- if((d1 = getdir(p1, slot)) == nil || !(d1->mode & DALLOC)){
- error = Ephase;
- goto out;
- }
- lock(&wpathlock);
- file->wpath->refs--;
- file->wpath = file->wpath->up;
- unlock(&wpathlock);
- goto found;
- }
-
- for(addr = 0; ; addr++){
- if(p == nil){
- p = getbuf(file->fs->dev, file->addr, Bread);
- if(p == nil || checktag(p, Tdir, QPNONE)){
- error = Ealloc;
- goto out;
- }
- d = getdir(p, file->slot);
- if(d == nil || !(d->mode & DALLOC)){
- error = Ealloc;
- goto out;
- }
- }
- qpath = d->qid.path;
- p1 = dnodebuf1(p, d, addr, 0);
- p = nil;
- if(p1 == nil || checktag(p1, Tdir, qpath)){
- error = Eentry;
- goto out;
- }
- for(slot = 0; slot < DIRPERBUF; slot++){
- d1 = getdir(p1, slot);
- if(!(d1->mode & DALLOC))
- continue;
- if(strncmp(wname, d1->name, NAMELEN) != 0)
- continue;
- /*
- * update walk path
- */
- if((w = newwp()) == nil){
- error = Ewalk;
- goto out;
- }
- w->addr = file->addr;
- w->slot = file->slot;
- w->up = file->wpath;
- file->wpath = w;
- slot += DIRPERBUF*addr;
- goto found;
- }
- putbuf(p1);
- p1 = nil;
- }
-
-found:
- file->addr = p1->addr;
- mkqid(&file->qid, d1, 1);
- putbuf(p1);
- p1 = nil;
- file->slot = slot;
- if(wqid != nil)
- *wqid = file->qid;
-
-out:
- if(p1 != nil)
- putbuf(p1);
- if(p != nil)
- putbuf(p);
-
- return error;
-}
-
-static int
-fswalk(Chan* chan, Fcall* f, Fcall* r)
-{
- int error, nwname;
- File *file, *nfile, tfile;
-
- /*
- * The file identified by f->fid must be valid in the
- * current session and must not have been opened for I/O
- * by an open or create message.
- */
- if((file = filep(chan, f->fid, 0)) == nil)
- return Efid;
- if(file->open != 0){
- qunlock(file);
- return Emode;
- }
-
- /*
- * If newfid is not the same as fid, allocate a new file;
- * a side effect is checking newfid is not already in use (error);
- * if there are no names to walk this will be equivalent to a
- * simple 'clone' operation.
- * Otherwise, fid and newfid are the same and if there are names
- * to walk make a copy of 'file' to be used during the walk as
- * 'file' must only be updated on success.
- * Finally, it's a no-op if newfid is the same as fid and f->nwname
- * is 0.
- */
- r->nwqid = 0;
- if(f->newfid != f->fid){
- if((nfile = filep(chan, f->newfid, 1)) == nil){
- qunlock(file);
- return Efidinuse;
- }
- }
- else if(f->nwname != 0){
- nfile = &tfile;
- memset(nfile, 0, sizeof(File));
- nfile->cp = chan;
- nfile->fid = ~0;
- }
- else{
- qunlock(file);
- return 0;
- }
- clone(nfile, file);
-
- /*
- * Should check name is not too long.
- */
- error = 0;
- for(nwname = 0; nwname < f->nwname; nwname++){
- error = walkname(nfile, f->wname[nwname], &r->wqid[r->nwqid]);
- if(error != 0 || ++r->nwqid >= MAXDAT/sizeof(Qid))
- break;
- }
-
- if(f->nwname == 0){
- /*
- * Newfid must be different to fid (see above)
- * so this is a simple 'clone' operation - there's
- * nothing to do except unlock unless there's
- * an error.
- */
- if(error){
- freewp(nfile->wpath);
- qunlock(nfile);
- freefp(nfile);
- }
- else
- qunlock(nfile);
- }
- else if(r->nwqid < f->nwname){
- /*
- * Didn't walk all elements, 'clunk' nfile
- * and leave 'file' alone.
- * Clear error if some of the elements were
- * walked OK.
- */
- freewp(nfile->wpath);
- if(nfile != &tfile){
- qunlock(nfile);
- freefp(nfile);
- }
- if(r->nwqid != 0)
- error = 0;
- }
- else{
- /*
- * Walked all elements. If newfid is the same
- * as fid must update 'file' from the temporary
- * copy used during the walk.
- * Otherwise just unlock (when using tfile there's
- * no need to unlock as it's a local).
- */
- if(nfile == &tfile){
- file->qid = nfile->qid;
- freewp(file->wpath);
- file->wpath = nfile->wpath;
- file->addr = nfile->addr;
- file->slot = nfile->slot;
- }
- else
- qunlock(nfile);
- }
- qunlock(file);
-
- return error;
-}
-
-static int
-fsopen(Chan* chan, Fcall* f, Fcall* r)
-{
- Iobuf *p;
- Dentry *d;
- File *file;
- Tlock *t;
- Qid qid;
- int error, ro, fmod, wok;
-
- wok = 0;
- p = nil;
-
- if(chan == cons.chan || writeallow)
- wok = 1;
-
- if((file = filep(chan, f->fid, 0)) == nil){
- error = Efid;
- goto out;
- }
-
- /*
- * if remove on close, check access here
- */
- ro = isro(file->fs->dev) || (writegroup && !ingroup(file->uid, writegroup));
- if(f->mode & ORCLOSE){
- if(ro){
- error = Eronly;
- goto out;
- }
- /*
- * check on parent directory of file to be deleted
- */
- if(file->wpath == 0 || file->wpath->addr == file->addr){
- error = Ephase;
- goto out;
- }
- p = getbuf(file->fs->dev, file->wpath->addr, Bread);
- if(p == nil || checktag(p, Tdir, QPNONE)){
- error = Ephase;
- goto out;
- }
- if((d = getdir(p, file->wpath->slot)) == nil || !(d->mode & DALLOC)){
- error = Ephase;
- goto out;
- }
- if(iaccess(file, d, DWRITE)){
- error = Eaccess;
- goto out;
- }
- putbuf(p);
- }
- p = getbuf(file->fs->dev, file->addr, Bread);
- if(p == nil || checktag(p, Tdir, QPNONE)){
- error = Ealloc;
- goto out;
- }
- if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
- error = Ealloc;
- goto out;
- }
- if(error = mkqidcmp(&file->qid, d))
- goto out;
- mkqid(&qid, d, 1);
- switch(f->mode & 7){
-
- case OREAD:
- if(iaccess(file, d, DREAD) && !wok)
- goto badaccess;
- fmod = FREAD;
- break;
-
- case OWRITE:
- if((d->mode & DDIR) || (iaccess(file, d, DWRITE) && !wok))
- goto badaccess;
- if(ro){
- error = Eronly;
- goto out;
- }
- fmod = FWRITE;
- break;
-
- case ORDWR:
- if((d->mode & DDIR)
- || (iaccess(file, d, DREAD) && !wok)
- || (iaccess(file, d, DWRITE) && !wok))
- goto badaccess;
- if(ro){
- error = Eronly;
- goto out;
- }
- fmod = FREAD+FWRITE;
- break;
-
- case OEXEC:
- if((d->mode & DDIR) || (iaccess(file, d, DEXEC) && !wok))
- goto badaccess;
- fmod = FREAD;
- break;
-
- default:
- error = Emode;
- goto out;
- }
- if(f->mode & OTRUNC){
- if((d->mode & DDIR) || (iaccess(file, d, DWRITE) && !wok))
- goto badaccess;
- if(ro){
- error = Eronly;
- goto out;
- }
- }
- t = 0;
- if(d->mode & DLOCK){
- if((t = tlocked(p, d)) == nil){
- error = Elocked;
- goto out;
- }
- }
- if(f->mode & ORCLOSE)
- fmod |= FREMOV;
- file->open = fmod;
- if((f->mode & OTRUNC) && !(d->mode & DAPND)){
- dtrunc(p, d);
- qid.vers = d->qid.version;
- }
- r->qid = qid;
- file->tlock = t;
- if(t != nil)
- t->file = file;
- file->lastra = 1;
- goto out;
-
-badaccess:
- error = Eaccess;
- file->open = 0;
-
-out:
- if(p != nil)
- putbuf(p);
- if(file != nil)
- qunlock(file);
-
- r->iounit = chan->msize-IOHDRSZ;
-
- return error;
-}
-
-static int
-dir9p2(Dir* dir, Dentry* dentry, void* strs)
-{
- char *op, *p;
-
- memset(dir, 0, sizeof(Dir));
- mkqid(&dir->qid, dentry, 1);
- dir->mode = (dir->qid.type<<24)|(dentry->mode & 0777);
- dir->atime = dentry->atime;
- dir->mtime = dentry->mtime;
- dir->length = dentry->size;
-
- op = p = strs;
- dir->name = p;
- p += sprint(p, "%s", dentry->name)+1;
-
- dir->uid = p;
- uidtostr(p, dentry->uid);
- p += strlen(p)+1;
-
- dir->gid = p;
- uidtostr(p, dentry->gid);
- p += strlen(p)+1;
-
- dir->muid = p;
- strcpy(p, "");
- p += strlen(p)+1;
-
- return p-op;
-}
-
-static int
-checkname9p2(char* name)
-{
- char *p;
-
- /*
- * Return length of string if valid, 0 if not.
- */
- if(name == nil)
- return 0;
-
- for(p = name; *p != 0; p++){
- if((*p & 0xFF) <= 040)
- return 0;
- }
-
- return p-name;
-}
-
-static int
-fscreate(Chan* chan, Fcall* f, Fcall* r)
-{
- Iobuf *p, *p1;
- Dentry *d, *d1;
- File *file;
- int error, slot, slot1, fmod, wok, l;
- long addr, addr1, path;
- Tlock *t;
- Wpath *w;
-
- wok = 0;
- p = nil;
-
- if(chan == cons.chan || writeallow)
- wok = 1;
-
- if((file = filep(chan, f->fid, 0)) == nil){
- error = Efid;
- goto out;
- }
- if(isro(file->fs->dev) || (writegroup && !ingroup(file->uid, writegroup))){
- error = Eronly;
- goto out;
- }
-
- p = getbuf(file->fs->dev, file->addr, Bread);
- if(p == nil || checktag(p, Tdir, QPNONE)){
- error = Ealloc;
- goto out;
- }
- if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
- error = Ealloc;
- goto out;
- }
- if(error = mkqidcmp(&file->qid, d))
- goto out;
- if(!(d->mode & DDIR)){
- error = Edir2;
- goto out;
- }
- if(iaccess(file, d, DWRITE) && !wok) {
- error = Eaccess;
- goto out;
- }
- accessdir(p, d, FREAD);
-
- /*
- * Check the name is valid and will fit in an old
- * directory entry.
- */
- if((l = checkname9p2(f->name)) == 0){
- error = Ename;
- goto out;
- }
- if(l+1 > NAMELEN){
- error = Etoolong;
- goto out;
- }
- if(strcmp(f->name, ".") == 0 || strcmp(f->name, "..") == 0){
- error = Edot;
- goto out;
- }
-
- addr1 = 0;
- slot1 = 0; /* set */
- for(addr = 0; ; addr++){
- if((p1 = dnodebuf(p, d, addr, 0)) == nil){
- if(addr1 != 0)
- break;
- p1 = dnodebuf(p, d, addr, Tdir);
- }
- if(p1 == nil){
- error = Efull;
- goto out;
- }
- if(checktag(p1, Tdir, d->qid.path)){
- putbuf(p1);
- goto phase;
- }
- for(slot = 0; slot < DIRPERBUF; slot++){
- d1 = getdir(p1, slot);
- if(!(d1->mode & DALLOC)){
- if(addr1 == 0){
- addr1 = p1->addr;
- slot1 = slot + addr*DIRPERBUF;
- }
- continue;
- }
- if(strncmp(f->name, d1->name, sizeof(d1->name)) == 0){
- putbuf(p1);
- error = Eexist;
- goto out;
- }
- }
- putbuf(p1);
- }
-
- switch(f->mode & 7){
- case OEXEC:
- case OREAD: /* seems only useful to make directories */
- fmod = FREAD;
- break;
-
- case OWRITE:
- fmod = FWRITE;
- break;
-
- case ORDWR:
- fmod = FREAD+FWRITE;
- break;
-
- default:
- error = Emode;
- goto out;
- }
- if(f->perm & PDIR)
- if((f->mode & OTRUNC) || (f->perm & PAPND) || (fmod & FWRITE))
- goto badaccess;
- /*
- * do it
- */
- path = qidpathgen(&file->fs->dev);
- if((p1 = getbuf(file->fs->dev, addr1, Bread|Bimm|Bmod)) == nil)
- goto phase;
- d1 = getdir(p1, slot1);
- if(d1 == nil || checktag(p1, Tdir, d->qid.path)) {
- putbuf(p1);
- goto phase;
- }
- if(d1->mode & DALLOC){
- putbuf(p1);
- goto phase;
- }
-
- strncpy(d1->name, f->name, sizeof(d1->name));
- if(chan == cons.chan){
- d1->uid = cons.uid;
- d1->gid = cons.gid;
- }
- else{
- d1->uid = file->uid;
- d1->gid = d->gid;
- f->perm &= d->mode | ~0666;
- if(f->perm & PDIR)
- f->perm &= d->mode | ~0777;
- }
- d1->qid.path = path;
- d1->qid.version = 0;
- d1->mode = DALLOC | (f->perm & 0777);
- if(f->perm & PDIR) {
- d1->mode |= DDIR;
- d1->qid.path |= QPDIR;
- }
- if(f->perm & PAPND)
- d1->mode |= DAPND;
- t = nil;
- if(f->perm & PLOCK){
- d1->mode |= DLOCK;
- t = tlocked(p1, d1);
- /* if nil, out of tlock structures */
- }
- accessdir(p1, d1, FWRITE);
- mkqid(&r->qid, d1, 0);
- putbuf(p1);
- accessdir(p, d, FWRITE);
-
- /*
- * do a walk to new directory entry
- */
- if((w = newwp()) == nil){
- error = Ewalk;
- goto out;
- }
- w->addr = file->addr;
- w->slot = file->slot;
- w->up = file->wpath;
- file->wpath = w;
- file->qid = r->qid;
- file->tlock = t;
- if(t != nil)
- t->file = file;
- file->lastra = 1;
- if(f->mode & ORCLOSE)
- fmod |= FREMOV;
- file->open = fmod;
- file->addr = addr1;
- file->slot = slot1;
- goto out;
-
-badaccess:
- error = Eaccess;
- goto out;
-
-phase:
- error = Ephase;
-
-out:
- if(p != nil)
- putbuf(p);
- if(file != nil)
- qunlock(file);
-
- r->iounit = chan->msize-IOHDRSZ;
-
- return error;
-}
-
-static int
-fsread(Chan* chan, Fcall* f, Fcall* r)
-{
- uchar *data;
- Iobuf *p, *p1;
- File *file;
- Dentry *d, *d1;
- Tlock *t;
- long addr, offset, start, tim;
- int error, iounit, nread, count, n, o, slot;
- Dir dir;
- char strdata[28*10];
-
- p = nil;
- data = (uchar*)r->data;
- count = f->count;
- offset = f->offset;
- nread = 0;
- if((file = filep(chan, f->fid, 0)) == nil){
- error = Efid;
- goto out;
- }
- if(file->qid.type & QTAUTH){
- nread = authread(file, data, count);
- if(nread < 0)
- error = Esystem;
- else
- error = 0;
- goto out;
- }
- if(!(file->open & FREAD)){
- error = Eopen;
- goto out;
- }
- iounit = chan->msize-IOHDRSZ;
- if(count < 0 || count > iounit){
- error = Ecount;
- goto out;
- }
- if(offset < 0){
- error = Eoffset;
- goto out;
- }
- p = getbuf(file->fs->dev, file->addr, Bread);
- if(p == nil || checktag(p, Tdir, QPNONE)){
- error = Ealloc;
- goto out;
- }
- if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
- error = Ealloc;
- goto out;
- }
- if(error = mkqidcmp(&file->qid, d))
- goto out;
- if(t = file->tlock){
- tim = time(0);
- if(t->time < tim || t->file != file){
- error = Ebroken;
- goto out;
- }
- /* renew the lock */
- t->time = tim + TLOCK;
- }
- accessdir(p, d, FREAD);
- if(d->mode & DDIR)
- goto dread;
- if(offset >= d->size)
- count = 0;
- else if(offset+count > d->size)
- count = d->size - offset;
- while(count > 0){
- if(p == nil){
- p = getbuf(file->fs->dev, file->addr, Bread);
- if(p == nil || checktag(p, Tdir, QPNONE)){
- error = Ealloc;
- goto out;
- }
- if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
- error = Ealloc;
- goto out;
- }
- }
- addr = offset / BUFSIZE;
- o = offset % BUFSIZE;
- n = BUFSIZE - o;
- if(n > count)
- n = count;
- p1 = dnodebuf1(p, d, addr, 0);
- p = nil;
- if(p1 != nil){
- if(checktag(p1, Tfile, QPNONE)){
- error = Ephase;
- putbuf(p1);
- goto out;
- }
- memmove(data+nread, p1->iobuf+o, n);
- putbuf(p1);
- }
- else
- memset(data+nread, 0, n);
- count -= n;
- nread += n;
- offset += n;
- }
- goto out;
-
-dread:
- /*
- * Pick up where we left off last time if nothing has changed,
- * otherwise must scan from the beginning.
- */
- if(offset == file->doffset /*&& file->qid.vers == file->dvers*/){
- addr = file->dslot/DIRPERBUF;
- slot = file->dslot%DIRPERBUF;
- start = offset;
- }
- else{
- addr = 0;
- slot = 0;
- start = 0;
- }
-
-dread1:
- if(p == nil){
- /*
- * This is just a check to ensure the entry hasn't
- * gone away during the read of each directory block.
- */
- p = getbuf(file->fs->dev, file->addr, Bread);
- if(p == nil || checktag(p, Tdir, QPNONE)){
- error = Ealloc;
- goto out1;
- }
- if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
- error = Ealloc;
- goto out1;
- }
- }
- p1 = dnodebuf1(p, d, addr, 0);
- p = nil;
- if(p1 == nil)
- goto out1;
- if(checktag(p1, Tdir, QPNONE)){
- error = Ephase;
- putbuf(p1);
- goto out1;
- }
-
- for(; slot < DIRPERBUF; slot++){
- d1 = getdir(p1, slot);
- if(!(d1->mode & DALLOC))
- continue;
- dir9p2(&dir, d1, strdata);
- if((n = convD2M(&dir, data+nread, iounit - nread)) <= BIT16SZ){
- putbuf(p1);
- goto out1;
- }
- start += n;
- if(start < offset)
- continue;
- if(count < n){
- putbuf(p1);
- goto out1;
- }
- count -= n;
- nread += n;
- offset += n;
- }
- putbuf(p1);
- slot = 0;
- addr++;
- goto dread1;
-
-out1:
- if(error == 0){
- file->doffset = offset;
- file->dvers = file->qid.vers;
- file->dslot = slot+DIRPERBUF*addr;
- }
-
-out:
- /*
- * Do we need this any more?
- count = f->count - nread;
- if(count > 0)
- memset(data+nread, 0, count);
- */
- if(p != nil)
- putbuf(p);
- if(file != nil)
- qunlock(file);
- r->count = nread;
- r->data = (char*)data;
-
- return error;
-}
-
-static int
-fswrite(Chan* chan, Fcall* f, Fcall* r)
-{
- Iobuf *p, *p1;
- Dentry *d;
- File *file;
- Tlock *t;
- long offset, addr, tim, qpath;
- int count, error, nwrite, o, n;
-
- offset = f->offset;
- count = f->count;
-
- nwrite = 0;
- p = nil;
-
- if((file = filep(chan, f->fid, 0)) == nil){
- error = Efid;
- goto out;
- }
- if(file->qid.type & QTAUTH){
- nwrite = authwrite(file, (uchar*)f->data, count);
- if(nwrite < 0)
- error = Esystem;
- else
- error = 0;
- goto out;
- }
- if(!(file->open & FWRITE)){
- error = Eopen;
- goto out;
- }
- if(isro(file->fs->dev) || (writegroup && !ingroup(file->uid, writegroup))){
- error = Eronly;
- goto out;
- }
- if(count < 0 || count > chan->msize-IOHDRSZ){
- error = Ecount;
- goto out;
- }
- if(offset < 0) {
- error = Eoffset;
- goto out;
- }
- if((p = getbuf(file->fs->dev, file->addr, Bread|Bmod)) == nil){
- error = Ealloc;
- goto out;
- }
- if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
- error = Ealloc;
- goto out;
- }
- if(error = mkqidcmp(&file->qid, d))
- goto out;
- if(t = file->tlock) {
- tim = time(0);
- if(t->time < tim || t->file != file){
- error = Ebroken;
- goto out;
- }
- /* renew the lock */
- t->time = tim + TLOCK;
- }
- accessdir(p, d, FWRITE);
- if(d->mode & DAPND)
- offset = d->size;
- if(offset+count > d->size)
- d->size = offset+count;
- while(count > 0){
- if(p == nil){
- p = getbuf(file->fs->dev, file->addr, Bread|Bmod);
- if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
- error = Ealloc;
- goto out;
- }
- }
- addr = offset / BUFSIZE;
- o = offset % BUFSIZE;
- n = BUFSIZE - o;
- if(n > count)
- n = count;
- qpath = d->qid.path;
- p1 = dnodebuf1(p, d, addr, Tfile);
- p = nil;
- if(p1 == nil) {
- error = Efull;
- goto out;
- }
- if(checktag(p1, Tfile, qpath)){
- putbuf(p1);
- error = Ephase;
- goto out;
- }
- memmove(p1->iobuf+o, f->data+nwrite, n);
- p1->flags |= Bmod;
- putbuf(p1);
- count -= n;
- nwrite += n;
- offset += n;
- }
-
-out:
- if(p != nil)
- putbuf(p);
- if(file != nil)
- qunlock(file);
- r->count = nwrite;
-
- return error;
-}
-
-static int
-_clunk(File* file, int remove, int wok)
-{
- Tlock *t;
- int error;
-
- error = 0;
- if(t = file->tlock){
- if(t->file == file)
- t->time = 0; /* free the lock */
- file->tlock = 0;
- }
- if(remove)
- error = doremove(file, wok);
- file->open = 0;
- freewp(file->wpath);
- freefp(file);
- qunlock(file);
-
- return error;
-}
-
-static int
-fsclunk(Chan* chan, Fcall* f, Fcall*)
-{
- File *file;
-
- if((file = filep(chan, f->fid, 0)) == nil)
- return Efid;
-
- _clunk(file, file->open & FREMOV, 0);
- return 0;
-}
-
-static int
-fsremove(Chan* chan, Fcall* f, Fcall*)
-{
- File *file;
-
- if((file = filep(chan, f->fid, 0)) == nil)
- return Efid;
-
- return _clunk(file, 1, chan == cons.chan);
-}
-
-static int
-fsstat(Chan* chan, Fcall* f, Fcall* r, uchar* data)
-{
- Dir dir;
- Iobuf *p;
- Dentry *d;
- File *file;
- int error, len;
-
- if((file = filep(chan, f->fid, 0)) == nil)
- return Efid;
-
- p = getbuf(file->fs->dev, file->addr, Bread);
- if(p == nil || checktag(p, Tdir, QPNONE)){
- error = Edir1;
- goto out;
- }
- if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
- error = Ealloc;
- goto out;
- }
- if(error = mkqidcmp(&file->qid, d))
- goto out;
-
- if(d->qid.path == QPROOT) /* stat of root gives time */
- d->atime = time(0);
-
- len = dir9p2(&dir, d, data);
- data += len;
- if((r->nstat = convD2M(&dir, data, chan->msize - len)) == 0)
- error = Ersc;
- else
- r->stat = data;
-
-out:
- if(p != nil)
- putbuf(p);
- if(file != nil)
- qunlock(file);
-
- return error;
-}
-
-static int
-fswstat(Chan* chan, Fcall* f, Fcall*, char *strs)
-{
- Iobuf *p, *p1;
- Dentry *d, *d1, xd;
- File *file;
- int error, slot, uid, gid, l;
- long addr;
- Dir dir;
- ulong mode;
-
- p = p1 = nil;
- d1 = nil;
-
- if((file = filep(chan, f->fid, 0)) == nil){
- error = Efid;
- goto out;
- }
-
- /*
- * if user none,
- * can't do anything
- * unless allow.
- */
- if(file->uid == 0 && !wstatallow){
- error = Eaccess;
- goto out;
- }
-
- if(isro(file->fs->dev) || (writegroup && !ingroup(file->uid, writegroup))){
- error = Eronly;
- goto out;
- }
-
- /*
- * first get parent
- */
- if(file->wpath){
- p1 = getbuf(file->fs->dev, file->wpath->addr, Bread);
- if(p1 == nil){
- error = Ephase;
- goto out;
- }
- d1 = getdir(p1, file->wpath->slot);
- if(d1 == nil || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)){
- error = Ephase;
- goto out;
- }
- }
-
- if((p = getbuf(file->fs->dev, file->addr, Bread)) == nil){
- error = Ealloc;
- goto out;
- }
- d = getdir(p, file->slot);
- if(d == nil || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)){
- error = Ealloc;
- goto out;
- }
- if(error = mkqidcmp(&file->qid, d))
- goto out;
-
- /*
- * Convert the message and fix up
- * fields not to be changed.
- */
- if(convM2D(f->stat, f->nstat, &dir, strs) == 0){
- print("9p2: convM2D returns 0\n");
- error = Econvert;
- goto out;
- }
- if(dir.uid == nil || strlen(dir.uid) == 0)
- uid = d->uid;
- else
- uid = strtouid(dir.uid);
- if(dir.gid == nil || strlen(dir.gid) == 0)
- gid = d->gid;
- else
- gid = strtouid(dir.gid);
- if(dir.name == nil || strlen(dir.name) == 0)
- dir.name = d->name;
- else{
- if((l = checkname9p2(dir.name)) == 0){
- error = Ename;
- goto out;
- }
- if(l > NAMELEN){
- error = Etoolong;
- goto out;
- }
- }
-
- /*
- * Before doing sanity checks, find out what the
- * new 'mode' should be:
- * if 'type' and 'mode' are both defaults, take the
- * new mode from the old directory entry;
- * else if 'type' is the default, use the new mode entry;
- * else if 'mode' is the default, create the new mode from
- * 'type' or'ed with the old directory mode;
- * else neither are defaults, use the new mode but check
- * it agrees with 'type'.
- */
- if(dir.qid.type == 0xFF && dir.mode == ~0){
- dir.mode = d->mode & 0777;
- if(d->mode & DLOCK)
- dir.mode |= DMEXCL;
- if(d->mode & DAPND)
- dir.mode |= DMAPPEND;
- if(d->mode & DDIR)
- dir.mode |= DMDIR;
- }
- else if(dir.qid.type == 0xFF){
- /* nothing to do */
- }
- else if(dir.mode == ~0)
- dir.mode = (dir.qid.type<<24)|(d->mode & 0777);
- else if(dir.qid.type != ((dir.mode>>24) & 0xFF)){
- error = Eqidmode;
- goto out;
- }
-
- /*
- * Check for unknown type/mode bits
- * and an attempt to change the directory bit.
- */
- if(dir.mode & ~(DMDIR|DMAPPEND|DMEXCL|0777)){
- error = Enotm;
- goto out;
- }
- if(d->mode & DDIR)
- mode = DMDIR;
- else
- mode = 0;
- if((dir.mode^mode) & DMDIR){
- error = Enotd;
- goto out;
- }
-
- if(dir.mtime == ~0)
- dir.mtime = d->mtime;
- if(dir.length == ~0)
- dir.length = d->size;
-
- /*
- * Currently, can't change length.
- */
- if(dir.length != d->size){
- error = Enotl;
- goto out;
- }
-
- /*
- * if chown,
- * must be god
- * wstatallow set to allow chown during boot
- */
- if(uid != d->uid && !wstatallow) {
- error = Enotu;
- goto out;
- }
-
- /*
- * if chgroup,
- * must be either
- * a) owner and in new group
- * b) leader of both groups
- * wstatallow and writeallow are set to allow chgrp during boot
- */
- while(gid != d->gid) {
- if(wstatallow || writeallow)
- break;
- if(d->uid == file->uid && ingroup(file->uid, gid))
- break;
- if(leadgroup(file->uid, gid))
- if(leadgroup(file->uid, d->gid))
- break;
- error = Enotg;
- goto out;
- }
-
- /*
- * if rename,
- * must have write permission in parent
- */
- while(strncmp(d->name, dir.name, sizeof(d->name)) != 0) {
- if(checkname(dir.name) || d1 == nil) {
- error = Ename;
- goto out;
- }
- if(strcmp(dir.name, ".") == 0 || strcmp(xd.name, "..") == 0) {
- error = Ename;
- goto out;
- }
-
- /*
- * drop entry to prevent lock, then
- * check that destination name is unique,
- */
- putbuf(p);
- for(addr = 0; ; addr++) {
- if((p = dnodebuf(p1, d1, addr, 0)) == nil)
- break;
- if(checktag(p, Tdir, d1->qid.path)) {
- putbuf(p);
- continue;
- }
- for(slot = 0; slot < DIRPERBUF; slot++) {
- d = getdir(p, slot);
- if(!(d->mode & DALLOC))
- continue;
- if(strncmp(dir.name, d->name, sizeof(d->name)) == 0) {
- error = Eexist;
- goto out;
- }
- }
- putbuf(p);
- }
-
- /*
- * reacquire entry
- */
- if((p = getbuf(file->fs->dev, file->addr, Bread)) == nil){
- error = Ephase;
- goto out;
- }
- d = getdir(p, file->slot);
- if(d == nil || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
- error = Ephase;
- goto out;
- }
-
- if(wstatallow || writeallow) /* set to allow rename during boot */
- break;
- if(d1 == nil || iaccess(file, d1, DWRITE)) {
- error = Eaccess;
- goto out;
- }
- break;
- }
-
- /*
- * if mode/time, either
- * a) owner
- * b) leader of either group
- */
- mode = dir.mode & 0777;
- if(dir.mode & DMAPPEND)
- mode |= DAPND;
- if(dir.mode & DMEXCL)
- mode |= DLOCK;
- while(d->mtime != dir.mtime || ((d->mode^mode) & (DAPND|DLOCK|0777))) {
- if(wstatallow) /* set to allow chmod during boot */
- break;
- if(d->uid == file->uid)
- break;
- if(leadgroup(file->uid, gid))
- break;
- if(leadgroup(file->uid, d->gid))
- break;
- error = Enotu;
- goto out;
- }
- d->mtime = dir.mtime;
- d->uid = uid;
- d->gid = gid;
- d->mode = (mode & (DAPND|DLOCK|0777)) | (d->mode & (DALLOC|DDIR));
-
- strncpy(d->name, dir.name, sizeof(d->name));
- accessdir(p, d, FWSTAT);
-
-out:
- if(p != nil)
- putbuf(p);
- if(p1 != nil)
- putbuf(p1);
- if(file != nil)
- qunlock(file);
-
- return error;
-}
-
-static int
-recv(Chan *c, uchar *buf, int n)
-{
- int fd, m, len;
-
- fd = c->chan;
- /* read count */
- qlock(&c->rlock);
- m = readn(fd, buf, BIT32SZ);
- if(m != BIT32SZ){
- qunlock(&c->rlock);
- if(m < 0){
- print("readn(BIT32SZ) fails: %r\n");
- return -1;
- }
- print("readn(BIT32SZ) returns %d: %r\n", m);
- return 0;
- }
-
- len = GBIT32(buf);
- if(len <= BIT32SZ || len > n){
- print("recv bad length %d\n", len);
- werrstr("bad length in 9P2000 message header");
- qunlock(&c->rlock);
- return -1;
- }
- len -= BIT32SZ;
- m = readn(fd, buf+BIT32SZ, len);
- qunlock(&c->rlock);
- if(m < len){
- print("recv wanted %d got %d\n", len, m);
- return 0;
- }
- return BIT32SZ+m;
-}
-
-static void
-send(Chan *c, uchar *buf, int n)
-{
- int fd, m;
-
- fd = c->chan;
- qlock(&c->wlock);
- m = write(fd, buf, n);
- qunlock(&c->wlock);
- if(m == n)
- return;
- panic("write failed");
-}
-
-void
-serve9p2(Chan *chan, uchar *ib, int nib)
-{
- uchar inbuf[MSIZE+IOHDRSZ], outbuf[MSIZE+IOHDRSZ];
- Fcall f, r;
- char ename[64];
- int error, n, type;
-
- chan->msize = MSIZE;
- fmtinstall('F', fcallfmt);
-
- for(;;){
- if(nib){
- memmove(inbuf, ib, nib);
- n = nib;
- nib = 0;
- }else
- n = recv(chan, inbuf, sizeof inbuf);
- if(chat){
- print("read msg %d (fd %d)\n", n, chan->chan);
- if(n <= 0)
- print("\terr: %r\n");
- }
- if(n == 0 && (chan == cons.srvchan || chan == cons.chan))
- continue;
- if(n <= 0)
- break;
- if(convM2S(inbuf, n, &f) != n){
- print("9p2: cannot decode\n");
- continue;
- }
-
- type = f.type;
- if(type < Tversion || type >= Tmax || (type&1) || type == Terror){
- print("9p2: bad message type %d\n", type);
- continue;
- }
-
- if(CHAT(chan))
- print("9p2: f %F\n", &f);
-
- r.type = type+1;
- r.tag = f.tag;
- error = 0;
-
- rlock(&mainlock);
- rlock(&chan->reflock);
- switch(type){
- default:
- r.type = Rerror;
- snprint(ename, sizeof ename, "unknown message: %F", &f);
- r.ename = ename;
- break;
- case Tversion:
- error = fsversion(chan, &f, &r);
- break;
- case Tauth:
- error = fsauth(chan, &f, &r);
- break;
- case Tattach:
- error = fsattach(chan, &f, &r);
- break;
- case Tflush:
- error = fsflush(chan, &f, &r);
- break;
- case Twalk:
- error = fswalk(chan, &f, &r);
- break;
- case Topen:
- error = fsopen(chan, &f, &r);
- break;
- case Tcreate:
- error = fscreate(chan, &f, &r);
- break;
- case Tread:
- r.data = (char*)inbuf;
- error = fsread(chan, &f, &r);
- break;
- case Twrite:
- error = fswrite(chan, &f, &r);
- break;
- case Tclunk:
- error = fsclunk(chan, &f, &r);
- break;
- case Tremove:
- error = fsremove(chan, &f, &r);
- break;
- case Tstat:
- error = fsstat(chan, &f, &r, inbuf);
- break;
- case Twstat:
- error = fswstat(chan, &f, &r, (char*)outbuf);
- break;
- }
- runlock(&chan->reflock);
- runlock(&mainlock);
-
- if(error != 0){
- r.type = Rerror;
- if(error >= MAXERR){
- snprint(ename, sizeof(ename), "error %d", error);
- r.ename = ename;
- }
- else
- r.ename = errstring[error];
- }
- if(CHAT(chan))
- print("9p2: r %F\n", &r);
-
- n = convS2M(&r, outbuf, sizeof outbuf);
- if(n == 0){
- type = r.type;
- r.type = Rerror;
- snprint(ename, sizeof(ename), "9p2: convS2M: type %d", type);
- r.ename = ename;
- print(ename);
- n = convS2M(&r, outbuf, sizeof outbuf);
- if(n == 0){
- /*
- * What to do here, the failure notification failed?
- */
- panic("can't write anything at all");
- }
- }
- send(chan, outbuf, n);
- }
- fileinit(chan);
- close(chan->chan);
- if(chan == cons.srvchan || chan == cons.chan)
- print("console chan read error");
-}
-
--- a/sys/src/cmd/disk/kfs/all.h
+++ /dev/null
@@ -1,8 +1,0 @@
-#include "u.h"
-#include "libc.h"
-#include "dat.h"
-#include "fns.h"
-
-#include <fcall.h>
-#include <auth.h>
-#include <authsrv.h>
--- a/sys/src/cmd/disk/kfs/auth.c
+++ /dev/null
@@ -1,120 +1,0 @@
-/*
- * Network listening authentication.
- * This and all the other network-related
- * code is due to Richard Miller.
- */
-#include "all.h"
-#include "9p1.h"
-
-int allownone;
-Nvrsafe nvr;
-Authkey authkey;
-int didread;
-
-/*
- * create a challenge for a fid space
- */
-void
-mkchallenge(Chan *cp)
-{
- int i;
-
- if(!didread && readnvram(&nvr, 0) >= 0){
- memmove(authkey.des, nvr.machkey, DESKEYLEN);
- didread = 1;
- }
-
- srand(truerand());
- for(i = 0; i < CHALLEN; i++)
- cp->chal[i] = nrand(256);
-
- cp->idoffset = 0;
- cp->idvec = 0;
-}
-
-/*
- * match a challenge from an attach
- */
-Nvrsafe nvr;
-
-int
-authorize(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- Ticket t;
- Authenticator a;
- int x;
- ulong bit;
-
- if (cp == cons.srvchan) /* local channel already safe */
- return 1;
-
- if(wstatallow) /* set to allow entry during boot */
- return 1;
-
- if(strcmp(in->uname, "none") == 0)
- return allownone || cp->authed;
-
- if(in->type == Toattach9p1)
- return 0;
-
- if(!didread)
- return 0;
-
- /* decrypt and unpack ticket */
- convM2T(in->ticket, sizeof(in->ticket), &t, &authkey);
- if(t.num != AuthTs){
-print("bad AuthTs num\n");
- return 0;
- }
-
- /* decrypt and unpack authenticator */
- convM2A(in->auth, sizeof(in->auth), &a, &t);
- if(a.num != AuthAc){
-print("bad AuthAc num\n");
- return 0;
- }
-
- /* challenges must match */
- if(memcmp(a.chal, cp->chal, sizeof(a.chal)) != 0){
-print("bad challenge\n");
- return 0;
- }
-
- /*
- * the id must be in a valid range. the range is specified by a
- * lower bount (idoffset) and a bit vector (idvec) where a
- * bit set to 1 means unusable
- */
- lock(&cp->idlock);
- x = a.id - cp->idoffset;
- bit = 1<<x;
- if(x < 0 || x > 31 || (bit&cp->idvec)){
- unlock(&cp->idlock);
- return 0;
- }
- cp->idvec |= bit;
-
- /* normalize the vector */
- while(cp->idvec&0xffff0001){
- cp->idvec >>= 1;
- cp->idoffset++;
- }
- unlock(&cp->idlock);
-
- /* ticket name and attach name must match */
- if(memcmp(in->uname, t.cuid, sizeof(in->uname)) != 0){
-print("names don't match\n");
- return 0;
- }
-
- /* copy translated name into input record */
- memmove(in->uname, t.suid, sizeof(in->uname));
-
- /* craft a reply */
- a.num = AuthAs;
- memmove(a.chal, cp->rchal, CHALLEN);
- convA2M(&a, ou->rauth, sizeof(ou->rauth), &t);
-
- cp->authed = 1;
- return 1;
-}
--- a/sys/src/cmd/disk/kfs/chk.c
+++ /dev/null
@@ -1,654 +1,0 @@
-#include "all.h"
-
-#define DSIZE 546000
-#define MAXDEPTH 100
-
-static char* abits;
-static long sizabits;
-static char* qbits;
-static long sizqbits;
-static char* name;
-static long sizname;
-static long fstart;
-static long fsize;
-static long nfiles;
-static long maxq;
-static char* fence;
-static char* fencebase;
-static Device dev;
-static long ndup;
-static long nused;
-static long nfdup;
-static long nqbad;
-static long nfree;
-static long nbad;
-static int mod;
-static int flags;
-static int ronly;
-static int cwflag;
-static long sbaddr;
-static long oldblock;
-static int depth;
-static int maxdepth;
-
-/* local prototypes */
-static int fsck(Dentry*);
-static void ckfreelist(Superb*);
-static void mkfreelist(Superb*);
-static Dentry* maked(long, int, long);
-static void modd(long, int, Dentry*);
-static void xread(long, long);
-static int amark(long);
-static int fmark(long);
-static void missing(void);
-static void qmark(long);
-static void* zalloc(ulong);
-static void* dalloc(ulong);
-static Iobuf* xtag(long, int, long);
-
-static
-void*
-zalloc(ulong n)
-{
- char *p;
-
- p = malloc(n);
- if(p == 0)
- panic("zalloc: out of memory\n");
- memset(p, '\0', n);
- return p;
-}
-
-static
-void*
-dalloc(ulong n)
-{
- char *p;
-
- if(fencebase == 0)
- fence = fencebase = zalloc(MAXDEPTH*sizeof(Dentry));
- p = fence;
- fence += n;
- if(fence > fencebase+MAXDEPTH*sizeof(Dentry))
- panic("dalloc too much memory\n");
- return p;
-}
-
-void
-check(Filsys *fs, long flag)
-{
- Iobuf *p;
- Superb *sb;
- Dentry *d;
- long raddr;
- long nqid;
-
- wlock(&mainlock);
- dev = fs->dev;
- flags = flag;
- fence = fencebase;
-
- sizname = 4000;
- name = zalloc(sizname);
- sizname -= NAMELEN+10; /* for safety */
-
- sbaddr = superaddr(dev);
- raddr = getraddr(dev);
- p = xtag(sbaddr, Tsuper, QPSUPER);
- if(!p){
- cprint("bad superblock\n");
- goto out;
- }
- sb = (Superb*)p->iobuf;
- fstart = 1;
-
- fsize = sb->fsize;
- sizabits = (fsize-fstart + 7)/8;
- abits = zalloc(sizabits);
-
- nqid = sb->qidgen+100; /* not as much of a botch */
- if(nqid > 1024*1024*8)
- nqid = 1024*1024*8;
- if(nqid < 64*1024)
- nqid = 64*1024;
-
- sizqbits = (nqid+7)/8;
- qbits = zalloc(sizqbits);
-
- mod = 0;
- nfree = 0;
- nfdup = 0;
- nused = 0;
- nbad = 0;
- ndup = 0;
- nqbad = 0;
- depth = 0;
- maxdepth = 0;
-
- if(flags & Ctouch) {
- oldblock = fsize/DSIZE;
- oldblock *= DSIZE;
- if(oldblock < 0)
- oldblock = 0;
- cprint("oldblock = %ld\n", oldblock);
- }
- if(amark(sbaddr))
- {}
- if(cwflag) {
- if(amark(sb->roraddr))
- {}
- if(amark(sb->next))
- {}
- }
-
- if(!(flags & Cquiet))
- cprint("checking file system: %s\n", fs->name);
- nfiles = 0;
- maxq = 0;
-
- d = maked(raddr, 0, QPROOT);
- if(d) {
- if(amark(raddr))
- {}
- if(fsck(d))
- modd(raddr, 0, d);
- depth--;
- fence -= sizeof(Dentry);
- if(depth)
- cprint("depth not zero on return\n");
- }
-
- if(flags & Cfree) {
- mkfreelist(sb);
- sb->qidgen = maxq;
- settag(p, Tsuper, QPNONE);
- }
-
- if(sb->qidgen < maxq)
- cprint("qid generator low path=%ld maxq=%ld\n",
- sb->qidgen, maxq);
- if(!(flags & Cfree))
- ckfreelist(sb);
- if(mod) {
- cprint("file system was modified\n");
- settag(p, Tsuper, QPNONE);
- }
-
- if(!(flags & Cquiet)){
- cprint("%8ld files\n", nfiles);
- cprint("%8ld blocks in the file system\n", fsize-fstart);
- cprint("%8ld used blocks\n", nused);
- cprint("%8ld free blocks\n", sb->tfree);
- }
- if(!(flags & Cfree)){
- if(nfree != sb->tfree)
- cprint("%8ld free blocks found\n", nfree);
- if(nfdup)
- cprint("%8ld blocks duplicated in the free list\n", nfdup);
- if(fsize-fstart-nused-nfree)
- cprint("%8ld missing blocks\n", fsize-fstart-nused-nfree);
- }
- if(ndup)
- cprint("%8ld address duplications\n", ndup);
- if(nbad)
- cprint("%8ld bad block addresses\n", nbad);
- if(nqbad)
- cprint("%8ld bad qids\n", nqbad);
- if(!(flags & Cquiet))
- cprint("%8ld maximum qid path\n", maxq);
- missing();
-
-out:
- if(p)
- putbuf(p);
- free(abits);
- free(name);
- free(qbits);
- wunlock(&mainlock);
-}
-
-static
-int
-touch(long a)
-{
- Iobuf *p;
-
- if((flags&Ctouch) && a && a < oldblock){
- p = getbuf(dev, a, Bread|Bmod);
- if(p)
- putbuf(p);
- return 1;
- }
- return 0;
-}
-
-static
-int
-checkdir(long a, long qpath)
-{
- Dentry *nd;
- int i, ns, dmod;
-
- ns = strlen(name);
- dmod = touch(a);
- for(i=0; i<DIRPERBUF; i++) {
- nd = maked(a, i, qpath);
- if(!nd)
- break;
- if(fsck(nd)) {
- modd(a, i, nd);
- dmod++;
- }
- depth--;
- fence -= sizeof(Dentry);
- name[ns] = 0;
- }
- name[ns] = 0;
- return dmod;
-}
-
-static
-int
-checkindir(long a, Dentry *d, long qpath)
-{
- Iobuf *p;
- int i, dmod;
-
- dmod = touch(a);
- p = xtag(a, Tind1, qpath);
- if(!p)
- return dmod;
- for(i=0; i<INDPERBUF; i++) {
- a = ((long*)p->iobuf)[i];
- if(!a)
- continue;
- if(amark(a)) {
- if(flags & Cbad) {
- ((long*)p->iobuf)[i] = 0;
- p->flags |= Bmod;
- }
- continue;
- }
- if(d->mode & DDIR)
- dmod += checkdir(a, qpath);
- else if(flags & Crdall)
- xread(a, qpath);
- }
- putbuf(p);
- return dmod;
-}
-
-static
-int
-fsck(Dentry *d)
-{
- char *s;
- Rune r;
- Iobuf *p;
- int l, i, ns, dmod;
- long a, qpath;
-
- depth++;
- if(depth >= maxdepth){
- maxdepth = depth;
- if(maxdepth >= MAXDEPTH){
- cprint("max depth exceeded: %s\n", name);
- return 0;
- }
- }
- dmod = 0;
- if(!(d->mode & DALLOC))
- return 0;
- nfiles++;
-
- ns = strlen(name);
- i = strlen(d->name);
- if(i >= NAMELEN){
- d->name[NAMELEN-1] = 0;
- cprint("%s->name (%s) not terminated\n", name, d->name);
- return 0;
- }
- ns += i;
- if(ns >= sizname){
- cprint("%s->name (%s) name too large\n", name, d->name);
- return 0;
- }
- for (s = d->name; *s; s += l){
- l = chartorune(&r, s);
- if (r == Runeerror)
- for (i = 0; i < l; i++){
- s[i] = '_';
- cprint("%s->name (%s) bad UTF\n", name, d->name);
- dmod++;
- }
- }
- strcat(name, d->name);
-
- if(d->mode & DDIR){
- if(ns > 1)
- strcat(name, "/");
- if(flags & Cpdir)
- cprint("%s\n", name);
- } else
- if(flags & Cpfile)
- cprint("%s\n", name);
-
- qpath = d->qid.path & ~QPDIR;
- qmark(qpath);
- if(qpath > maxq)
- maxq = qpath;
- for(i=0; i<NDBLOCK; i++) {
- a = d->dblock[i];
- if(!a)
- continue;
- if(amark(a)) {
- d->dblock[i] = 0;
- dmod++;
- continue;
- }
- if(d->mode & DDIR)
- dmod += checkdir(a, qpath);
- else if(flags & Crdall)
- xread(a, qpath);
- }
- a = d->iblock;
- if(a && amark(a)) {
- d->iblock = 0;
- dmod++;
- }
- else if(a)
- dmod += checkindir(a, d, qpath);
-
- a = d->diblock;
- if(a && amark(a)) {
- d->diblock = 0;
- return dmod + 1;
- }
- dmod += touch(a);
- if(p = xtag(a, Tind2, qpath)){
- for(i=0; i<INDPERBUF; i++){
- a = ((long*)p->iobuf)[i];
- if(!a)
- continue;
- if(amark(a)) {
- if(flags & Cbad) {
- ((long*)p->iobuf)[i] = 0;
- p->flags |= Bmod;
- }
- continue;
- }
- dmod += checkindir(a, d, qpath);
- }
- putbuf(p);
- }
- return dmod;
-}
-
-static
-void
-ckfreelist(Superb *sb)
-{
- long a, lo, hi;
- int n, i;
- Iobuf *p;
- Fbuf *fb;
-
-
- strcpy(name, "free list");
- cprint("check %s\n", name);
- fb = &sb->fbuf;
- a = sbaddr;
- p = 0;
- lo = 0;
- hi = 0;
- for(;;) {
- n = fb->nfree;
- if(n < 0 || n > FEPERBUF) {
- cprint("check: nfree bad %ld\n", a);
- break;
- }
- for(i=1; i<n; i++) {
- a = fb->free[i];
- if(a && !fmark(a)) {
- if(!lo || lo > a)
- lo = a;
- if(!hi || hi < a)
- hi = a;
- }
- }
- a = fb->free[0];
- if(!a)
- break;
- if(fmark(a))
- break;
- if(!lo || lo > a)
- lo = a;
- if(!hi || hi < a)
- hi = a;
- if(p)
- putbuf(p);
- p = xtag(a, Tfree, QPNONE);
- if(!p)
- break;
- fb = (Fbuf*)p->iobuf;
- }
- if(p)
- putbuf(p);
- cprint("lo = %ld; hi = %ld\n", lo, hi);
-}
-
-/*
- * make freelist from scratch
- */
-static
-void
-mkfreelist(Superb *sb)
-{
- long a;
- int i, b;
-
- strcpy(name, "free list");
- memset(&sb->fbuf, 0, sizeof(sb->fbuf));
- sb->fbuf.nfree = 1;
- sb->tfree = 0;
- for(a=fsize-fstart-1; a >= 0; a--) {
- i = a/8;
- if(i < 0 || i >= sizabits)
- continue;
- b = 1 << (a&7);
- if(abits[i] & b)
- continue;
- addfree(dev, fstart+a, sb);
- abits[i] |= b;
- }
-}
-
-static
-Dentry*
-maked(long a, int s, long qpath)
-{
- Iobuf *p;
- Dentry *d, *d1;
-
- p = xtag(a, Tdir, qpath);
- if(!p)
- return 0;
- d = getdir(p, s);
- d1 = dalloc(sizeof(Dentry));
- memmove(d1, d, sizeof(Dentry));
- putbuf(p);
- return d1;
-}
-
-static
-void
-modd(long a, int s, Dentry *d1)
-{
- Iobuf *p;
- Dentry *d;
-
- if(!(flags & Cbad))
- return;
- p = getbuf(dev, a, Bread);
- d = getdir(p, s);
- if(!d) {
- if(p)
- putbuf(p);
- return;
- }
- memmove(d, d1, sizeof(Dentry));
- p->flags |= Bmod;
- putbuf(p);
-}
-
-static
-void
-xread(long a, long qpath)
-{
- Iobuf *p;
-
- p = xtag(a, Tfile, qpath);
- if(p)
- putbuf(p);
-}
-
-static
-Iobuf*
-xtag(long a, int tag, long qpath)
-{
- Iobuf *p;
-
- if(a == 0)
- return 0;
- p = getbuf(dev, a, Bread);
- if(!p) {
- cprint("check: \"%s\": xtag: p null\n", name);
- if(flags & (Cream|Ctag)) {
- p = getbuf(dev, a, Bmod);
- if(p) {
- memset(p->iobuf, 0, RBUFSIZE);
- settag(p, tag, qpath);
- mod++;
- return p;
- }
- }
- return 0;
- }
- if(checktag(p, tag, qpath)) {
- cprint("check: \"%s\": xtag: checktag\n", name);
- if(flags & Cream)
- memset(p->iobuf, 0, RBUFSIZE);
- if(flags & (Cream|Ctag)) {
- settag(p, tag, qpath);
- mod++;
- }
- return p;
- }
- return p;
-}
-
-static
-int
-amark(long a)
-{
- long i;
- int b;
-
- if(a < fstart || a >= fsize) {
- cprint("check: \"%s\": range %ld\n",
- name, a);
- nbad++;
- return 1;
- }
- a -= fstart;
- i = a/8;
- b = 1 << (a&7);
- if(abits[i] & b) {
- if(!ronly) {
- if(ndup < 10)
- cprint("check: \"%s\": address dup %ld\n",
- name, fstart+a);
- else
- if(ndup == 10)
- cprint("...");
- }
- ndup++;
- return 0; /* really?? */
- }
- abits[i] |= b;
- nused++;
- return 0;
-}
-
-static
-int
-fmark(long a)
-{
- long i;
- int b;
-
- if(a < fstart || a >= fsize) {
- cprint("check: \"%s\": range %ld\n",
- name, a);
- nbad++;
- return 1;
- }
- a -= fstart;
- i = a/8;
- b = 1 << (a&7);
- if(abits[i] & b) {
- cprint("check: \"%s\": address dup %ld\n",
- name, fstart+a);
- nfdup++;
- return 1;
- }
- abits[i] |= b;
- nfree++;
- return 0;
-}
-
-static
-void
-missing(void)
-{
- long a, i;
- int b, n;
-
- n = 0;
- for(a=fsize-fstart-1; a>=0; a--) {
- i = a/8;
- b = 1 << (a&7);
- if(!(abits[i] & b)) {
- cprint("missing: %ld\n", fstart+a);
- n++;
- }
- if(n > 10) {
- cprint(" ...\n");
- break;
- }
- }
-}
-
-static
-void
-qmark(long qpath)
-{
- int i, b;
-
- i = qpath/8;
- b = 1 << (qpath&7);
- if(i < 0 || i >= sizqbits) {
- nqbad++;
- if(nqbad < 20)
- cprint("check: \"%s\": qid out of range %lux\n",
- name, qpath);
- return;
- }
- if((qbits[i] & b) && !ronly) {
- nqbad++;
- if(nqbad < 20)
- cprint("check: \"%s\": qid dup %lux\n",
- name, qpath);
- }
- qbits[i] |= b;
-}
--- a/sys/src/cmd/disk/kfs/con.c
+++ /dev/null
@@ -1,705 +1,0 @@
-#include "all.h"
-#include "9p1.h"
-
-static char elem[NAMELEN];
-static Filsys* cur_fs;
-static char conline[100];
-
-void
-consserve(void)
-{
- con_session();
- cmd_exec("cfs");
- cmd_exec("user");
-}
-
-int
-cmd_exec(char *arg)
-{
- char *s, *c;
- int i;
-
- for(i=0; s = command[i].string; i++) {
- for(c=arg; *s; c++)
- if(*c != *s++)
- goto brk;
- if(*c == '\0' || *c == ' ' || *c == '\t'){
- cons.arg = c;
- (*command[i].func)();
- return 1;
- }
- brk:;
- }
- return 0;
-}
-
-void
-cmd_check(void)
-{
- char *s;
- int flags;
-
- flags = 0;
- for(s = cons.arg; *s; s++){
- while(*s == ' ' || *s == '\t')
- s++;
- if(*s == '\0')
- break;
- switch(*s){
- /* rebuild the free list */
- case 'f': flags |= Cfree; break;
- /* fix bad tags */
- case 't': flags |= Ctag; break;
- /* fix bad tags and clear the contents of the block */
- case 'c': flags |= Cream; break;
- /* delete all redundant references to a block */
- case 'd': flags |= Cbad; break;
- /* read and check tags on all blocks */
- case 'r': flags |= Crdall; break;
- /* write all of the blocks you touch */
- case 'w': flags |= Ctouch; break;
- /* print all directories as they are read */
- case 'p': flags |= Cpdir; break;
- /* print all files as they are read */
- case 'P': flags |= Cpfile; break;
- /* quiet, just report really nasty stuff */
- case 'q': flags |= Cquiet; break;
- }
- }
- check(cur_fs, flags);
-}
-
-enum
-{
- Sset = (1<<0),
- Setc = (1<<1),
-};
-void
-cmd_stats(void)
-{
- cprint("work stats\n");
- cprint(" work = %A rps\n", (Filta){&cons.work, 1});
- cprint(" rate = %A tBps\n", (Filta){&cons.rate, 1000});
- cprint(" hits = %A iops\n", (Filta){&cons.bhit, 1});
- cprint(" read = %A iops\n", (Filta){&cons.bread, 1});
- cprint(" init = %A iops\n", (Filta){&cons.binit, 1});
-/* for(i = 0; i < MAXTAG; i++)
- cprint(" tag %G = %A iops\n", i, (Filta){&cons.tags[i], 1});
-*/
-}
-
-void
-cmd_sync(void)
-{
- rlock(&mainlock);
- syncall();
- runlock(&mainlock);
-}
-
-void
-cmd_halt(void)
-{
- wlock(&mainlock);
- syncall();
- superok(cur_fs->dev, superaddr(cur_fs->dev), 1);
- print("kfs: file system halted\n");
-}
-
-void
-cmd_start(void)
-{
- superok(cur_fs->dev, superaddr(cur_fs->dev), 0);
- wunlock(&mainlock);
- print("kfs: file system started\n");
-}
-
-void
-cmd_help(void)
-{
- int i;
-
- for(i=0; command[i].string; i++)
- cprint(" %s %s\n", command[i].string, command[i].args);
- cprint("check options:\n"
- " r read all blocks\n"
- " f rebuild the free list\n"
- " t fix all bad tags\n"
- " c fix bad tags and zero the blocks\n"
- " d delete all redundant references to blocks\n"
- " p print directories as they are checked\n"
- " P print all files as they are checked\n"
- " w write all blocks that are read\n");
-}
-
-void
-cmd_create(void)
-{
- int uid, gid, err;
- long perm;
- char oelem[NAMELEN];
- char name[NAMELEN];
-
- if(err = con_clone(FID1, FID2)){
- cprint("clone failed: %s\n", errstring[err]);
- return;
- }
- if(skipbl(1)){
- cprint("skipbl\n");
- return;
- }
- oelem[0] = 0;
- while(nextelem()) {
- if(oelem[0])
- if(err = con_walk(FID2, oelem)){
- cprint("walk failed: %s\n", errstring[err]);
- return;
- }
- memmove(oelem, elem, NAMELEN);
- }
- if(skipbl(1))
- return;
- uid = strtouid(cname(name));
- if(uid == 0){
- cprint("unknown user %s\n", name);
- return;
- }
- gid = strtouid(cname(name));
- if(gid == 0){
- cprint("unknown group %s\n", name);
- return;
- }
- perm = number(0777, 8);
- skipbl(0);
- for(; *cons.arg; cons.arg++){
- if(*cons.arg == 'l')
- perm |= PLOCK;
- else
- if(*cons.arg == 'a')
- perm |= PAPND;
- else
- if(*cons.arg == 'd')
- perm |= PDIR;
- else
- break;
- }
- err = con_create(FID2, elem, uid, gid, perm, 0);
- if(err)
- cprint("can't create %s: %s\n", elem, errstring[err]);
-}
-
-void
-cmd_clri(void)
-{
- if(con_clone(FID1, FID2))
- return;
- if(skipbl(1))
- return;
- while(nextelem())
- if(con_walk(FID2, elem)){
- cprint("can't walk %s\n", elem);
- return;
- }
- con_clri(FID2);
-}
-
-void
-cmd_rename(void)
-{
- ulong perm;
- Dentry d;
- char stat[DIRREC];
- char oelem[NAMELEN], noelem[NAMELEN], nxelem[NAMELEN];
- int err;
-
- if(con_clone(FID1, FID2))
- return;
- if(skipbl(1))
- return;
- oelem[0] = 0;
- while(nextelem()) {
- if(oelem[0])
- if(con_walk(FID2, oelem)){
- cprint("file does not exits");
- return;
- }
- memmove(oelem, elem, NAMELEN);
- }
- if(skipbl(1))
- return;
- if(cons.arg[0]=='/'){
- if(con_clone(FID1, FID3))
- return;
- noelem[0] = 0;
- while(nextelem()){
- if(noelem[0])
- if(con_walk(FID3, noelem)){
- cprint("target path %s does not exist", noelem);
- return;
- }
- memmove(noelem, elem, NAMELEN);
- }
- if(!con_walk(FID3, elem)){
- cprint("target %s already exists\n", elem);
- return;
- }
- if(con_walk(FID2, oelem)){
- cprint("src %s does not exist\n", oelem);
- return;
- }
- /*
- * we know the target does not exist,
- * the source does exist.
- * to do the rename, create the target and then
- * copy the directory entry directly. then remove the source.
- */
- if(err = con_stat(FID2, stat)){
- cprint("can't stat file: %s\n", errstring[err]);
- return;
- }
- convM2D9p1(stat, &d);
- perm = (d.mode&0777)|((d.mode&0x7000)<<17);
- if(err = con_create(FID3, elem, d.uid, d.gid, perm, (d.mode&DDIR)?OREAD:ORDWR)){
- cprint("can't create %s: %s\n", elem, errstring[err]);
- return;
- }
- if(err = con_swap(FID2, FID3)){
- cprint("can't swap data: %s\n", errstring[err]);
- return;
- }
- if(err = con_remove(FID2)){
- cprint("can't remove file: %s\n", errstring[err]);
- return;
- }
- }else{
- cname(nxelem);
- if(strchr(nxelem, '/')){
- cprint("bad rename target: not full path, but contains slashes\n");
- return;
- }
- if(!con_walk(FID2, nxelem))
- cprint("file %s already exists\n", nxelem);
- else if(con_walk(FID2, oelem))
- cprint("file does not already exist\n");
- else if(err = con_stat(FID2, stat))
- cprint("can't stat file: %s\n", errstring[err]);
- else{
- convM2D9p1(stat, &d);
- strncpy(d.name, nxelem, NAMELEN);
- convD2M9p1(&d, stat);
- if(err = con_wstat(FID2, stat))
- cprint("can't move file: %s\n", errstring[err]);
- }
- }
-}
-
-void
-cmd_remove(void)
-{
- if(con_clone(FID1, FID2))
- return;
- if(skipbl(1))
- return;
- while(nextelem())
- if(con_walk(FID2, elem)){
- cprint("can't walk %s\n", elem);
- return;
- }
- con_remove(FID2);
-}
-
-void
-cmd_cfs(void)
-{
- Filsys *fs;
-
- if(*cons.arg != ' ') {
- fs = &filesys[0]; /* default */
- } else {
- if(skipbl(1)){
- cprint("skipbl\n");
- return;
- }
- if(!nextelem())
- fs = &filesys[0]; /* default */
- else
- fs = fsstr(elem);
- }
- if(fs == 0) {
- cprint("unknown file system %s\n", elem);
- return;
- }
- if(con_attach(FID1, "adm", fs->name))
- panic("FID1 attach to root");
- cur_fs = fs;
-}
-
-/*
- * find out the length of a file
- * given the mesg version of a stat buffer
- * we call this because convM2D is different
- * for the file system than in the os
- */
-static uvlong
-statlen(char *ap)
-{
- uchar *p;
- ulong ll, hl;
-
- p = (uchar*)ap;
- p += 3*28+5*4;
- ll = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
- hl = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24);
- return ll | ((uvlong) hl << 32);
-}
-
-int
-adduser(char *user, int isgroup)
-{
- char stat[DIRREC];
- char msg[100];
- Uid *u;
- int i, c, nu;
-
- /*
- * check uniq of name
- * and get next uid
- */
- cmd_exec("cfs");
- cmd_exec("user");
- if(isgroup)
- nu = 9000;
- else
- nu = 0;
- for(i=0, u=uid; i<conf.nuid; i++,u++) {
- c = u->uid;
- if(c == 0)
- break;
- if(strcmp(uidspace+u->offset, user) == 0)
- return 1;
- if(c >= 9000 && !isgroup)
- continue;
- if(c > nu)
- nu = c;
- }
- nu++;
- if(isgroup){
- if(nu >= 0x10000) {
- cprint("out of group ids\n");
- return 0;
- }
- } else {
- if(nu >= 9000) {
- cprint("out of user ids\n");
- return 0;
- }
- }
-
- /*
- * write onto adm/users
- */
- if(con_clone(FID1, FID2)
- || con_path(FID2, "/adm/users")
- || con_open(FID2, 1)) {
- cprint("can't open /adm/users\n");
- return 0;
- }
-
- sprint(msg, "%d:%s:%s:\n", nu, user, user);
- cprint("add user %s", msg);
- c = strlen(msg);
- i = con_stat(FID2, stat);
- if(i){
- cprint("can't stat /adm/users: %s\n", errstring[i]);
- return 0;
- }
- i = con_write(FID2, msg, statlen(stat), c);
- if(i != c){
- cprint("short write on /adm/users: %d %d\n", c, i);
- return 0;
- }
- return 1;
-}
-
-void
-cmd_newuser(void)
-{
- char user[NAMELEN], param[NAMELEN], msg[100];
- int i, c;
-
- /*
- * get uid
- */
- cname(user);
- cname(param);
- for(i=0; i<NAMELEN; i++) {
- c = user[i];
- if(c == 0)
- break;
- if(c >= '0' && c <= '9'
- || c >= 'a' && c <= 'z'
- || c >= 'A' && c <= 'Z')
- continue;
- cprint("bad character in name: 0x%x\n", c);
- return;
- }
- if(i < 2) {
- cprint("name too short: %s\n", user);
- return;
- }
- if(i >= NAMELEN) {
- cprint("name too long: %s\n", user);
- return;
- }
-
- switch(param[0]){
- case 0:
- if(!adduser(user, 0))
- return;
- cmd_exec("user");
- break;
- case ':':
- adduser(user, 1);
- cmd_exec("user");
- return;
- case '#':
- adduser(user, 0);
- cmd_exec("user");
- return;
- }
-
- /*
- * create directories
- */
- cmd_exec("user");
- sprint(msg, "create /usr/%s %s %s 775 d", user, user, user);
- cmd_exec(msg);
- sprint(msg, "create /usr/%s/tmp %s %s 775 d", user, user, user);
- cmd_exec(msg);
- sprint(msg, "create /usr/%s/lib %s %s 775 d", user, user, user);
- cmd_exec(msg);
- sprint(msg, "create /usr/%s/bin %s %s 775 d", user, user, user);
- cmd_exec(msg);
- sprint(msg, "create /usr/%s/bin/rc %s %s 775 d", user, user, user);
- cmd_exec(msg);
- sprint(msg, "create /usr/%s/bin/mips %s %s 775 d", user, user, user);
- cmd_exec(msg);
- sprint(msg, "create /usr/%s/bin/386 %s %s 775 d", user, user, user);
- cmd_exec(msg);
- sprint(msg, "create /usr/%s/bin/power %s %s 775 d", user, user, user);
- cmd_exec(msg);
- sprint(msg, "create /usr/%s/bin/alpha %s %s 775 d", user, user, user);
- cmd_exec(msg);
-}
-
-void
-cmd_checkuser(void)
-{
- uchar buf[DIRREC], *p;
- static char utime[4];
-
- if(con_clone(FID1, FID2)
- || con_path(FID2, "/adm/users")
- || con_open(FID2, 0)
- || con_stat(FID2, (char*)buf))
- return;
- p = buf + 3*NAMELEN + 4*4;
- if(memcmp(utime, p, 4) == 0)
- return;
- memmove(utime, p, 4);
- cmd_user();
-}
-
-void
-cmd_allow(void)
-{
- wstatallow = 1;
-}
-
-void
-cmd_disallow(void)
-{
- wstatallow = 0;
-}
-
-void
-cmd_chat(void)
-{
- chat = 1 - chat;
-}
-
-void
-cmd_atime(void)
-{
- noatime = !noatime;
- if(noatime)
- cprint("atimes will not be updated\n");
- else
- cprint("atimes will be updated\n");
-}
-
-void
-cmd_noneattach(void)
-{
- allownone = !allownone;
- if(allownone)
- cprint("none can attach to new connections\n");
- else
- cprint("none can only attach on authenticated connections\n");
-}
-
-void
-cmd_listen(void)
-{
- char addr[NAMELEN];
-
- if(skipbl(0))
- strcpy(addr, "tcp!*!564"); /* 9fs */
- else
- cname(addr);
-
- if(netserve(addr))
- cprint("announce %s failed\n", addr);
- else
- cprint("announce %s\n", addr);
-}
-
-void
-cmd_nowritegroup(void)
-{
- writegroup = 0;
-}
-
-Command command[] =
-{
- "allow", cmd_allow, "",
- "allowoff", cmd_disallow, "",
- "atime", cmd_atime, "",
- "cfs", cmd_cfs, "[filesys]",
- "chat", cmd_chat, "",
- "check", cmd_check, "[cdfpPqrtw]",
- "clri", cmd_clri, "filename",
- "create", cmd_create, "filename user group perm [ald]",
- "disallow", cmd_disallow, "",
- "halt", cmd_halt, "",
- "help", cmd_help, "",
- "listen", cmd_listen, "[address]",
- "newuser", cmd_newuser, "username",
- "noneattach", cmd_noneattach, "",
- "nowritegroup", cmd_nowritegroup, "",
- "remove", cmd_remove, "filename",
- "rename", cmd_rename, "file newname",
- "start", cmd_start, "",
- "stats", cmd_stats, "[fw]",
- "sync", cmd_sync, "",
- "user", cmd_user, "",
- 0
-};
-
-int
-skipbl(int err)
-{
- if(*cons.arg != ' ') {
- if(err)
- cprint("syntax error\n");
- return 1;
- }
- while(*cons.arg == ' ')
- cons.arg++;
- return 0;
-}
-
-char*
-_cname(char *name)
-{
- int i, c;
-
- memset(name, 0, NAMELEN);
- for(i=0;; i++) {
- c = *cons.arg;
- switch(c) {
- case ' ':
- case '\t':
- case '\n':
- case '\0':
- return name;
- }
- if(i < NAMELEN-1)
- name[i] = c;
- cons.arg++;
- }
-}
-
-char*
-cname(char *name)
-{
- skipbl(0);
- return _cname(name);
-}
-
-int
-nextelem(void)
-{
- char *e;
- int i, c;
-
- e = elem;
- while(*cons.arg == '/')
- cons.arg++;
- c = *cons.arg;
- if(c == 0 || c == ' ')
- return 0;
- for(i = 0; c = *cons.arg; i++) {
- if(c == ' ' || c == '/')
- break;
- if(i == NAMELEN) {
- cprint("path name component too long\n");
- return 0;
- }
- *e++ = c;
- cons.arg++;
- }
- *e = 0;
- return 1;
-}
-
-long
-number(int d, int base)
-{
- int c, sign, any;
- long n;
-
- sign = 0;
- any = 0;
- n = 0;
-
- c = *cons.arg;
- while(c == ' ') {
- cons.arg++;
- c = *cons.arg;
- }
- if(c == '-') {
- sign = 1;
- cons.arg++;
- c = *cons.arg;
- }
- while((c >= '0' && c <= '9') ||
- (base == 16 && c >= 'a' && c <= 'f') ||
- (base == 16 && c >= 'A' && c <= 'F')) {
- n *= base;
- if(c >= 'a' && c <= 'f')
- n += c - 'a' + 10;
- else
- if(c >= 'A' && c <= 'F')
- n += c - 'A' + 10;
- else
- n += c - '0';
- cons.arg++;
- c = *cons.arg;
- any = 1;
- }
- if(!any)
- return d;
- if(sign)
- n = -n;
- return n;
-}
--- a/sys/src/cmd/disk/kfs/console.c
+++ /dev/null
@@ -1,371 +1,0 @@
-#include "all.h"
-#include "9p1.h"
-
-void
-fcall9p1(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- int t;
-
- rlock(&mainlock);
- t = in->type;
- if(t < 0 || t >= MAXSYSCALL || (t&1) || !call9p1[t]) {
- print("bad message type %d\n", t);
- panic("");
- }
- ou->type = t+1;
- ou->err = 0;
-
- rlock(&cp->reflock);
- (*call9p1[t])(cp, in, ou);
- runlock(&cp->reflock);
-
- if(ou->err)
- if(CHAT(cp))
- print(" error: %s\n", errstring[ou->err]);
- cons.work.count++;
- runlock(&mainlock);
-}
-
-int
-con_session(void)
-{
- Oldfcall in, ou;
-
- in.type = Tsession9p1;
- fcall9p1(cons.chan, &in, &ou);
- return ou.err;
-}
-
-int
-con_attach(int fid, char *uid, char *arg)
-{
- Oldfcall in, ou;
-
- in.type = Tattach9p1;
- in.fid = fid;
- strncpy(in.uname, uid, NAMELEN);
- strncpy(in.aname, arg, NAMELEN);
- fcall9p1(cons.chan, &in, &ou);
- return ou.err;
-}
-
-int
-con_clone(int fid1, int fid2)
-{
- Oldfcall in, ou;
-
- in.type = Tclone9p1;
- in.fid = fid1;
- in.newfid = fid2;
- fcall9p1(cons.chan, &in, &ou);
- return ou.err;
-}
-
-int
-con_path(int fid, char *path)
-{
- Oldfcall in, ou;
- char *p;
-
- in.type = Twalk9p1;
- in.fid = fid;
-
-loop:
- if(*path == 0)
- return 0;
- strncpy(in.name, path, NAMELEN);
- if(p = strchr(path, '/')) {
- path = p+1;
- if(p = strchr(in.name, '/'))
- *p = 0;
- } else
- path = strchr(path, 0);
- if(in.name[0]) {
- fcall9p1(cons.chan, &in, &ou);
- if(ou.err)
- return ou.err;
- }
- goto loop;
-}
-
-int
-con_walk(int fid, char *name)
-{
- Oldfcall in, ou;
-
- in.type = Twalk9p1;
- in.fid = fid;
- strncpy(in.name, name, NAMELEN);
- fcall9p1(cons.chan, &in, &ou);
- return ou.err;
-}
-
-int
-con_stat(int fid, char *data)
-{
- Oldfcall in, ou;
-
- in.type = Tstat9p1;
- in.fid = fid;
- fcall9p1(cons.chan, &in, &ou);
- if(ou.err == 0)
- memmove(data, ou.stat, sizeof ou.stat);
- return ou.err;
-}
-
-int
-con_wstat(int fid, char *data)
-{
- Oldfcall in, ou;
-
- in.type = Twstat9p1;
- in.fid = fid;
- memmove(in.stat, data, sizeof in.stat);
- fcall9p1(cons.chan, &in, &ou);
- return ou.err;
-}
-
-int
-con_open(int fid, int mode)
-{
- Oldfcall in, ou;
-
- in.type = Topen9p1;
- in.fid = fid;
- in.mode = mode;
- fcall9p1(cons.chan, &in, &ou);
- return ou.err;
-}
-
-int
-con_read(int fid, char *data, long offset, int count)
-{
- Oldfcall in, ou;
-
- in.type = Tread9p1;
- in.fid = fid;
- in.offset = offset;
- in.count = count;
- ou.data = data;
- fcall9p1(cons.chan, &in, &ou);
- if(ou.err)
- return 0;
- return ou.count;
-}
-
-int
-con_write(int fid, char *data, long offset, int count)
-{
- Oldfcall in, ou;
-
- in.type = Twrite9p1;
- in.fid = fid;
- in.data = data;
- in.offset = offset;
- in.count = count;
- fcall9p1(cons.chan, &in, &ou);
- if(ou.err)
- return 0;
- return ou.count;
-}
-
-int
-con_remove(int fid)
-{
- Oldfcall in, ou;
-
- in.type = Tremove9p1;
- in.fid = fid;
- fcall9p1(cons.chan, &in, &ou);
- return ou.err;
-}
-
-int
-con_create(int fid, char *name, int uid, int gid, long perm, int mode)
-{
- Oldfcall in, ou;
-
- in.type = Tcreate9p1;
- in.fid = fid;
- strncpy(in.name, name, NAMELEN);
- in.perm = perm;
- in.mode = mode;
- cons.uid = uid; /* beyond ugly */
- cons.gid = gid;
- fcall9p1(cons.chan, &in, &ou);
- return ou.err;
-}
-
-int
-doclri(File *f)
-{
- Iobuf *p, *p1;
- Dentry *d, *d1;
- int err;
-
- err = 0;
- p = 0;
- p1 = 0;
- if(isro(f->fs->dev)) {
- err = Eronly;
- goto out;
- }
- /*
- * check on parent directory of file to be deleted
- */
- if(f->wpath == 0 || f->wpath->addr == f->addr) {
- err = Ephase;
- goto out;
- }
- p1 = getbuf(f->fs->dev, f->wpath->addr, Bread);
- d1 = getdir(p1, f->wpath->slot);
- if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
- err = Ephase;
- goto out;
- }
-
- accessdir(p1, d1, FWRITE);
- putbuf(p1);
- p1 = 0;
-
- /*
- * check on file to be deleted
- */
- p = getbuf(f->fs->dev, f->addr, Bread);
- d = getdir(p, f->slot);
-
-
- /*
- * do it
- */
- memset(d, 0, sizeof(Dentry));
- settag(p, Tdir, QPNONE);
- freewp(f->wpath);
- freefp(f);
-
-out:
- if(p1)
- putbuf(p1);
- if(p)
- putbuf(p);
- return err;
-}
-
-void
-f_clri(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
- File *f;
-
- if(CHAT(cp)) {
- print("c_clri %d\n", cp->chan);
- print(" fid = %d\n", in->fid);
- }
-
- f = filep(cp, in->fid, 0);
- if(!f) {
- ou->err = Efid;
- goto out;
- }
- ou->err = doclri(f);
-
-out:
- ou->fid = in->fid;
- if(f)
- qunlock(f);
-}
-
-int
-con_clri(int fid)
-{
- Oldfcall in, ou;
- Chan *cp;
-
- in.type = Tremove9p1;
- in.fid = fid;
- cp = cons.chan;
-
- rlock(&mainlock);
- ou.type = Tremove9p1+1;
- ou.err = 0;
-
- rlock(&cp->reflock);
-
- f_clri(cp, &in, &ou);
-
- runlock(&cp->reflock);
-
- cons.work.count++;
- runlock(&mainlock);
- return ou.err;
-}
-
-int
-con_swap(int fid1, int fid2)
-{
- int err;
- Iobuf *p1, *p2;
- File *f1, *f2;
- Dentry *d1, *d2;
- Dentry dt1, dt2;
- Chan *cp;
-
- cp = cons.chan;
- err = 0;
- rlock(&mainlock);
- rlock(&cp->reflock);
-
- f2 = nil;
- p1 = p2 = nil;
- f1 = filep(cp, fid1, 0);
- if(!f1){
- err = Efid;
- goto out;
- }
- p1 = getbuf(f1->fs->dev, f1->addr, Bread|Bmod);
- d1 = getdir(p1, f1->slot);
- if(!d1 || !(d1->mode&DALLOC)){
- err = Ealloc;
- goto out;
- }
-
- f2 = filep(cp, fid2, 0);
- if(!f2){
- err = Efid;
- goto out;
- }
- if(memcmp(&f1->fs->dev, &f2->fs->dev, 4)==0
- && f2->addr == f1->addr)
- p2 = p1;
- else
- p2 = getbuf(f2->fs->dev, f2->addr, Bread|Bmod);
- d2 = getdir(p2, f2->slot);
- if(!d2 || !(d2->mode&DALLOC)){
- err = Ealloc;
- goto out;
- }
-
- dt1 = *d1;
- dt2 = *d2;
- *d1 = dt2;
- *d2 = dt1;
- memmove(d1->name, dt1.name, NAMELEN);
- memmove(d2->name, dt2.name, NAMELEN);
-
- mkqid(&f1->qid, d1, 1);
- mkqid(&f2->qid, d2, 1);
-out:
- if(f1)
- qunlock(f1);
- if(f2)
- qunlock(f2);
- if(p1)
- putbuf(p1);
- if(p2 && p2!=p1)
- putbuf(p2);
-
- runlock(&cp->reflock);
- cons.work.count++;
- runlock(&mainlock);
-
- return err;
-}
--- a/sys/src/cmd/disk/kfs/dat.c
+++ /dev/null
@@ -1,87 +1,0 @@
-#include "all.h"
-
-Uid* uid;
-char* uidspace;
-short* gidspace;
-RWLock mainlock;
-long boottime;
-Tlock *tlocks;
-Conf conf;
-Cons cons;
-Chan *chan;
-char service[2*NAMELEN];
-char *progname;
-char *procname;
-int RBUFSIZE;
-int BUFSIZE;
-int DIRPERBUF;
-int INDPERBUF;
-int INDPERBUF2;
-int FEPERBUF;
-
-Filsys filesys[MAXFILSYS] =
-{
- {"main", {Devwren, 0, 0, 0}, 0},
-};
-
-Device devnone = {Devnone, 0, 0, 0};
-
-Devcall devcall[MAXDEV] = {
- [Devnone] {0},
- [Devwren] {wreninit, wrenream, wrencheck, wrensuper, wrenroot, wrensize, wrenread, wrenwrite},
-};
-
-char* tagnames[] =
-{
- [Tbuck] "Tbuck",
- [Tdir] "Tdir",
- [Tfile] "Tfile",
- [Tfree] "Tfree",
- [Tind1] "Tind1",
- [Tind2] "Tind2",
- [Tnone] "Tnone",
- [Tsuper] "Tsuper",
- [Tvirgo] "Tvirgo",
- [Tcache] "Tcache",
-};
-
-char *errstring[MAXERR] =
-{
- [Ebadspc] "attach -- bad specifier",
- [Efid] "unknown fid",
- [Echar] "bad character in directory name",
- [Eopen] "read/write -- on non open fid",
- [Ecount] "read/write -- count too big",
- [Ealloc] "phase error -- directory entry not allocated",
- [Eqid] "phase error -- qid does not match",
- [Eauth] "authentication failed",
- [Eauthmsg] "kfs: authentication not required",
- [Eaccess] "access permission denied",
- [Eentry] "directory entry not found",
- [Emode] "open/create -- unknown mode",
- [Edir1] "walk -- in a non-directory",
- [Edir2] "create -- in a non-directory",
- [Ephase] "phase error -- cannot happen",
- [Eexist] "create -- file exists",
- [Edot] "create -- . and .. illegal names",
- [Eempty] "remove -- directory not empty",
- [Ebadu] "attach -- privileged user",
- [Enotu] "wstat -- not owner",
- [Enotg] "wstat -- not in group",
- [Enotl] "wstat -- attempt to change length",
- [Enotd] "wstat -- attempt to change directory",
- [Enotm] "wstat -- unknown type/mode",
- [Ename] "create/wstat -- bad character in file name",
- [Ewalk] "walk -- too many (system wide)",
- [Eronly] "file system read only",
- [Efull] "file system full",
- [Eoffset] "read/write -- offset negative",
- [Elocked] "open/create -- file is locked",
- [Ebroken] "close/read/write -- lock is broken",
- [Efidinuse] "fid already in use",
- [Etoolong] "name too long",
- [Ersc] "it's russ's fault. bug him.",
- [Econvert] "protocol botch",
- [Eqidmode] "wstat -- qid.type/dir.mode mismatch",
- [Esystem] "kfs system error",
-};
--- a/sys/src/cmd/disk/kfs/dat.h
+++ /dev/null
@@ -1,170 +1,0 @@
-typedef struct Chan Chan;
-typedef struct Command Command;
-typedef struct Conf Conf;
-typedef struct Cons Cons;
-typedef struct Devcall Devcall;
-
-#define MAXBUFSIZE (16*1024) /* max. buffer size */
-
-#include "portdat.h"
-
-struct Chan
-{
- int chan; /* fd request came in on */
- QLock rlock, wlock; /* lock for reading/writing messages on chan */
- int type;
- int flags;
- long whotime;
- File* flist; /* base of file structures */
- Lock flock; /* manipulate flist */
- RWLock reflock; /* lock for Tflush */
- int msize; /* version */
- int authed; /* someone other than ``none'' has authed */
-
-/* 9p1 auth */
- uchar chal[8];
- uchar rchal[8];
- int idoffset;
- int idvec;
- Lock idlock;
-};
-
-/*
- * console cons.flag flags
- */
-enum
-{
- Fchat = (1<<0), /* print out filesys rpc traffic */
- Fuid = (1<<2), /* print out uids */
- /* debugging flags for drivers */
-};
-
-struct Cons
-{
- int flags; /* overall flags for all channels */
- int uid; /* botch -- used to get uid on cons_create */
- int gid; /* botch -- used to get gid on cons_create */
- int allow; /* no-protection flag */
- long offset; /* used to read files, c.f. fchar */
- char* arg; /* pointer to remaining line */
-
- Chan *chan; /* console channel */
- Chan *srvchan; /* local server channel */
-
- Filter work; /* thruput in messages */
- Filter rate; /* thruput in bytes */
- Filter bhit; /* getbufs that hit */
- Filter bread; /* getbufs that miss and read */
- Filter binit; /* getbufs that miss and dont read */
- Filter tags[MAXTAG]; /* reads of each type of block */
-};
-
-struct Conf
-{
- ulong niobuf; /* number of iobufs to allocate */
- ulong nuid; /* distinct uids */
- ulong uidspace; /* space for uid names -- derrived from nuid */
- ulong gidspace; /* space for gid names -- derrived from nuid */
- ulong nserve; /* server processes */
- ulong nfile; /* number of fid -- system wide */
- ulong nwpath; /* number of active paths, derrived from nfile */
- ulong bootsize; /* number of bytes reserved for booting */
-};
-
-struct Command
-{
- char *string;
- void (*func)(void);
- char *args;
-};
-
-struct Devcall
-{
- void (*init)(Device);
- void (*ream)(Device);
- int (*check)(Device);
- long (*super)(Device);
- long (*root)(Device);
- long (*size)(Device);
- int (*read)(Device, long, void*);
- int (*write)(Device, long, void*);
-};
-
-/*
- * device types
- */
-enum
-{
- Devnone = 0,
- Devwren,
- MAXDEV
-};
-
-/*
- * file systems
- */
-enum
-{
- MAXFILSYS = 4
-};
-
-/*
- * should be in portdat.h
- */
-#define QPDIR 0x80000000L
-#define QPNONE 0
-#define QPROOT 1
-#define QPSUPER 2
-
-/*
- * perm argument in p9 create
- */
-#define PDIR (1L<<31) /* is a directory */
-#define PAPND (1L<<30) /* is append only */
-#define PLOCK (1L<<29) /* is locked on open */
-
-#define NOF (-1)
-
-#define FID1 1
-#define FID2 2
-#define FID3 3
-
-#define SECOND(n) (n)
-#define MINUTE(n) (n*SECOND(60))
-#define HOUR(n) (n*MINUTE(60))
-#define DAY(n) (n*HOUR(24))
-#define TLOCK MINUTE(5)
-
-#define CHAT(cp) (chat)
-#define QID9P1(a,b) (Qid9p1){a,b}
-
-extern Uid* uid;
-extern char* uidspace;
-extern short* gidspace;
-extern char* errstring[MAXERR];
-extern Chan* chans;
-extern RWLock mainlock;
-extern long boottime;
-extern Tlock *tlocks;
-extern Device devnone;
-extern Filsys filesys[];
-extern char service[];
-extern char* tagnames[];
-extern Conf conf;
-extern Cons cons;
-extern Command command[];
-extern Chan *chan;
-extern Devcall devcall[];
-extern char *progname;
-extern char *procname;
-extern long niob;
-extern long nhiob;
-extern Hiob *hiob;
-extern int chat;
-extern int writeallow;
-extern int wstatallow;
-extern int allownone;
-extern int noatime;
-extern int writegroup;
-
-extern Lock wpathlock;
--- a/sys/src/cmd/disk/kfs/dentry.c
+++ /dev/null
@@ -1,174 +1,0 @@
-#include "all.h"
-
-Dentry*
-getdir(Iobuf *p, int slot)
-{
- Dentry *d;
-
- if(!p)
- return 0;
- d = (Dentry*)p->iobuf + slot%DIRPERBUF;
- return d;
-}
-
-void
-accessdir(Iobuf *p, Dentry *d, int f)
-{
- long t;
-
- if(p && !isro(p->dev)) {
- if(!(f & (FWRITE|FWSTAT)) && noatime)
- return;
- t = time(nil);
- if(f & (FREAD|FWRITE|FWSTAT)){
- d->atime = t;
- p->flags |= Bmod;
- }
- if(f & FWRITE) {
- d->mtime = t;
- d->qid.version++;
- p->flags |= Bmod;
- }
- }
-}
-
-void
-dbufread(Iobuf *p, Dentry *d, long a)
-{
- USED(p, d, a);
-}
-
-long
-rel2abs(Iobuf *p, Dentry *d, long a, int tag, int putb)
-{
- long addr, qpath;
- Device dev;
-
- if(a < 0) {
- print("dnodebuf: neg\n");
- return 0;
- }
- qpath = d->qid.path;
- dev = p->dev;
- if(a < NDBLOCK) {
- addr = d->dblock[a];
- if(!addr && tag) {
- addr = balloc(dev, tag, qpath);
- d->dblock[a] = addr;
- p->flags |= Bmod|Bimm;
- }
- if(putb)
- putbuf(p);
- return addr;
- }
- a -= NDBLOCK;
- if(a < INDPERBUF) {
- addr = d->iblock;
- if(!addr && tag) {
- addr = balloc(dev, Tind1, qpath);
- d->iblock = addr;
- p->flags |= Bmod|Bimm;
- }
- if(putb)
- putbuf(p);
- addr = indfetch(p, d, addr, a, Tind1, tag);
- return addr;
- }
- a -= INDPERBUF;
- if(a < INDPERBUF2) {
- addr = d->diblock;
- if(!addr && tag) {
- addr = balloc(dev, Tind2, qpath);
- d->diblock = addr;
- p->flags |= Bmod|Bimm;
- }
- if(putb)
- putbuf(p);
- addr = indfetch(p, d, addr, a/INDPERBUF, Tind2, Tind1);
- addr = indfetch(p, d, addr, a%INDPERBUF, Tind1, tag);
- return addr;
- }
- if(putb)
- putbuf(p);
- print("dnodebuf: trip indirect\n");
- return 0;
-}
-
-Iobuf*
-dnodebuf(Iobuf *p, Dentry *d, long a, int tag)
-{
- long addr;
-
- addr = rel2abs(p, d, a, tag, 0);
- if(addr)
- return getbuf(p->dev, addr, Bread);
- return 0;
-}
-
-/*
- * same as dnodebuf but it calls putpuf(p)
- * to reduce interference.
- */
-Iobuf*
-dnodebuf1(Iobuf *p, Dentry *d, long a, int tag)
-{
- long addr;
- Device dev;
-
- dev = p->dev;
- addr = rel2abs(p, d, a, tag, 1);
- if(addr)
- return getbuf(dev, addr, Bread);
- return 0;
-
-}
-
-long
-indfetch(Iobuf *p, Dentry *d, long addr, long a, int itag, int tag)
-{
- Iobuf *bp;
-
- if(!addr)
- return 0;
- bp = getbuf(p->dev, addr, Bread);
- if(!bp || checktag(bp, itag, d->qid.path)) {
- if(!bp) {
- print("ind fetch bp = 0\n");
- return 0;
- }
- print("ind fetch tag\n");
- putbuf(bp);
- return 0;
- }
- addr = ((long*)bp->iobuf)[a];
- if(!addr && tag) {
- addr = balloc(p->dev, tag, d->qid.path);
- if(addr) {
- ((long*)bp->iobuf)[a] = addr;
- bp->flags |= Bmod;
- if(localfs || tag == Tdir)
- bp->flags |= Bimm;
- settag(bp, itag, d->qid.path);
- }
- }
- putbuf(bp);
- return addr;
-}
-
-void
-dtrunc(Iobuf *p, Dentry *d)
-{
- int i;
-
- bfree(p->dev, d->diblock, 2);
- d->diblock = 0;
- bfree(p->dev, d->iblock, 1);
- d->iblock = 0;
- for(i=NDBLOCK-1; i>=0; i--) {
- bfree(p->dev, d->dblock[i], 0);
- d->dblock[i] = 0;
- }
- d->size = 0;
- p->flags |= Bmod|Bimm;
- accessdir(p, d, FWRITE);
-}
--- a/sys/src/cmd/disk/kfs/devmulti.c
+++ /dev/null
@@ -1,244 +1,0 @@
-#include "all.h"
-
-enum{
- MAXWREN = 7,
-};
-
-static char WMAGIC[] = "kfs wren device\n";
-static char MMAGIC[] = "kfs multi-wren device %4d/%4d\n";
-
-typedef struct Wren Wren;
-
-struct Wren{
- QLock;
- Device dev;
- ulong nblocks;
- int fd;
-};
-
-static char *wmagic = WMAGIC;
-static Wren *wrens;
-static int maxwren;
-char *wrenfile;
-int nwren;
-int badmagic;
-
-static Wren *
-wren(Device dev)
-{
- int i;
-
- for(i = 0; i < maxwren; i++)
- if(devcmp(dev, wrens[i].dev) == 0)
- return &wrens[i];
- panic("can't find wren for %D", dev);
- return 0;
-}
-
-/*
- * find out the length of a file
- * given the mesg version of a stat buffer
- * we call this because convM2D is different
- * for the file system than in the os
- */
-uvlong
-statlen(char *ap)
-{
- uchar *p;
- ulong ll, hl;
-
- p = (uchar*)ap;
- p += 3*NAMELEN+5*4;
- ll = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
- hl = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24);
- return ll | ((uvlong) hl << 32);
-}
-
-static void
-wrenpartinit(Device dev, int k)
-{
- char buf[MAXBUFSIZE], d[DIRREC];
- char file[128], magic[64];
- Wren *w;
- int fd, i, nmagic;
-
- if(wrens == 0)
- wrens = ialloc(MAXWREN * sizeof *wrens);
- w = &wrens[maxwren];
- if(nwren > 0)
- sprint(file, "%s%d", wrenfile, k);
- else
- strcpy(file, wrenfile);
- fd = open(file, ORDWR);
- if(fd < 0)
- panic("can't open %s", file);
- if(fstat(fd, d) < 0)
- panic("can't stat %s\n", file);
- seek(fd, 0, 0);
- i = read(fd, buf, sizeof buf);
- if(i < sizeof buf)
- panic("can't read %s", file);
- badmagic = 0;
- RBUFSIZE = 1024;
- sprint(magic, wmagic, k, nwren);
- nmagic = strlen(magic);
- if(strncmp(buf+256, magic, nmagic) == 0){
- RBUFSIZE = atol(buf+256+nmagic);
- if(RBUFSIZE % 512){
- fprint(2, "kfs: bad buffersize(%d): assuming 1k blocks\n", RBUFSIZE);
- RBUFSIZE = 1024;
- }
- }else
- badmagic = 1;
- w->dev = dev;
- w->nblocks = statlen(d)/RBUFSIZE;
- if(k > 0)
- w->nblocks -= 1; /* don't count magic */
- w->fd = fd;
- maxwren++;
-}
-
-void
-wreninit(Device dev)
-{
- int i;
-
- if(nwren > 0)
- wmagic = MMAGIC;
- i = 0;
- do{
- wrenpartinit(dev, i);
- }while(++i < nwren);
-}
-
-static void
-wrenpartream(Device dev, int k)
-{
- Wren *w;
- char buf[MAXBUFSIZE], magic[64];
- int fd, i;
-
- if(RBUFSIZE % 512)
- panic("kfs: bad buffersize(%d): restart a multiple of 512\n", RBUFSIZE);
- print("kfs: reaming the file system using %d byte blocks\n", RBUFSIZE);
- w = wren(dev)+k;
- fd = w->fd;
- memset(buf, 0, sizeof buf);
- sprint(magic, wmagic, k, nwren);
- sprint(buf+256, "%s%d\n", magic, RBUFSIZE);
- qlock(w);
- i = seek(fd, 0, 0) < 0 || write(fd, buf, RBUFSIZE) != RBUFSIZE;
- qunlock(w);
- if(i < 0)
- panic("can't ream disk");
-}
-
-void
-wrenream(Device dev)
-{
- int i;
-
- i = 0;
- do{
- wrenpartream(dev, i);
- }while(++i < nwren);
-}
-
-static int
-wrentag(char *p, int tag, long qpath)
-{
- Tag *t;
-
- t = (Tag*)(p+BUFSIZE);
- return t->tag != tag || (qpath&~QPDIR) != t->path;
-}
-
-int
-wrencheck(Device dev)
-{
- char buf[MAXBUFSIZE];
-
- if(badmagic)
- return 1;
- if(RBUFSIZE > sizeof buf)
- panic("bufsize too big");
- if(wrenread(dev, wrensuper(dev), buf) || wrentag(buf, Tsuper, QPSUPER)
- || wrenread(dev, wrenroot(dev), buf) || wrentag(buf, Tdir, QPROOT))
- return 1;
- if(((Dentry *)buf)[0].mode & DALLOC)
- return 0;
- return 1;
-}
-
-long
-wrensize(Device dev)
-{
- Wren *w;
- int i, nb;
-
- w = wren(dev);
- nb = 0;
- i = 0;
- do{
- nb += w[i].nblocks;
- }while(++i < nwren);
- return nb;
-}
-
-long
-wrensuper(Device dev)
-{
- USED(dev);
- return 1;
-}
-
-long
-wrenroot(Device dev)
-{
- USED(dev);
- return 2;
-}
-
-int
-wrenread(Device dev, long addr, void *b)
-{
- Wren *w;
- int fd, i;
-
- w = wren(dev);
- for(i=0; i<nwren; i++){
- if(addr < w->nblocks)
- break;
- addr -= w->nblocks;
- ++w;
- }
- if(i > 0)
- addr++;
- fd = w->fd;
- qlock(w);
- i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || read(fd, b, RBUFSIZE) != RBUFSIZE;
- qunlock(w);
- return i;
-}
-
-int
-wrenwrite(Device dev, long addr, void *b)
-{
- Wren *w;
- int fd, i;
-
- w = wren(dev);
- for(i=0; i<nwren; i++){
- if(addr < w->nblocks)
- break;
- addr -= w->nblocks;
- ++w;
- }
- if(i > 0)
- addr++;
- fd = w->fd;
- qlock(w);
- i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || write(fd, b, RBUFSIZE) != RBUFSIZE;
- qunlock(w);
- return i;
-}
--- a/sys/src/cmd/disk/kfs/devwren.c
+++ /dev/null
@@ -1,174 +1,0 @@
-#include "all.h"
-
-enum{
- MAXWREN = 7,
-};
-
-#define WMAGIC "kfs wren device\n"
-
-typedef struct Wren Wren;
-
-struct Wren{
- QLock;
- Device dev;
- uvlong size;
- int fd;
-};
-
-static Wren *wrens;
-static int maxwren;
-char *wrenfile;
-int nwren;
-int badmagic;
-
-static Wren *
-wren(Device dev)
-{
- int i;
-
- for(i = 0; i < maxwren; i++)
- if(devcmp(dev, wrens[i].dev) == 0)
- return &wrens[i];
- panic("can't find wren for %D", dev);
- return 0;
-}
-
-void
-wreninit(Device dev)
-{
- char buf[MAXBUFSIZE];
- Wren *w;
- Dir *d;
- int fd, i;
-
- if(wrens == 0)
- wrens = ialloc(MAXWREN * sizeof *wrens);
- w = &wrens[maxwren];
- fd = open(wrenfile, ORDWR);
- if(fd < 0)
- panic("can't open %s", wrenfile);
- if((d = dirfstat(fd)) == nil)
- panic("can't stat %s\n", wrenfile);
- seek(fd, 0, 0);
- i = read(fd, buf, sizeof buf);
- if(i < sizeof buf)
- panic("can't read %s", wrenfile);
- badmagic = 0;
- RBUFSIZE = 1024;
- if(strncmp(buf+256, WMAGIC, strlen(WMAGIC)) == 0){
- RBUFSIZE = atol(buf+256+strlen(WMAGIC));
- if(RBUFSIZE % 512){
- fprint(2, "kfs: bad buffersize(%d): assuming 1k blocks\n", RBUFSIZE);
- RBUFSIZE = 1024;
- }
- }else
- badmagic = 1;
- w->dev = dev;
- w->size = d->length;
- free(d);
- w->fd = fd;
- maxwren++;
-}
-
-void
-wrenream(Device dev)
-{
- Wren *w;
- char buf[MAXBUFSIZE];
- int fd, i;
-
- if(RBUFSIZE % 512)
- panic("kfs: bad buffersize(%d): restart a multiple of 512\n", RBUFSIZE);
- if(RBUFSIZE > sizeof(buf))
- panic("kfs: bad buffersize(%d): must be at most %d\n", RBUFSIZE, sizeof(buf));
-
- print("kfs: reaming the file system using %d byte blocks\n", RBUFSIZE);
- w = wren(dev);
- fd = w->fd;
- memset(buf, 0, sizeof buf);
- sprint(buf+256, "%s%d\n", WMAGIC, RBUFSIZE);
- qlock(w);
- i = seek(fd, 0, 0) < 0 || write(fd, buf, RBUFSIZE) != RBUFSIZE;
- qunlock(w);
- if(i < 0)
- panic("can't ream disk");
-}
-
-int
-wrentag(char *p, int tag, long qpath)
-{
- Tag *t;
-
- t = (Tag*)(p+BUFSIZE);
- return t->tag != tag || (qpath&~QPDIR) != t->path;
-}
-
-int
-wrencheck(Device dev)
-{
- char buf[MAXBUFSIZE];
-
- if(badmagic)
- return 1;
- if(RBUFSIZE > sizeof(buf))
- panic("kfs: bad buffersize(%d): must be at most %d\n", RBUFSIZE, sizeof(buf));
-
- if(wrenread(dev, wrensuper(dev), buf) || wrentag(buf, Tsuper, QPSUPER)
- || wrenread(dev, wrenroot(dev), buf) || wrentag(buf, Tdir, QPROOT))
- return 1;
- if(((Dentry *)buf)[0].mode & DALLOC)
- return 0;
- return 1;
-}
-
-long
-wrensize(Device dev)
-{
- return wren(dev)->size / RBUFSIZE;
-}
-
-long
-wrensuper(Device dev)
-{
- USED(dev);
- return 1;
-}
-
-long
-wrenroot(Device dev)
-{
- USED(dev);
- return 2;
-}
-
-int
-wrenread(Device dev, long addr, void *b)
-{
- Wren *w;
- int fd, i;
-
- w = wren(dev);
- fd = w->fd;
- qlock(w);
- i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || read(fd, b, RBUFSIZE) != RBUFSIZE;
- qunlock(w);
- if(i)
- print("wrenread failed: %r\n");
- return i;
-}
-
-int
-wrenwrite(Device dev, long addr, void *b)
-{
- Wren *w;
- int fd, i;
-
- w = wren(dev);
- fd = w->fd;
- qlock(w);
- i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || write(fd, b, RBUFSIZE) != RBUFSIZE;
- qunlock(w);
- if(i)
- print("wrenwrite failed: %r\n");
- return i;
-}
--- a/sys/src/cmd/disk/kfs/errno.h
+++ /dev/null
@@ -1,35 +1,0 @@
-enum{
- Enevermind, /* never mind */
- Enofd, /* no free file descriptors */
- Efidinuse, /* fid already in use */
- Ebadfd, /* fid out of range or not open */
- Ebadusefd, /* inappropriate use of fid */
- Ebadarg, /* bad arg in system call */
- Enonexist, /* file does not exist */
- Efilename, /* file name syntax */
- Ebadchar, /* bad character in file name */
- Ebadsharp, /* unknown device in # filename */
- Ebadexec, /* a.out header invalid */
- Eioload, /* i/o error in demand load */
- Eperm, /* permission denied */
- Enotdir, /* not a directory */
- Enochild, /* no living children */
- Enoseg, /* no free segments */
- Ebuf, /* buffer wrong size */
- Ebadmount, /* inconsistent mount */
- Enomount, /* mount table full */
- Enomntdev, /* no free mount devices */
- Eshutdown, /* mounted device shut down */
- Einuse, /* device or object already in use */
- Eio, /* i/o error */
- Eisdir, /* file is a directory */
- Ebaddirread, /* directory read not quantized */
- Esegaddr, /* illegal segment addresses or size */
- Enoenv, /* no free environment resources */
- Eprocdied, /* process exited */
- Enocreate, /* mounted directory forbids creation */
- Enotunion, /* attempt to union with non-mounted directory */
- Emount, /* inconsistent mount */
- Enosrv, /* no free server slots */
- Egreg, /* it's all greg's fault */
-};
--- a/sys/src/cmd/disk/kfs/fns.h
+++ /dev/null
@@ -1,42 +1,0 @@
-#include "portfns.h"
-
-long belong(char *);
-Chan* chaninit(char*);
-void check(Filsys *, long);
-int cmd_exec(char*);
-void consserve(void);
-void confinit(void);
-int fsinit(int, int);
-void *ialloc(ulong);
-int nextelem(void);
-long number(int, int);
-Device scsidev(char*);
-int skipbl(int);
-void startproc(void (*)(void), char *);
-void syncproc(void);
-void syncall(void);
-
-int fprint(int, char*, ...);
-void wreninit(Device);
-int wrencheck(Device);
-void wrenream(Device);
-long wrensize(Device);
-long wrensuper(Device);
-long wrenroot(Device);
-int wrenread(Device, long, void *);
-int wrenwrite(Device, long, void *);
-
-/*
- * macros for compat with bootes
- */
-#define localfs 1
-
-#define devgrow(d, s) 0
-#define nofree(d, a) 0
-#define isro(d) 0
-
-#define superaddr(d) ((*devcall[d.type].super)(d))
-#define getraddr(d) ((*devcall[d.type].root)(d))
-#define devsize(d) ((*devcall[d.type].size)(d))
-#define devwrite(d, a, v) ((*devcall[d.type].write)(d, a, v))
-#define devread(d, a, v) ((*devcall[d.type].read)(d, a, v))
--- a/sys/src/cmd/disk/kfs/ialloc.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#include "all.h"
-
-void *ialloc(ulong n){
- void *p;
-
- if(p = malloc(n))
- memset(p, 0, n);
- return p;
-}
--- a/sys/src/cmd/disk/kfs/iobuf.c
+++ /dev/null
@@ -1,235 +1,0 @@
-#include "all.h"
-
-#define DEBUG 0
-
-long niob;
-long nhiob;
-Hiob *hiob;
-
-Iobuf*
-getbuf(Device dev, long addr, int flag)
-{
- Iobuf *p, *s;
- Hiob *hp;
- long h;
-
- if(DEBUG)
- print("getbuf %D(%ld) f=%x\n", dev, addr, flag);
- h = addr +
- dev.type*1009L +
- dev.ctrl*10007L +
- dev.unit*100003L +
- dev.part*1000003L;
- if(h < 0)
- h = ~h;
- h %= nhiob;
- hp = &hiob[h];
-
-loop:
- lock(hp);
-
-/*
- * look for it in the active list
- */
- s = hp->link;
- for(p=s;;) {
- if(p->addr == addr && !devcmp(p->dev, dev)) {
- if(p != s) {
- p->back->fore = p->fore;
- p->fore->back = p->back;
- p->fore = s;
- p->back = s->back;
- s->back = p;
- p->back->fore = p;
- hp->link = p;
- }
- unlock(hp);
- qlock(p);
- if(p->addr != addr || devcmp(p->dev, dev)) {
- qunlock(p);
- goto loop;
- }
- p->flags |= flag;
- cons.bhit.count++;
- p->iobuf = p->xiobuf;
- return p;
- }
- p = p->fore;
- if(p == s)
- break;
- }
- if(flag & Bprobe) {
- unlock(hp);
- return 0;
- }
-
-/*
- * not found
- * take oldest unlocked entry in this queue
- */
-xloop:
- p = s->back;
- if(!canqlock(p)) {
- if(p == hp->link) {
- unlock(hp);
- print("iobuf all locked\n");
- goto loop;
- }
- s = p;
- goto xloop;
- }
- /*
- * its dangerous to flush the pseudo
- * devices since they recursively call
- * getbuf/putbuf. deadlock!
- */
- if(p->flags & Bres) {
- qunlock(p);
- if(p == hp->link) {
- unlock(hp);
- print("iobuf all resed\n");
- goto loop;
- }
- s = p;
- goto xloop;
- }
- if(p->flags & Bmod) {
- unlock(hp);
- if(!devwrite(p->dev, p->addr, p->xiobuf))
- p->flags &= ~(Bimm|Bmod);
- qunlock(p);
- goto loop;
- }
- hp->link = p;
- p->addr = addr;
- p->dev = dev;
- p->flags = flag;
- unlock(hp);
- p->iobuf = p->xiobuf;
- if(flag & Bread) {
- if(devread(p->dev, p->addr, p->iobuf)) {
- p->flags = 0;
- p->dev = devnone;
- p->addr = -1;
- p->iobuf = (char*)-1;
- qunlock(p);
- return 0;
- }
- cons.bread.count++;
- return p;
- }
- cons.binit.count++;
- return p;
-}
-
-/*
- * syncblock tries to put out a block per hashline
- * returns 0 all done,
- * returns 1 if it missed something
- */
-int
-syncblock(void)
-{
- Iobuf *p, *s, *q;
- Hiob *hp;
- long h;
- int flag;
-
- flag = 0;
- for(h=0; h<nhiob; h++) {
- q = 0;
- hp = &hiob[h];
- lock(hp);
- s = hp->link;
- for(p=s;;) {
- if(p->flags & Bmod) {
- if(q)
- flag = 1; /* more than 1 mod/line */
- q = p;
- }
- p = p->fore;
- if(p == s)
- break;
- }
- unlock(hp);
- if(q) {
- if(!canqlock(q)) {
- flag = 1; /* missed -- was locked */
- continue;
- }
- if(!(q->flags & Bmod)) {
- qunlock(q);
- continue;
- }
- if(!devwrite(q->dev, q->addr, q->xiobuf))
- q->flags &= ~(Bmod|Bimm);
- qunlock(q);
- }
- }
- return flag;
-}
-
-void
-sync(char *reason)
-{
- long i;
-
- print("sync: %s\n", reason);
- for(i=10*nhiob; i>0; i--)
- if(!syncblock())
- return;
- print("sync shorted\n");
-}
-
-void
-putbuf(Iobuf *p)
-{
- if(canqlock(p))
- print("buffer not locked %D(%ld)\n", p->dev, p->addr);
- if(p->flags & Bimm) {
- if(!(p->flags & Bmod))
- print("imm and no mod %D(%ld)\n", p->dev, p->addr);
- if(!devwrite(p->dev, p->addr, p->iobuf))
- p->flags &= ~(Bmod|Bimm);
- }
- p->iobuf = (char*)-1;
- qunlock(p);
-}
-
-int
-checktag(Iobuf *p, int tag, long qpath)
-{
- Tag *t;
-
- t = (Tag*)(p->iobuf+BUFSIZE);
- if(t->tag != tag) {
- if(1 || CHAT(0))
- print(" tag = %G; expected %G; addr = %lud\n",
- t->tag, tag, p->addr);
- return 2;
- }
- if(qpath != QPNONE) {
- qpath &= ~QPDIR;
- if(qpath != t->path) {
- if(qpath == (t->path&~QPDIR)) /* old bug */
- return 0;
- if(1 || CHAT(0))
- print(" tag/path = %lux; expected %G/%lux\n",
- t->path, tag, qpath);
- return 1;
- }
- }
- return 0;
-}
-
-void
-settag(Iobuf *p, int tag, long qpath)
-{
- Tag *t;
-
- t = (Tag*)(p->iobuf+BUFSIZE);
- t->tag = tag;
- if(qpath != QPNONE)
- t->path = qpath & ~QPDIR;
- p->flags |= Bmod;
-}
--- a/sys/src/cmd/disk/kfs/main.c
+++ /dev/null
@@ -1,558 +1,0 @@
-#include "all.h"
-
-int sfd;
-int cmdmode = 0660;
-int rfd;
-int chat;
-extern char *wrenfile;
-extern int nwren;
-char *myname;
-int cmdfd;
-int writeallow; /* never on; for compatibility with fs */
-int wstatallow;
-int writegroup;
-int allownone;
-int noatime;
-int srvfd(char*, int, int);
-void usage(void);
-void confinit(void);
-Chan *chaninit(char*);
-void consinit(void);
-void forkserve(void);
-
-void
-main(int argc, char *argv[])
-{
- Filsys *fs;
- int ream, fsok;
- int newbufsize, nocheck;
- char buf[NAMELEN];
- int pid, ctl;
-
- progname = "kfs";
- procname = "init";
-
- /*
- * insulate from invoker's environment and keep it from swapping
- */
- rfork(RFNAMEG|RFNOTEG|RFREND);
-
- confinit();
- sfd = -1;
- ream = 0;
- newbufsize = 0;
- nocheck = 0;
- wrenfile = "/dev/sdC0/fs";
-
- pid = getpid();
- snprint(buf, sizeof buf, "/proc/%d/ctl", pid);
- ctl = open(buf, OWRITE);
- fprint(ctl, "noswap\n");
- close(ctl);
-
- buf[0] = '\0';
-
- ARGBEGIN{
- case 'b':
- newbufsize = atol(ARGF());
- break;
- case 'c':
- nocheck = 1;
- break;
- case 'f':
- wrenfile = ARGF();
- break;
- case 'm':
- nwren = atol(ARGF());
- break;
- case 'n':
- strncpy(buf, ARGF(), NAMELEN-1);
- buf[NAMELEN-1] = '\0';
- break;
- case 'p':
- cmdmode = atol(ARGF());
- break;
- case 'r':
- ream = 1;
- break;
- case 's':
- sfd = 0;
- rfd = dup(1, -1);
- close(1);
- if(open("/dev/cons", OWRITE) < 0)
- open("#c/cons", OWRITE);
- break;
- case 'B':
- conf.niobuf = strtoul(ARGF(), 0, 0);
- break;
- case 'C':
- chat = 1;
- break;
- default:
- usage();
- }ARGEND
-
- if(argc != 0)
- usage();
-
- cmdfd = 2;
-
- if (access(wrenfile, AREAD|AWRITE) == -1)
- sysfatal("%s cannot access device", wrenfile);
-
- formatinit();
- sublockinit();
-
- if(buf[0])
- sprint(service, "kfs.%s", buf);
- else
- strcpy(service, "kfs");
- chan = chaninit(service);
- consinit();
- tlocks = ialloc(NTLOCK * sizeof *tlocks);
- uid = ialloc(conf.nuid * sizeof(*uid));
- uidspace = ialloc(conf.uidspace * sizeof(*uidspace));
- gidspace = ialloc(conf.gidspace * sizeof(*gidspace));
-
- /*
- * init global locks
- */
- wlock(&mainlock); wunlock(&mainlock);
-
- /*
- * init the file system, ream it if needed, and get the block sizes
- */
- ream = fsinit(ream, newbufsize);
- iobufinit();
- for(fs=filesys; fs->name; fs++)
- if(fs->flags & FREAM){ /* set by fsinit if reamed */
- ream++;
- rootream(fs->dev, getraddr(fs->dev));
- superream(fs->dev, superaddr(fs->dev));
- }
-
- boottime = time(nil);
-
- consserve();
- fsok = superok(filesys[0].dev, superaddr(filesys[0].dev), 0);
- if(!nocheck && !ream && !fsok)
- cmd_exec("check fq");
-
- startproc(forkserve, "srv");
- startproc(syncproc, "sync");
-
- exits(0);
-}
-
-void
-forkserve(void)
-{
- serve(chan);
-}
-
-static
-struct
-{
- int nfilter;
- Filter* filters[100];
-}f;
-
-int alarmed;
-
-void
-catchalarm(void *regs, char *msg)
-{
- USED(regs, msg);
- if(strcmp(msg, "alarm") == 0){
- alarmed = 1;
- noted(NCONT);
- } else
- noted(NDFLT);
-}
-
-/*
- * process to synch blocks
- * it puts out a block/line every second
- * it waits 10 seconds if catches up.
- * in both cases, it takes about 10 seconds
- * to get up-to-date.
- *
- * it also updates the filter stats
- * and executes commands
- */
-void
-syncproc(void)
-{
- char buf[4*1024];
- Filter *ft;
- ulong c0, c1;
- long t, n, d;
- int i, p[2];
-
- /*
- * make a pipe for commands
- */
- if(pipe(p) < 0)
- panic("command pipe");
- sprint(buf, "#s/%s.cmd", service);
- srvfd(buf, cmdmode, p[0]);
- close(p[0]);
- cmdfd = p[1];
- notify(catchalarm);
-
- t = time(nil);
- for(;;){
- i = syncblock();
- alarmed = 0;
- alarm(i ? 1000: 10000);
- n = read(cmdfd, buf, sizeof buf - 1);
- if(n <= 0 && !alarmed)
- sleep(i ? 1000: 10000);
- alarm(0);
- if(n > 0){
- buf[n] = '\0';
- if(cmd_exec(buf))
- fprint(cmdfd, "done");
- else
- fprint(cmdfd, "unknown command");
- }
- n = time(nil);
- d = n - t;
- if(d < 0 || d > 5*60)
- d = 0;
- while(d >= 1) {
- d -= 1;
- for(i=0; i<f.nfilter; i++) {
- ft = f.filters[i];
- c0 = ft->count;
- c1 = c0 - ft->oldcount;
- ft->oldcount = c0;
- ft->filter[0] = famd(ft->filter[0], c1, 59, 60);
- ft->filter[1] = famd(ft->filter[1], c1, 599, 600);
- ft->filter[2] = famd(ft->filter[2], c1, 5999, 6000);
- }
- }
- t = n;
- }
-}
-
-void
-dofilter(Filter *ft)
-{
- int i;
-
- i = f.nfilter;
- if(i >= sizeof f.filters / sizeof f.filters[0]) {
- print("dofilter: too many filters\n");
- return;
- }
- f.filters[i] = ft;
- f.nfilter = i+1;
-}
-
-void
-startproc(void (*f)(void), char *name)
-{
- switch(rfork(RFMEM|RFFDG|RFPROC)){
- case -1:
- panic("can't fork");
- case 0:
- break;
- default:
- return;
- }
- procname = name;
- f();
- _exits(nil);
-}
-
-void
-confinit(void)
-{
- conf.niobuf = 0;
- conf.nuid = 600;
- conf.nserve = 2;
- conf.uidspace = conf.nuid*6;
- conf.gidspace = conf.nuid*3;
- cons.flags = 0;
-}
-
-static void
-dochaninit(Chan *cp, int fd)
-{
- cp->chan = fd;
- fileinit(cp);
- wlock(&cp->reflock);
- wunlock(&cp->reflock);
- lock(&cp->flock);
- unlock(&cp->flock);
-}
-
-Chan*
-chaninit(char *server)
-{
- Chan *cp;
- char buf[3*NAMELEN];
- int p[2];
-
- sprint(buf, "#s/%s", server);
- if(sfd < 0){
- if(pipe(p) < 0)
- panic("can't make a pipe");
- sfd = p[0];
- rfd = p[1];
- }
- srvfd(buf, 0666, sfd);
- close(sfd);
- cp = ialloc(sizeof *cp);
- cons.srvchan = cp;
- dochaninit(cp, rfd);
- return cp;
-}
-
-int
-netserve(char *netaddr)
-{
- int afd, lfd, fd;
- char adir[2*NAMELEN], ldir[2*NAMELEN];
- Chan *netchan;
-
- if(access("/net/tcp/clone", 0) < 0)
- bind("#I", "/net", MAFTER);
- if(access("/net.alt/tcp/clone", 0) < 0)
- bind("#I1", "/net.alt", MAFTER);
-
- afd = announce(netaddr, adir);
- if (afd < 0)
- return -1;
- switch (rfork(RFMEM|RFFDG|RFPROC)) {
- case -1:
- return -1;
- case 0:
- break;
- default:
- return 0;
- }
- for (;;) {
- lfd = listen(adir, ldir);
- if (lfd < 0)
- continue;
- fd = accept(lfd, ldir);
- if (fd < 0) {
- close(lfd);
- continue;
- }
- netchan = mallocz(sizeof(Chan), 1);
- if(netchan == nil)
- panic("out of memory");
- dochaninit(netchan, fd);
- switch (rfork(RFMEM|RFFDG|RFPROC)) {
- case -1:
- panic("can't fork");
- case 0:
- close(afd);
- close(lfd);
- serve(netchan);
- free(netchan);
- exits(0);
- default:
- close(fd);
- close(lfd);
- continue;
- }
- }
-}
-
-int
-srvfd(char *s, int mode, int sfd)
-{
- int fd;
- char buf[32];
-
- fd = create(s, ORCLOSE|OWRITE, mode);
- if(fd < 0){
- remove(s);
- fd = create(s, ORCLOSE|OWRITE, mode);
- if(fd < 0)
- panic(s);
- }
- sprint(buf, "%d", sfd);
- if(write(fd, buf, strlen(buf)) != strlen(buf))
- panic("srv write");
- return sfd;
-}
-
-void
-consinit(void)
-{
- int i;
-
- cons.chan = ialloc(sizeof(Chan));
- wlock(&cons.chan->reflock);
- wunlock(&cons.chan->reflock);
- lock(&cons.chan->flock);
- unlock(&cons.chan->flock);
- dofilter(&cons.work);
- dofilter(&cons.rate);
- dofilter(&cons.bhit);
- dofilter(&cons.bread);
- dofilter(&cons.binit);
- for(i = 0; i < MAXTAG; i++)
- dofilter(&cons.tags[i]);
-}
-
-/*
- * always called with mainlock locked
- */
-void
-syncall(void)
-{
- for(;;)
- if(!syncblock())
- return;
-}
-
-int
-askream(Filsys *fs)
-{
- char c;
-
- print("File system %s inconsistent\n", fs->name);
- print("Would you like to ream it (y/n)? ");
- read(0, &c, 1);
- return c == 'y';
-}
-
-ulong
-memsize(void)
-{
- char *p, buf[128];
- int fd, n, by2pg, secs;
-
- by2pg = 4*1024;
- p = getenv("cputype");
- if(p && strcmp(p, "68020") == 0)
- by2pg = 8*1024;
-
- secs = 4*1024*1024;
-
- fd = open("/dev/swap", OREAD);
- if(fd < 0)
- return secs;
- n = read(fd, buf, sizeof(buf)-1);
- close(fd);
- if(n <= 0)
- return secs;
- buf[n] = 0;
- p = strchr(buf, '/');
- if(p)
- secs = strtoul(p+1, 0, 0)*by2pg;
- return secs;
-}
-
-/*
- * init the devices
- * wipe some of the file systems, or all if ream is set
- * this code really assumes that only one file system exists
- */
-int
-fsinit(int ream, int newbufsize)
-{
- Filsys *fs;
-
- RBUFSIZE = 4 * 1024;
- for(fs=filesys; fs->name; fs++)
- (*devcall[fs->dev.type].init)(fs->dev);
- if(newbufsize == 0)
- newbufsize = RBUFSIZE;
-
- if(conf.niobuf == 0) {
- conf.niobuf = memsize()/10;
- if(conf.niobuf > 2*1024*1024)
- conf.niobuf = 2*1024*1024;
- conf.niobuf /= newbufsize;
- if(conf.niobuf < 30)
- conf.niobuf = 30;
- }
-
- BUFSIZE = RBUFSIZE - sizeof(Tag);
-
- for(fs=filesys; fs->name; fs++)
- if(ream || (*devcall[fs->dev.type].check)(fs->dev) && askream(fs)){
- RBUFSIZE = newbufsize;
- BUFSIZE = RBUFSIZE - sizeof(Tag);
- (*devcall[fs->dev.type].ream)(fs->dev);
- fs->flags |= FREAM;
- ream = 1;
- }
-
- /*
- * set up the block size dependant variables
- */
- BUFSIZE = RBUFSIZE - sizeof(Tag);
- DIRPERBUF = BUFSIZE / sizeof(Dentry);
- INDPERBUF = BUFSIZE / sizeof(long);
- INDPERBUF2 = INDPERBUF * INDPERBUF;
- FEPERBUF = (BUFSIZE - sizeof(Super1) - sizeof(long)) / sizeof(long);
- return ream;
-}
-
-/*
- * allocate rest of mem
- * for io buffers.
- */
-#define HWIDTH 5 /* buffers per hash */
-void
-iobufinit(void)
-{
- long i;
- Iobuf *p, *q;
- Hiob *hp;
-
- i = conf.niobuf*RBUFSIZE;
- niob = i / (sizeof(Iobuf) + RBUFSIZE + sizeof(Hiob)/HWIDTH);
- nhiob = niob / HWIDTH;
- while(!prime(nhiob))
- nhiob++;
- if(chat)
- print(" %ld buffers; %ld hashes\n", niob, nhiob);
- hiob = ialloc(nhiob * sizeof(Hiob));
- hp = hiob;
- for(i=0; i<nhiob; i++) {
- lock(hp);
- unlock(hp);
- hp++;
- }
- p = ialloc(niob * sizeof(Iobuf));
- hp = hiob;
- for(i=0; i<niob; i++) {
- qlock(p);
- qunlock(p);
- if(hp == hiob)
- hp = hiob + nhiob;
- hp--;
- q = hp->link;
- if(q) {
- p->fore = q;
- p->back = q->back;
- q->back = p;
- p->back->fore = p;
- } else {
- hp->link = p;
- p->fore = p;
- p->back = p;
- }
- p->dev = devnone;
- p->addr = -1;
- p->xiobuf = ialloc(RBUFSIZE);
- p->iobuf = (char*)-1;
- p++;
- }
-}
-
-void
-usage(void)
-{
- fprint(2, "usage: kfs [-cCr] [-b bufsize] [-s infd outfd] [-f fsfile]\n");
- exits(0);
-}
--- a/sys/src/cmd/disk/kfs/misc.c
+++ /dev/null
@@ -1,86 +1,0 @@
-#include "all.h"
-
-extern int cmdfd;
-
-Float
-famd(Float a, int b, int c, int d)
-{
- ulong x, m;
-
- x = (a + b) * c;
- m = x % d;
- x /= d;
- if(m >= d / 2)
- x++;
- return x;
-}
-
-ulong
-fdf(Float a, int d)
-{
- ulong x, m;
-
- m = a % d;
- x = a / d;
- if(m >= d / 2)
- x++;
- return x;
-}
-
-long
-belong(char *s)
-{
- uchar *x;
-
- x = (uchar *)s;
- return (x[0] << 24) + (x[1] << 16) + (x[2] << 8) + x[3];
-}
-
-void
-panic(char *fmt, ...)
-{
- char buf[8192], *s;
- va_list arg;
-
-
- s = buf;
- s += sprint(s, "%s %s %d: ", progname, procname, getpid());
- va_start(arg, fmt);
- s = vseprint(s, buf + sizeof(buf) / sizeof(*buf), fmt, arg);
- va_end(arg);
- *s++ = '\n';
- write(2, buf, s - buf);
-abort();
- exits(buf);
-}
-
-#define SIZE 4096
-
-void
-cprint(char *fmt, ...)
-{
- char buf[SIZE], *out;
- va_list arg;
-
- va_start(arg, fmt);
- out = vseprint(buf, buf+SIZE, fmt, arg);
- va_end(arg);
- write(cmdfd, buf, (long)(out-buf));
-}
-
-/*
- * print goes to fd 2 [sic] because fd 1 might be
- * otherwise preoccupied when the -s flag is given to kfs.
- */
-int
-print(char *fmt, ...)
-{
- va_list arg;
- int n;
-
- va_start(arg, fmt);
- n = vfprint(2, fmt, arg);
- va_end(arg);
- return n;
-}
-
--- a/sys/src/cmd/disk/kfs/mkfile
+++ /dev/null
@@ -1,54 +1,0 @@
-</$objtype/mkfile
-
-TARG=kfs
-
-OFILES=\
- 9p1.$O\
- 9p1lib.$O\
- 9p2.$O\
- 9p12.$O\
- auth.$O\
- chk.$O\
- con.$O\
- console.$O\
- dat.$O\
- dentry.$O\
- ialloc.$O\
- iobuf.$O\
- main.$O\
- misc.$O\
- porttime.$O\
- sub.$O\
- uid.$O\
- ofcallfmt.$O\
-
-HFILES=\
- all.h\
- dat.h\
- errno.h\
- fns.h\
- portfns.h\
- portdat.h\
-
-BIN=/$objtype/bin/disk
-
-UPDATE=mkfile\
- $HFILES\
- ${OFILES:%.$O=%.c}\
-
-</sys/src/cmd/mkone
-
-$O.out: devwren.$O
-
-$O.gfs: $OFILES devmulti.$O
- $LD $LDFLAGS -o $target $prereq
-
-
-test:VQ:
- echo rm -fr /srv/il!$sysname!11111
- echo 'kill 8.out|rc'
- echo rm /srv/il!$sysname!11111
- echo 8.out -Crf /tmp/disk
- echo disk/kfscmd ''''listen il!*!11111''''
- echo srv il!$sysname!11111
- echo mount /srv/il!$sysname!11111 /n/emelie
--- a/sys/src/cmd/disk/kfs/ofcallfmt.c
+++ /dev/null
@@ -1,181 +1,0 @@
-#include "all.h"
-#include "9p1.h"
-
-static void dumpsome(char*, char*, long);
-static void fdirconv(char*, Dentry*);
-
-int
-ofcallfmt(Fmt *f1)
-{
- char buf[512];
- Oldfcall *f;
- int fid, type, tag, n;
- Dentry d;
-
- f = va_arg(f1->args, Oldfcall*);
- type = f->type;
- fid = f->fid;
- tag = f->tag;
- switch(type){
- case Tnop9p1: /* 50 */
- sprint(buf, "Tnop9p1 tag %ud", tag);
- break;
- case Rnop9p1:
- sprint(buf, "Rnop9p1 tag %ud", tag);
- break;
- case Tsession9p1: /* 52 */
- sprint(buf, "Tsession9p1 tag %ud", tag);
- break;
- case Rsession9p1:
- sprint(buf, "Rsession9p1 tag %ud", tag);
- break;
- case Rerror9p1: /* 55 */
- sprint(buf, "Rerror9p1 tag %ud error %.64s", tag, f->ename);
- break;
- case Tflush9p1: /* 56 */
- sprint(buf, "Tflush9p1 tag %ud oldtag %d", tag, f->oldtag);
- break;
- case Rflush9p1:
- sprint(buf, "Rflush9p1 tag %ud", tag);
- break;
- case Tattach9p1: /* 58 */
- sprint(buf, "Tattach9p1 tag %ud fid %d uname %.28s aname %.28s auth %.28s",
- tag, f->fid, f->uname, f->aname, f->auth);
- break;
- case Rattach9p1:
- sprint(buf, "Rattach9p1 tag %ud fid %d qid 0x%lux|0x%lux",
- tag, fid, f->qid.path, f->qid.version);
- break;
- case Tclone9p1: /* 60 */
- sprint(buf, "Tclone9p1 tag %ud fid %d newfid %d", tag, fid, f->newfid);
- break;
- case Rclone9p1:
- sprint(buf, "Rclone9p1 tag %ud fid %d", tag, fid);
- break;
- case Twalk9p1: /* 62 */
- sprint(buf, "Twalk9p1 tag %ud fid %d name %.28s", tag, fid, f->name);
- break;
- case Rwalk9p1:
- sprint(buf, "Rwalk9p1 tag %ud fid %d qid 0x%lux|0x%lux",
- tag, fid, f->qid.path, f->qid.version);
- break;
- case Topen9p1: /* 64 */
- sprint(buf, "Topen9p1 tag %ud fid %d mode %d", tag, fid, f->mode);
- break;
- case Ropen9p1:
- sprint(buf, "Ropen9p1 tag %ud fid %d qid 0x%lux|0x%lux",
- tag, fid, f->qid.path, f->qid.version);
- break;
- case Tcreate9p1: /* 66 */
- sprint(buf, "Tcreate9p1 tag %ud fid %d name %.28s perm 0x%lux mode %d",
- tag, fid, f->name, f->perm, f->mode);
- break;
- case Rcreate9p1:
- sprint(buf, "Rcreate9p1 tag %ud fid %d qid 0x%lux|0x%lux",
- tag, fid, f->qid.path, f->qid.version);
- break;
- case Tread9p1: /* 68 */
- sprint(buf, "Tread9p1 tag %ud fid %d offset %ld count %ld",
- tag, fid, f->offset, f->count);
- break;
- case Rread9p1:
- n = sprint(buf, "Rread9p1 tag %ud fid %d count %ld ", tag, fid, f->count);
- dumpsome(buf+n, f->data, f->count);
- break;
- case Twrite9p1: /* 70 */
- n = sprint(buf, "Twrite9p1 tag %ud fid %d offset %ld count %ld ",
- tag, fid, f->offset, f->count);
- dumpsome(buf+n, f->data, f->count);
- break;
- case Rwrite9p1:
- sprint(buf, "Rwrite9p1 tag %ud fid %d count %ld", tag, fid, f->count);
- break;
- case Tclunk9p1: /* 72 */
- sprint(buf, "Tclunk9p1 tag %ud fid %d", tag, fid);
- break;
- case Rclunk9p1:
- sprint(buf, "Rclunk9p1 tag %ud fid %d", tag, fid);
- break;
- case Tremove9p1: /* 74 */
- sprint(buf, "Tremove9p1 tag %ud fid %d", tag, fid);
- break;
- case Rremove9p1:
- sprint(buf, "Rremove9p1 tag %ud fid %d", tag, fid);
- break;
- case Tstat9p1: /* 76 */
- sprint(buf, "Tstat9p1 tag %ud fid %d", tag, fid);
- break;
- case Rstat9p1:
- n = sprint(buf, "Rstat9p1 tag %ud fid %d", tag, fid);
- convM2D9p1(f->stat, &d);
- sprint(buf+n, " stat ");
- fdirconv(buf+n+6, &d);
- break;
- case Twstat9p1: /* 78 */
- convM2D9p1(f->stat, &d);
- n = sprint(buf, "Twstat9p1 tag %ud fid %d stat ", tag, fid);
- fdirconv(buf+n, &d);
- break;
- case Rwstat9p1:
- sprint(buf, "Rwstat9p1 tag %ud fid %d", tag, fid);
- break;
- case Tclwalk9p1: /* 81 */
- sprint(buf, "Tclwalk9p1 tag %ud fid %d newfid %d name %.28s",
- tag, fid, f->newfid, f->name);
- break;
- case Rclwalk9p1:
- sprint(buf, "Rclwalk9p1 tag %ud fid %d qid 0x%lux|0x%lux",
- tag, fid, f->qid.path, f->qid.version);
- break;
- default:
- sprint(buf, "unknown type %d", type);
- }
- return fmtstrcpy(f1, buf);
-}
-
-static void
-fdirconv(char *buf, Dentry *d)
-{
- sprint(buf, "'%s' uid=%d gid=%d "
- "q %lux|%lux m %uo "
- "at %ld mt %ld l %ld ",
- d->name, d->uid, d->gid,
- d->qid.path, d->qid.version, d->mode,
- d->atime, d->mtime, d->size);
-}
-
-/*
- * dump out count (or DUMPL, if count is bigger) bytes from
- * buf to ans, as a string if they are all printable,
- * else as a series of hex bytes
- */
-#define DUMPL 24
-
-static void
-dumpsome(char *ans, char *buf, long count)
-{
- int i, printable;
- char *p;
-
- printable = 1;
- if(count > DUMPL)
- count = DUMPL;
- for(i=0; i<count && printable; i++)
- if((buf[i]<32 && buf[i] !='\n' && buf[i] !='\t') || (uchar)buf[i]>127)
- printable = 0;
- p = ans;
- *p++ = '\'';
- if(printable){
- memmove(p, buf, count);
- p += count;
- }else{
- for(i=0; i<count; i++){
- if(i>0 && i%4==0)
- *p++ = ' ';
- sprint(p, "%2.2ux", buf[i]);
- p += 2;
- }
- }
- *p++ = '\'';
- *p = 0;
-}
--- a/sys/src/cmd/disk/kfs/portdat.h
+++ /dev/null
@@ -1,368 +1,0 @@
-/*
- * fundamental constants
- */
-#define NAMELEN 28 /* size of names */
-#define NDBLOCK 6 /* number of direct blocks in Dentry */
-#define MAXDAT 8192 /* max allowable data message */
-#define NTLOCK 200 /* number of active file Tlocks */
-
-typedef struct Fbuf Fbuf;
-typedef struct Super1 Super1;
-typedef struct Superb Superb;
-// typedef struct Qid Qid;
-typedef struct Dentry Dentry;
-typedef struct Tag Tag;
-
-typedef struct Device Device;
-typedef struct Qid9p1 Qid9p1;
-typedef struct File File;
-typedef struct Filsys Filsys;
-typedef struct Filta Filta;
-typedef struct Filter Filter;
-typedef ulong Float;
-typedef struct Hiob Hiob;
-typedef struct Iobuf Iobuf;
-typedef struct P9call P9call;
-typedef struct Tlock Tlock;
-// typedef struct Tm Tm;
-typedef struct Uid Uid;
-typedef struct Wpath Wpath;
-typedef struct AuthRpc AuthRpc;
-
-/*
- * DONT TOUCH -- data structures stored on disk
- */
-/* DONT TOUCH, this is the disk structure */
-struct Qid9p1
-{
- long path;
- long version;
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct Dentry
-{
- char name[NAMELEN];
- short uid;
- short gid;
- ushort mode;
- #define DALLOC 0x8000
- #define DDIR 0x4000
- #define DAPND 0x2000
- #define DLOCK 0x1000
- #define DREAD 0x4
- #define DWRITE 0x2
- #define DEXEC 0x1
- Qid9p1 qid;
- long size;
- long dblock[NDBLOCK];
- long iblock;
- long diblock;
- long atime;
- long mtime;
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct Tag
-{
- short pad;
- short tag;
- long path;
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct Super1
-{
- long fstart;
- long fsize;
- long tfree;
- long qidgen; /* generator for unique ids */
-
- long fsok; /* file system ok */
-
- /*
- * garbage for WWC device
- */
- long roraddr; /* dump root addr */
- long last; /* last super block addr */
- long next; /* next super block addr */
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct Fbuf
-{
- long nfree;
- long free[1]; /* changes based on BUFSIZE */
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct Superb
-{
- Super1;
- Fbuf fbuf;
-};
-
-struct Device
-{
- char type;
- char ctrl;
- char unit;
- char part;
-};
-
-/*
- * for load stats
- */
-struct Filter
-{
- ulong count; /* count and old count kept separate */
- ulong oldcount; /* so interrput can read them */
- Float filter[3]; /* filters for 1m 10m 100m */
-};
-
-struct Filta
-{
- Filter* f;
- int scale;
-};
-
-/*
- * array of qids that are locked
- */
-struct Tlock
-{
- Device dev;
- long time;
- long qpath;
- File* file;
-};
-
-struct File
-{
- QLock;
- Qid qid;
- Wpath* wpath;
- Chan* cp; /* null means a free slot */
- Tlock* tlock; /* if file is locked */
- File* next; /* in cp->flist */
- File* list; /* in list of free files */
- Filsys* fs;
- long addr;
- long slot;
- long lastra; /* read ahead address */
- ulong fid;
- short uid;
- char open;
- #define FREAD 1
- #define FWRITE 2
- #define FREMOV 4
- #define FWSTAT 8
- long doffset; /* directory reading */
- ulong dvers;
- long dslot;
-
- /* for network authentication */
- AuthRpc *rpc;
- short cuid;
-};
-
-struct Filsys
-{
- char* name; /* name of filesys */
- Device dev; /* device that filesys is on */
- int flags;
- #define FREAM (1<<1) /* mkfs */
- #define FRECOVER (1<<2) /* install last dump */
-};
-
-struct Hiob
-{
- Iobuf* link;
- Lock;
-};
-
-struct Iobuf
-{
- QLock;
- Device dev;
- Iobuf *next; /* for hash */
- Iobuf *fore; /* for lru */
- Iobuf *back; /* for lru */
- char *iobuf; /* only active while locked */
- char *xiobuf; /* "real" buffer pointer */
- long addr;
- int flags;
-};
-
-struct P9call
-{
- uchar calln;
- uchar rxflag;
- short msize;
- void (*func)(Chan*, int);
-};
-
-// struct Tm
-// {
-// /* see ctime(3) */
-// int sec;
-// int min;
-// int hour;
-// int mday;
-// int mon;
-// int year;
-// int wday;
-// int yday;
-// int isdst;
-// };
-
-struct Uid
-{
- short uid; /* user id */
- short lead; /* leader of group */
- short offset; /* byte offset in uidspace */
-};
-
-struct Wpath
-{
- Wpath *up; /* pointer upwards in path */
- Wpath *list; /* link in free chain */
- long addr; /* directory entry addr of parent */
- long slot; /* directory entry slot of parent */
- short refs; /* number of files using this structure */
-};
-
-#define MAXFDATA 8192
-
-/*
- * error codes generated from the file server
- */
-enum
-{
- Ebadspc = 1,
- Efid,
- Efidinuse,
- Echar,
- Eopen,
- Ecount,
- Ealloc,
- Eqid,
- Eauth,
- Eauthmsg,
- Eaccess,
- Eentry,
- Emode,
- Edir1,
- Edir2,
- Ephase,
- Eexist,
- Edot,
- Eempty,
- Ebadu,
- Enotu,
- Enotg,
- Ename,
- Ewalk,
- Eronly,
- Efull,
- Eoffset,
- Elocked,
- Ebroken,
- Etoolong,
- Ersc,
- Eqidmode,
- Econvert,
- Enotm,
- Enotd,
- Enotl,
- Enotw,
- Esystem,
-
- MAXERR
-};
-
-/*
- * devnone block numbers
- */
-enum
-{
- Cwio1 = 1,
- Cwio2,
- Cwxx1,
- Cwxx2,
- Cwxx3,
- Cwxx4,
- Cwdump1,
- Cwdump2,
- Cuidbuf,
-};
-
-/*
- * tags on block
- */
-enum
-{
- Tnone = 0,
- Tsuper, /* the super block */
- Tdir, /* directory contents */
- Tind1, /* points to blocks */
- Tind2, /* points to Tind1 */
- Tfile, /* file contents */
- Tfree, /* in free list */
- Tbuck, /* cache fs bucket */
- Tvirgo, /* fake worm virgin bits */
- Tcache, /* cw cache things */
- MAXTAG
-};
-
-/*
- * flags to getbuf
- */
-enum
-{
- Bread = (1<<0), /* read the block if miss */
- Bprobe = (1<<1), /* return null if miss */
- Bmod = (1<<2), /* set modified bit in buffer */
- Bimm = (1<<3), /* set immediate bit in buffer */
- Bres = (1<<4), /* reserved, never renammed */
-};
-
-/*
- * open modes passed into P9 open/create
- */
-enum
-{
- MREAD = 0,
- MWRITE,
- MBOTH,
- MEXEC,
- MTRUNC = (1<<4), /* truncate on open */
- MCEXEC = (1<<5), /* close on exec (host) */
- MRCLOSE = (1<<6), /* remove on close */
-};
-
-/*
- * check flags
- */
-enum
-{
- Crdall = (1<<0), /* read all files */
- Ctag = (1<<1), /* rebuild tags */
- Cpfile = (1<<2), /* print files */
- Cpdir = (1<<3), /* print directories */
- Cfree = (1<<4), /* rebuild free list */
- Cream = (1<<6), /* clear all bad tags */
- Cbad = (1<<7), /* clear all bad blocks */
- Ctouch = (1<<8), /* touch old dir and indir */
- Cquiet = (1<<9), /* report just nasty things */
-};
-
-/*
- * buffer size variables
- */
-extern int RBUFSIZE;
-extern int BUFSIZE;
-extern int DIRPERBUF;
-extern int INDPERBUF;
-extern int INDPERBUF2;
-extern int FEPERBUF;
--- a/sys/src/cmd/disk/kfs/portfns.h
+++ /dev/null
@@ -1,104 +1,0 @@
-void accessdir(Iobuf*, Dentry*, int);
-void authfree(File*);
-void addfree(Device, long, Superb*);
-long balloc(Device, int, long);
-void bfree(Device, long, int);
-int byname(void*, void*);
-int byuid(void*, void*);
-int checkname(char*);
-int checktag(Iobuf*, int, long);
-void cmd_user(void);
-char* cname(char*);
-int con_attach(int, char*, char*);
-int con_clone(int, int);
-int con_create(int, char*, int, int, long, int);
-int con_open(int, int);
-int con_path(int, char*);
-int con_read(int, char*, long, int);
-int con_remove(int);
-int con_stat(int, char*);
-int con_swap(int, int);
-int con_clri(int);
-int con_session(void);
-int con_walk(int, char*);
-int con_write(int, char*, long, int);
-int con_wstat(int, char*);
-void cprint(char*, ...);
-void datestr(char*, long);
-void dbufread(Iobuf*, Dentry*, long);
-Qid dentryqid(Dentry*);
-int devcmp(Device, Device);
-Iobuf* dnodebuf(Iobuf*, Dentry*, long, int);
-Iobuf* dnodebuf1(Iobuf*, Dentry*, long, int);
-void dofilter(Filter*);
-int doremove(File *, int);
-void dtrunc(Iobuf*, Dentry*);
-void exit(void);
-Float famd(Float, int, int, int);
-int fchar(void);
-ulong fdf(Float, int);
-void fileinit(Chan*);
-void sublockinit(void);
-File* filep(Chan*, int, int);
-int fname(char*);
-void formatinit(void);
-void freefp(File*);
-void freewp(Wpath*);
-Filsys* fsstr(char*);
-Iobuf* getbuf(Device, long, int);
-Dentry* getdir(Iobuf*, int);
-long getraddr(Device);
-Wpath* getwp(Wpath*);
-void hexdump(void*, int);
-int iaccess(File*, Dentry*, int);
-long indfetch(Iobuf*, Dentry*, long, long , int, int);
-int ingroup(int, int);
-void iobufinit(void);
-int leadgroup(int, int);
-void mkchallenge(Chan*);
-void mkqid(Qid*, Dentry*, int);
-int mkqidcmp(Qid*, Dentry*);
-void mkqid9p1(Qid9p1*, Qid*);
-void mkqid9p2(Qid*, Qid9p1*, int);
-int netserve(char*);
-File* newfp(Chan*);
-Qid newqid(Device);
-void newstart(void);
-Wpath* newwp(void);
-int oconvD2M(Dentry*, void*);
-int oconvM2D(void*, Dentry*);
-int ofcallfmt(Fmt*);
-void panic(char*, ...);
-int prime(long);
-void putbuf(Iobuf*);
-void putwp(Wpath*);
-long qidpathgen(Device*);
-void rootream(Device, long);
-void settag(Iobuf*, int, long);
-void serve(Chan*);
-void serve9p1(Chan*, uchar*, int);
-void serve9p2(Chan*, uchar*, int);
-void strrand(void*, int);
-int strtouid(char*);
-int strtouid1(char*);
-int superok(Device, long, int);
-void superream(Device, long);
-void sync(char*);
-int syncblock(void);
-int Tfmt(Fmt*);
-Tlock* tlocked(Iobuf*, Dentry*);
-void uidtostr(char*,int);
-void uidtostr1(char*,int);
-
-#pragma varargck argpos cprint 1
-#pragma varargck argpos panic 1
-
-#pragma varargck type "C" Chan*
-#pragma varargck type "D" Device
-#pragma varargck type "A" Filta
-#pragma varargck type "G" int
-#pragma varargck type "T" long
-#pragma varargck type "F" Fcall*
-
-typedef struct Oldfcall Oldfcall; /* needed for pragma */
-#pragma varargck type "O" Oldfcall*
--- a/sys/src/cmd/disk/kfs/porttime.c
+++ /dev/null
@@ -1,243 +1,0 @@
-#include "all.h"
-
-static int sunday(Tm *t, int d);
-static int dysize(int);
-static void ct_numb(char*, int);
-static void klocaltime(long tim, Tm *ct);
-static void kgmtime(long tim, Tm *ct);
-
-static char dmsize[12] =
-{
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-/*
- * The following table is used for 1974 and 1975 and
- * gives the day number of the first day after the Sunday of the
- * change.
- */
-static struct
-{
- short yrfrom;
- short yrto;
- short daylb;
- short dayle;
-} daytab[] =
-{
- 87, 999, 97, 303,
- 76, 86, 119, 303,
- 75, 75, 58, 303,
- 74, 74, 5, 333,
- 0, 73, 119, 303,
-};
-
-static struct
-{
- short minuteswest; /* minutes west of Greenwich */
- short dsttime; /* dst correction */
-} timezone =
-{
- 5*60, 1
-};
-
-static void
-klocaltime(long tim, Tm *ct)
-{
- int daylbegin, daylend, dayno, i;
- long copyt;
-
- copyt = tim - timezone.minuteswest*60L;
- kgmtime(copyt, ct);
- dayno = ct->yday;
- for(i=0;; i++)
- if(ct->year >= daytab[i].yrfrom &&
- ct->year <= daytab[i].yrto) {
- daylbegin = sunday(ct, daytab[i].daylb);
- daylend = sunday(ct, daytab[i].dayle);
- break;
- }
- if(timezone.dsttime &&
- (dayno>daylbegin || (dayno==daylbegin && ct->hour>=2)) &&
- (dayno<daylend || (dayno==daylend && ct->hour<1))) {
- copyt += 60L*60L;
- kgmtime(copyt, ct);
- }
-}
-
-/*
- * The argument is a 0-origin day number.
- * The value is the day number of the last
- * Sunday before or after the day.
- */
-static
-sunday(Tm *t, int d)
-{
- if(d >= 58)
- d += dysize(t->year) - 365;
- return d - (d - t->yday + t->wday + 700) % 7;
-}
-
-static void
-kgmtime(long tim, Tm *ct)
-{
- int d0, d1;
- long hms, day;
-
- /*
- * break initial number into days
- */
- hms = tim % 86400L;
- day = tim / 86400L;
- if(hms < 0) {
- hms += 86400L;
- day -= 1;
- }
-
- /*
- * generate hours:minutes:seconds
- */
- ct->sec = hms % 60;
- d1 = hms / 60;
- ct->min = d1 % 60;
- d1 /= 60;
- ct->hour = d1;
-
- /*
- * day is the day number.
- * generate day of the week.
- * The addend is 4 mod 7 (1/1/1970 was Thursday)
- */
-
- ct->wday = (day + 7340036L) % 7;
-
- /*
- * year number
- */
- if(day >= 0)
- for(d1 = 70; day >= dysize(d1); d1++)
- day -= dysize(d1);
- else
- for (d1 = 70; day < 0; d1--)
- day += dysize(d1-1);
- ct->year = d1;
- ct->yday = d0 = day;
-
- /*
- * generate month
- */
-
- if(dysize(d1) == 366)
- dmsize[1] = 29;
- for(d1 = 0; d0 >= dmsize[d1]; d1++)
- d0 -= dmsize[d1];
- dmsize[1] = 28;
- ct->mday = d0 + 1;
- ct->mon = d1;
-}
-
-void
-datestr(char *s, long t)
-{
- Tm tm;
-
- klocaltime(t, &tm);
- sprint(s, "%.4d%.2d%.2d", tm.year+1900, tm.mon+1, tm.mday);
-}
-
-int
-Tfmt(Fmt *f1)
-{
- char s[30];
- char *cp;
- long t;
- Tm tm;
-
- t = va_arg(f1->args, long);
- if(t == 0)
- return fmtstrcpy(f1, "The Epoch");
-
- klocaltime(t, &tm);
- strcpy(s, "Day Mon 00 00:00:00 1900");
- cp = &"SunMonTueWedThuFriSat"[tm.wday*3];
- s[0] = cp[0];
- s[1] = cp[1];
- s[2] = cp[2];
- cp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[tm.mon*3];
- s[4] = cp[0];
- s[5] = cp[1];
- s[6] = cp[2];
- ct_numb(s+8, tm.mday);
- ct_numb(s+11, tm.hour+100);
- ct_numb(s+14, tm.min+100);
- ct_numb(s+17, tm.sec+100);
- if(tm.year >= 100) {
- s[20] = '2';
- s[21] = '0';
- }
- ct_numb(s+22, tm.year+100);
-
- return fmtstrcpy(f1, s);
-}
-
-static
-dysize(int y)
-{
-
- if((y%4) == 0)
- return 366;
- return 365;
-}
-
-static
-void
-ct_numb(char *cp, int n)
-{
-
- if(n >= 10)
- cp[0] = (n/10)%10 + '0';
- else
- cp[0] = ' ';
- cp[1] = n%10 + '0';
-}
-
-/*
- * compute the next time after t
- * that has hour hr and is not on
- * day in bitpattern --
- * for automatic dumps
- */
-long
-nextime(long t, int hr, int day)
-{
- Tm tm;
- int nhr;
-
- if(hr < 0 || hr >= 24)
- hr = 5;
- if((day&0x7f) == 0x7f)
- day = 0;
-
-loop:
- klocaltime(t, &tm);
- t -= tm.sec;
- t -= tm.min*60;
- nhr = tm.hour;
- do {
- t += 60*60;
- nhr++;
- } while(nhr%24 != hr);
- klocaltime(t, &tm);
- if(tm.hour != hr) {
- t += 60*60;
- klocaltime(t, &tm);
- if(tm.hour != hr) {
- t -= 60*60;
- klocaltime(t, &tm);
- }
- }
- if(day & (1<<tm.wday)) {
- t += 12*60*60;
- goto loop;
- }
- return t;
-}
--- a/sys/src/cmd/disk/kfs/print.c
+++ /dev/null
@@ -1,288 +1,0 @@
-#include "all.h"
-
-#define PTR sizeof(char*)
-#define SHORT sizeof(int)
-#define INT sizeof(int)
-#define LONG sizeof(long)
-#define IDIGIT 30
-#define MAXCON 30
-
-static int convcount = { 10 };
-
-#define PUT(o, c) if((o)->p < (o)->ep) *(o)->p++ = c
-
-static int noconv(Op*);
-static int cconv(Op*);
-static int dconv(Op*);
-static int hconv(Op*);
-static int lconv(Op*);
-static int oconv(Op*);
-static int sconv(Op*);
-static int uconv(Op*);
-static int xconv(Op*);
-static int percent(Op*);
-
-static
-int (*fmtconv[MAXCON])(Op*) =
-{
- noconv,
- cconv, dconv, hconv, lconv,
- oconv, sconv, uconv, xconv,
- percent,
-};
-static
-char fmtindex[128] =
-{
- ['c'] 1,
- ['d'] 2,
- ['h'] 3,
- ['l'] 4,
- ['o'] 5,
- ['s'] 6,
- ['u'] 7,
- ['x'] 8,
- ['%'] 9,
-};
-
-int
-fmtinstall(char c, int (*f)(Op*))
-{
-
- c &= 0177;
- if(fmtindex[c] == 0) {
- if(convcount >= MAXCON)
- return 1;
- fmtindex[c] = convcount++;
- }
- fmtconv[fmtindex[c]] = f;
- return 0;
-}
-
-char*
-doprint(char *p, char *ep, char *fmt, void *argp)
-{
- int sf1, c;
- Op o;
-
- o.p = p;
- o.ep = ep;
- o.argp = argp;
-
-loop:
- c = *fmt++;
- if(c != '%') {
- if(c == 0) {
- if(o.p < o.ep)
- *o.p = 0;
- return o.p;
- }
- PUT(&o, c);
- goto loop;
- }
- o.f1 = 0;
- o.f2 = -1;
- o.f3 = 0;
- c = *fmt++;
- sf1 = 0;
- if(c == '-') {
- sf1 = 1;
- c = *fmt++;
- }
- while(c >= '0' && c <= '9') {
- o.f1 = o.f1*10 + c-'0';
- c = *fmt++;
- }
- if(sf1)
- o.f1 = -o.f1;
- if(c != '.')
- goto l1;
- c = *fmt++;
- while(c >= '0' && c <= '9') {
- if(o.f2 < 0)
- o.f2 = 0;
- o.f2 = o.f2*10 + c-'0';
- c = *fmt++;
- }
-l1:
- if(c == 0)
- fmt--;
- c = (*fmtconv[fmtindex[c&0177]])(&o);
- if(c < 0) {
- o.f3 |= -c;
- c = *fmt++;
- goto l1;
- }
- o.argp = (char*)o.argp + c;
- goto loop;
-}
-
-int
-numbconv(Op *op, int base)
-{
- char b[IDIGIT];
- int i, f, n, r;
- long v;
- short h;
-
- f = 0;
- switch(op->f3 & (FLONG|FSHORT|FUNSIGN)) {
- case FLONG:
- v = *(long*)op->argp;
- r = LONG;
- break;
-
- case FUNSIGN|FLONG:
- v = *(ulong*)op->argp;
- r = LONG;
- break;
-
- case FSHORT:
- h = *(int*)op->argp;
- v = h;
- r = SHORT;
- break;
-
- case FUNSIGN|FSHORT:
- h = *(int*)op->argp;
- v = (ushort)h;
- r = SHORT;
- break;
-
- default:
- v = *(int*)op->argp;
- r = INT;
- break;
-
- case FUNSIGN:
- v = *(unsigned*)op->argp;
- r = INT;
- break;
- }
- if(!(op->f3 & FUNSIGN) && v < 0) {
- v = -v;
- f = 1;
- }
- b[IDIGIT-1] = 0;
- for(i = IDIGIT-2;; i--) {
- n = (ulong)v % base;
- n += '0';
- if(n > '9')
- n += 'a' - ('9'+1);
- b[i] = n;
- if(i < 2)
- break;
- v = (ulong)v / base;
- if(op->f2 >= 0 && i >= IDIGIT-op->f2)
- continue;
- if(v <= 0)
- break;
- }
-sout:
- if(f)
- b[--i] = '-';
- strconv(b+i, op, op->f1, -1);
- return r;
-}
-
-void
-strconv(char *o, Op *op, int f1, int f2)
-{
- int n, c;
- char *p;
-
- n = strlen(o);
- if(f1 >= 0)
- while(n < f1) {
- PUT(op, ' ');
- n++;
- }
- for(p=o; c = *p++;)
- if(f2 != 0) {
- PUT(op, c);
- f2--;
- }
- if(f1 < 0) {
- f1 = -f1;
- while(n < f1) {
- PUT(op, ' ');
- n++;
- }
- }
-}
-
-static int
-noconv(Op *op)
-{
-
- strconv("***", op, 0, -1);
- return 0;
-}
-
-static int
-cconv(Op *op)
-{
- char b[2];
-
- b[0] = *(int*)op->argp;
- b[1] = 0;
- strconv(b, op, op->f1, -1);
- return INT;
-}
-
-static int
-dconv(Op *op)
-{
-
- return numbconv(op, 10);
-}
-
-static int
-hconv(Op *op)
-{
- USED(op);
- return -FSHORT;
-}
-
-static int
-lconv(Op *op)
-{
- USED(op);
- return -FLONG;
-}
-
-static int
-oconv(Op *op)
-{
- USED(op);
- return numbconv(op, 8);
-}
-
-static int
-sconv(Op *op)
-{
-
- strconv(*(char**)op->argp, op, op->f1, op->f2);
- return PTR;
-}
-
-static int
-uconv(Op *op)
-{
- USED(op);
- return -FUNSIGN;
-}
-
-static int
-xconv(Op *op)
-{
-
- return numbconv(op, 16);
-}
-
-static int
-percent(Op *op)
-{
-
- PUT(op, '%');
- return 0;
-}
--- a/sys/src/cmd/disk/kfs/sub.c
+++ /dev/null
@@ -1,687 +1,0 @@
-#include "all.h"
-
-Lock wpathlock;
-
-struct {
- Lock flock;
- File* ffree; /* free file structures */
- Wpath* wfree;
-} suballoc;
-
-enum{
- Finc= 128, /* allocation chunksize for files */
- Fmax= 10000, /* maximum file structures to be allocated */
-
- Winc= 8*128, /* allocation chunksize for wpath */
- Wmax= 8*10000, /* maximum wpath structures to be allocated */
-};
-
-
-Filsys*
-fsstr(char *p)
-{
- Filsys *fs;
-
- for(fs=filesys; fs->name; fs++)
- if(strcmp(fs->name, p) == 0)
- return fs;
- return 0;
-}
-
-void
-fileinit(Chan *cp)
-{
- File *f;
- Tlock *t;
-
-loop:
- lock(&cp->flock);
- f = cp->flist;
- if(!f) {
- unlock(&cp->flock);
- return;
- }
- cp->flist = f->next;
- unlock(&cp->flock);
-
- qlock(f);
- if(t = f->tlock) {
- t->time = 0;
- f->tlock = 0;
- }
- if(f->open & FREMOV)
- doremove(f, 0);
- freewp(f->wpath);
- f->open = 0;
- f->cp = 0;
- qunlock(f);
-
- goto loop;
-}
-
-/*
- * returns a locked file structure
- */
-File*
-filep(Chan *cp, int fid, int flag)
-{
- File *f, *prev;
-
- if(fid == NOF)
- return 0;
-
-loop:
- lock(&cp->flock);
- for(prev=0,f=cp->flist; f; prev=f,f=f->next) {
- if(f->fid != fid)
- continue;
- if(prev) {
- prev->next = f->next;
- f->next = cp->flist;
- cp->flist = f;
- }
- goto out;
- }
- if(flag) {
- f = newfp(cp);
- if(f) {
- f->fid = fid;
- goto out;
- }
- }
-else print("cannot find %p.%ud (list=%p)\n", cp, fid, cp->flist);
- unlock(&cp->flock);
- return 0;
-
-out:
- unlock(&cp->flock);
- qlock(f);
- if(f->fid != fid) {
- qunlock(f);
- goto loop;
- }
- return f;
-}
-
-void
-sublockinit(void)
-{
- lock(&suballoc.flock);
- lock(&wpathlock);
- conf.nfile = 0;
- conf.nwpath = 0;
- unlock(&suballoc.flock);
- unlock(&wpathlock);
-}
-
-/*
- * always called with cp->flock locked
- */
-File*
-newfp(Chan *cp)
-{
- File *f, *e;
-
-retry:
- lock(&suballoc.flock);
- f = suballoc.ffree;
- if(f != nil){
- suballoc.ffree = f->list;
- unlock(&suballoc.flock);
- f->list = 0;
- f->cp = cp;
- f->next = cp->flist;
- f->wpath = 0;
- f->tlock = 0;
- f->dslot = 0;
- f->doffset = 0;
- f->uid = 0;
- f->cuid = 0;
- cp->flist = f;
- return f;
- }
- unlock(&suballoc.flock);
-
- if(conf.nfile > Fmax){
- print("%d: out of files\n", cp->chan);
- return 0;
- }
-
- /*
- * create a few new files
- */
- f = malloc(Finc*sizeof(*f));
- memset(f, 0, Finc*sizeof(*f));
- lock(&suballoc.flock);
- for(e = f+Finc; f < e; f++){
- qlock(f);
- qunlock(f);
- f->list = suballoc.ffree;
- suballoc.ffree = f;
- }
- conf.nfile += Finc;
- unlock(&suballoc.flock);
- goto retry;
-}
-
-void
-freefp(File *fp)
-{
- Chan *cp;
- File *f, *prev;
-
- if(!fp || !(cp = fp->cp))
- return;
- authfree(fp);
- lock(&cp->flock);
- for(prev=0,f=cp->flist; f; prev=f,f=f->next) {
- if(f != fp)
- continue;
- if(prev)
- prev->next = f->next;
- else
- cp->flist = f->next;
- f->cp = 0;
- lock(&suballoc.flock);
- f->list = suballoc.ffree;
- suballoc.ffree = f;
- unlock(&suballoc.flock);
- break;
- }
- unlock(&cp->flock);
-}
-
-Wpath*
-newwp(void)
-{
- Wpath *w, *e;
-
-retry:
- lock(&wpathlock);
- w = suballoc.wfree;
- if(w != nil){
- suballoc.wfree = w->list;
- unlock(&wpathlock);
- memset(w, 0, sizeof(*w));
- w->refs = 1;
- w->up = 0;
- return w;
- }
- unlock(&wpathlock);
-
- if(conf.nwpath > Wmax){
- print("out of wpaths\n");
- return 0;
- }
-
- /*
- * create a few new wpaths
- */
- w = malloc(Winc*sizeof(*w));
- memset(w, 0, Winc*sizeof(*w));
- lock(&wpathlock);
- for(e = w+Winc; w < e; w++){
- w->list = suballoc.wfree;
- suballoc.wfree = w;
- }
- conf.nwpath += Winc;
- unlock(&wpathlock);
- goto retry;
-}
-
-/*
- * increment the references for the whole path
- */
-Wpath*
-getwp(Wpath *w)
-{
- Wpath *nw;
-
- lock(&wpathlock);
- for(nw = w; nw; nw=nw->up)
- nw->refs++;
- unlock(&wpathlock);
- return w;
-}
-
-/*
- * decrement the reference for each element of the path
- */
-void
-freewp(Wpath *w)
-{
- lock(&wpathlock);
- for(; w; w=w->up){
- w->refs--;
- if(w->refs == 0){
- w->list = suballoc.wfree;
- suballoc.wfree = w;
- }
- }
- unlock(&wpathlock);
-}
-
-/*
- * decrement the reference for just this element
- */
-void
-putwp(Wpath *w)
-{
- lock(&wpathlock);
- w->refs--;
- if(w->refs == 0){
- w->list = suballoc.wfree;
- suballoc.wfree = w;
- }
- unlock(&wpathlock);
-}
-
-int
-iaccess(File *f, Dentry *d, int m)
-{
- if(wstatallow)
- return 0;
-
- /*
- * owner is next
- */
- if(f->uid == d->uid)
- if((m<<6) & d->mode)
- return 0;
- /*
- * group membership is hard
- */
- if(ingroup(f->uid, d->gid))
- if((m<<3) & d->mode)
- return 0;
- /*
- * other access for everyone except members of group 9999
- */
- if(m & d->mode){
- /*
- * walk directories regardless.
- * otherwise its impossible to get
- * from the root to noworld's directories.
- */
- if((d->mode & DDIR) && (m == DEXEC))
- return 0;
- if(!ingroup(f->uid, 9999))
- return 0;
- }
- return 1;
-}
-
-Tlock*
-tlocked(Iobuf *p, Dentry *d)
-{
- Tlock *t, *t1;
- long qpath, tim;
- Device dev;
-
- tim = time(0);
- qpath = d->qid.path;
- dev = p->dev;
- t1 = 0;
- for(t=tlocks+NTLOCK-1; t>=tlocks; t--) {
- if(t->qpath == qpath)
- if(t->time >= tim)
- if(devcmp(t->dev, dev) == 0)
- return 0; /* its locked */
- if(!t1 && t->time < tim)
- t1 = t; /* steal first lock */
- }
- if(t1) {
- t1->dev = dev;
- t1->qpath = qpath;
- t1->time = tim + TLOCK;
- }
- /* botch
- * out of tlock nodes simulates
- * a locked file
- */
- return t1;
-}
-
-Qid
-newqid(Device dev)
-{
- Iobuf *p;
- Superb *sb;
- Qid qid;
-
- p = getbuf(dev, superaddr(dev), Bread|Bmod);
- if(!p || checktag(p, Tsuper, QPSUPER))
- panic("newqid: super block");
- sb = (Superb*)p->iobuf;
- sb->qidgen++;
- qid.path = sb->qidgen;
- qid.vers = 0;
- qid.type = 0;
- putbuf(p);
- return qid;
-}
-
-/*
- * what are legal characters in a name?
- * only disallow control characters.
- * a) utf avoids control characters.
- * b) '/' may not be the separator
- */
-int
-checkname(char *n)
-{
- int i, c;
-
- for(i=0; i<NAMELEN; i++) {
- c = *n & 0xff;
- if(c == 0) {
- if(i == 0)
- return 1;
- memset(n, 0, NAMELEN-i);
- return 0;
- }
- if(c <= 040)
- return 1;
- n++;
- }
- return 1; /* too long */
-}
-
-void
-bfree(Device dev, long addr, int d)
-{
- Iobuf *p;
- long a;
- int i;
-
- if(!addr)
- return;
- if(d > 0) {
- d--;
- p = getbuf(dev, addr, Bread);
- if(p) {
- for(i=INDPERBUF-1; i>=0; i--) {
- a = ((long*)p->iobuf)[i];
- bfree(dev, a, d);
- }
- putbuf(p);
- }
- }
- /*
- * stop outstanding i/o
- */
- p = getbuf(dev, addr, Bprobe);
- if(p) {
- p->flags &= ~(Bmod|Bimm);
- putbuf(p);
- }
- /*
- * dont put written worm
- * blocks into free list
- */
- if(nofree(dev, addr))
- return;
- p = getbuf(dev, superaddr(dev), Bread|Bmod);
- if(!p || checktag(p, Tsuper, QPSUPER))
- panic("bfree: super block");
- addfree(dev, addr, (Superb*)p->iobuf);
- putbuf(p);
-}
-
-long
-balloc(Device dev, int tag, long qid)
-{
- Iobuf *bp, *p;
- Superb *sb;
- long a;
- int n;
-
- p = getbuf(dev, superaddr(dev), Bread|Bmod);
- if(!p || checktag(p, Tsuper, QPSUPER))
- panic("balloc: super block");
- sb = (Superb*)p->iobuf;
-
-loop:
- n = --sb->fbuf.nfree;
- sb->tfree--;
- if(n < 0 || n >= FEPERBUF)
- panic("balloc: bad freelist");
- a = sb->fbuf.free[n];
- if(n <= 0) {
- if(a == 0) {
- sb->tfree = 0;
- sb->fbuf.nfree = 1;
- if(devgrow(dev, sb))
- goto loop;
- putbuf(p);
- return 0;
- }
- bp = getbuf(dev, a, Bread);
- if(!bp || checktag(bp, Tfree, QPNONE)) {
- if(bp)
- putbuf(bp);
- putbuf(p);
- return 0;
- }
- memmove(&sb->fbuf, bp->iobuf, (FEPERBUF+1)*sizeof(long));
- putbuf(bp);
- }
- bp = getbuf(dev, a, Bmod);
- memset(bp->iobuf, 0, RBUFSIZE);
- settag(bp, tag, qid);
- if(tag == Tind1 || tag == Tind2 || tag == Tdir)
- bp->flags |= Bimm;
- putbuf(bp);
- putbuf(p);
- return a;
-}
-
-void
-addfree(Device dev, long addr, Superb *sb)
-{
- int n;
- Iobuf *p;
-
- if(addr >= sb->fsize){
- print("addfree: bad addr %lux\n", addr);
- return;
- }
- n = sb->fbuf.nfree;
- if(n < 0 || n > FEPERBUF)
- panic("addfree: bad freelist");
- if(n >= FEPERBUF) {
- p = getbuf(dev, addr, Bmod);
- if(p == 0)
- panic("addfree: getbuf");
- memmove(p->iobuf, &sb->fbuf, (FEPERBUF+1)*sizeof(long));
- settag(p, Tfree, QPNONE);
- putbuf(p);
- n = 0;
- }
- sb->fbuf.free[n++] = addr;
- sb->fbuf.nfree = n;
- sb->tfree++;
- if(addr >= sb->fsize)
- sb->fsize = addr+1;
-}
-
-int
-Cfmt(Fmt *f1)
-{
- Chan *cp;
-
- cp = va_arg(f1->args, Chan*);
- return fmtprint(f1, "C%d.%.3d", cp->type, cp->chan);
-}
-
-int
-Dfmt(Fmt *f1)
-{
- Device d;
-
- d = va_arg(f1->args, Device);
- return fmtprint(f1, "D%d.%d.%d.%d", d.type, d.ctrl, d.unit, d.part);
-}
-
-int
-Afmt(Fmt *f1)
-{
- Filta a;
-
- a = va_arg(f1->args, Filta);
- return fmtprint(f1, "%6lud %6lud %6lud",
- fdf(a.f->filter[0], a.scale*60),
- fdf(a.f->filter[1], a.scale*600),
- fdf(a.f->filter[2], a.scale*6000));
-}
-
-int
-Gfmt(Fmt *f1)
-{
- int t;
-
- t = va_arg(f1->args, int);
- if(t >= 0 && t < MAXTAG)
- return fmtstrcpy(f1, tagnames[t]);
- else
- return fmtprint(f1, "<badtag %d>", t);
-}
-
-void
-formatinit(void)
-{
-
- fmtinstall('C', Cfmt); /* print channels */
- fmtinstall('D', Dfmt); /* print devices */
- fmtinstall('A', Afmt); /* print filters */
- fmtinstall('G', Gfmt); /* print tags */
- fmtinstall('T', Tfmt); /* print times */
- fmtinstall('O', ofcallfmt); /* print old fcalls */
-}
-int
-devcmp(Device d1, Device d2)
-{
-
- if(d1.type == d2.type)
- if(d1.ctrl == d2.ctrl)
- if(d1.unit == d2.unit)
- if(d1.part == d2.part)
- return 0;
- return 1;
-}
-
-void
-rootream(Device dev, long addr)
-{
- Iobuf *p;
- Dentry *d;
-
- p = getbuf(dev, addr, Bmod|Bimm);
- memset(p->iobuf, 0, RBUFSIZE);
- settag(p, Tdir, QPROOT);
- d = getdir(p, 0);
- strcpy(d->name, "/");
- d->uid = -1;
- d->gid = -1;
- d->mode = DALLOC | DDIR | 0775;
- d->qid = QID9P1(QPROOT|QPDIR,0);
- d->atime = time(0);
- d->mtime = d->atime;
- putbuf(p);
-}
-
-int
-superok(Device dev, long addr, int set)
-{
- Iobuf *p;
- Superb *s;
- int ok;
-
- p = getbuf(dev, addr, Bread|Bmod|Bimm);
- s = (Superb*)p->iobuf;
- ok = s->fsok;
- s->fsok = set;
- putbuf(p);
- return ok;
-}
-
-void
-superream(Device dev, long addr)
-{
- Iobuf *p;
- Superb *s;
- long i;
-
- p = getbuf(dev, addr, Bmod|Bimm);
- memset(p->iobuf, 0, RBUFSIZE);
- settag(p, Tsuper, QPSUPER);
-
- s = (Superb*)p->iobuf;
- s->fstart = 1;
- s->fsize = devsize(dev);
- s->fbuf.nfree = 1;
- s->qidgen = 10;
- for(i=s->fsize-1; i>=addr+2; i--)
- addfree(dev, i, s);
- putbuf(p);
-}
-
-/*
- * returns 1 if n is prime
- * used for adjusting lengths
- * of hashing things.
- * there is no need to be clever
- */
-int
-prime(long n)
-{
- long i;
-
- if((n%2) == 0)
- return 0;
- for(i=3;; i+=2) {
- if((n%i) == 0)
- return 0;
- if(i*i >= n)
- return 1;
- }
-}
-
-void
-hexdump(void *a, int n)
-{
- char s1[30], s2[4];
- uchar *p;
- int i;
-
- p = a;
- s1[0] = 0;
- for(i=0; i<n; i++) {
- sprint(s2, " %.2ux", p[i]);
- strcat(s1, s2);
- if((i&7) == 7) {
- print("%s\n", s1);
- s1[0] = 0;
- }
- }
- if(s1[0])
- print("%s\n", s1);
-}
-
-long
-qidpathgen(Device *dev)
-{
- Iobuf *p;
- Superb *sb;
- long path;
-
- p = getbuf(*dev, superaddr((*dev)), Bread|Bmod);
- if(!p || checktag(p, Tsuper, QPSUPER))
- panic("newqid: super block");
- sb = (Superb*)p->iobuf;
- sb->qidgen++;
- path = sb->qidgen;
- putbuf(p);
- return path;
-}
-
--- a/sys/src/cmd/disk/kfs/uid.c
+++ /dev/null
@@ -1,427 +1,0 @@
-#include "all.h"
-
-struct
-{
- RWLock uidlock;
- char* uidbuf;
- int flen;
- int find;
-} uidgc;
-
-int
-byuid(void *a1, void *a2)
-{
- Uid *u1, *u2;
-
- u1 = a1;
- u2 = a2;
- return u2->uid - u1->uid;
-}
-
-int
-byname(void *a1, void *a2)
-{
- Uid *u1, *u2;
-
- u1 = a1;
- u2 = a2;
- return strcmp(uidspace+u2->offset, uidspace+u1->offset);
-}
-
-int
-fchar(void)
-{
-
- if(uidgc.find >= uidgc.flen) {
- uidgc.find = 0;
- uidgc.flen = con_read(FID2, uidgc.uidbuf, cons.offset, MAXDAT);
- if(uidgc.flen <= 0)
- return 0;
- cons.offset += uidgc.flen;
- }
- return uidgc.uidbuf[uidgc.find++];
-}
-
-int
-fname(char *name)
-{
- int i, c;
-
- memset(name, 0, NAMELEN);
- for(i=0;; i++) {
- c = fchar();
- switch(c) {
- case ':':
- case '\n':
- case ',':
- case ' ':
- case '#':
- case 0:
- return c;
- }
- if(i < NAMELEN-1)
- name[i] = c;
- }
-}
-
-#ifdef sometime
-/*
- * file format is
- * uid:name:lead:member,member,...\n
- */
-void
-read_user(void)
-{
- int c;
-
- if((c=fname(ustr))!=':' || (c=fname(name))!=':' || (c=fname(lead))!=':')
- goto skipline;
- n = atol(ustr);
- if(n == 0)
- goto skipline;
- if(readu){
- o -= strlen(name)+1;
- if(o < 0) {
- cprint("conf.uidspace(%ld) too small\n", conf.uidspace);
- return -1;
- }
- strcpy(uidspace+o, name);
- uid[u].uid = n;
- uid[u].offset = o;
- u++;
- if(u >= conf.nuid) {
- cprint("conf.nuid(%ld) too small\n", conf.nuid);
- goto initu;
- }
- }else{
- o = strtouid1(name);
- if(o == 0 && strcmp(name, "") != 0)
- o = n;
- for(c=0; c<u; c++)
- if(uid[c].uid == n) {
- uid[c].lead = o;
- break;
- }
- while(((c=fname(name))==',' || c=='\n') && name[0]){
-work here
- if(c=='\n')
- break;
- }
- }
-
-skipline:
- while(c != '\n')
- fname(ustr);
-}
-#endif
-
-/*
- -1:adm:adm:
- 0:none:adm:
- 1:tor:tor:
- 10000:sys::
- 10001:map:map:
- 10002:doc::
- 10003:upas:upas:
- 10004:font::
- 10005:bootes:bootes:
-*/
-
-struct {
- int uid;
- char *name;
- int leader;
-}
-admusers[] = {
- -1, "adm", -1,
- 0, "none", -1,
- 1, "tor", 1,
- 2, "glenda", 2,
- 10000, "sys", 0,
- 10001, "upas", 10001,
- 10002, "bootes", 10002,
- 0, 0, 0,
-};
-
-
-void
-cmd_user(void)
-{
- int c, n, o, u, g, i;
- char name[NAMELEN];
-
- if(con_clone(FID1, FID2))
- goto ainitu;
- if(con_path(FID2, "/adm/users"))
- goto ainitu;
- if(con_open(FID2, 0)){
- goto ainitu;
- }
-
- wlock(&uidgc.uidlock);
- uidgc.uidbuf = malloc(MAXDAT);
-
- memset(uid, 0, conf.nuid * sizeof(*uid));
- memset(uidspace, 0, conf.uidspace * sizeof(*uidspace));
- memset(gidspace, 0, conf.gidspace * sizeof(*gidspace));
-
- uidgc.flen = 0;
- uidgc.find = 0;
- cons.offset = 0;
- u = 0;
- o = conf.uidspace;
-
-ul1:
- c = fname(name);
- if(c != ':')
- goto uskip;
- n = atol(name);
- if(n == 0)
- goto uskip;
- c = fname(name);
- if(c != ':')
- goto uskip;
- o -= strlen(name)+1;
- if(o < 0) {
- cprint("conf.uidspace(%ld) too small\n", conf.uidspace);
- goto initu;
- }
- strcpy(uidspace+o, name);
- uid[u].uid = n;
- uid[u].offset = o;
- u++;
- if(u >= conf.nuid) {
- cprint("conf.nuid(%ld) too small\n", conf.nuid);
- goto initu;
- }
-
-uskip:
- if(c == '\n')
- goto ul1;
- if(c) {
- c = fname(name);
- goto uskip;
- }
-/* cprint("%d uids read\n", u);/**/
- qsort(uid, u, sizeof(uid[0]), byuid);
- for(c=u-1; c>0; c--)
- if(uid[c].uid == uid[c-1].uid) {
- cprint("duplicate uids: %d\n", uid[c].uid);
- cprint(" %s", uidspace+uid[c].offset);
- cprint(" %s\n", uidspace+uid[c-1].offset);
- }
- qsort(uid, u, sizeof(uid[0]), byname);
- for(c=u-1; c>0; c--)
- if(!strcmp(uidspace+uid[c].offset,
- uidspace+uid[c-1].offset)) {
- cprint("kfs: duplicate names: %s\n", uidspace+uid[c].offset);
- cprint(" %d", uid[c].uid);
- cprint(" %d\n", uid[c-1].uid);
- }
- if(cons.flags & Fuid)
- for(c=0; c<u; c++)
- cprint("%6d %s\n", uid[c].uid, uidspace+uid[c].offset);
-
- uidgc.flen = 0;
- uidgc.find = 0;
- cons.offset = 0;
- g = 0;
-
-gl1:
- c = fname(name);
- if(c != ':')
- goto gskip;
- n = atol(name); /* number */
- if(n == 0)
- goto gskip;
- c = fname(name); /* name */
- if(c != ':')
- goto gskip;
- c = fname(name); /* leader */
- if(c != ':')
- goto gskip;
- o = strtouid1(name);
- if(o == 0 && strcmp(name, "") != 0)
- o = n;
- for(c=0; c<u; c++)
- if(uid[c].uid == n) {
- uid[c].lead = o;
- break;
- }
- c = fname(name); /* list of members */
- if(c != ',' && c != '\n')
- goto gskip;
- if(!name[0])
- goto gskip;
- gidspace[g++] = n;
-gl2:
- n = strtouid1(name);
- if(n)
- gidspace[g++] = n;
- if(g >= conf.gidspace-2) {
- cprint("conf.gidspace(%ld) too small\n", conf.gidspace);
- goto initu;
- }
- if(c == '\n')
- goto gl3;
- c = fname(name);
- if(c == ',' || c == '\n')
- goto gl2;
- cprint("gid truncated\n");
-
-gl3:
- gidspace[g++] = 0;
-
-gskip:
- if(c == '\n')
- goto gl1;
- if(c) {
- c = fname(name);
- goto gskip;
- }
- if(cons.flags & Fuid) {
- o = 0;
- for(c=0; c<g; c++) {
- n = gidspace[c];
- if(n == 0) {
- o = 0;
- continue;
- }
- uidtostr1(name, n);
- if(o) {
- if(o > 6) {
- cprint("\n %s", name);
- o = 1;
- } else
- cprint(" %s", name);
- } else
- cprint("\n%6s", name);
- o++;
- }
- cprint("\n");
- }
- goto out;
-
-ainitu:
- wlock(&uidgc.uidlock);
- uidgc.uidbuf = malloc(MAXDAT);
-
-initu:
- cprint("initializing minimal user table\n");
- memset(uid, 0, conf.nuid * sizeof(*uid));
- memset(uidspace, 0, conf.uidspace * sizeof(*uidspace));
- memset(gidspace, 0, conf.gidspace * sizeof(*gidspace));
- o = conf.uidspace;
- u = 0;
-
- for(i=0; admusers[i].name; i++){
- o -= strlen(admusers[i].name)+1;
- strcpy(uidspace+o, admusers[i].name);
- uid[u].uid = admusers[i].uid;
- uid[u].lead = admusers[i].leader;
- uid[u].offset = o;
- u++;
- }
-
-out:
- free(uidgc.uidbuf);
- writegroup = strtouid1("write");
- wunlock(&uidgc.uidlock);
-
-}
-
-void
-uidtostr(char *name, int id)
-{
- rlock(&uidgc.uidlock);
- uidtostr1(name, id);
- runlock(&uidgc.uidlock);
-}
-
-void
-uidtostr1(char *name, int id)
-{
- Uid *u;
- int i;
-
- if(id == 0){
- strncpy(name, "none", NAMELEN);
- return;
- }
- for(i=0, u=uid; i<conf.nuid; i++,u++) {
- if(u->uid == id) {
- strncpy(name, uidspace+u->offset, NAMELEN);
- return;
- }
- }
- strncpy(name, "none", NAMELEN);
-}
-
-int
-strtouid(char *s)
-{
- int i;
-
- rlock(&uidgc.uidlock);
- i = strtouid1(s);
- runlock(&uidgc.uidlock);
- return i;
-}
-
-int
-strtouid1(char *s)
-{
- Uid *u;
- int i;
-
- for(i=0, u=uid; i<conf.nuid; i++,u++)
- if(!strcmp(s, uidspace+u->offset))
- return u->uid;
- return 0;
-}
-
-int
-ingroup(int u, int g)
-{
- short *p;
-
- if(u == g)
- return 1;
- rlock(&uidgc.uidlock);
- for(p=gidspace; *p;) {
- if(*p != g) {
- for(p++; *p++;)
- ;
- continue;
- }
- for(p++; *p; p++)
- if(*p == u) {
- runlock(&uidgc.uidlock);
- return 1;
- }
- }
- runlock(&uidgc.uidlock);
- return 0;
-}
-
-int
-leadgroup(int ui, int gi)
-{
- Uid *u;
- int i;
-
- rlock(&uidgc.uidlock);
- for(i=0, u=uid; i<conf.nuid; i++,u++) {
- if(u->uid == gi) {
- i = u->lead;
- runlock(&uidgc.uidlock);
- if(i == ui)
- return 1;
- if(i == 0)
- return ingroup(ui, gi);
- return 0;
- }
- }
- runlock(&uidgc.uidlock);
- return 0;
-}
--- a/sys/src/cmd/disk/kfscmd.c
+++ /dev/null
@@ -1,56 +1,0 @@
-#include <u.h>
-#include <libc.h>
-
-void
-main(int argc, char *argv[])
-{
- char *name, buf[4*1024];
- int fd, n, i, errs;
-
- name = 0;
- ARGBEGIN{
- case 'n':
- name = ARGF();
- break;
- default:
- fprint(2, "usage: kfscmd [-n server] commands\n");
- exits("usage");
- }ARGEND
-
- if(name)
- snprint(buf, sizeof buf, "/srv/kfs.%s.cmd", name);
- else
- strcpy(buf, "/srv/kfs.cmd");
- fd = open(buf, ORDWR);
- if(fd < 0){
- fprint(2, "kfscmd: can't open commands file\n");
- exits("commands file");
- }
-
- errs = 0;
- for(i = 0; i < argc; i++){
- if(write(fd, argv[i], strlen(argv[i])) != strlen(argv[i])){
- fprint(2, "%s: error writing %s: %r", argv0, argv[i]);
- errs++;
- continue;
- }
- for(;;){
- n = read(fd, buf, sizeof buf - 1);
- if(n < 0){
- fprint(2, "%s: error executing %s: %r", argv0, argv[i]);
- errs++;
- break;
- }
- buf[n] = '\0';
- if(strcmp(buf, "done") == 0 || strcmp(buf, "success") == 0)
- break;
- if(strcmp(buf, "unknown command") == 0){
- errs++;
- print("kfscmd: command %s not recognized\n", argv[i]);
- break;
- }
- write(1, buf, n);
- }
- }
- exits(errs ? "errors" : 0);
-}
--- a/sys/src/cmd/disk/mkfile
+++ b/sys/src/cmd/disk/mkfile
@@ -2,7 +2,6 @@
TARG=exsort\
format\
- kfscmd\
mbr\
mkext\
mkfs\
@@ -10,7 +9,6 @@
DIRS=\
9660\
- kfs\
prep\
smart\
# sacfs\
@@ -29,23 +27,20 @@
</sys/src/cmd/mkmany
-all:V: all-kfs
+all:V: all-dirs
-install:V: install-kfs ksync
+install:V: install-dirs
-clean:V: clean-kfs
+clean:V: clean-dirs
-nuke:V: nuke-kfs
+nuke:V: nuke-dirs
-installall:V: installall-kfs
+installall:V: installall-dirs
-%-kfs:V:
+%-dirs:V:
for(i in $DIRS) @{
cd $i
mk $MKFLAGS $stem
}
-
-ksync:
- touch $BIN/ksync
$O.format: /$objtype/lib/libdisk.a