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 "vnc.h"
2
#include "vncv.h"
3
#include <libsec.h>
4
 
5
char*	encodings = "copyrect hextile corre rre raw mousewarp";
6
int		bpp12;
7
int		shared;
8
int		verbose;
9
Vnc*		vnc;
10
int		mousefd;
11
int		tls;
12
 
13
static int	vncstart(Vnc*, int);
14
 
15
enum
16
{
17
	NProcs	= 4
18
};
19
 
20
static int pids[NProcs];
21
static char killkin[] = "die vnc kin";
22
 
23
/*
24
 * called by any proc when exiting to tear everything down.
25
 */
26
static void
27
shutdown(void)
28
{
29
	int i, pid;
30
 
31
	hangup(vnc->ctlfd);
32
	close(vnc->ctlfd);
33
	vnc->ctlfd = -1;
34
	close(vnc->datafd);
35
	vnc->datafd = -1;
36
 
37
	pid = getpid();
38
	for(i = 0; i < NProcs; i++)
39
		if(pids[i] != pid)
40
			postnote(PNPROC, pids[i], killkin);
41
}
42
 
43
char*
44
netmkvncaddr(char *inserver)
45
{
46
	char *p, portstr[NETPATHLEN], *server;
47
	int port;
48
 
49
	server = strdup(inserver);
50
	assert(server != nil);
51
 
52
	port = 5900;
53
	if(tls)
54
		port = 35729;
55
	if(p = strchr(server, ':')) {
56
		*p++ = '\0';
57
		port += atoi(p);
58
	}
59
 
60
	snprint(portstr, sizeof portstr, "%d", port);
61
	p = netmkaddr(server, "tcp", portstr);
62
	free(server);
63
	return p;
64
}
65
 
66
void
67
vnchungup(Vnc*)
68
{
69
	sysfatal("connection closed");
70
}
71
 
72
void
73
usage(void)
74
{
75
	fprint(2, "usage: vncv [-e encodings] [-k keypattern] [-csv] host[:n]\n");
76
	exits("usage");
77
}
78
 
79
void
80
main(int argc, char **argv)
81
{
82
	int p, fd, dfd, cfd, shared;
83
	char *keypattern, *addr;
84
	Point d;
85
	TLSconn conn;
86
 
87
	keypattern = nil;
88
	shared = 0;
89
	ARGBEGIN{
90
	case 'c':
91
		bpp12 = 1;
92
		break;
93
	case 'e':
94
		encodings = EARGF(usage());
95
		break;
96
	case 's':
97
		shared = 1;
98
		break;
99
	case 't':
100
		tls = 1;
101
		break;
102
	case 'v':
103
		verbose = 1;
104
		break;
105
	case 'k':
106
		keypattern = EARGF(usage());
107
		break;
108
	default:
109
		usage();
110
	}ARGEND;
111
 
112
	if(argc != 1)
113
		usage();
114
 
115
	addr = netmkvncaddr(argv[0]);
116
	serveraddr = argv[0];
117
	dfd = dial(addr, nil, nil, &cfd);
118
	if(dfd < 0)
119
		sysfatal("cannot dial %s: %r", addr);
120
	if(tls){
121
		dfd = tlsClient(dfd, &conn);
122
		if(dfd < 0)
123
			sysfatal("tlsClient: %r");
124
		/* XXX check thumbprint */
125
	}
126
	vnc = vncinit(dfd, cfd, nil);
127
 
128
	if(vnchandshake(vnc) < 0)
129
		sysfatal("handshake failure: %r");
130
	if(vncauth(vnc, keypattern) < 0)
131
		sysfatal("authentication failure: %r");
132
	if(vncstart(vnc, shared) < 0)
133
		sysfatal("init failure: %r");
134
 
135
	initdraw(0, 0, "vncv");
136
	display->locking = 1;
137
	unlockdisplay(display);
138
 
139
	d = addpt(vnc->dim, Pt(2*Borderwidth, 2*Borderwidth));
140
	if(verbose)
141
		fprint(2, "screen size %P, desktop size %P\n", display->image->r.max, d);
142
 
143
	choosecolor(vnc);
144
	sendencodings(vnc);
145
	initmouse();
146
 
147
	rfork(RFREND);
148
	atexit(shutdown);
149
	pids[0] = getpid();
150
 
151
	switch(p = rfork(RFPROC|RFMEM)){
152
	case -1:
153
		sysfatal("rfork: %r");
154
	default:
155
		break;
156
	case 0:
157
		atexit(shutdown);
158
		readfromserver(vnc);
159
		exits(nil);
160
	}
161
	pids[1] = p;
162
 
163
	switch(p = rfork(RFPROC|RFMEM)){
164
	case -1:
165
		sysfatal("rfork: %r");
166
	default:
167
		break;
168
	case 0:
169
		atexit(shutdown);
170
		checksnarf(vnc);
171
		exits(nil);
172
	}
173
	pids[2] = p;
174
 
175
	fd = open("/dev/label", OWRITE);
176
	if(fd >= 0){
177
		fprint(fd, "vnc %s", serveraddr);
178
		close(fd);
179
	}
180
	if(access("/dev/snarf", AEXIST) >= 0){
181
		switch(p = rfork(RFPROC|RFMEM)){
182
		case -1:
183
			sysfatal("rfork: %r");
184
		default:
185
			break;
186
		case 0:
187
			atexit(shutdown);
188
			readkbd(vnc);
189
			exits(nil);
190
		}
191
	}
192
	pids[3] = p;
193
 
194
	readmouse(vnc);
195
	exits(nil);
196
}
197
 
198
static int
199
vncstart(Vnc *v, int shared)
200
{
201
	vncwrchar(v, shared);
202
	vncflush(v);
203
	v->dim = vncrdpoint(v);
204
	v->Pixfmt = vncrdpixfmt(v);
205
	v->name = vncrdstring(v);
206
	return 0;
207
}