1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  This is free software; you can redistribute it and/or modify
5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  it under the terms of the GNU General Public License as published by
6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  the Free Software Foundation; either version 2 of the License, or
7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  (at your option) any later version.
8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  This software is distributed in the hope that it will be useful,
10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  GNU General Public License for more details.
13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  You should have received a copy of the GNU General Public License
15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  along with this software; if not, write to the Free Software
16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  USA.
18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * vncviewer.c - the Xt-based VNC viewer.
22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef __STRICT_ANSI__
25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define _BSD_SOURCE
26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define _POSIX_SOURCE
27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <stdio.h>
29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <stdlib.h>
30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <string.h>
31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <time.h>
32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <rfb/rfbclient.h>
33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "tls.h"
34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void Dummy(rfbClient* client) {
36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool DummyPoint(rfbClient* client, int x, int y) {
38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return TRUE;
39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void DummyRect(rfbClient* client, int x, int y, int w, int h) {
41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef __MINGW32__
44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char* NoPassword(rfbClient* client) {
45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return strdup("");
46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef SOCKET
48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <winsock2.h>
49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define close closesocket
50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <stdio.h>
52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <termios.h>
53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char* ReadPassword(rfbClient* client) {
56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef __MINGW32__
57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* FIXME */
58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientErr("ReadPassword on MinGW32 NOT IMPLEMENTED\n");
59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return NoPassword(client);
60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int i;
62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char* p=malloc(9);
63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	struct termios save,noecho;
64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	p[0]=0;
65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(tcgetattr(fileno(stdin),&save)!=0) return p;
66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	noecho=save; noecho.c_lflag &= ~ECHO;
67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(tcsetattr(fileno(stdin),TCSAFLUSH,&noecho)!=0) return p;
68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fprintf(stderr,"Password: ");
69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	i=0;
70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while(1) {
71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int c=fgetc(stdin);
72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if(c=='\n')
73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if(i<8) {
75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			p[i]=c;
76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			i++;
77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			p[i]=0;
78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	tcsetattr(fileno(stdin),TCSAFLUSH,&save);
81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return p;
82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool MallocFrameBuffer(rfbClient* client) {
85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(client->frameBuffer)
86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    free(client->frameBuffer);
87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->frameBuffer=malloc(client->width*client->height*client->format.bitsPerPixel/8);
88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return client->frameBuffer?TRUE:FALSE;
89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void initAppData(AppData* data) {
92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data->shareDesktop=TRUE;
93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data->viewOnly=FALSE;
94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data->encodingsString="tight zrle ultra copyrect hextile zlib corre rre raw";
95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data->useBGR233=FALSE;
96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data->nColours=0;
97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data->forceOwnCmap=FALSE;
98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data->forceTrueColour=FALSE;
99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data->requestedDepth=0;
100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data->compressLevel=3;
101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data->qualityLevel=5;
102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG
103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data->enableJPEG=TRUE;
104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data->enableJPEG=FALSE;
106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data->useRemoteCursor=FALSE;
108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,
111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int bytesPerPixel) {
112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClient* client=(rfbClient*)calloc(sizeof(rfbClient),1);
113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(!client) {
114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientErr("Couldn't allocate client structure!\n");
115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return NULL;
116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  initAppData(&client->appData);
118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->endianTest = 1;
119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->programName="";
120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->serverHost=strdup("");
121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->serverPort=5900;
122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->destHost = NULL;
124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->destPort = 5900;
125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->CurrentKeyboardLedState = 0;
127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->HandleKeyboardLedState = (HandleKeyboardLedStateProc)DummyPoint;
128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* default: use complete frame buffer */
130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->updateRect.x = -1;
131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->format.bitsPerPixel = bytesPerPixel*8;
133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->format.depth = bitsPerSample*samplesPerPixel;
134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->appData.requestedDepth=client->format.depth;
135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->format.bigEndian = *(char *)&client->endianTest?FALSE:TRUE;
136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->format.trueColour = TRUE;
137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->format.bitsPerPixel == 8) {
139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->format.redMax = 7;
140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->format.greenMax = 7;
141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->format.blueMax = 3;
142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->format.redShift = 0;
143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->format.greenShift = 3;
144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->format.blueShift = 6;
145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  } else {
146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->format.redMax = (1 << bitsPerSample) - 1;
147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->format.greenMax = (1 << bitsPerSample) - 1;
148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->format.blueMax = (1 << bitsPerSample) - 1;
149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(!client->format.bigEndian) {
150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      client->format.redShift = 0;
151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      client->format.greenShift = bitsPerSample;
152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      client->format.blueShift = bitsPerSample * 2;
153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else {
154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if(client->format.bitsPerPixel==8*3) {
155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->format.redShift = bitsPerSample*2;
156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->format.greenShift = bitsPerSample*1;
157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->format.blueShift = 0;
158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else {
159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->format.redShift = bitsPerSample*3;
160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->format.greenShift = bitsPerSample*2;
161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->format.blueShift = bitsPerSample;
162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->bufoutptr=client->buf;
167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->buffered=0;
168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ
170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->raw_buffer_size = -1;
171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->decompStreamInited = FALSE;
172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG
174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  memset(client->zlibStreamActive,0,sizeof(rfbBool)*4);
175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->jpegSrcManager = NULL;
176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->HandleCursorPos = DummyPoint;
180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->SoftCursorLockArea = DummyRect;
181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->SoftCursorUnlockScreen = Dummy;
182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->GotFrameBufferUpdate = DummyRect;
183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->FinishedFrameBufferUpdate = NULL;
184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->GetPassword = ReadPassword;
185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->MallocFrameBuffer = MallocFrameBuffer;
186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->Bell = Dummy;
187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->CurrentKeyboardLedState = 0;
188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->HandleKeyboardLedState = (HandleKeyboardLedStateProc)DummyPoint;
189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->QoS_DSCP = 0;
190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->authScheme = 0;
192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->subAuthScheme = 0;
193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->GetCredential = NULL;
194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->tlsSession = NULL;
195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->sock = -1;
196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->listenSock = -1;
197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->listenAddress = NULL;
198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->listen6Sock = -1;
199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->listen6Address = NULL;
200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->clientAuthSchemes = NULL;
201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return client;
202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool rfbInitConnection(rfbClient* client)
205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* Unless we accepted an incoming connection, make a TCP connection to the
207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     given VNC server */
208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!client->listenSpecified) {
210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!client->serverHost)
211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (client->destHost) {
213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (!ConnectToRFBRepeater(client,client->serverHost,client->serverPort,client->destHost,client->destPort))
214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return FALSE;
215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else {
216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (!ConnectToRFBServer(client,client->serverHost,client->serverPort))
217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return FALSE;
218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* Initialise the VNC connection, including reading the password */
222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!InitialiseRFBConnection(client))
224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->width=client->si.framebufferWidth;
227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->height=client->si.framebufferHeight;
228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->MallocFrameBuffer(client);
229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!SetFormatAndEncodings(client))
231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->updateRect.x < 0) {
234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->updateRect.x = client->updateRect.y = 0;
235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->updateRect.w = client->width;
236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->updateRect.h = client->height;
237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->appData.scaleSetting>1)
240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (!SendScaleSetting(client, client->appData.scaleSetting))
242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          return FALSE;
243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (!SendFramebufferUpdateRequest(client,
244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			      client->updateRect.x / client->appData.scaleSetting,
245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			      client->updateRect.y / client->appData.scaleSetting,
246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			      client->updateRect.w / client->appData.scaleSetting,
247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			      client->updateRect.h / client->appData.scaleSetting,
248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			      FALSE))
249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	      return FALSE;
250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  else
252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (!SendFramebufferUpdateRequest(client,
254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			      client->updateRect.x, client->updateRect.y,
255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			      client->updateRect.w, client->updateRect.h,
256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			      FALSE))
257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return TRUE;
261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool rfbInitClient(rfbClient* client,int* argc,char** argv) {
264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  int i,j;
265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(argv && argc && *argc) {
267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(client->programName==0)
268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      client->programName=argv[0];
269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    for (i = 1; i < *argc; i++) {
271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      j = i;
272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (strcmp(argv[i], "-listen") == 0) {
273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	listenForIncomingConnections(client);
274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	break;
275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (strcmp(argv[i], "-listennofork") == 0) {
276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	listenForIncomingConnectionsNoFork(client, -1);
277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	break;
278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (strcmp(argv[i], "-play") == 0) {
279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->serverPort = -1;
280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	j++;
281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (i+1<*argc && strcmp(argv[i], "-encodings") == 0) {
282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->appData.encodingsString = argv[i+1];
283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	j+=2;
284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (i+1<*argc && strcmp(argv[i], "-compress") == 0) {
285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->appData.compressLevel = atoi(argv[i+1]);
286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	j+=2;
287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (i+1<*argc && strcmp(argv[i], "-quality") == 0) {
288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->appData.qualityLevel = atoi(argv[i+1]);
289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	j+=2;
290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (i+1<*argc && strcmp(argv[i], "-scale") == 0) {
291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        client->appData.scaleSetting = atoi(argv[i+1]);
292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        j+=2;
293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (i+1<*argc && strcmp(argv[i], "-qosdscp") == 0) {
294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        client->QoS_DSCP = atoi(argv[i+1]);
295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        j+=2;
296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (i+1<*argc && strcmp(argv[i], "-repeaterdest") == 0) {
297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char* colon=strchr(argv[i+1],':');
298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(client->destHost)
300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  free(client->destHost);
301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        client->destPort = 5900;
302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->destHost = strdup(argv[i+1]);
304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(colon) {
305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  client->destHost[(int)(colon-argv[i+1])] = '\0';
306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  client->destPort = atoi(colon+1);
307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        j+=2;
309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else {
310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char* colon=strchr(argv[i],':');
311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(client->serverHost)
313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  free(client->serverHost);
314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(colon) {
316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  client->serverHost = strdup(argv[i]);
317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  client->serverHost[(int)(colon-argv[i])] = '\0';
318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  client->serverPort = atoi(colon+1);
319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  client->serverHost = strdup(argv[i]);
321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(client->serverPort >= 0 && client->serverPort < 5900)
323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  client->serverPort += 5900;
324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      /* purge arguments */
326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (j>i) {
327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	*argc-=j-i;
328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	memmove(argv+i,argv+j,(*argc-i)*sizeof(char*));
329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	i--;
330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(!rfbInitConnection(client)) {
335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientCleanup(client);
336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return TRUE;
340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbClientCleanup(rfbClient* client) {
343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ
344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG
345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  int i;
346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  for ( i = 0; i < 4; i++ ) {
348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (client->zlibStreamActive[i] == TRUE ) {
349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (inflateEnd (&client->zlibStream[i]) != Z_OK &&
350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  client->zlibStream[i].msg != NULL)
351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientLog("inflateEnd: %s\n", client->zlibStream[i].msg);
352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if ( client->decompStreamInited == TRUE ) {
356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (inflateEnd (&client->decompStream) != Z_OK &&
357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->decompStream.msg != NULL)
358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("inflateEnd: %s\n", client->decompStream.msg );
359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->jpegSrcManager)
362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    free(client->jpegSrcManager);
363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  FreeTLS(client);
367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->sock >= 0)
369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    close(client->sock);
370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->listenSock >= 0)
371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    close(client->listenSock);
372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  free(client->desktopName);
373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  free(client->serverHost);
374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->destHost)
375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    free(client->destHost);
376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->clientAuthSchemes)
377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    free(client->clientAuthSchemes);
378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  free(client);
379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
380