Beispiel #1
0
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;
}
Beispiel #2
0
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;
	}
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
int
Fsproto(Fs *f, Proto *p)
{
	if(f->np >= Maxproto)
		return -1;

	p->f = f;

	if(p->ipproto > 0){
		if(f->t2p[p->ipproto] != nil)
			return -1;
		f->t2p[p->ipproto] = p;
	}

	p->qid.type = QTDIR;
	p->qid.path = QID(f->np, 0, Qprotodir);
	p->conv = malloc(sizeof(Conv*)*(p->nc+1));
	if(p->conv == nil)
		panic("Fsproto");

	p->x = f->np;
	f->p[f->np++] = p;

	return 0;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
Chan *
ipattach(char *spec)
{
	Chan *c;

	c = devattach('I', spec);
	c->qid.path = QID(0, 0, Qtopdir);
	c->qid.type = QTDIR;
	c->qid.vers = 0;
	return c;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
Chan *
ipattach(char *spec)
{
	Chan *c;

	if(atoi(spec) != 0)
		error("bad specification");

	c = devattach('I', spec);
	mkqid(&c->qid, QID(0, 0, Qtopdir), 0, QTDIR);
	c->dev = 0;

	return c;
}
Beispiel #13
0
void
ixp_srv_walkandclone(Ixp9Req *req, IxpLookupFn lookup) {
	IxpFileId *file, *tfile;
	int i;

	file = ixp_srv_clonefiles(req->fid->aux);
	for(i=0; i < req->ifcall.twalk.nwname; i++) {
		if(!strcmp(req->ifcall.twalk.wname[i], "..")) {
			if(file->next) {
				tfile = file;
				file = file->next;
				ixp_srv_freefile(tfile);
			}
		}else{
			tfile = lookup(file, req->ifcall.twalk.wname[i]);
			if(!tfile)
				break;
			assert(!tfile->next);
			if(strcmp(req->ifcall.twalk.wname[i], ".")) {
				tfile->next = file;
				file = tfile;
			}
		}
		req->ofcall.rwalk.wqid[i].type = file->tab.qtype;
		req->ofcall.rwalk.wqid[i].path = QID(file->tab.type, file->id);
	}
	/* There should be a way to do this on freefid() */
	if(i < req->ifcall.twalk.nwname) {
		while((tfile = file)) {
			file=file->next;
			ixp_srv_freefile(tfile);
		}
		ixp_respond(req, Enofile);
		return;
	}
	/* Remove refs for req->fid if no new fid */
	if(req->ifcall.hdr.fid == req->ifcall.twalk.newfid) {
		tfile = req->fid->aux;
		req->fid->aux = file;
		while((file = tfile)) {
			tfile = tfile->next;
			ixp_srv_freefile(file);
		}
	}else
		req->newfid->aux = file;
	req->ofcall.rwalk.nwqid = i;
	ixp_respond(req, nil);
}
Beispiel #14
0
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;
}
Beispiel #15
0
static int
ip1gen(Chan *c, int i, Dir *dp)
{
	Qid q;
	char *p;
	int prot;
	int len = 0;
	Fs *f;
	extern ulong	kerndate;

	f = ipfs[c->dev];

	prot = 0666;
	mkqid(&q, QID(0, 0, i), 0, QTFILE);
	switch(i) {
	default:
		return -1;
	case Qarp:
		p = "arp";
		prot = 0664;
		break;
	case Qbootp:
		p = "bootp";
		break;
	case Qndb:
		p = "ndb";
		len = strlen(f->ndb);
		q.vers = f->ndbvers;
		break;
	case Qiproute:
		p = "iproute";
		prot = 0664;
		break;
	case Qipselftab:
		p = "ipselftab";
		prot = 0444;
		break;
	case Qlog:
		p = "log";
		break;
	}
	devdir(c, q, p, len, network, prot, dp);
	if(i == Qndb && f->ndbmtime > kerndate)
		dp->mtime = f->ndbmtime;
	return 1;
}
Beispiel #16
0
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", qlen(cv->rq), cv->owner, cv->perm, dp);
		return 1;
	case Qerr:
		devdir(c, q, "err", qlen(cv->eq), 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 Qsnoop:
		if(strcmp(cv->p->name, "ipifc") != 0)
			return -1;
		devdir(c, q, "snoop", qlen(cv->sq), cv->owner, 0400, dp);
		return 1;
	case Qstatus:
		p = "status";
		break;
	}
	devdir(c, q, p, 0, cv->owner, 0444, dp);
	return 1;
}
Beispiel #17
0
int
dostat(int id, Dirtab *dir, uint8_t *buf, int nbuf, uint clock)
{
    Dir d;

    d.qid.path = QID(id, dir->qid);
    d.qid.vers = 0;
    d.qid.type = dir->type;
    d.mode = dir->perm;
    d.length = 0;	/* would be nice to do better */
    d.name = dir->name;
    d.uid = user;
    d.gid = user;
    d.muid = user;
    d.atime = clock;
    d.mtime = clock;
    return convD2M(&d, buf, nbuf);
}
Beispiel #18
0
static int
efilegen(Chan *c, SDunit *unit, int i, Dir *dp)
{
	Qid q;
	SDfile *e;

	i -= SDnpart;
	if(unit->nefile == 0 || i >= unit->nefile)
		return -1;
	if(i < 0)
		return 0;
	e = unit->efile + i;
	if(emptystr(e->user))
		kstrdup(&e->user, eve);
	mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), i, Qextra),
		unit->vers, QTFILE);
	devdir(c, q, e->name, 0, e->user, e->perm, dp);
	return 1;
}
Beispiel #19
0
static Chan*
ipattach(char* spec)
{
	Chan *c;
	int dev;

	dev = atoi(spec);
	if(dev >= Nfs)
		error("bad specification");

	ipgetfs(dev);
	c = devattach('I', spec);
	mkqid(&c->qid, QID(0, 0, Qtopdir), 0, QTDIR);
	c->dev = dev;

	c->aux = newipaux(commonuser(), "none");

	return c;
}
Beispiel #20
0
static
int
dostat(Filsys *fs, int id, Dirtab *dir, uint8_t *buf, int nbuf, uint clock)
{
	Dir d;

	d.qid.path = QID(id, dir->qid);
	if(dir->qid == Qsnarf)
		d.qid.vers = snarfversion;
	else
		d.qid.vers = 0;
	d.qid.type = dir->type;
	d.mode = dir->perm;
	d.length = 0;	/* would be nice to do better */
	d.name = dir->name;
	d.uid = fs->user;
	d.gid = fs->user;
	d.muid = fs->user;
	d.atime = clock;
	d.mtime = clock;
	return convD2M(&d, buf, nbuf);
}
Beispiel #21
0
static int
sd1gen(Chan* c, int i, Dir* dp)
{
	Qid q;
	SDperm *p;

	switch(i){
	case Qtopctl:
		mkqid(&q, QID(0, 0, 0, Qtopctl), 0, QTFILE);
		qlock(&topctlunit.ctl);
		p = &topctlunit.ctlperm;
		if(p->user == nil || p->user[0] == 0){
			kstrdup(&p->name, "sdctl");
			kstrdup(&p->user, eve);
			p->perm = 0640;
		}
		devdir(c, q, p->name, 0, p->user, p->perm, dp);
		qunlock(&topctlunit.ctl);
		return 1;
	}
	return -1;
}
Beispiel #22
0
static void
progclose(Chan *c)
{
	int i;
	Prog *f;
	Osenv *o;
	Progctl *ctl;

	switch(QID(c->qid)) {
	case Qns:
	case Qheap:
		free(c->aux);
		break;
	case Qdbgctl:
		if((c->flag & COPEN) == 0)
			return;
		ctl = c->aux;
		acquire();
		closedbgctl(ctl, progpid(PID(c->qid)));
		release();
		break;
	case Qwait:
		acquire();
		i = 0;
		for(;;) {
			f = progn(i++);
			if(f == nil)
				break;
			o = f->osenv;
			if(o->waitq == c->aux)
				o->waitq = nil;
			if(o->childq == c->aux)
				o->childq = nil;
		}
		release();
		qfree(c->aux);
	}
}
Beispiel #23
0
static void
newproto(char *name, int type, int maxconv)
{
	int l;
	Proto *p;

	if(np >= MAXPROTO) {
		print("no %s: increase MAXPROTO", name);
		return;
	}

	p = &proto[np];
	strcpy(p->name, name);
	p->stype = type;
	p->qid.path = QID(np, 0, Qprotodir);
	p->qid.type = QTDIR;
	p->x = np++;
	p->maxconv = maxconv;
	l = sizeof(Conv*)*(p->maxconv+1);
	p->conv = mallocz(l, 1);
	if(p->conv == 0)
		panic("no memory");
}
Beispiel #24
0
static
Xfid*
fsysread(Xfid *x, Fid *f)
{
    Fcall t;
    uint8_t *b;
    int i, id, n, o, e, j, k, *ids, nids;
    Dirtab *d, dt;
    Column *c;
    uint clock, len;
    char buf[16];

    if(f->qid.type & QTDIR) {
        if(FILE(f->qid) == Qacme) {	/* empty dir */
            t.data = nil;
            t.count = 0;
            respond(x, &t, nil);
            return x;
        }
        o = x->offset;
        e = x->offset+x->count;
        clock = getclock();
        b = emalloc(messagesize);
        id = WIN(f->qid);
        n = 0;
        if(id > 0)
            d = dirtabw;
        else
            d = dirtab;
        d++;	/* first entry is '.' */
        for(i=0; d->name!=nil && i<e; i+=len) {
            len = dostat(WIN(x->f->qid), d, b+n, x->count-n, clock);
            if(len <= BIT16SZ)
                break;
            if(i >= o)
                n += len;
            d++;
        }
        if(id == 0) {
            qlock(&row);
            nids = 0;
            ids = nil;
            for(j=0; j<row.ncol; j++) {
                c = row.col[j];
                for(k=0; k<c->nw; k++) {
                    ids = erealloc(ids, (nids+1)*sizeof(int));
                    ids[nids++] = c->w[k]->id;
                }
            }
            qunlock(&row);
            qsort(ids, nids, sizeof ids[0], idcmp);
            j = 0;
            dt.name = buf;
            for(; j<nids && i<e; i+=len) {
                k = ids[j];
                sprint(dt.name, "%d", k);
                dt.qid = QID(k, Qdir);
                dt.type = QTDIR;
                dt.perm = DMDIR|0700;
                len = dostat(k, &dt, b+n, x->count-n, clock);
                if(len == 0)
                    break;
                if(i >= o)
                    n += len;
                j++;
            }
            free(ids);
        }
        t.data = (char*)b;
        t.count = n;
        respond(x, &t, nil);
        free(b);
        return x;
    }
    sendp(x->c, xfidread);
    return nil;
}
Beispiel #25
0
static
Xfid*
fsyswalk(Xfid *x, Fid *f)
{
    Fcall t;
    int c, i, j, id;
    Qid q;
    uint8_t type;
    uint32_t path;
    Fid *nf;
    Dirtab *d, *dir;
    Window *w;
    char *err;

    nf = nil;
    w = nil;
    if(f->open)
        return respond(x, &t, "walk of open file");
    if(x->fid != x->newfid) {
        nf = newfid(x->newfid);
        if(nf->busy)
            return respond(x, &t, "newfid already in use");
        nf->busy = TRUE;
        nf->open = FALSE;
        nf->mntdir = f->mntdir;
        if(f->mntdir)
            f->mntdir->ref++;
        nf->dir = f->dir;
        nf->qid = f->qid;
        nf->w = f->w;
        nf->nrpart = 0;	/* not open, so must be zero */
        if(nf->w)
            incref(nf->w);
        f = nf;	/* walk f */
    }

    t.nwqid = 0;
    err = nil;
    dir = nil;
    id = WIN(f->qid);
    q = f->qid;

    if(x->nwname > 0) {
        for(i=0; i<x->nwname; i++) {
            if((q.type & QTDIR) == 0) {
                err = Enotdir;
                break;
            }

            if(strcmp(x->wname[i], "..") == 0) {
                type = QTDIR;
                path = Qdir;
                id = 0;
                if(w) {
                    winclose(w);
                    w = nil;
                }
Accept:
                if(i == MAXWELEM) {
                    err = "name too long";
                    break;
                }
                q.type = type;
                q.vers = 0;
                q.path = QID(id, path);
                t.wqid[t.nwqid++] = q;
                continue;
            }

            /* is it a numeric name? */
            for(j=0; (c=x->wname[i][j]); j++)
                if(c<'0' || '9'<c)
                    goto Regular;
            /* yes: it's a directory */
            if(w)	/* name has form 27/23; get out before losing w */
                break;
            id = atoi(x->wname[i]);
            qlock(&row);
            w = lookid(id, FALSE);
            if(w == nil) {
                qunlock(&row);
                break;
            }
            incref(w);	/* we'll drop reference at end if there's an error */
            path = Qdir;
            type = QTDIR;
            qunlock(&row);
            dir = dirtabw;
            goto Accept;

Regular:
//			if(FILE(f->qid) == Qacme)	/* empty directory */
//				break;
            if(strcmp(x->wname[i], "new") == 0) {
                if(w)
                    error("w set in walk to new");
                sendp(cnewwindow, nil);	/* signal newwindowthread */
                w = recvp(cnewwindow);	/* receive new window */
                incref(w);
                type = QTDIR;
                path = QID(w->id, Qdir);
                id = w->id;
                dir = dirtabw;
                goto Accept;
            }

            if(id == 0)
                d = dirtab;
            else
                d = dirtabw;
            d++;	/* skip '.' */
            for(; d->name; d++)
                if(strcmp(x->wname[i], d->name) == 0) {
                    path = d->qid;
                    type = d->type;
                    dir = d;
                    goto Accept;
                }

            break;	/* file not found */
        }

        if(i==0 && err == nil)
            err = Eexist;
    }

    if(err!=nil || t.nwqid<x->nwname) {
        if(nf) {
            nf->busy = FALSE;
            fsysdelid(nf->mntdir);
        }
    } else if(t.nwqid  == x->nwname) {
        if(w) {
            f->w = w;
            w = nil;	/* don't drop the reference */
        }
        if(dir)
            f->dir = dir;
        f->qid = q;
    }

    if(w != nil)
        winclose(w);

    return respond(x, &t, err);
}
Beispiel #26
0
static int
loopbackgen(Chan *c, char*, Dirtab*, int, int i, Dir *dp)
{
	Dirtab *tab;
	int len, type;
	Qid qid;

	type = TYPE(c->qid.path);
	if(i == DEVDOTDOT){
		switch(type){
		case Qtopdir:
		case Qloopdir:
			snprint(up->genbuf, sizeof(up->genbuf), "#X%ld", c->dev);
			mkqid(&qid, QID(0, Qtopdir), 0, QTDIR);
			devdir(c, qid, up->genbuf, 0, eve, 0555, dp);
			break;
		case Qportdir:
			snprint(up->genbuf, sizeof(up->genbuf), "loopback%ld", c->dev);
			mkqid(&qid, QID(0, Qloopdir), 0, QTDIR);
			devdir(c, qid, up->genbuf, 0, eve, 0555, dp);
			break;
		default:
			panic("loopbackgen %llux", c->qid.path);
		}
		return 1;
	}

	switch(type){
	case Qtopdir:
		if(i != 0)
			return -1;
		snprint(up->genbuf, sizeof(up->genbuf), "loopback%ld", c->dev);
		mkqid(&qid, QID(0, Qloopdir), 0, QTDIR);
		devdir(c, qid, up->genbuf, 0, eve, 0555, dp);
		return 1;
	case Qloopdir:
		if(i >= 2)
			return -1;
		snprint(up->genbuf, sizeof(up->genbuf), "%d", i);
		mkqid(&qid, QID(i, QID(0, Qportdir)), 0, QTDIR);
		devdir(c, qid, up->genbuf, 0, eve, 0555, dp);
		return 1;
	case Qportdir:
		if(i >= nelem(loopportdir))
			return -1;
		tab = &loopportdir[i];
		mkqid(&qid, QID(ID(c->qid.path), tab->qid.path), 0, QTFILE);
		devdir(c, qid, tab->name, tab->length, eve, tab->perm, dp);
		return 1;
	default:
		/* non directory entries end up here; must be in lowest level */
		if(c->qid.type & QTDIR)
			panic("loopbackgen: unexpected directory");	
		if(i != 0)
			return -1;
		tab = &loopdirs[type];
		if(tab == nil)
			panic("loopbackgen: unknown type: %d", type);
		len = tab->length;
		devdir(c, c->qid, tab->name, len, eve, tab->perm, dp);
		return 1;
	}
}
Beispiel #27
0
static Chan*
loopbackattach(char *spec)
{
	Loop *volatile lb;
	Queue *q;
	Chan *c;
	int chan;
	int dev;

	dev = 0;
	if(spec != nil){
		dev = atoi(spec);
		if(dev >= Nloopbacks)
			error(Ebadspec);
	}

	c = devattach('X', spec);
	if(waserror()){
		chanfree(c);
		nexterror();
	}

	lb = &loopbacks[dev];
	qlock(lb);
	if(waserror()){
		lb->ref--;
		qunlock(lb);
		nexterror();
	}

	lb->ref++;
	if(lb->ref == 1){
		for(chan = 0; chan < 2; chan++){
			lb->link[chan].ci.mode = Trelative;
			lb->link[chan].ci.a = &lb->link[chan];
			lb->link[chan].ci.f = linkintr;
			lb->link[chan].limit = Loopqlim;
			q = qopen(lb->link[chan].limit, 0, 0, 0);
			lb->link[chan].iq = q;
			if(q == nil){
				freelb(lb);
				exhausted("memory");
			}
			q = qopen(lb->link[chan].limit, 0, 0, 0);
			lb->link[chan].oq = q;
			if(q == nil){
				freelb(lb);
				exhausted("memory");
			}
			lb->link[chan].indrop = 1;

			lb->link[chan].delaynns = Delayn;
			lb->link[chan].delay0ns = Delay0;
		}
	}
	poperror();
	qunlock(lb);

	poperror();

	mkqid(&c->qid, QID(0, Qtopdir), 0, QTDIR);
	c->aux = lb;
	c->dev = dev;
	return c;
}
Beispiel #28
0
static int
aoegen(Chan *c, char *, Dirtab *, int, int s, Dir *dp)
{
	int i;
	Aoedev *d;
	Qid q;

	if(c->qid.path == 0){
		switch(s){
		case DEVDOTDOT:
			q.path = 0;
			q.type = QTDIR;
			devdir(c, q, "#æ", 0, eve, 0555, dp);
			break;
		case 0:
			q.path = Qtopdir;
			q.type = QTDIR;
			devdir(c, q, "aoe", 0, eve, 0555, dp);
			break;
		default:
			return -1;
		}
		return 1;
	}

	switch(TYPE(c->qid)){
	default:
		return -1;
	case Qtopdir:
		if(s == DEVDOTDOT){
			mkqid(&q, Qzero, 0, QTDIR);
			devdir(c, q, "aoe", 0, eve, 0555, dp);
			return 1;
		}
		if(s < Qtopfiles)
			return topgen(c, Qtopbase + s, dp);
		s -= Qtopfiles;
		if(s >= units.ref)
			return -1;
		mkqid(&q, QID(s, Qunitdir), 0, QTDIR);
		d = unit2dev(s);
		assert(d != nil);
		devdir(c, q, unitname(d), 0, eve, 0555, dp);
		return 1;
	case Qtopctl:
	case Qtoplog:
		return topgen(c, TYPE(c->qid), dp);
	case Qunitdir:
		if(s == DEVDOTDOT){
			mkqid(&q, QID(0, Qtopdir), 0, QTDIR);
			uprint("%uld", UNIT(c->qid));
			devdir(c, q, up->genbuf, 0, eve, 0555, dp);
			return 1;
		}
		return unitgen(c, Qunitbase+s, dp);
	case Qctl:
	case Qdata:
	case Qconfig:
	case Qident:
		return unitgen(c, TYPE(c->qid), dp);
	case Qdevlinkdir:
		i = UNIT(c->qid);
		if(s == DEVDOTDOT){
			mkqid(&q, QID(i, Qunitdir), 0, QTDIR);
			devdir(c, q, "devlink", 0, eve, 0555, dp);
			return 1;
		}
		if(i >= units.ref)
			return -1;
		d = unit2dev(i);
		if(s >= d->ndl)
			return -1;
		uprint("%d", s);
		mkqid(&q, Q3(s, i, Qdevlink), 0, QTFILE);
		devdir(c, q, up->genbuf, 0, eve, 0755, dp);
		return 1;
	case Qdevlink:
		uprint("%d", s);
		mkqid(&q, Q3(s, UNIT(c->qid), Qdevlink), 0, QTFILE);
		devdir(c, q, up->genbuf, 0, eve, 0755, dp);
		return 1;
	}
}
Beispiel #29
0
int
devsfgen(Chan *c, char *name, Dirtab *tab, int x, int s, Dir *dp)
{
	int		t;
	Qid		q;
	ulong		path;
	Engine		*E = (Engine *)c->aux;


	USED(name);
	USED(tab);
	USED(x);

	q.vers = 0;

	if (s == DEVDOTDOT)
	{
		switch(QID(c->qid))
		{
		case Qtopdir:
		case Qmroot:
			mkqid(&q, Qtopdir, 0, QTDIR);
			devdir(c, q, "#j", 0, eve, 0500, dp);
			break;
		case Qdir:
			mkqid(&q, Qmroot, 0, QTDIR);
			devdir(c, q, up->genbuf, 0, eve, 0500, dp);
			break;
		default:
			panic("devsunflowerwalk %llux", c->qid.path);
			return -1;
		}
		return 1;
	}


	/*	Top level directory (say, /dev)		*/
        t = QID(c->qid);
	if (t == Qtopdir)
	{
		snprint(mname, MAX_MNAME, "sunflower.%s", E->attachspec);

		switch(s)
		{
		case 0:
			mkqid(&q, Qmroot, 0, QTDIR);
			devdir(c, q, mname, 0, eve, 0555, dp);
			break;
		default:
			return -1;
		}
		return 1;
	}


	/*	Second level (say /dev/sunflower)	*/
        if (t == Qmroot || t == Qmctl || t == Qminfo || t == Qnetin || t == Qnetout)
	{
		switch (s)
		{
		case 0:
			mkqid(&q, Qmctl, 0, QTFILE);
			devdir(c, q, "ctl", 0, eve, 0200, dp);
			break;

		case 1:
			mkqid(&q, Qminfo, 0, QTFILE);
			devdir(c, q, "info", 0, eve, 0400, dp);
			break;

        	case 2:
			mkqid(&q, Qnetin, 0, QTFILE);
                	devdir(c, q, "netin", 0, eve, 0222, dp);
                	break;

        	case 3:
			mkqid(&q, Qnetout, 0, QTFILE);
                	devdir(c, q, "netout", 0, eve, 0444, dp);
                	break;

		default:
			if (s <= 2*E->nnodes+3)
                	{
				int	n = s-4;
				int	id = n >> 1;

				if (n & 1)
				{
					sprint(up->genbuf, "%d.%d",
						(E->sp[id])->NODE_ID,
						(E->sp[id])->runnable);
				}
				else
				{
					sprint(up->genbuf, "%d", (E->sp[id])->NODE_ID);
				}

				mkqid(&q, (id << QSHIFT)|Qdir, 0, QTDIR);
				devdir(c, q, up->genbuf, 0, eve, 0555, dp);
				return 1;
			}
			else
                	{
				return -1;
                	}
		}
Beispiel #30
0
static int
cmdgen(Chan *c, char *name, Dirtab *d, int nd, int s, Dir *dp)
{
	Qid q;
	Conv *cv;

	USED(name);
	USED(nd);
	USED(d);

	if(s == DEVDOTDOT){
		switch(TYPE(c->qid)){
		case Qtopdir:
		case Qcmd:
			mkqid(&q, QID(0, Qtopdir), 0, QTDIR);
			devdir(c, q, "#C", 0, eve, DMDIR|0555, dp);
			break;
		case Qconvdir:
			mkqid(&q, QID(0, Qcmd), 0, QTDIR);
			devdir(c, q, "cmd", 0, eve, DMDIR|0555, dp);
			break;
		default:
			panic("cmdgen %llux", c->qid.path);
		}
		return 1;
	}

	switch(TYPE(c->qid)) {
	case Qtopdir:
		if(s >= 1)
			return -1;
		mkqid(&q, QID(0, Qcmd), 0, QTDIR);
		devdir(c, q, "cmd", 0, "cmd", DMDIR|0555, dp);
		return 1;
	case Qcmd:
		if(s < cmd.nc) {
			cv = cmd.conv[s];
			mkqid(&q, QID(s, Qconvdir), 0, QTDIR);
			sprint(up->genbuf, "%d", s);
			devdir(c, q, up->genbuf, 0, cv->owner, DMDIR|0555, dp);
			return 1;
		}
		s -= cmd.nc;
		if(s == 0){
			mkqid(&q, QID(0, Qclonus), 0, QTFILE);
			devdir(c, q, "clone", 0, "cmd", 0666, dp);
			return 1;
		}
		return -1;
	case Qclonus:
		if(s == 0){
			mkqid(&q, QID(0, Qclonus), 0, QTFILE);
			devdir(c, q, "clone", 0, "cmd", 0666, dp);
			return 1;
		}
		return -1;
	case Qconvdir:
		return cmd3gen(c, Qconvbase+s, dp);
	case Qdata:
	case Qstderr:
	case Qctl:
	case Qstatus:
	case Qwait:
		return cmd3gen(c, TYPE(c->qid), dp);
	}
	return -1;
}