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