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 | ((DREAD|DWRITE|DEXEC) << 6) | ((DREAD|DWRITE|DEXEC) << 3) | ((DREAD|DWRITE|DEXEC) << 0); d->qid = QID9P1(QPROOT|QPDIR,0); d->atime = time(0); d->mtime = d->atime; putbuf(p); }
void f_attach(Chan *cp, Oldfcall *in, Oldfcall *ou) { Iobuf *p; Dentry *d; File *f; int u; Filsys *fs; int32_t 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_walk(Chan *cp, Oldfcall *in, Oldfcall *ou) { Iobuf *p, *p1; Dentry *d, *d1; File *f; Wpath *w, *ow; int slot; int32_t 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); }