xref: /plan9/sys/src/cmd/aux/listen1.c (revision 386d4ae8d5c308eb1d0c32224e279d633afd6901)
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 
5 int verbose;
6 int trusted;
7 
8 void
usage(void)9 usage(void)
10 {
11 	fprint(2, "usage: listen1 [-tv] address cmd args...\n");
12 	exits("usage");
13 }
14 
15 void
becomenone(void)16 becomenone(void)
17 {
18 	int fd;
19 
20 	fd = open("#c/user", OWRITE);
21 	if(fd < 0 || write(fd, "none", strlen("none")) < 0)
22 		sysfatal("can't become none: %r");
23 	close(fd);
24 	if(newns("none", nil) < 0)
25 		sysfatal("can't build namespace: %r");
26 }
27 
28 char*
remoteaddr(char * dir)29 remoteaddr(char *dir)
30 {
31 	static char buf[128];
32 	char *p;
33 	int n, fd;
34 
35 	snprint(buf, sizeof buf, "%s/remote", dir);
36 	fd = open(buf, OREAD);
37 	if(fd < 0)
38 		return "";
39 	n = read(fd, buf, sizeof(buf));
40 	close(fd);
41 	if(n > 0){
42 		buf[n] = 0;
43 		p = strchr(buf, '!');
44 		if(p)
45 			*p = 0;
46 		return buf;
47 	}
48 	return "";
49 }
50 
51 void
main(int argc,char ** argv)52 main(int argc, char **argv)
53 {
54 	char data[60], dir[40], ndir[40];
55 	int ctl, nctl, fd;
56 
57 	ARGBEGIN{
58 	default:
59 		usage();
60 	case 't':
61 		trusted = 1;
62 		break;
63 	case 'v':
64 		verbose = 1;
65 		break;
66 	}ARGEND
67 
68 	if(argc < 2)
69 		usage();
70 
71 	if(!verbose){
72 		close(1);
73 		fd = open("/dev/null", OWRITE);
74 		if(fd != 1){
75 			dup(fd, 1);
76 			close(fd);
77 		}
78 	}
79 
80 	if(!trusted)
81 		becomenone();
82 
83 	print("listen started\n");
84 	ctl = announce(argv[0], dir);
85 	if(ctl < 0)
86 		sysfatal("announce %s: %r", argv[0]);
87 
88 	for(;;){
89 		nctl = listen(dir, ndir);
90 		if(nctl < 0)
91 			sysfatal("listen %s: %r", argv[0]);
92 
93 		switch(rfork(RFFDG|RFPROC|RFNOWAIT|RFENVG|RFNAMEG|RFNOTEG)){
94 		case -1:
95 			reject(nctl, ndir, "host overloaded");
96 			close(nctl);
97 			continue;
98 		case 0:
99 			fd = accept(nctl, ndir);
100 			if(fd < 0){
101 				fprint(2, "accept %s: can't open  %s/data: %r\n",
102 					argv[0], ndir);
103 				_exits(0);
104 			}
105 			print("incoming call for %s from %s in %s\n", argv[0],
106 				remoteaddr(ndir), ndir);
107 			fprint(nctl, "keepalive");
108 			close(ctl);
109 			close(nctl);
110 			putenv("net", ndir);
111 			snprint(data, sizeof data, "%s/data", ndir);
112 			bind(data, "/dev/cons", MREPL);
113 			dup(fd, 0);
114 			dup(fd, 1);
115 			dup(fd, 2);
116 			close(fd);
117 			exec(argv[1], argv+1);
118 			if(argv[1][0] != '/')
119 				exec(smprint("/bin/%s", argv[1]), argv+1);
120 			fprint(2, "%s: exec: %r\n", argv0);
121 			exits(nil);
122 		default:
123 			close(nctl);
124 			break;
125 		}
126 	}
127 }
128