static void topdirinit(int ncores) { int i; Dirtab *d; ntoptab = 2 + ncores; toptab = malloc(ntoptab * sizeof(Dirtab)); if (toptab == nil) return; d = toptab; strncpy(d->name, ".", KNAMELEN); mkqid(&d->qid, Qdir, 0, QTDIR); d->perm = DMDIR|0555; d++; strncpy(d->name, "ctrdesc", KNAMELEN); mkqid(&d->qid, Qgctl, 0, 0); d->perm = 0444; for (i = 2; i < ncores + 2; i++) { d = &toptab[i]; snprint(d->name, KNAMELEN, "core%4.4ud", i - 2); mkqid(&d->qid, PMCQID(i - 2, Qcore), 0, QTDIR); d->perm = DMDIR|0555; } }
static int cmd3gen(Chan *c, int i, Dir *dp) { Qid q; Conv *cv; cv = cmd.conv[CONV(c->qid)]; switch(i){ default: return -1; case Qdata: mkqid(&q, QID(CONV(c->qid), Qdata), 0, QTFILE); devdir(c, q, "data", 0, cv->owner, cv->perm, dp); return 1; case Qstderr: mkqid(&q, QID(CONV(c->qid), Qstderr), 0, QTFILE); devdir(c, q, "stderr", 0, cv->owner, 0444, dp); return 1; case Qctl: mkqid(&q, QID(CONV(c->qid), Qctl), 0, QTFILE); devdir(c, q, "ctl", 0, cv->owner, cv->perm, dp); return 1; case Qstatus: mkqid(&q, QID(CONV(c->qid), Qstatus), 0, QTFILE); devdir(c, q, "status", 0, cv->owner, 0444, dp); return 1; case Qwait: mkqid(&q, QID(CONV(c->qid), Qwait), 0, QTFILE); devdir(c, q, "wait", 0, cv->owner, 0444, dp); return 1; } }
static void ctrdirinit(void) { int nr, i; Dirtab *d; nr = pmcnregs(); npmctab = 1 + 2*nr; pmctab = malloc(npmctab * sizeof(Dirtab)); if (pmctab == nil){ free(toptab); toptab = nil; return; } d = pmctab; strncpy(d->name, ".", KNAMELEN); mkqid(&d->qid, Qctr, 0, QTDIR); d->perm = DMDIR|0555; for (i = 1; i < nr + 1; i++) { d = &pmctab[i]; snprint(d->name, KNAMELEN, "ctr%2.2ud", i - 1); mkqid(&d->qid, PMCQID(i - 1, Qdata), 0, 0); d->perm = 0600; d = &pmctab[nr + i]; snprint(d->name, KNAMELEN, "ctr%2.2udctl", i - 1); mkqid(&d->qid, PMCQID(i - 1, Qctl), 0, 0); d->perm = 0600; } }
static Chan* sdattach(char* spec) { Chan *c; char *p; SDev *sdev; int idno, subno; if(*spec == '\0'){ c = devattach(sddevtab.dc, spec); mkqid(&c->qid, QID(0, 0, 0, Qtopdir), 0, QTDIR); return c; } if(spec[0] != 's' || spec[1] != 'd') error(Ebadspec); idno = spec[2]; subno = strtol(&spec[3], &p, 0); if(p == &spec[3]) error(Ebadspec); if((sdev=sdgetdev(idno)) == nil) error(Enonexist); if(sdgetunit(sdev, subno) == nil){ decref(&sdev->r); error(Enonexist); } c = devattach(sddevtab.dc, spec); mkqid(&c->qid, QID(sdev->idno, subno, 0, Qunitdir), 0, QTDIR); c->dev = (sdev->idno << UnitLOG) + subno; decref(&sdev->r); return c; }
static int fswalk(Usbfs *fs, Fid *fid, char *name) { int cn, i; char *es; Dirtab *tab; Ether *e; Qid qid; e = fs->aux; qid = fid->qid; qid.path &= ~fs->qid; if((qid.type & QTDIR) == 0){ werrstr("walk in non-directory"); return -1; } if(strcmp(name, "..") == 0){ /* must be /etherU%d; i.e. our root dir. */ fid->qid.path = mkqid(0, Qroot) | fs->qid; fid->qid.vers = 0; fid->qid.type = QTDIR; return 0; } switch(qtype(qid.path)){ case Qroot: if(name[0] >= '0' && name[0] <= '9'){ es = name; cn = strtoul(name, &es, 10); if(cn >= e->nconns || *es != 0){ werrstr(Enotfound); return -1; } fid->qid.path = mkqid(cn, Qndir) | fs->qid; fid->qid.vers = 0; return 0; } /* fall */ case Qndir: if(qtype(qid.path) == Qroot) tab = rootdirtab; else tab = conndirtab; cn = qnum(qid.path); for(i = 0; tab[i].name != nil; tab++) if(strcmp(tab[i].name, name) == 0){ fid->qid.path = mkqid(cn, tab[i].qid)|fs->qid; fid->qid.vers = 0; if((tab[i].mode & DMDIR) != 0) fid->qid.type = QTDIR; else fid->qid.type = QTFILE; return 0; } break; default: sysfatal("usb: ether: fswalk bug"); } return -1; }
static char* fswalk1(Fid *fid, char *name, Qid *qid) { int i; switch((int)fid->qid.path) { default: return "fswalk1: cannot happen"; case Qroot: if(strcmp(name, factname) == 0) { *qid = mkqid(QTDIR, Qfactotum); fid->qid = *qid; return nil; } if(strcmp(name, "..") == 0) { *qid = fid->qid; return nil; } return "not found"; case Qfactotum: for(i=0; i<nelem(dirtab); i++) if(strcmp(name, dirtab[i].name) == 0) { *qid = mkqid(0, dirtab[i].qidpath); fid->qid = *qid; return nil; } if(strcmp(name, "..") == 0) { *qid = mkqid(QTDIR, qtop); fid->qid = *qid; return nil; } return "not found"; } }
static int sd2gen(Chan* c, int i, Dir* dp) { Qid q; uvlong l; SDpart *pp; SDperm *perm; SDunit *unit; SDev *sdev; int rv; sdev = sdgetdev(DEV(c->qid)); assert(sdev); unit = sdev->unit[UNIT(c->qid)]; rv = -1; switch(i){ case Qctl: mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), PART(c->qid), Qctl), unit->vers, QTFILE); perm = &unit->ctlperm; if(emptystr(perm->user)){ kstrdup(&perm->user, eve); perm->perm = 0644; /* nothing secret in ctl */ } devdir(c, q, "ctl", 0, perm->user, perm->perm, dp); rv = 1; break; case Qraw: mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), PART(c->qid), Qraw), unit->vers, QTFILE); perm = &unit->rawperm; if(emptystr(perm->user)){ kstrdup(&perm->user, eve); perm->perm = DMEXCL|0600; } devdir(c, q, "raw", 0, perm->user, perm->perm, dp); rv = 1; break; case Qpart: pp = &unit->part[PART(c->qid)]; l = (pp->end - pp->start) * unit->secsize; mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), PART(c->qid), Qpart), unit->vers+pp->vers, QTFILE); if(emptystr(pp->user)) kstrdup(&pp->user, eve); devdir(c, q, pp->name, l, pp->user, pp->perm, dp); rv = 1; break; } decref(&sdev->r); return rv; }
static int fswalk(Usbfs*_1, Fid *fid, char *name) { Qid q; int qd, qf; int i; int rc; Dev *dev; Dir d; int (*xfswalk)(Usbfs *fs, Fid *f, char *name); q = fid->qid; qd = qiddev(q.path); qf = qidfile(q.path); q.type = QTDIR; q.vers = 0; if(strcmp(name, "..") == 0) if(qd == Dtop || qf == Qdir){ q.path = mkqid(Dtop, Qdir); fid->qid = q; return 0; } if(qd != 0){ qlock(&fslck); if(fs[qd] == nil){ qunlock(&fslck); werrstr(Eio); return -1; } dev = fs[qd]->dev; if(dev != nil) incref(&dev->Ref); xfswalk = fs[qd]->walk; qunlock(&fslck); rc = xfswalk(fs[qd], fid, name); if(dev != nil) closedev(dev); return rc; } qlock(&fslck); for(i = 0; i < nfs; i++) if(fs[i] != nil && strcmp(name, fs[i]->name) == 0){ q.path = mkqid(i, Qdir); fs[i]->stat(fs[i], q, &d); /* may be a file */ fid->qid = d.qid; qunlock(&fslck); return 0; } qunlock(&fslck); werrstr(Enotfound); return -1; }
void putimage(Image *i) { Image *f, **l; Chan *c; if(i->notext) return; lock(i); if(--i->ref == 0) { l = &ihash(i->qid.path); mkqid(&i->qid, ~0, ~0, QTFILE); unlock(i); c = i->c; lock(&imagealloc); for(f = *l; f; f = f->hash) { if(f == i) { *l = i->hash; break; } l = &f->hash; } i->next = imagealloc.free; imagealloc.free = i; unlock(&imagealloc); ccloseq(c); /* does not block */ return; } unlock(i); }
/* * all uarts must be uartsetup() by this point or inside of uartinstall() */ static void uartreset(void) { int i; Dirtab *dp; uartinstall(); ndir = 1+3*nuart; uartdir = xalloc(ndir * sizeof(Dirtab)); dp = uartdir; strcpy(dp->name, "."); mkqid(&dp->qid, 0, 0, QTDIR); dp->length = 0; dp->perm = DMDIR|0555; dp++; for(i = 0; i < nuart; i++){ /* 3 directory entries per port */ strcpy(dp->name, uart[i]->name); dp->qid.path = NETQID(i, Ndataqid); dp->perm = 0660; dp++; sprint(dp->name, "%sctl", uart[i]->name); dp->qid.path = NETQID(i, Nctlqid); dp->perm = 0660; dp++; sprint(dp->name, "%sstatus", uart[i]->name); dp->qid.path = NETQID(i, Nstatqid); dp->perm = 0444; dp++; } }
static int srvgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) { Srv *sp; Qid q; if(s == DEVDOTDOT){ devdir(c, c->qid, "#s", 0, eve, 0555, dp); return 1; } qlock(&srvlk); for(sp = srv; sp && s; sp = sp->link) s--; if(sp == 0) { qunlock(&srvlk); return -1; } mkqid(&q, sp->path, 0, QTFILE); /* make sure name string continues to exist after we release lock */ kstrcpy(up->genbuf, sp->name, sizeof up->genbuf); devdir(c, q, up->genbuf, 0, sp->owner, sp->perm, dp); qunlock(&srvlk); return 1; }
Chan* devattach(int dc, char *spec) { if (0) print_func_entry(); Chan *c; char *buf; /* * There are no error checks here because * this can only be called from the driver of dc * which pretty much guarantees devtabget will * succeed. */ c = newchan(); mkqid(&c->qid, 0, 0, QTDIR); c->dev = devtabget(dc, 0); if(spec == nil) spec = ""; buf = smalloc(1+UTFmax+strlen(spec)+1); sprint(buf, "#%C%s", dc, spec); c->path = newpath(buf); free(buf); if (0) print_func_exit(); return c; }
/* * create a pipe, no streams are created until an open */ static Chan* pipeattach(char *spec) { Pipe *p; Chan *c; c = devattach('|', spec); p = malloc(sizeof(Pipe)); if(p == 0) exhausted("memory"); p->ref = 1; p->q[0] = qopen(Pipeqsize, 0, 0, 0); if(p->q[0] == 0){ free(p); exhausted("memory"); } p->q[1] = qopen(Pipeqsize, 0, 0, 0); if(p->q[1] == 0){ free(p->q[0]); free(p); exhausted("memory"); } lock(&pipealloc); p->path = ++pipealloc.path; unlock(&pipealloc); mkqid(&c->qid, PIPEQID(2*p->path, Qdir), 0, QTDIR); c->aux = p; c->devno = 0; return c; }
static int dupgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp) { Fgrp *fgrp = up->env->fgrp; Chan *f; static int perm[] = { 0400, 0200, 0600, 0 }; int p; Qid q; if(s == DEVDOTDOT){ devdir(c, c->qid, ".", 0, eve, DMDIR|0555, dp); return 1; } if(s == 0) return 0; s--; if(s/2 > fgrp->maxfd) return -1; if((f=fgrp->fd[s/2]) == nil) return 0; if(s & 1){ p = 0400; sprint(up->genbuf, "%dctl", s/2); }else{ p = perm[f->mode&3]; sprint(up->genbuf, "%d", s/2); } mkqid(&q, s+1, 0, QTFILE); devdir(c, q, up->genbuf, 0, eve, p, dp); return 1; }
static int dirgen(Usbfs*_1, Qid _2, int n, Dir *d, void *_3) { int i; Dev *dev; char *nm; qlock(&fslck); for(i = 0; i < nfs; i++) if(fs[i] != nil && n-- == 0){ d->qid.type = QTDIR; d->qid.path = mkqid(i, Qdir); d->qid.vers = 0; dev = fs[i]->dev; if(dev != nil) incref(&dev->Ref); nm = d->name; fs[i]->stat(fs[i], d->qid, d); d->name = nm; strncpy(d->name, fs[i]->name, Namesz); if(dev != nil) closedev(dev); qunlock(&fslck); return 0; } qunlock(&fslck); return -1; }
static int flash2gen(Chan *c, ulong p, Dir *dp) { Flashpart *fp; Flash *f; Qid q; int mode; f = flash.card[c->dev]; fp = &f->part[PART(p)]; if(fp->name == nil) return 0; mkqid(&q, p, 0, QTFILE); switch(TYPE(p)){ case Qdata: mode = 0660; if(f->write == nil) mode = 0440; devdir(c, q, fp->name, fp->end-fp->start, eve, mode, dp); return 1; case Qctl: snprint(up->genbuf, sizeof(up->genbuf), "%sctl", fp->name); devdir(c, q, up->genbuf, 0, eve, 0660, dp); return 1; default: return -1; } }
void usbfsadd(Usbfs *dfs) { int i, j; dprint(2, "%s: fsadd %s\n", argv0, dfs->name); qlock(&fslck); for(i = 1; i < nfs; i++) if(fs[i] == nil) break; if(i >= nfs){ if((nfs%Incr) == 0){ fs = realloc(fs, sizeof(Usbfs*) * (nfs+Incr)); if(fs == nil) sysfatal("realloc: %r"); for(j = nfs; j < nfs+Incr; j++) fs[j] = nil; } if(nfs == 0) /* do not use entry 0 */ nfs++; fs[nfs++] = dfs; }else fs[i] = dfs; dfs->qid = mkqid(i, 0); fsused++; qunlock(&fslck); }
static void fscreate(Req *r) { FInfo fi; int rc, is_dir; char *npath; Aux *a = r->fid->aux; a->end = a->off = 0; a->cache = emalloc9p(max(Sess->mtu, MTU)); is_dir = (r->ifcall.perm & DMDIR) == DMDIR; npath = smprint("%s/%s", a->path, r->ifcall.name); if(Sess->caps & CAP_NT_SMBS) rc = ntcreateopen(a, mapfile(npath), r->ifcall.mode, r->ifcall.perm, 1, is_dir, &fi); else rc = smbcreateopen(a, mapfile(npath), r->ifcall.mode, r->ifcall.perm, 1, is_dir, &fi); if(rc == -1){ free(npath); responderrstr(r); return; } r->fid->qid = mkqid(npath, fi.attribs & ATTR_DIRECTORY, fi.changed, 0, 0); r->ofcall.qid = r->fid->qid; free(a->path); a->path = npath; respond(r, nil); }
static int topgen(Chan *c, ulong type, Dir *d) { int perm; vlong size; char *p; Qid q; perm = 0444; size = 0; switch(type){ default: return -1; case Qtopctl: p = "ctl"; perm = 0644; break; case Qtoplog: p = "log"; size = eventcount(); break; } mkqid(&q, type, 0, QTFILE); devdir(c, q, p, size, eve, perm, d); return 1; }
static void I2D(Dir *d, Share *sp, char *path, FInfo *fi) { char *name; if((name = strrchr(fi->name, '\\')) != nil) name++; else name = fi->name; d->name = estrdup9p(name); d->type = 'C'; d->dev = sp->tid; d->uid = estrdup9p("bill"); d->gid = estrdup9p("trog"); d->muid = estrdup9p("boyd"); d->atime = fi->accessed; d->mtime = fi->written; if(fi->attribs & ATTR_READONLY) d->mode = 0444; else d->mode = 0666; d->length = fi->size; d->qid = mkqid(path, fi->attribs & ATTR_DIRECTORY, fi->changed, 0, 0); if(fi->attribs & ATTR_DIRECTORY){ d->length = 0; d->mode |= DMDIR|0111; } }
static int pipegen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp) { Qid q; int len; Pipe *p; if(i == DEVDOTDOT){ devdir(c, c->qid, "#|", 0, eve, DMDIR|0555, dp); return 1; } i++; /* skip . */ if(tab==0 || i>=ntab) return -1; tab += i; p = c->aux; switch((ulong)tab->qid.path){ case Qdata0: len = qlen(p->q[0]); break; case Qdata1: len = qlen(p->q[1]); break; default: len = tab->length; break; } mkqid(&q, NETQID(NETID(c->qid.path), tab->qid.path), 0, QTFILE); devdir(c, q, tab->name, len, eve, p->perm, dp); return 1; }
static int ip2gen(Chan *c, int i, Dir *dp) { Qid q; switch(i) { case Qclone: mkqid(&q, QID(PROTO(c->qid), 0, Qclone), 0, QTFILE); devdir(c, q, "clone", 0, network, 0666, dp); return 1; case Qstats: mkqid(&q, QID(PROTO(c->qid), 0, Qstats), 0, QTFILE); devdir(c, q, "stats", 0, network, 0444, dp); return 1; } return -1; }
static struct chan *rootattach(char *spec) { struct chan *c; if (*spec) error(EINVAL, ERROR_FIXME); c = devattach(devname(), spec); mkqid(&c->qid, roottab[0].qid.path, roottab[0].qid.vers, QTDIR); return c; }
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; }
static Chan * cmdattach(char *spec) { Chan *c; if(cmd.conv == nil) error(Enomem); c = devattach('C', spec); mkqid(&c->qid, QID(0, Qtopdir), 0, QTDIR); return c; }
static Chan* srvattach(char *spec) { Chan *c; SrvFile *d; char srvname[16]; qlock(&dev.l); if(waserror()){ qunlock(&dev.l); nexterror(); } if(spec[0] != '\0'){ for(d = dev.devices; d != nil; d = d->devlist){ if(strcmp(spec, d->spec) == 0){ if(!srvcanattach(d)) error(Eperm); c = devattach('s', spec); c->aux = d; c->qid = d->qid; d->ref++; poperror(); qunlock(&dev.l); return c; } } } d = malloc(sizeof(SrvFile)); if(d == nil) error(Enomem); d->ref = 1; kstrdup(&d->spec, spec); kstrdup(&d->user, up->env->user); snprint(srvname, sizeof(srvname), "srv%ld", up->env->pgrp->pgrpid); kstrdup(&d->name, srvname); d->perm = DMDIR|0770; mkqid(&d->qid, dev.pathgen++, 0, QTDIR); d->devlist = dev.devices; dev.devices = d; poperror(); qunlock(&dev.l); c = devattach('s', spec); c->aux = d; c->qid = d->qid; return c; }
static Chan* aoeattach(char *spec) { Chan *c; if(*spec) error(Enonexist); aoeinit(); c = devattach(L'æ', spec); mkqid(&c->qid, Qzero, 0, QTDIR); return c; }
static int sd1gen(Chan* c, int i, Dir* dp) { Qid q; switch(i){ case Qtopctl: mkqid(&q, QID(0, 0, 0, Qtopctl), 0, QTFILE); devdir(c, q, "sdctl", 0, eve, 0644, dp); /* no secrets */ return 1; } return -1; }
static int flashgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) { Qid q; char *n; if(s == DEVDOTDOT){ mkqid(&q, QID(0, Qtopdir), 0, QTDIR); n = "#F"; if(c->dev != 0){ snprint(up->genbuf, sizeof up->genbuf, "#F%ld", c->dev); n = up->genbuf; } devdir(c, q, n, 0, eve, 0555, dp); return 1; } switch(TYPE(c->qid.path)){ case Qtopdir: if(s != 0) break; mkqid(&q, QID(0, Qflashdir), 0, QTDIR); n = "flash"; if(c->dev != 0){ snprint(up->genbuf, sizeof up->genbuf, "flash%ld", c->dev); n = up->genbuf; } devdir(c, q, n, 0, eve, 0555, dp); return 1; case Qflashdir: if(s >= 2*nelem(flash.card[c->dev]->part)) return -1; return flash2gen(c, QID(s>>1, s&1?Qctl:Qdata), dp); case Qctl: case Qdata: return flash2gen(c, (ulong)c->qid.path, dp); } return -1; }
static void fillstat(Dir *dir, char *name, int type, int path, ulong perm) { dir->name = estrdup(name); dir->uid = estrdup(owner); dir->gid = estrdup(owner); dir->mode = perm; dir->length = 0; dir->qid = mkqid(type, path); dir->atime = time(0); dir->mtime = time(0); dir->muid = estrdup(""); }