Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/net.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname port/net.c 1991/1107
## diff -e /dev/null /n/bootesdump/1991/1107/sys/src/9/port/net.c
0a
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"errno.h"

enum
{
	Qlisten=	1,
	Qclone=		2,
	Q2nd=		3,
	Q3rd=		4,
};

/*
 *  generate a 3 level directory
 */
int
netgen(Chan *c, void *vp, int ntab, int i, Dir *dp)
{
	Qid q;
	char buf[32];
	Network *np = vp;

	q.vers = 0;

	/* top level directory contains the name of the network */
	if(c->qid.path == CHDIR){
		switch(i){
		case 0:
			q.path = CHDIR | Q2nd;
			strcpy(buf, np->name);
			devdir(c, q, buf, 0, 0666, dp);
			break;
		default:
			return -1;
		}
		return 1;
	}

	/* second level contains clone plus all the conversations */
	if(c->qid.path == (CHDIR | Q2nd)){
		if(i == 0){
			q.path = Qclone;
			devdir(c, q, "clone", 0, 0666, dp);
		}else if(i < np->nconv){
			q.path = CHDIR|STREAMQID(i, Q3rd);
			sprint(buf, "%d", i);
			devdir(c, q, buf, 0, 0666, dp);
		}else
			return -1;
		return 1;
	}

	if((c->qid.path & CHDIR) == 0)
		return -1;

	/* third level depends on the number of info files */
	switch(i){
	case 0:
		q.path = STREAMQID(STREAMID(c->qid.path), Sdataqid);
		devdir(c, q, "data", 0, 0666, dp);
		break;
	case 1:
		q.path = STREAMQID(STREAMID(c->qid.path), Sctlqid);
		devdir(c, q, "ctl", 0, 0666, dp);
		break;
	case 2:
		if(np->listen == 0)
			return 0;
		q.path = STREAMQID(STREAMID(c->qid.path), Qlisten);
		devdir(c, q, "listen", 0, 0666, dp);
		break;
	default:
		if(i >= 3 + np->ninfo)
			return -1;
		i -= 3;
		q.path = Qlisten + i + 1;
		devdir(c, q, np->info[i].name, 0, 0666, dp);
	}
	return 1;
}

Chan *
netopen(Chan *c, int omode, Network *np)
{
	int conv;

	if(c->qid.path & CHDIR){
		if(omode != OREAD)
			error(Eperm);
	} else {
		switch(STREAMTYPE(c->qid.path)){
		case Sdataqid:
		case Sctlqid:
			break;
		case Qlisten:
			conv = (*np->listen)(c);
			c->qid.path = STREAMQID(conv, Sctlqid);
			break;
		case Qclone:
			conv = (*np->clone)(c);
			c->qid.path = STREAMQID(conv, Sctlqid);
			break;
		default:
			if(omode != OREAD)
				error(Ebadarg);
		}
		switch(STREAMTYPE(c->qid.path)){
		case Sdataqid:
		case Sctlqid:
			streamopen(c, np->devp);
			if(np->protop && c->stream->devq->next->info != np->protop)
				pushq(c->stream, np->protop);
			break;
		}
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

long
netread(Chan *c, void *a, long n, ulong offset, Network *np)
{
	int i;
	char buf[256];

	if(c->stream)
		return streamread(c, a, n);

	if(c->qid.path&CHDIR)
		return devdirread(c, a, n, (Dirtab*)np, 0, netgen);

	if(c->qid.path <= Qlisten || c->qid.path > Qlisten + np->ninfo)
		error(Ebadusefd);

	i = c->qid.path - Qlisten - 1;
	(*np->info[i].fill)(c, buf, sizeof(buf));
	return stringread(c, a, n, buf, offset);
}
.
## diffname port/net.c 1991/1108
## diff -e /n/bootesdump/1991/1107/sys/src/9/port/net.c /n/bootesdump/1991/1108/sys/src/9/port/net.c
140,141c
	(*np->info[t-Qinf].fill)(c, buf, sizeof(buf));
.
137c
	t = STREAMTYPE(c->qid.path);
	if(t < Qinf || t >= Qinf + np->ninfo)
.
128c
	int t;
.
84a
int	 
netwalk(Chan *c, char *name, Network *np)
{
	if(strcmp(name, "..") == 0) {
		switch(STREAMTYPE(c->qid.path)){
		case Q2nd:
			c->qid.path = CHDIR;
			break;
		case Q3rd:
			c->qid.path = CHDIR|Q2nd;
			break;
		default:
			panic("netwalk %lux", c->qid.path);
		}
		return 1;
	}

	return devwalk(c, name, (Dirtab*)np, 0, netgen);
}

void
netstat(Chan *c, char *db, Network *np)
{
	int i;
	Dir dir;

	for(i=0;; i++)
		switch(netgen(c, (Dirtab*)np, 0, i, &dir)){
		case -1:
			/*
			 * devices with interesting directories usually don't get
			 * here, which is good because we've lost the name by now.
			 */
			if(c->qid.path & CHDIR){
				devdir(c, c->qid, ".", 0L, CHDIR|0700, &dir);
				convD2M(&dir, db);
				return;
			}
			print("netstat %c %lux\n", devchar[c->type], c->qid.path);
			error(Enonexist);
		case 0:
			break;
		case 1:
			if(eqqid(c->qid, dir.qid)){
				convD2M(&dir, db);
				return;
			}
			break;
		}
}

.
80a
		break;
.
79c
		if(i >= np->ninfo)
			return -1;
		q.path = STREAMQID(STREAMID(c->qid.path), Qinf+i);
.
76,77d
56,58d
43c
	if(STREAMID(c->qid.path) == 0){
.
13a
	Qinf=		5,
.
7a
#include	"fcall.h"

.
## diffname port/net.c 1991/1109
## diff -e /n/bootesdump/1991/1108/sys/src/9/port/net.c /n/bootesdump/1991/1109/sys/src/9/port/net.c
120c
				devdir(c, c->qid, ".", 0L, eve, CHDIR|0700, &dir);
.
80c
		devdir(c, q, np->info[i].name, 0, eve, 0666, dp);
.
73c
		devdir(c, q, "listen", 0, eve, 0666, dp);
.
67c
		devdir(c, q, "ctl", 0, eve, 0666, dp);
.
63c
		devdir(c, q, "data", 0, eve, 0666, dp);
.
53c
			devdir(c, q, buf, 0, eve, 0666, dp);
.
49c
			devdir(c, q, "clone", 0, eve, 0666, dp);
.
37c
			devdir(c, q, buf, 0, eve, 0666, dp);
.
## diffname port/net.c 1991/1114
## diff -e /n/bootesdump/1991/1109/sys/src/9/port/net.c /n/bootesdump/1991/1114/sys/src/9/port/net.c
50,52c
		}else if(i <= np->nconv){
			q.path = CHDIR|STREAMQID(i-1, Q3rd);
			sprint(buf, "%d", i-1);
.
46c
	if(STREAMTYPE(c->qid.path) == Q2nd){
.
## diffname port/net.c 1991/1115
## diff -e /n/bootesdump/1991/1114/sys/src/9/port/net.c /n/bootesdump/1991/1115/sys/src/9/port/net.c
194c
	return stringread(a, n, buf, offset);
}

int
netown(Network *np, int id, char *o, int omode)
{
	static int access[] = { 0400, 0200, 0600, 0100 };
	Netprot *p;
	int mode;
	int t;

	p = &np->prot[id];
	lock(np);
	if(*p->owner){
		if(strncmp(o, p->owner, NAMELEN) == 0)	/* User */
			mode = p->mode;
		else if(strncmp(o, eve, NAMELEN) == 0)	/* Bootes is group */
			mode = p->mode<<3;
		else
			mode = p->mode<<6;		/* Other */

		t = access[omode&3];
		if((t & mode) == t){
			unlock(np);
			return 0;
		} else {
			unlock(np);
			return -1;
		}
	}
	strncpy(p->owner, o, NAMELEN);
	np->prot[id].mode = 0660;
	unlock(np);
	return 0;
}

void
netdisown(Network *np, int id)
{
	*np->prot[id].owner = 0;
.
155,156c
			id = (*np->clone)(c);
			c->qid.path = STREAMQID(id, Sctlqid);
.
151,152c
			streamopen(c, np->devp);
			id = (*np->listen)(c);
			streamclose(c);
			c->qid.path = STREAMQID(id, Sctlqid);
.
148a
			id = STREAMID(c->qid.path);
			if(netown(np, id, u->p->user, omode&7) < 0)
				error(Eperm);
.
140c
	int id;
.
136a
void
netwstat(Chan *c, char *db, Network *np)
{
	Dir dir;
	Netprot *p;

	p = &np->prot[STREAMID(c->qid.path)];
	lock(np);
	if(strncmp(p->owner, u->p->user, NAMELEN)){
		unlock(np);
		error(Eperm);
	}
	convM2D(db, &dir);
	strncpy(p->owner, dir.uid, NAMELEN);
	p->mode = dir.mode;
	unlock(np);
}

.
120c
				devdir(c, c->qid, ".", 0L, eve, CHDIR|0555, &dir);
.
80c
		devdir(c, q, np->info[i].name, 0, eve, 0444, dp);
.
73c
		devdir(c, q, "listen", 0, o, perm, dp);
.
67c
		devdir(c, q, "ctl", 0, o, perm, dp);
.
63c
		devdir(c, q, "data", 0, o, perm, dp);
.
59a
	id = STREAMID(c->qid.path);
	p = &np->prot[id];
	if(*p->owner){
		o = p->owner;
		perm = p->mode;
	} else {
		o = eve;
		perm = 0666;
	}
.
53c
			devdir(c, q, buf, 0, eve, 0555, dp);
.
46c
	t = STREAMTYPE(c->qid.path);
	if(t == Q2nd || t == Qclone){
.
37c
			devdir(c, q, buf, 0, eve, 0555, dp);
.
27a
	int t;
	int id;
	Netprot *p;
	int perm;
	char *o;
.
## diffname port/net.c 1991/1116
## diff -e /n/bootesdump/1991/1115/sys/src/9/port/net.c /n/bootesdump/1991/1116/sys/src/9/port/net.c
205a
			if(netown(np, id, u->p->user, omode&7) < 0)
				error(Eperm);
.
183,184d
## diffname port/net.c 1991/1122
## diff -e /n/bootesdump/1991/1116/sys/src/9/port/net.c /n/bootesdump/1991/1122/sys/src/9/port/net.c
173c
	int id = 0;
.
## diffname port/net.c 1992/0111
## diff -e /n/bootesdump/1991/1122/sys/src/9/port/net.c /n/bootesdump/1992/0111/sys/src/9/port/net.c
6c
#include	"../port/error.h"
.
## diffname port/net.c 1992/0321
## diff -e /n/bootesdump/1992/0111/sys/src/9/port/net.c /n/bootesdump/1992/0321/sys/src/9/port/net.c
2c
#include	"../port/lib.h"
.
## diffname port/net.c 1992/0416
## diff -e /n/bootesdump/1992/0321/sys/src/9/port/net.c /n/bootesdump/1992/0416/sys/src/9/port/net.c
270a
if(np == 0) panic("np == 0");
.
## diffname port/net.c 1992/0619
## diff -e /n/bootesdump/1992/0416/sys/src/9/port/net.c /n/bootesdump/1992/0619/sys/src/9/port/net.c
8,9d
## diffname port/net.c 1992/0623
## diff -e /n/bootesdump/1992/0619/sys/src/9/port/net.c /n/bootesdump/1992/0623/sys/src/9/port/net.c
269,270c
	p->owner[0] = 0;
.
267c
netdisown(Netprot *p)
.
261,262c
	p->mode = 0660;
	unlock(&netlock);
.
256c
			unlock(&netlock);
.
253c
			unlock(&netlock);
.
241,242c
	lock(&netlock);
.
237d
234c
netown(Netprot *p, char *o, int omode)
.
232a
void
netadd(Network *np, Netprot *p, int id)
{
	Netprot **l, *pp;

	memset(p, 0, sizeof(Netprot));
	p->id = id;

	l = &np->prot;
	for(pp = np->prot; pp; pp = pp->next){
		if(pp->id == id)
			panic("netadd");
		l = &pp->next;
	}
	*l = p;
}

Lock netlock;

.
230c
	return readstr(offset, a, n, buf);
.
202c
			p = findprot(np, id);
if(p == 0) print("netopen: can't find %d\n", id);
			if(netown(p, u->p->user, omode&7) < 0)
.
171a
	Netprot *p;
.
156c
	p = findprot(np, STREAMID(c->qid.path));
	if(p == 0)
		error(Enonexist);
.
64,66c
	p = findprot(np, STREAMID(c->qid.path));
	if(p && *p->owner){
.
27d
17a
 *  find protection structure
 */
static Netprot*
findprot(Network *np, int id)
{
	Netprot *p;

	for(p = np->prot; p; p = p->next)
		if(p->id == id)
			break;
	return p;
}

/*
.
## diffname port/net.c 1992/0625
## diff -e /n/bootesdump/1992/0623/sys/src/9/port/net.c /n/bootesdump/1992/0625/sys/src/9/port/net.c
218d
78c
	if(p == 0)
		return 0;
	if(*p->owner){
.
67a
			if(findprot(np, i-1) == 0)
				return 0;
.
## diffname port/net.c 1992/0711
## diff -e /n/bootesdump/1992/0625/sys/src/9/port/net.c /n/bootesdump/1992/0711/sys/src/9/port/net.c
44a
	USED(ntab);
.
## diffname port/net.c 1992/0819
## diff -e /n/bootesdump/1992/0711/sys/src/9/port/net.c /n/bootesdump/1992/0819/sys/src/9/port/net.c
307a
}

#undef	CHDIR	/* BUG */
#include "/sys/src/libc/9syscall/sys.h"

void
netwstat(Chan *c, char *db, Network *np)
{
	Dir dir;
	Netprot *p;

	p = findprot(np, STREAMID(c->qid.path));
	if(p == 0)
		error(Enonexist);
	lock(np);

	/*
	 *  A network channel's ownership/permissions can be changed only if the
	 *  wstat is by the owner or (HACK!) if it is performed using an fwstat.
	 *  The latter allows processes started by a network listener to gain
	 *  ownership of the connection.  The open file descriptor is used as
	 *  a capability for the connection.
	 */
	if(strncmp(p->owner, u->p->user, NAMELEN) != 0 && u->scallnr != FWSTAT){
		unlock(np);
		error(Eperm);
	}
	convM2D(db, &dir);
	strncpy(p->owner, dir.uid, NAMELEN);
	p->mode = dir.mode;

	unlock(np);
.
167,186d
## diffname port/net.c 1992/0906
## diff -e /n/bootesdump/1992/0819/sys/src/9/port/net.c /n/bootesdump/1992/0906/sys/src/9/port/net.c
10,14c
	Qlisten	= 1,
	Qclone	= 2,
	Q2nd	= 3,
	Q3rd	= 4,
	Qinf	= 5,
.
## diffname port/net.c 1992/1217
## diff -e /n/bootesdump/1992/0906/sys/src/9/port/net.c /n/bootesdump/1992/1217/sys/src/9/port/net.c
154c
			print("netstat %C %lux\n", devchar[c->type], c->qid.path);
.
## diffname port/net.c 1993/0323
## diff -e /n/bootesdump/1992/1217/sys/src/9/port/net.c /n/bootesdump/1993/0323/sys/src/9/port/net.c
159a
				if(c->flag&CMSG)
					dir.mode |= CHMOUNT;
.
## diffname port/net.c 1993/0330
## diff -e /n/bootesdump/1993/0323/sys/src/9/port/net.c /n/bootesdump/1993/0330/sys/src/9/port/net.c
139,166c
	devstat(c, db, (Dirtab*)np, 1, netgen);
.
## diffname port/net.c 1993/0501
## diff -e /n/bootesdump/1993/0330/sys/src/9/port/net.c /n/fornaxdump/1993/0501/sys/src/brazil/port/net.c
286c
	if(strncmp(p->owner, up->user, NAMELEN) != 0 && up->scallnr != FWSTAT){
.
178c
			if(netown(p, up->user, omode&7) < 0)
.
165a
			ptclone(c, 0, id);
.
161a
			ptclone(c, 1, id);
.
139c
	int i;
	Dir dir;

	for(i=0;; i++)
		switch(netgen(c, (Dirtab*)np, 0, i, &dir)){
		case -1:
		/*
		 * devices with interesting directories usually don't get
		 * here, which is good because we've lost the name by now.
		 */
			if(c->qid.path & CHDIR){
				devdir(c, c->qid, c->path->elem, 0L, eve, CHDIR|0555, &dir);
				convD2M(&dir, db);
				return;
			}
			print("netstat %C %lux\n", devchar[c->type], c->qid.path);
			error(Enonexist);
		case 0:
			break;
		case 1:
			if(eqqid(c->qid, dir.qid)){
				if(c->flag&CMSG)
					dir.mode |= CHMOUNT;
				convD2M(&dir, db);
				return;
			}
			break;
		}
.
## diffname port/net.c 1993/0508
## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/net.c /n/fornaxdump/1993/0508/sys/src/brazil/port/net.c
244a
	p->net = np;
.
224,226d
203,205d
192c
			id = (*np->open)(c, -1);
.
187d
185d
182a
			id = (*np->open)(c, id);
.
## diffname port/net.c 1993/0522
## diff -e /n/fornaxdump/1993/0508/sys/src/brazil/port/net.c /n/fornaxdump/1993/0522/sys/src/brazil/port/net.c
297c
	p = findprot(np, NETID(c->qid.path));
.
223c
	t = NETTYPE(c->qid.path);
	if(t == Nctlqid)
		readnum(offset, a, n, NETID(c->qid.path), NUMSIZE);

.
199,201c
		switch(NETTYPE(c->qid.path)){
		case Ndataqid:
		case Nctlqid:
.
192c
			c->qid.path = NETQID(id, Nctlqid);
.
187c
			c->qid.path = NETQID(id, Nctlqid);
.
179,182c
		switch(NETTYPE(c->qid.path)){
		case Ndataqid:
		case Nctlqid:
			id = NETID(c->qid.path);
.
120c
		switch(NETTYPE(c->qid.path)){
.
109c
		q.path = NETQID(NETID(c->qid.path), Qinf+i);
.
102c
		q.path = NETQID(NETID(c->qid.path), Qlisten);
.
96c
		q.path = NETQID(NETID(c->qid.path), Nctlqid);
.
92c
		q.path = NETQID(NETID(c->qid.path), Ndataqid);
.
80c
	p = findprot(np, NETID(c->qid.path));
.
71c
			q.path = CHDIR|NETQID(i-1, Q3rd);
.
63c
	t = NETTYPE(c->qid.path);
.
## diffname port/net.c 1995/0804
## diff -e /n/fornaxdump/1993/0522/sys/src/brazil/port/net.c /n/fornaxdump/1995/0804/sys/src/brazil/port/net.c
45d
35c
netgen(Chan *c, void *vp, int, int i, Dir *dp)
.
## diffname port/net.c 1996/0531 # deleted
## diff -e /n/fornaxdump/1995/0804/sys/src/brazil/port/net.c /n/fornaxdump/1996/0531/sys/src/brazil/port/net.c
1,320d

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].