plan 9 kernel history: overview | file list | diff list

1991/1107/port/net.c (diff list | history)

port/net.c on 1991/1107
1991/1107    
#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); 
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)