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