Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <auth.h>
4
 
5
int verbose;
6
int trusted;
7
 
8
void
9
usage(void)
10
{
11
	fprint(2, "usage: listen1 [-tv] address cmd args...\n");
12
	exits("usage");
13
}
14
 
15
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*
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
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
}