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 srvgen(Chan *c, char *name, Dirtab *tab, int ntab, int s, Dir *dp) { SrvFile *f; USED(name); USED(tab); USED(ntab); if(s == DEVDOTDOT){ devdir(c, c->qid, "#s", 0, eve, 0555, dp); return 1; } f = c->aux; if((c->qid.type & QTDIR) == 0){ if(s > 0) return -1; devdir(c, f->qid, f->name, f->length, f->user, f->perm, dp); return 1; } for(f = f->entry; f != nil; f = f->entry){ if(s-- == 0) break; } if(f == nil) return -1; devdir(c, f->qid, f->name, f->length, f->user, f->perm, dp); return 1; }
static int pipegen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp) { int id, len; Qid qid; Pipe *p; USED(name); if(i == DEVDOTDOT){ devdir(c, c->qid, "#|", 0, eve, 0555, dp); return 1; } i++; /* skip . */ if(tab==0 || i>=ntab) return -1; tab += i; p = c->aux; switch(NETTYPE(tab->qid.path)){ case Qdata0: len = qlen(p->q[0]); break; case Qdata1: len = qlen(p->q[1]); break; default: len = tab->length; break; } id = NETID(c->qid.path); qid.path = NETQID(id, tab->qid.path); qid.vers = 0; qid.type = QTFILE; devdir(c, qid, tab->name, len, eve, tab->perm, dp); return 1; }
static int envgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp) { Egrp *eg; Evalue *e; if(s == DEVDOTDOT){ devdir(c, c->qid, "#e", 0, eve, DMDIR|0775, dp); return 1; } eg = envgrp(c); rlock(eg); if(name != nil) e = envlookup(eg, name, -1); else if(s < eg->nent) e = &eg->ent[s]; else e = nil; if(e == nil || name != nil && (strlen(e->name) >= sizeof(up->genbuf))) { runlock(eg); return -1; } /* make sure name string continues to exist after we release lock */ kstrcpy(up->genbuf, e->name, sizeof up->genbuf); devdir(c, e->qid, up->genbuf, e->len, eve, 0666, dp); runlock(eg); return 1; }
static int pipestat(struct chan *c, uint8_t * db, int n) { Pipe *p; struct dir dir; struct dirtab *tab; int perm; p = c->aux; tab = p->pipedir; switch (NETTYPE(c->qid.path)) { case Qdir: devdir(c, c->qid, ".", 0, eve, DMDIR | 0555, &dir); break; case Qdata0: perm = tab[1].perm; perm |= qreadable(p->q[0]) ? DMREADABLE : 0; perm |= qwritable(p->q[0]) ? DMWRITABLE : 0; devdir(c, c->qid, tab[1].name, qlen(p->q[0]), eve, perm, &dir); break; case Qdata1: perm = tab[2].perm; perm |= qreadable(p->q[1]) ? DMREADABLE : 0; perm |= qwritable(p->q[1]) ? DMWRITABLE : 0; devdir(c, c->qid, tab[2].name, qlen(p->q[1]), eve, perm, &dir); break; default: panic("pipestat"); } n = convD2M(&dir, db, n); if (n < BIT16SZ) error(ENODATA, ERROR_FIXME); return n; }
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; }
static int envgen(Chan *c, char *name, Dirtab *d, int nd, int s, Dir *dp) { Egrp *eg; Evalue *e; USED(name); USED(d); USED(nd); if(s == DEVDOTDOT){ devdir(c, c->qid, "#e", 0, eve, DMDIR|0775, dp); return 1; } eg = up->env->egrp; qlock(&eg->l); for(e = eg->entries; e != nil && s != 0; e = e->next) s--; if(e == nil) { qunlock(&eg->l); return -1; } /* make sure name string continues to exist after we release lock */ kstrcpy(up->genbuf, e->var, sizeof up->genbuf); devdir(c, e->qid, up->genbuf, e->len, eve, 0666, dp); qunlock(&eg->l); return 1; }
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 pipestat(Chan *c, uchar *db, int n) { Pipe *p; Dir dir; p = c->aux; switch(NETTYPE(c->qid.path)){ case Qdir: devdir(c, c->qid, ".", 0, eve, DMDIR|0555, &dir); break; case Qdata0: devdir(c, c->qid, "data", qlen(p->q[0]), eve, p->perm, &dir); break; case Qdata1: devdir(c, c->qid, "data1", qlen(p->q[1]), eve, p->perm, &dir); break; default: panic("pipestat"); } n = convD2M(&dir, db, n); if(n < BIT16SZ) error(Eshortstat); return n; }
static int envgen(Chan *c, char *name, Dirtab* dir, int i, int s, Dir *dp) { Proc *up = externup(); Egrp *eg; Evalue *e; if(s == DEVDOTDOT){ devdir(c, c->qid, "#e", 0, eve, DMDIR|0775, dp); return 1; } eg = envgrp(c); rlock(&eg->rwl); e = 0; if(name) e = envlookup(eg, name, -1); else if(s < eg->nent) e = eg->ent[s]; if(e == 0) { runlock(&eg->rwl); return -1; } /* make sure name string continues to exist after we release lock */ kstrcpy(up->genbuf, e->name, sizeof up->genbuf); devdir(c, e->qid, up->genbuf, e->len, eve, 0666, dp); runlock(&eg->rwl); 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; } }
static int vcongen(Chan *c, char *d, Dirtab* dir, int i, int s, Dir *dp) { Proc *up = externup(); Qid q; int t = TYPE(c->qid); int vdidx = DEV(c->qid); if(vdidx >= nvcon) error(Ebadarg); switch(t){ case Qtopdir: if(s == DEVDOTDOT){ q = (Qid){QID(0, Qtopdir), 0, QTDIR}; snprint(up->genbuf, sizeof up->genbuf, "#%C", vcondevtab.dc); devdir(c, q, up->genbuf, 0, eve, DMDIR|0555, dp); return 1; } return devgen(c, nil, topdir, nelem(topdir), s, dp); case Qvirtcon: if(s == DEVDOTDOT){ q = (Qid){QID(0, Qtopdir), 0, QTDIR}; snprint(up->genbuf, sizeof up->genbuf, "#%C", vcondevtab.dc); devdir(c, q, up->genbuf, 0, eve, DMDIR|0555, dp); return 1; } if(s >= nvcon) return -1; snprint(up->genbuf, sizeof up->genbuf, vcons[s]->devname); q = (Qid) {QID(s, Qvcpipe), 0, 0}; devdir(c, q, up->genbuf, 0, eve, 0666, dp); return 1; } return -1; }
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 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 rootgen(Chan *c, char *name, Dirtab *dt, int i, int s, Dir *dp) { int t; Dirtab *d; Dirlist *l; switch((int)c->qid.path){ case Qdir: if(s == DEVDOTDOT){ devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp); return 1; } return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp); case Qboot: if(s == DEVDOTDOT){ devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp); return 1; } return devgen(c, name, bootlist.dir, bootlist.ndir, s, dp); default: if(s == DEVDOTDOT){ if((int)c->qid.path < Qboot) devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp); else devdir(c, (Qid){Qboot, 0, QTDIR}, "#/", 0, eve, 0555, dp); return 1; } if(s != 0) return -1; if((int)c->qid.path < Qboot){ t = c->qid.path-1; l = &rootlist; }else{ t = c->qid.path - Qboot - 1; l = &bootlist; } if(t >= l->ndir) return -1; if(t < 0){ print("rootgen %llud %d %d\n", c->qid.path, s, t); panic("whoops"); } d = &l->dir[t]; devdir(c, d->qid, d->name, d->length, eve, d->perm, dp); return 1; } }
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; }
/* * the zeroth element of the table MUST be the directory itself for .. */ int devgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp) { if (0) print_func_entry(); if(tab == 0) { if (0) print_func_exit(); return -1; } if(i == DEVDOTDOT){ /* nothing */ }else if(name){ for(i=1; i<ntab; i++) if(strcmp(tab[i].name, name) == 0) break; if(i==ntab) { if (0) print_func_exit(); return -1; } tab += i; }else{ /* skip over the first element, that for . itself */ i++; if(i >= ntab) { if (0) print_func_exit(); return -1; } tab += i; } devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); if (0) print_func_exit(); 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; }
int pmcgen(Chan *c, char *name, Dirtab* dir, int j, int s, Dir *dp) { int t, i, n; Dirtab *l, *d; if(s == DEVDOTDOT){ devdir(c, (Qid){Qdir, 0, QTDIR}, "#ε", 0, eve, 0555, dp); c->aux = nil; return 1; } /* first, for directories, generate children */ switch((int)PMCTYPE(c->qid.path)){ case Qdir: return devgen(c, name, toptab, ntoptab, s, dp); case Qctr: return devgen(c, name, pmctab, npmctab, s, dp); case Qcore: c->aux = (void *)PMCID(c->qid.path); /* core no */ return devgen(c, name, pmctab, npmctab, s, dp); default: if(s != 0) return -1; t = PMCTYPE(c->qid.path); if(t < Qctr){ i = t; l = toptab; n = ntoptab; }else{ i = PMCID(t); if (t == Qctl) i += (npmctab - 1)/2; l = pmctab; n = npmctab; } if(i >=n) return -1; d = &l[i]; devdir(c, d->qid, d->name, d->length, eve, d->perm, dp); return 1; } }
static int acpigen(Chan *c, char* d, Dirtab *tab, int ntab, int i, Dir *dp) { Qid qid; if(i == DEVDOTDOT){ mkqid(&qid, Qdir, 0, QTDIR); devdir(c, qid, ".", 0, eve, 0555, dp); return 1; } i++; /* skip first element for . itself */ if(tab==0 || i>=ntab) return -1; tab += i; qid = tab->qid; qid.path &= ~Qdir; qid.vers = 0; devdir(c, qid, tab->name, tab->length, eve, tab->perm, dp); return 1; }
static int pcmgen(Chan *c, char*, Dirtab *, int , int i, Dir *dp) { int slotno; Qid qid; long len; PCMslot *pp; if(i == DEVDOTDOT){ mkqid(&qid, Qdir, 0, QTDIR); devdir(c, qid, "#y", 0, eve, 0555, dp); return 1; } if(i >= Nents*nslot) return -1; slotno = i/Nents; pp = slot + slotno; len = 0; switch(i%Nents){ case 0: qid.path = QID(slotno, Qmem); snprint(up->genbuf, sizeof up->genbuf, "pcm%dmem", slotno); len = pp->memlen; break; case 1: qid.path = QID(slotno, Qattr); snprint(up->genbuf, sizeof up->genbuf, "pcm%dattr", slotno); len = pp->memlen; break; case 2: qid.path = QID(slotno, Qctl); snprint(up->genbuf, sizeof up->genbuf, "pcm%dctl", slotno); break; } qid.vers = 0; qid.type = QTFILE; devdir(c, qid, up->genbuf, len, eve, 0660, dp); 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 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 rootgen(Chan *c, char *name, Dirtab *tab, int nd, int s, Dir *dp) { int p, i; Rootdata *r; if(s == DEVDOTDOT){ p = rootdata[c->qid.path].dotdot; c->qid.path = p; c->qid.type = QTDIR; name = "#/"; if(p != 0){ for(i = 0; i < rootmaxq; i++) if(roottab[i].qid.path == c->qid.path){ name = roottab[i].name; break; } } devdir(c, c->qid, name, 0, eve, 0555, dp); return 1; } if(name != nil){ isdir(c); r = &rootdata[(int)c->qid.path]; tab = r->ptr; for(i=0; i<r->size; i++, tab++) if(strcmp(tab->name, name) == 0){ devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); return 1; } return -1; } if(s >= nd) return -1; tab += s; devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); return 1; }
static int lptgen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp) { Qid qid; if(i == DEVDOTDOT){ mkqid(&qid, Qdir, 0, QTDIR); devdir(c, qid, ".", 0, eve, 0555, dp); return 1; } i++; /* skip first element for . itself */ if(tab==0 || i>=ntab) return -1; tab += i; qid = tab->qid; qid.path &= ~Qdir; if(qid.path < Qdata) qid.path += lptbase[c->dev]; qid.vers = c->dev; snprint(up->genbuf, sizeof up->genbuf, "lpt%lud%s", c->dev+1, tab->name); devdir(c, qid, up->genbuf, tab->length, eve, tab->perm, dp); return 1; }
static int ip3gen(Chan *c, int i, Dir *dp) { Qid q; Conv *cv; char *p; cv = ipfs[c->dev]->p[PROTO(c->qid)]->conv[CONV(c->qid)]; if(cv->owner == nil) kstrdup(&cv->owner, eve); mkqid(&q, QID(PROTO(c->qid), CONV(c->qid), i), 0, QTFILE); switch(i) { default: return -1; case Qctl: devdir(c, q, "ctl", 0, cv->owner, cv->perm, dp); return 1; case Qdata: devdir(c, q, "data", 0, cv->owner, cv->perm, dp); return 1; case Qlisten: devdir(c, q, "listen", 0, cv->owner, cv->perm, dp); return 1; case Qlocal: p = "local"; break; case Qremote: p = "remote"; break; case Qstatus: p = "status"; break; } devdir(c, q, p, 0, cv->owner, 0444, dp); return 1; }
int devstat(struct chan *c, uint8_t * db, int n, struct dirtab *tab, int ntab, Devgen * gen) { int i; struct dir dir; char *p, *elem; dir.qid.path = 0; for (i = 0;; i++) switch ((*gen) (c, NULL, tab, ntab, i, &dir)) { case -1: if (c->qid.type & QTDIR) { printd("DEVSTAT got a dir: %llu\n", c->qid.path); if (c->name == NULL) elem = "???"; else if (strcmp(c->name->s, "/") == 0) elem = "/"; else for (elem = p = c->name->s; *p; p++) if (*p == '/') elem = p + 1; devdir(c, c->qid, elem, 0, eve, DMDIR | 0555, &dir); n = convD2M(&dir, db, n); if (n == 0) error(Ebadarg); return n; } printd("DEVSTAT fails:%c %llu\n", devtab[c->type].dc, c->qid.path); set_errno(ENOENT); error(Enonexist); case 0: printd("DEVSTAT got 0\n"); break; case 1: printd("DEVSTAT gen returns path %p name %s, want path %p\n", dir.qid.path, dir.name, c->qid.path); if (c->qid.path == dir.qid.path) { if (c->flag & CMSG) dir.mode |= DMMOUNT; n = convD2M(&dir, db, n); if (n == 0) error(Ebadarg); return n; } break; } }
static int unitgen(Chan *c, ulong type, Dir *dp) { int perm, t; ulong vers; vlong size; char *p; Aoedev *d; Qid q; d = unit2dev(UNIT(c->qid)); perm = 0644; size = 0; vers = d->vers; t = QTFILE; switch(type){ default: return -1; case Qctl: p = "ctl"; break; case Qdata: p = "data"; perm = 0640; if(UP(d)) size = d->bsize; break; case Qconfig: p = "config"; if(UP(d)) size = d->nconfig; break; case Qident: p = "ident"; if(UP(d)) size = sizeof d->ident; break; case Qdevlinkdir: p = "devlink"; t = QTDIR; perm = 0555; break; } mkqid(&q, QID(UNIT(c->qid), type), vers, t); devdir(c, q, p, size, eve, perm, dp); return 1; }
/* * the zeroth element of the table MUST be the directory itself for .. */ int devgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp) { USED(name); if(tab == 0) return -1; if(i != DEVDOTDOT){ /* skip over the first element, that for . itself */ i++; if(i >= ntab) return -1; tab += i; } devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); return 1; }
int32_t devstat(Chan *c, uint8_t *db, int32_t n, Dirtab *tab, int ntab, Devgen *gen) { if (0) print_func_entry(); int i; Dir dir; char *p, *elem; for(i=0;; i++){ switch((*gen)(c, nil, tab, ntab, i, &dir)){ case -1: if(c->qid.type & QTDIR){ if(c->path == nil) elem = "???"; else if(strcmp(c->path->s, "/") == 0) elem = "/"; else for(elem=p=c->path->s; *p; p++) if(*p == '/') elem = p+1; devdir(c, c->qid, elem, 0, eve, DMDIR|0555, &dir); n = convD2M(&dir, db, n); if(n == 0) error(Ebadarg); if (0) print_func_exit(); return n; } error(Enonexist); case 0: break; case 1: if(c->qid.path == dir.qid.path) { if(c->flag&CMSG) dir.mode |= DMMOUNT; n = convD2M(&dir, db, n); if(n == 0) error(Ebadarg); if (0) print_func_exit(); return n; } break; } } if (0) print_func_exit(); }