00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef __STRICT_ANSI__
00025 #define _BSD_SOURCE
00026 #define _POSIX_SOURCE
00027 #endif
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <time.h>
00032 #include <rfb/rfbclient.h>
00033 #include "tls.h"
00034
00035 static void Dummy(rfbClient* client) {
00036 }
00037 static rfbBool DummyPoint(rfbClient* client, int x, int y) {
00038 return TRUE;
00039 }
00040 static void DummyRect(rfbClient* client, int x, int y, int w, int h) {
00041 }
00042
00043 #ifdef __MINGW32__
00044 static char* NoPassword(rfbClient* client) {
00045 return strdup("");
00046 }
00047 #undef SOCKET
00048 #include <winsock2.h>
00049 #define close closesocket
00050 #else
00051 #include <stdio.h>
00052 #include <termios.h>
00053 #endif
00054
00055 static char* ReadPassword(rfbClient* client) {
00056 #ifdef __MINGW32__
00057
00058 rfbClientErr("ReadPassword on MinGW32 NOT IMPLEMENTED\n");
00059 return NoPassword(client);
00060 #else
00061 int i;
00062 char* p=malloc(9);
00063 struct termios save,noecho;
00064 p[0]=0;
00065 if(tcgetattr(fileno(stdin),&save)!=0) return p;
00066 noecho=save; noecho.c_lflag &= ~ECHO;
00067 if(tcsetattr(fileno(stdin),TCSAFLUSH,&noecho)!=0) return p;
00068 fprintf(stderr,"Password: ");
00069 i=0;
00070 while(1) {
00071 int c=fgetc(stdin);
00072 if(c=='\n')
00073 break;
00074 if(i<8) {
00075 p[i]=c;
00076 i++;
00077 p[i]=0;
00078 }
00079 }
00080 tcsetattr(fileno(stdin),TCSAFLUSH,&save);
00081 return p;
00082 #endif
00083 }
00084 static rfbBool MallocFrameBuffer(rfbClient* client) {
00085 if(client->frameBuffer)
00086 free(client->frameBuffer);
00087 client->frameBuffer=malloc(client->width*client->height*client->format.bitsPerPixel/8);
00088 return client->frameBuffer?TRUE:FALSE;
00089 }
00090
00091 static void initAppData(AppData* data) {
00092 data->shareDesktop=TRUE;
00093 data->viewOnly=FALSE;
00094 data->encodingsString="tight zrle ultra copyrect hextile zlib corre rre raw";
00095 data->useBGR233=FALSE;
00096 data->nColours=0;
00097 data->forceOwnCmap=FALSE;
00098 data->forceTrueColour=FALSE;
00099 data->requestedDepth=0;
00100 data->compressLevel=3;
00101 data->qualityLevel=5;
00102 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
00103 data->enableJPEG=TRUE;
00104 #else
00105 data->enableJPEG=FALSE;
00106 #endif
00107 data->useRemoteCursor=FALSE;
00108 }
00109
00110 rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,
00111 int bytesPerPixel) {
00112 rfbClient* client=(rfbClient*)calloc(sizeof(rfbClient),1);
00113 if(!client) {
00114 rfbClientErr("Couldn't allocate client structure!\n");
00115 return NULL;
00116 }
00117 initAppData(&client->appData);
00118 client->endianTest = 1;
00119 client->programName="";
00120 client->serverHost=strdup("");
00121 client->serverPort=5900;
00122
00123 client->destHost = NULL;
00124 client->destPort = 5900;
00125
00126 client->CurrentKeyboardLedState = 0;
00127 client->HandleKeyboardLedState = (HandleKeyboardLedStateProc)DummyPoint;
00128
00129
00130 client->updateRect.x = -1;
00131
00132 client->format.bitsPerPixel = bytesPerPixel*8;
00133 client->format.depth = bitsPerSample*samplesPerPixel;
00134 client->appData.requestedDepth=client->format.depth;
00135 client->format.bigEndian = *(char *)&client->endianTest?FALSE:TRUE;
00136 client->format.trueColour = TRUE;
00137
00138 if (client->format.bitsPerPixel == 8) {
00139 client->format.redMax = 7;
00140 client->format.greenMax = 7;
00141 client->format.blueMax = 3;
00142 client->format.redShift = 0;
00143 client->format.greenShift = 3;
00144 client->format.blueShift = 6;
00145 } else {
00146 client->format.redMax = (1 << bitsPerSample) - 1;
00147 client->format.greenMax = (1 << bitsPerSample) - 1;
00148 client->format.blueMax = (1 << bitsPerSample) - 1;
00149 if(!client->format.bigEndian) {
00150 client->format.redShift = 0;
00151 client->format.greenShift = bitsPerSample;
00152 client->format.blueShift = bitsPerSample * 2;
00153 } else {
00154 if(client->format.bitsPerPixel==8*3) {
00155 client->format.redShift = bitsPerSample*2;
00156 client->format.greenShift = bitsPerSample*1;
00157 client->format.blueShift = 0;
00158 } else {
00159 client->format.redShift = bitsPerSample*3;
00160 client->format.greenShift = bitsPerSample*2;
00161 client->format.blueShift = bitsPerSample;
00162 }
00163 }
00164 }
00165
00166 client->bufoutptr=client->buf;
00167 client->buffered=0;
00168
00169 #ifdef LIBVNCSERVER_HAVE_LIBZ
00170 client->raw_buffer_size = -1;
00171 client->decompStreamInited = FALSE;
00172
00173 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
00174 memset(client->zlibStreamActive,0,sizeof(rfbBool)*4);
00175 client->jpegSrcManager = NULL;
00176 #endif
00177 #endif
00178
00179 client->HandleCursorPos = DummyPoint;
00180 client->SoftCursorLockArea = DummyRect;
00181 client->SoftCursorUnlockScreen = Dummy;
00182 client->GotFrameBufferUpdate = DummyRect;
00183 client->FinishedFrameBufferUpdate = NULL;
00184 client->GetPassword = ReadPassword;
00185 client->MallocFrameBuffer = MallocFrameBuffer;
00186 client->Bell = Dummy;
00187 client->CurrentKeyboardLedState = 0;
00188 client->HandleKeyboardLedState = (HandleKeyboardLedStateProc)DummyPoint;
00189 client->QoS_DSCP = 0;
00190
00191 client->authScheme = 0;
00192 client->subAuthScheme = 0;
00193 client->GetCredential = NULL;
00194 client->tlsSession = NULL;
00195 client->sock = -1;
00196 client->listenSock = -1;
00197 client->listenAddress = NULL;
00198 client->listen6Sock = -1;
00199 client->listen6Address = NULL;
00200 client->clientAuthSchemes = NULL;
00201 return client;
00202 }
00203
00204 static rfbBool rfbInitConnection(rfbClient* client)
00205 {
00206
00207
00208
00209 if (!client->listenSpecified) {
00210 if (!client->serverHost)
00211 return FALSE;
00212 if (client->destHost) {
00213 if (!ConnectToRFBRepeater(client,client->serverHost,client->serverPort,client->destHost,client->destPort))
00214 return FALSE;
00215 } else {
00216 if (!ConnectToRFBServer(client,client->serverHost,client->serverPort))
00217 return FALSE;
00218 }
00219 }
00220
00221
00222
00223 if (!InitialiseRFBConnection(client))
00224 return FALSE;
00225
00226 client->width=client->si.framebufferWidth;
00227 client->height=client->si.framebufferHeight;
00228 client->MallocFrameBuffer(client);
00229
00230 if (!SetFormatAndEncodings(client))
00231 return FALSE;
00232
00233 if (client->updateRect.x < 0) {
00234 client->updateRect.x = client->updateRect.y = 0;
00235 client->updateRect.w = client->width;
00236 client->updateRect.h = client->height;
00237 }
00238
00239 if (client->appData.scaleSetting>1)
00240 {
00241 if (!SendScaleSetting(client, client->appData.scaleSetting))
00242 return FALSE;
00243 if (!SendFramebufferUpdateRequest(client,
00244 client->updateRect.x / client->appData.scaleSetting,
00245 client->updateRect.y / client->appData.scaleSetting,
00246 client->updateRect.w / client->appData.scaleSetting,
00247 client->updateRect.h / client->appData.scaleSetting,
00248 FALSE))
00249 return FALSE;
00250 }
00251 else
00252 {
00253 if (!SendFramebufferUpdateRequest(client,
00254 client->updateRect.x, client->updateRect.y,
00255 client->updateRect.w, client->updateRect.h,
00256 FALSE))
00257 return FALSE;
00258 }
00259
00260 return TRUE;
00261 }
00262
00263 rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv) {
00264 int i,j;
00265
00266 if(argv && argc && *argc) {
00267 if(client->programName==0)
00268 client->programName=argv[0];
00269
00270 for (i = 1; i < *argc; i++) {
00271 j = i;
00272 if (strcmp(argv[i], "-listen") == 0) {
00273 listenForIncomingConnections(client);
00274 break;
00275 } else if (strcmp(argv[i], "-listennofork") == 0) {
00276 listenForIncomingConnectionsNoFork(client, -1);
00277 break;
00278 } else if (strcmp(argv[i], "-play") == 0) {
00279 client->serverPort = -1;
00280 j++;
00281 } else if (i+1<*argc && strcmp(argv[i], "-encodings") == 0) {
00282 client->appData.encodingsString = argv[i+1];
00283 j+=2;
00284 } else if (i+1<*argc && strcmp(argv[i], "-compress") == 0) {
00285 client->appData.compressLevel = atoi(argv[i+1]);
00286 j+=2;
00287 } else if (i+1<*argc && strcmp(argv[i], "-quality") == 0) {
00288 client->appData.qualityLevel = atoi(argv[i+1]);
00289 j+=2;
00290 } else if (i+1<*argc && strcmp(argv[i], "-scale") == 0) {
00291 client->appData.scaleSetting = atoi(argv[i+1]);
00292 j+=2;
00293 } else if (i+1<*argc && strcmp(argv[i], "-qosdscp") == 0) {
00294 client->QoS_DSCP = atoi(argv[i+1]);
00295 j+=2;
00296 } else if (i+1<*argc && strcmp(argv[i], "-repeaterdest") == 0) {
00297 char* colon=strchr(argv[i+1],':');
00298
00299 if(client->destHost)
00300 free(client->destHost);
00301 client->destPort = 5900;
00302
00303 client->destHost = strdup(argv[i+1]);
00304 if(colon) {
00305 client->destHost[(int)(colon-argv[i+1])] = '\0';
00306 client->destPort = atoi(colon+1);
00307 }
00308 j+=2;
00309 } else {
00310 char* colon=strchr(argv[i],':');
00311
00312 if(client->serverHost)
00313 free(client->serverHost);
00314
00315 if(colon) {
00316 client->serverHost = strdup(argv[i]);
00317 client->serverHost[(int)(colon-argv[i])] = '\0';
00318 client->serverPort = atoi(colon+1);
00319 } else {
00320 client->serverHost = strdup(argv[i]);
00321 }
00322 if(client->serverPort >= 0 && client->serverPort < 5900)
00323 client->serverPort += 5900;
00324 }
00325
00326 if (j>i) {
00327 *argc-=j-i;
00328 memmove(argv+i,argv+j,(*argc-i)*sizeof(char*));
00329 i--;
00330 }
00331 }
00332 }
00333
00334 if(!rfbInitConnection(client)) {
00335 rfbClientCleanup(client);
00336 return FALSE;
00337 }
00338
00339 return TRUE;
00340 }
00341
00342 void rfbClientCleanup(rfbClient* client) {
00343 #ifdef LIBVNCSERVER_HAVE_LIBZ
00344 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
00345 int i;
00346
00347 for ( i = 0; i < 4; i++ ) {
00348 if (client->zlibStreamActive[i] == TRUE ) {
00349 if (inflateEnd (&client->zlibStream[i]) != Z_OK &&
00350 client->zlibStream[i].msg != NULL)
00351 rfbClientLog("inflateEnd: %s\n", client->zlibStream[i].msg);
00352 }
00353 }
00354
00355 if ( client->decompStreamInited == TRUE ) {
00356 if (inflateEnd (&client->decompStream) != Z_OK &&
00357 client->decompStream.msg != NULL)
00358 rfbClientLog("inflateEnd: %s\n", client->decompStream.msg );
00359 }
00360
00361 if (client->jpegSrcManager)
00362 free(client->jpegSrcManager);
00363 #endif
00364 #endif
00365
00366 FreeTLS(client);
00367
00368 if (client->sock >= 0)
00369 close(client->sock);
00370 if (client->listenSock >= 0)
00371 close(client->listenSock);
00372 free(client->desktopName);
00373 free(client->serverHost);
00374 if (client->destHost)
00375 free(client->destHost);
00376 if (client->clientAuthSchemes)
00377 free(client->clientAuthSchemes);
00378 free(client);
00379 }