xref: /plan9/sys/src/lib9p/listen.c (revision 22a127bbfe4dd304949cc596400de973c0138e31)
1*22a127bbSDavid du Colombier #include <u.h>
2*22a127bbSDavid du Colombier #include <libc.h>
3*22a127bbSDavid du Colombier #include <auth.h>
4*22a127bbSDavid du Colombier #include <fcall.h>
5*22a127bbSDavid du Colombier #include <thread.h>
6*22a127bbSDavid du Colombier #include <9p.h>
7*22a127bbSDavid du Colombier 
8*22a127bbSDavid du Colombier static void listenproc(void*);
9*22a127bbSDavid du Colombier static void srvproc(void*);
10*22a127bbSDavid du Colombier static char *getremotesys(char*);
11*22a127bbSDavid du Colombier 
12*22a127bbSDavid du Colombier void
_listensrv(Srv * os,char * addr)13*22a127bbSDavid du Colombier _listensrv(Srv *os, char *addr)
14*22a127bbSDavid du Colombier {
15*22a127bbSDavid du Colombier 	Srv *s;
16*22a127bbSDavid du Colombier 
17*22a127bbSDavid du Colombier 	if(_forker == nil)
18*22a127bbSDavid du Colombier 		sysfatal("no forker");
19*22a127bbSDavid du Colombier 	s = emalloc9p(sizeof *s);
20*22a127bbSDavid du Colombier 	*s = *os;
21*22a127bbSDavid du Colombier 	s->addr = estrdup9p(addr);
22*22a127bbSDavid du Colombier 	_forker(listenproc, s, 0);
23*22a127bbSDavid du Colombier }
24*22a127bbSDavid du Colombier 
25*22a127bbSDavid du Colombier static void
listenproc(void * v)26*22a127bbSDavid du Colombier listenproc(void *v)
27*22a127bbSDavid du Colombier {
28*22a127bbSDavid du Colombier 	char ndir[NETPATHLEN], dir[NETPATHLEN];
29*22a127bbSDavid du Colombier 	int ctl, data, nctl;
30*22a127bbSDavid du Colombier 	Srv *os, *s;
31*22a127bbSDavid du Colombier 
32*22a127bbSDavid du Colombier 	os = v;
33*22a127bbSDavid du Colombier 	ctl = announce(os->addr, dir);
34*22a127bbSDavid du Colombier 	if(ctl < 0){
35*22a127bbSDavid du Colombier 		fprint(2, "%s: announce %s: %r", argv0, os->addr);
36*22a127bbSDavid du Colombier 		return;
37*22a127bbSDavid du Colombier 	}
38*22a127bbSDavid du Colombier 
39*22a127bbSDavid du Colombier 	for(;;){
40*22a127bbSDavid du Colombier 		nctl = listen(dir, ndir);
41*22a127bbSDavid du Colombier 		if(nctl < 0){
42*22a127bbSDavid du Colombier 			fprint(2, "%s: listen %s: %r", argv0, os->addr);
43*22a127bbSDavid du Colombier 			break;
44*22a127bbSDavid du Colombier 		}
45*22a127bbSDavid du Colombier 
46*22a127bbSDavid du Colombier 		data = accept(ctl, ndir);
47*22a127bbSDavid du Colombier 		if(data < 0){
48*22a127bbSDavid du Colombier 			fprint(2, "%s: accept %s: %r\n", argv0, ndir);
49*22a127bbSDavid du Colombier 			continue;
50*22a127bbSDavid du Colombier 		}
51*22a127bbSDavid du Colombier 
52*22a127bbSDavid du Colombier 		s = emalloc9p(sizeof *s);
53*22a127bbSDavid du Colombier 		*s = *os;
54*22a127bbSDavid du Colombier 		s->addr = getremotesys(ndir);
55*22a127bbSDavid du Colombier 		s->infd = s->outfd = data;
56*22a127bbSDavid du Colombier 		s->fpool = nil;
57*22a127bbSDavid du Colombier 		s->rpool = nil;
58*22a127bbSDavid du Colombier 		s->rbuf = nil;
59*22a127bbSDavid du Colombier 		s->wbuf = nil;
60*22a127bbSDavid du Colombier 		_forker(srvproc, s, 0);
61*22a127bbSDavid du Colombier 	}
62*22a127bbSDavid du Colombier 	free(os->addr);
63*22a127bbSDavid du Colombier 	free(os);
64*22a127bbSDavid du Colombier }
65*22a127bbSDavid du Colombier 
66*22a127bbSDavid du Colombier static void
srvproc(void * v)67*22a127bbSDavid du Colombier srvproc(void *v)
68*22a127bbSDavid du Colombier {
69*22a127bbSDavid du Colombier 	int data;
70*22a127bbSDavid du Colombier 	Srv *s;
71*22a127bbSDavid du Colombier 
72*22a127bbSDavid du Colombier 	s = v;
73*22a127bbSDavid du Colombier 	data = s->infd;
74*22a127bbSDavid du Colombier 	srv(s);
75*22a127bbSDavid du Colombier 	close(data);
76*22a127bbSDavid du Colombier 	free(s->addr);
77*22a127bbSDavid du Colombier 	free(s);
78*22a127bbSDavid du Colombier }
79*22a127bbSDavid du Colombier 
80*22a127bbSDavid du Colombier static char*
getremotesys(char * ndir)81*22a127bbSDavid du Colombier getremotesys(char *ndir)
82*22a127bbSDavid du Colombier {
83*22a127bbSDavid du Colombier 	char buf[128], *serv, *sys;
84*22a127bbSDavid du Colombier 	int fd, n;
85*22a127bbSDavid du Colombier 
86*22a127bbSDavid du Colombier 	snprint(buf, sizeof buf, "%s/remote", ndir);
87*22a127bbSDavid du Colombier 	sys = nil;
88*22a127bbSDavid du Colombier 	fd = open(buf, OREAD);
89*22a127bbSDavid du Colombier 	if(fd >= 0){
90*22a127bbSDavid du Colombier 		n = read(fd, buf, sizeof(buf)-1);
91*22a127bbSDavid du Colombier 		if(n>0){
92*22a127bbSDavid du Colombier 			buf[n-1] = 0;
93*22a127bbSDavid du Colombier 			serv = strchr(buf, '!');
94*22a127bbSDavid du Colombier 			if(serv)
95*22a127bbSDavid du Colombier 				*serv = 0;
96*22a127bbSDavid du Colombier 			sys = estrdup9p(buf);
97*22a127bbSDavid du Colombier 		}
98*22a127bbSDavid du Colombier 		close(fd);
99*22a127bbSDavid du Colombier 	}
100*22a127bbSDavid du Colombier 	if(sys == nil)
101*22a127bbSDavid du Colombier 		sys = estrdup9p("unknown");
102*22a127bbSDavid du Colombier 	return sys;
103*22a127bbSDavid du Colombier }
104