Beispiel #1
0
int32_t
netifwstat(Netif *nif, Chan *c, uint8_t *db, int32_t n)
{
	Proc *up = externup();
	Dir *dir;
	Netfile *f;
	int l;

	f = nif->f[NETID(c->qid.path)];
	if(f == 0)
		error(Enonexist);

	if(netown(f, up->user, OWRITE) < 0)
		error(Eperm);

	dir = smalloc(sizeof(Dir)+n);
	l = convM2D(db, n, &dir[0], (char*)&dir[1]);
	if(l == 0){
		free(dir);
		error(Eshortstat);
	}
	if(!emptystr(dir[0].uid))
		strncpy(f->owner, dir[0].uid, KNAMELEN);
	if(dir[0].mode != (uint32_t)~0UL)
		f->mode = dir[0].mode;
	free(dir);
	return l;
}
Beispiel #2
0
int netifwstat(struct ether *nif, struct chan *c, uint8_t * db, int n)
{
	struct dir *dir;
	struct netfile *f;
	int m;

	f = nif->f[NETID(c->qid.path)];
	if (f == 0) {
		set_errno(ENOENT);
		error(Enonexist);
	}

	if (netown(f, current->user, OWRITE) < 0)
		error(Eperm);

	dir = kzmalloc(sizeof(struct dir) + n, 0);
	m = convM2D(db, n, &dir[0], (char *)&dir[1]);
	if (m == 0) {
		kfree(dir);
		error(Eshortstat);
	}
	if (!emptystr(dir[0].uid))
		strncpy(f->owner, dir[0].uid, KNAMELEN);
	if (dir[0].mode != ~0UL)
		f->mode = dir[0].mode;
	kfree(dir);
	return m;
}
Beispiel #3
0
/*
 *  Increment the reference count of a network device.
 *  If id < 0, return an unused ether device.
 */
static int openfile(struct ether *nif, int id)
{
	ERRSTACK(1);
	struct netfile *f, **fp, **efp;

	if (id >= 0) {
		f = nif->f[id];
		if (f == 0)
			error(Enodev);
		qlock(&f->qlock);
		qreopen(f->in);
		f->inuse++;
		qunlock(&f->qlock);
		return id;
	}

	qlock(&nif->qlock);
	if (waserror()) {
		qunlock(&nif->qlock);
		nexterror();
	}
	efp = &nif->f[nif->nfile];
	for (fp = nif->f; fp < efp; fp++) {
		f = *fp;
		if (f == 0) {
			f = kzmalloc(sizeof(struct netfile), 0);
			if (f == 0)
				exhausted("memory");
			/* since we lock before netifinit (if we ever call that...) */
			qlock_init(&f->qlock);
			f->in = qopen(nif->limit, Qmsg, 0, 0);
			if (f->in == NULL) {
				kfree(f);
				exhausted("memory");
			}
			*fp = f;
			qlock(&f->qlock);
		} else {
			qlock(&f->qlock);
			if (f->inuse) {
				qunlock(&f->qlock);
				continue;
			}
		}
		f->inuse = 1;
		qreopen(f->in);
		netown(f, current->user, 0);
		qunlock(&f->qlock);
		qunlock(&nif->qlock);
		poperror();
		return fp - nif->f;
	}
	error(Enodev);
	return -1;	/* not reached */
}
Beispiel #4
0
/*
 *  Increment the reference count of a network device.
 *  If id < 0, return an unused ether device.
 */
static int
openfile(Netif *nif, int id)
{
	Proc *up = externup();
	Netfile *f, **fp, **efp;

	if(id >= 0){
		f = nif->f[id];
		if(f == 0)
			error(Enodev);
		qlock(&f->q);
		qreopen(f->iq);
		f->inuse++;
		qunlock(&f->q);
		return id;
	}

	qlock(&nif->q);
	if(waserror()){
		qunlock(&nif->q);
		nexterror();
	}
	efp = &nif->f[nif->nfile];
	for(fp = nif->f; fp < efp; fp++){
		f = *fp;
		if(f == 0){
			f = malloc(sizeof(Netfile));
			if(f == 0)
				exhausted("memory");
			f->iq = qopen(nif->limit, Qmsg, 0, 0);
			if(f->iq == nil){
				free(f);
				exhausted("memory");
			}
			*fp = f;
			qlock(&f->q);
		} else {
			qlock(&f->q);
			if(f->inuse){
				qunlock(&f->q);
				continue;
			}
		}
		f->inuse = 1;
		qreopen(f->iq);
		netown(f, up->user, 0);
		qunlock(&f->q);
		qunlock(&nif->q);
		poperror();
		return fp - nif->f;
	}
	error(Enodev);
	return -1;	/* not reached */
}
Beispiel #5
0
Chan*
netifopen(Netif *nif, Chan *c, int omode)
{
	Proc *up = externup();
	int id;
	Netfile *f;

	id = 0;
	if(c->qid.type & QTDIR){
		if(omode != OREAD)
			error(Eperm);
	} else {
		switch(NETTYPE(c->qid.path)){
		case Ndataqid:
		case Nctlqid:
			id = NETID(c->qid.path);
			openfile(nif, id);
			break;
		case Ncloneqid:
			id = openfile(nif, -1);
			c->qid.path = NETQID(id, Nctlqid);
			break;
		default:
			if(omode != OREAD)
				error(Ebadarg);
		}
		switch(NETTYPE(c->qid.path)){
		case Ndataqid:
		case Nctlqid:
			f = nif->f[id];
			if(netown(f, up->user, omode&7) < 0){
				netifclose(nif, c);
				error(Eperm);
			}
			break;
		}
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	c->iounit = qiomaxatomic;
	return c;
}
Beispiel #6
0
struct chan *netifopen(struct ether *nif, struct chan *c, int omode)
{
	int id;
	struct netfile *f;

	id = 0;
	if (c->qid.type & QTDIR) {
		if (!IS_RDONLY(omode))
			error(Eperm);
	} else {
		switch (NETTYPE(c->qid.path)) {
			case Ndataqid:
			case Nctlqid:
				id = NETID(c->qid.path);
				openfile(nif, id);
				break;
			case Ncloneqid:
				id = openfile(nif, -1);
				c->qid.path = NETQID(id, Nctlqid);
				break;
			default:
				if (!IS_RDONLY(omode))
					error(Ebadarg);
		}
		switch (NETTYPE(c->qid.path)) {
			case Ndataqid:
			case Nctlqid:
				f = nif->f[id];
				if (netown(f, current->user, omode & 7) < 0)
					error(Eperm);
				break;
		}
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	c->iounit = qiomaxatomic;
	return c;
}