changes from Tim Jansen: threading issues, new client can be rejected, and more

pull/1/head
dscho 23 years ago
parent fbf2c977fe
commit 45a4b4a223

@ -83,7 +83,7 @@ Whenever you draw something, you have to call
This tells LibVNCServer to send updates to all connected clients. This tells LibVNCServer to send updates to all connected clients.
Before you draw something, be sure to call Before you draw something, be sure to call
rfbUndrawCursor(cl). rfbUndrawCursor(screen).
This tells LibVNCServer to hide the cursor. This tells LibVNCServer to hide the cursor.
Remark: There are vncviewers out there, which know a cursor encoding, so Remark: There are vncviewers out there, which know a cursor encoding, so
that network traffic is low, and also the cursor doesn't need to be that network traffic is low, and also the cursor doesn't need to be

@ -42,7 +42,7 @@ rfbSendCursorShape(cl)
CARD8 bitmapByte; CARD8 bitmapByte;
pCursor = cl->screen->getCursorPtr(cl); pCursor = cl->screen->getCursorPtr(cl);
//if(!pCursor) return TRUE; /*if(!pCursor) return TRUE;*/
if (cl->useRichCursorEncoding) { if (cl->useRichCursorEncoding) {
if(pCursor && !pCursor->richSource) if(pCursor && !pCursor->richSource)
@ -227,7 +227,7 @@ rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskSt
cursor->width=width; cursor->width=width;
cursor->height=height; cursor->height=height;
//cursor->backRed=cursor->backGreen=cursor->backBlue=0xffff; /*cursor->backRed=cursor->backGreen=cursor->backBlue=0xffff;*/
cursor->foreRed=cursor->foreGreen=cursor->foreBlue=0xffff; cursor->foreRed=cursor->foreGreen=cursor->foreBlue=0xffff;
cursor->source = (char*)calloc(w,height); cursor->source = (char*)calloc(w,height);

@ -67,10 +67,11 @@ void clientgone(rfbClientPtr cl)
free(cl->clientData); free(cl->clientData);
} }
void newclient(rfbClientPtr cl) enum rfbNewClientAction newclient(rfbClientPtr cl)
{ {
cl->clientData = (void*)calloc(sizeof(ClientData),1); cl->clientData = (void*)calloc(sizeof(ClientData),1);
cl->clientGoneHook = clientgone; cl->clientGoneHook = clientgone;
return RFB_CLIENT_ACCEPT;
} }
/* aux function to draw a line */ /* aux function to draw a line */

@ -92,7 +92,7 @@ httpInitSockets(rfbScreenInfoPtr rfbScreen)
exit(1); exit(1);
} }
//AddEnabledDevice(httpListenSock); /*AddEnabledDevice(httpListenSock);*/
} }
@ -151,7 +151,7 @@ httpCheckFds(rfbScreenInfoPtr rfbScreen)
return; return;
} }
//AddEnabledDevice(httpSock); /*AddEnabledDevice(httpSock);*/
} }
} }
@ -161,7 +161,7 @@ httpCloseSock(rfbScreenInfoPtr rfbScreen)
{ {
fclose(rfbScreen->httpFP); fclose(rfbScreen->httpFP);
rfbScreen->httpFP = NULL; rfbScreen->httpFP = NULL;
//RemoveEnabledDevice(httpSock); /*RemoveEnabledDevice(httpSock);*/
rfbScreen->httpSock = -1; rfbScreen->httpSock = -1;
} }

@ -41,7 +41,7 @@ char rfbEndianTest = (_BYTE_ORDER == _LITTLE_ENDIAN);
*/ */
void void
rfbLog(char *format, ...) rfbLog(const char *format, ...)
{ {
va_list args; va_list args;
char buf[256]; char buf[256];
@ -61,7 +61,7 @@ rfbLog(char *format, ...)
UNLOCK(logMutex); UNLOCK(logMutex);
} }
void rfbLogPerror(char *str) void rfbLogPerror(const char *str)
{ {
rfbLog("%s: %s\n", str, strerror(errno)); rfbLog("%s: %s\n", str, strerror(errno));
} }
@ -128,7 +128,7 @@ void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,in
} else { } else {
sraRgnOr(cl->modifiedRegion,copyRegion); sraRgnOr(cl->modifiedRegion,copyRegion);
} }
SIGNAL(cl->updateCond); TSIGNAL(cl->updateCond);
UNLOCK(cl->updateMutex); UNLOCK(cl->updateMutex);
} }
@ -186,7 +186,7 @@ void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion)
while((cl=rfbClientIteratorNext(iterator))) { while((cl=rfbClientIteratorNext(iterator))) {
LOCK(cl->updateMutex); LOCK(cl->updateMutex);
sraRgnOr(cl->modifiedRegion,modRegion); sraRgnOr(cl->modifiedRegion,modRegion);
SIGNAL(cl->updateCond); TSIGNAL(cl->updateCond);
UNLOCK(cl->updateMutex); UNLOCK(cl->updateMutex);
} }
@ -281,7 +281,7 @@ clientInput(void *data)
/* Get rid of the output thread. */ /* Get rid of the output thread. */
LOCK(cl->updateMutex); LOCK(cl->updateMutex);
SIGNAL(cl->updateCond); TSIGNAL(cl->updateCond);
UNLOCK(cl->updateMutex); UNLOCK(cl->updateMutex);
IF_PTHREADS(pthread_join(output_thread, NULL)); IF_PTHREADS(pthread_join(output_thread, NULL));
@ -290,31 +290,52 @@ clientInput(void *data)
return NULL; return NULL;
} }
void* static void*
listenerRun(void *data) listenerRun(void *data)
{ {
rfbScreenInfoPtr rfbScreen=(rfbScreenInfoPtr)data; rfbScreenInfoPtr rfbScreen=(rfbScreenInfoPtr)data;
int client_fd; int client_fd;
struct sockaddr_in peer; struct sockaddr_in peer;
pthread_t client_thread;
rfbClientPtr cl; rfbClientPtr cl;
int len; int len;
len = sizeof(peer); len = sizeof(peer);
/* TODO: this thread wont die by restarting the server */
while ((client_fd = accept(rfbScreen->rfbListenSock, while ((client_fd = accept(rfbScreen->rfbListenSock,
(struct sockaddr *)&peer, &len)) >= 0) { (struct sockaddr*)&peer, &len)) >= 0) {
cl = rfbNewClient(rfbScreen,client_fd); cl = rfbNewClient(rfbScreen,client_fd);
pthread_create(&client_thread, NULL, clientInput, (void *)cl);
len = sizeof(peer); len = sizeof(peer);
if (cl && !cl->onHold )
rfbStartOnHoldClient(cl);
} }
}
void
rfbStartOnHoldClient(rfbClientPtr cl)
{
pthread_create(&cl->client_thread, NULL, clientInput, (void *)cl);
}
rfbLog("accept failed\n"); #else
exit(1);
void
rfbStartOnHoldClient(rfbClientPtr cl)
{
cl->onHold = FALSE;
} }
#endif #endif
void void
rfbRefuseOnHoldClient(rfbClientPtr cl)
{
rfbCloseClient(cl);
rfbClientConnectionGone(cl);
}
static void
defaultKbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl) defaultKbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl)
{ {
} }
@ -423,6 +444,11 @@ void doNothingWithClient(rfbClientPtr cl)
{ {
} }
enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl)
{
return RFB_CLIENT_ACCEPT;
}
rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv, rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
int width,int height,int bitsPerSample,int samplesPerPixel, int width,int height,int bitsPerSample,int samplesPerPixel,
int bytesPerPixel) int bytesPerPixel)
@ -435,6 +461,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
if(width&3) if(width&3)
fprintf(stderr,"WARNING: Width (%d) is not a multiple of 4. VncViewer has problems with that.\n",width); fprintf(stderr,"WARNING: Width (%d) is not a multiple of 4. VncViewer has problems with that.\n",width);
rfbScreen->autoPort=FALSE;
rfbScreen->rfbClientHead=0; rfbScreen->rfbClientHead=0;
rfbScreen->rfbPort=5900; rfbScreen->rfbPort=5900;
rfbScreen->socketInitDone=FALSE; rfbScreen->socketInitDone=FALSE;
@ -536,7 +563,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
rfbScreen->setXCutText = defaultSetXCutText; rfbScreen->setXCutText = defaultSetXCutText;
rfbScreen->getCursorPtr = defaultGetCursorPtr; rfbScreen->getCursorPtr = defaultGetCursorPtr;
rfbScreen->setTranslateFunction = rfbSetTranslateFunction; rfbScreen->setTranslateFunction = rfbSetTranslateFunction;
rfbScreen->newClientHook = doNothingWithClient; rfbScreen->newClientHook = defaultNewClientHook;
rfbScreen->displayHook = 0; rfbScreen->displayHook = 0;
/* initialize client list and iterator mutex */ /* initialize client list and iterator mutex */
@ -597,7 +624,7 @@ rfbProcessEvents(rfbScreenInfoPtr rfbScreen,long usec)
i = rfbGetClientIterator(rfbScreen); i = rfbGetClientIterator(rfbScreen);
cl=rfbClientIteratorNext(i); cl=rfbClientIteratorNext(i);
while(cl) { while(cl) {
if(cl->sock>=0 && FB_UPDATE_PENDING(cl)) { if(cl->sock>=0 && (!cl->onHold) && FB_UPDATE_PENDING(cl)) {
if(cl->screen->rfbDeferUpdateTime == 0) { if(cl->screen->rfbDeferUpdateTime == 0) {
rfbSendFramebufferUpdate(cl,cl->modifiedRegion); rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
} else if(cl->startDeferring.tv_usec == 0) { } else if(cl->startDeferring.tv_usec == 0) {

74
rfb.h

@ -26,6 +26,11 @@
* USA. * USA.
*/ */
#if(defined __cplusplus)
extern "C"
{
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -90,7 +95,7 @@ typedef unsigned long KeySym;
#undef SOCKET #undef SOCKET
#define SOCKET int #define SOCKET int
#else #else
int max(int,int); #define max(a,b) (((a)>(b))?(a):(b))
#include <sys/time.h> #include <sys/time.h>
#include <netinet/in.h> #include <netinet/in.h>
#define SOCKET int #define SOCKET int
@ -116,7 +121,7 @@ int max(int,int);
#define MUTEX(mutex) pthread_mutex_t (mutex) #define MUTEX(mutex) pthread_mutex_t (mutex)
#define INIT_MUTEX(mutex) pthread_mutex_init(&(mutex),NULL) #define INIT_MUTEX(mutex) pthread_mutex_init(&(mutex),NULL)
#define TINI_MUTEX(mutex) pthread_mutex_destroy(&(mutex)) #define TINI_MUTEX(mutex) pthread_mutex_destroy(&(mutex))
#define SIGNAL(cond) pthread_cond_signal(&(cond)) #define TSIGNAL(cond) pthread_cond_signal(&(cond))
#define WAIT(cond,mutex) pthread_cond_wait(&(cond),&(mutex)) #define WAIT(cond,mutex) pthread_cond_wait(&(cond),&(mutex))
#define COND(cond) pthread_cond_t (cond) #define COND(cond) pthread_cond_t (cond)
#define INIT_COND(cond) pthread_cond_init(&(cond),NULL) #define INIT_COND(cond) pthread_cond_init(&(cond),NULL)
@ -129,7 +134,7 @@ int max(int,int);
#define MUTEX(mutex) #define MUTEX(mutex)
#define INIT_MUTEX(mutex) #define INIT_MUTEX(mutex)
#define TINI_MUTEX(mutex) #define TINI_MUTEX(mutex)
#define SIGNAL(cond) #define TSIGNAL(cond)
#define WAIT(cond,mutex) this_is_unsupported #define WAIT(cond,mutex) this_is_unsupported
#define COND(cond) #define COND(cond)
#define INIT_COND(cond) #define INIT_COND(cond)
@ -151,19 +156,25 @@ int max(int,int);
#define MAX_ENCODINGS 10 #define MAX_ENCODINGS 10
struct rfbClientRec; struct _rfbClientRec;
struct rfbScreenInfo; struct _rfbScreenInfo;
struct rfbCursor; struct rfbCursor;
typedef void (*KbdAddEventProcPtr) (Bool down, KeySym keySym, struct rfbClientRec* cl); enum rfbNewClientAction {
typedef void (*KbdReleaseAllKeysProcPtr) (struct rfbClientRec* cl); RFB_CLIENT_ACCEPT,
typedef void (*PtrAddEventProcPtr) (int buttonMask, int x, int y, struct rfbClientRec* cl); RFB_CLIENT_ON_HOLD,
typedef void (*SetXCutTextProcPtr) (char* str,int len, struct rfbClientRec* cl); RFB_CLIENT_REFUSE
typedef struct rfbCursor* (*GetCursorProcPtr) (struct rfbClientRec* pScreen); };
typedef Bool (*SetTranslateFunctionProcPtr)(struct rfbClientRec* cl);
typedef Bool (*PasswordCheckProcPtr)(struct rfbClientRec* cl,char* encryptedPassWord,int len); typedef void (*KbdAddEventProcPtr) (Bool down, KeySym keySym, struct _rfbClientRec* cl);
typedef void (*NewClientHookPtr)(struct rfbClientRec* cl); typedef void (*KbdReleaseAllKeysProcPtr) (struct _rfbClientRec* cl);
typedef void (*DisplayHookPtr)(struct rfbClientRec* cl); typedef void (*PtrAddEventProcPtr) (int buttonMask, int x, int y, struct _rfbClientRec* cl);
typedef void (*SetXCutTextProcPtr) (char* str,int len, struct _rfbClientRec* cl);
typedef struct rfbCursor* (*GetCursorProcPtr) (struct _rfbClientRec* pScreen);
typedef Bool (*SetTranslateFunctionProcPtr)(struct _rfbClientRec* cl);
typedef Bool (*PasswordCheckProcPtr)(struct _rfbClientRec* cl,char* encryptedPassWord,int len);
typedef enum rfbNewClientAction (*NewClientHookPtr)(struct _rfbClientRec* cl);
typedef void (*DisplayHookPtr)(struct _rfbClientRec* cl);
typedef struct { typedef struct {
CARD32 count; CARD32 count;
@ -180,7 +191,7 @@ typedef struct {
* rfbProcessEvents for each of these. * rfbProcessEvents for each of these.
*/ */
typedef struct typedef struct _rfbScreenInfo
{ {
int width; int width;
int paddedWidthInBytes; int paddedWidthInBytes;
@ -246,6 +257,7 @@ typedef struct
char* desktopName; char* desktopName;
char rfbThisHost[255]; char rfbThisHost[255];
Bool autoPort;
int rfbPort; int rfbPort;
SOCKET rfbListenSock; SOCKET rfbListenSock;
int maxSock; int maxSock;
@ -258,7 +270,7 @@ typedef struct
int udpPort; int udpPort;
SOCKET udpSock; SOCKET udpSock;
struct rfbClientRec* udpClient; struct _rfbClientRec* udpClient;
Bool udpSockConnected; Bool udpSockConnected;
struct sockaddr_in udpRemoteAddr; struct sockaddr_in udpRemoteAddr;
@ -282,7 +294,7 @@ typedef struct
Bool rfbAlwaysShared; Bool rfbAlwaysShared;
Bool rfbNeverShared; Bool rfbNeverShared;
Bool rfbDontDisconnect; Bool rfbDontDisconnect;
struct rfbClientRec* rfbClientHead; struct _rfbClientRec* rfbClientHead;
/* cursor */ /* cursor */
int cursorX, cursorY,underCursorBufferLen; int cursorX, cursorY,underCursorBufferLen;
@ -346,9 +358,9 @@ typedef struct sraRegion* sraRegionPtr;
* Per-client structure. * Per-client structure.
*/ */
typedef void (*ClientGoneHookPtr)(struct rfbClientRec* cl); typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl);
typedef struct rfbClientRec { typedef struct _rfbClientRec {
/* back pointer to the screen */ /* back pointer to the screen */
rfbScreenInfoPtr screen; rfbScreenInfoPtr screen;
@ -364,6 +376,10 @@ typedef struct rfbClientRec {
SOCKET sock; SOCKET sock;
char *host; char *host;
#ifdef HAVE_PTHREADS
pthread_t client_thread;
#endif
/* Possible client states: */ /* Possible client states: */
enum { enum {
RFB_PROTOCOL_VERSION, /* establishing protocol version */ RFB_PROTOCOL_VERSION, /* establishing protocol version */
@ -373,6 +389,7 @@ typedef struct rfbClientRec {
} state; } state;
Bool reverseConnection; Bool reverseConnection;
Bool onHold;
Bool readyForSetColourMapEntries; Bool readyForSetColourMapEntries;
Bool useCopyRect; Bool useCopyRect;
int preferredEncoding; int preferredEncoding;
@ -477,8 +494,8 @@ typedef struct rfbClientRec {
Bool enableBackChannel; Bool enableBackChannel;
#endif #endif
struct rfbClientRec *prev; struct _rfbClientRec *prev;
struct rfbClientRec *next; struct _rfbClientRec *next;
#ifdef HAVE_PTHREADS #ifdef HAVE_PTHREADS
/* whenever a client is referenced, the refCount has to be incremented /* whenever a client is referenced, the refCount has to be incremented
@ -741,8 +758,8 @@ extern void rfbProcessSizeArguments(int* width,int* height,int* bpp,int* argc, c
/* main.c */ /* main.c */
extern void rfbLog(char *format, ...); extern void rfbLog(const char *format, ...);
extern void rfbLogPerror(char *str); extern void rfbLogPerror(const char *str);
void rfbScheduleCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy); void rfbScheduleCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy);
void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy); void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy);
@ -753,6 +770,7 @@ void rfbDoCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,i
void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2); void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2);
void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion); void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion);
void doNothingWithClient(rfbClientPtr cl); void doNothingWithClient(rfbClientPtr cl);
enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl);
/* to check against plain passwords */ /* to check against plain passwords */
Bool rfbCheckPasswordByList(rfbClientPtr cl,char* response,int len); Bool rfbCheckPasswordByList(rfbClientPtr cl,char* response,int len);
@ -764,6 +782,12 @@ extern rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
extern void rfbInitServer(rfbScreenInfoPtr rfbScreen); extern void rfbInitServer(rfbScreenInfoPtr rfbScreen);
extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo); extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo);
/* functions to accept/refuse a client that has been put on hold
by a NewClientHookPtr function. Must not be called in other
situations. */
extern void rfbStartOnHoldClient(rfbClientPtr cl);
extern void rfbRefuseOnHoldClient(rfbClientPtr cl);
/* call one of these two functions to service the vnc clients. /* call one of these two functions to service the vnc clients.
usec are the microseconds the select on the fds waits. usec are the microseconds the select on the fds waits.
if you are using the event loop, set this to some value > 0, so the if you are using the event loop, set this to some value > 0, so the
@ -773,3 +797,7 @@ extern void rfbRunEventLoop(rfbScreenInfoPtr screenInfo, long usec, Bool runInBa
extern void rfbProcessEvents(rfbScreenInfoPtr screenInfo,long usec); extern void rfbProcessEvents(rfbScreenInfoPtr screenInfo,long usec);
#endif #endif
#if(defined __cplusplus)
}
#endif

@ -61,7 +61,7 @@ void rfbDecrClientRef(rfbClientPtr cl)
LOCK(cl->refCountMutex); LOCK(cl->refCountMutex);
cl->refCount--; cl->refCount--;
if(cl->refCount<=0) /* just to be sure also < 0 */ if(cl->refCount<=0) /* just to be sure also < 0 */
SIGNAL(cl->deleteCond); TSIGNAL(cl->deleteCond);
UNLOCK(cl->refCountMutex); UNLOCK(cl->refCountMutex);
} }
#endif #endif
@ -271,14 +271,29 @@ rfbNewTCPOrUDPClient(rfbScreen,sock,isUDP)
if (WriteExact(cl, pv, sz_rfbProtocolVersionMsg) < 0) { if (WriteExact(cl, pv, sz_rfbProtocolVersionMsg) < 0) {
rfbLogPerror("rfbNewClient: write"); rfbLogPerror("rfbNewClient: write");
rfbCloseClient(cl); rfbCloseClient(cl);
/* TODO: memory leak here (cl is never freed)
* can rfbClientConnectionGone called at this time?
* tim@tjansen.de
*/
return NULL; return NULL;
} }
} }
cl->clientData = NULL; cl->clientData = NULL;
cl->clientGoneHook = doNothingWithClient; cl->clientGoneHook = doNothingWithClient;
cl->screen->newClientHook(cl); switch (cl->screen->newClientHook(cl)) {
case RFB_CLIENT_ON_HOLD:
cl->onHold = TRUE;
break;
case RFB_CLIENT_ACCEPT:
cl->onHold = FALSE;
break;
case RFB_CLIENT_REFUSE:
rfbCloseClient(cl);
rfbClientConnectionGone(cl);
cl = NULL;
break;
}
return cl; return cl;
} }
@ -781,7 +796,7 @@ rfbProcessClientNormalMessage(cl)
sraRgnOr(cl->modifiedRegion,tmpRegion); sraRgnOr(cl->modifiedRegion,tmpRegion);
sraRgnSubtract(cl->copyRegion,tmpRegion); sraRgnSubtract(cl->copyRegion,tmpRegion);
} }
SIGNAL(cl->updateCond); TSIGNAL(cl->updateCond);
UNLOCK(cl->updateMutex); UNLOCK(cl->updateMutex);
sraRgnDestroy(tmpRegion); sraRgnDestroy(tmpRegion);
@ -1431,7 +1446,7 @@ rfbProcessUDPInput(rfbScreenInfoPtr rfbScreen)
rfbClientPtr cl=rfbScreen->udpClient; rfbClientPtr cl=rfbScreen->udpClient;
rfbClientToServerMsg msg; rfbClientToServerMsg msg;
if(!cl) if((!cl) || cl->onHold)
return; return;
if ((n = read(rfbScreen->udpSock, (char *)&msg, sizeof(msg))) <= 0) { if ((n = read(rfbScreen->udpSock, (char *)&msg, sizeof(msg))) <= 0) {

@ -69,9 +69,10 @@ struct timeval
#include "rfb.h" #include "rfb.h"
//#ifndef WIN32 /*#ifndef WIN32
int max(int i,int j) { return(i<j?j:i); } int max(int i,int j) { return(i<j?j:i); }
//#endif #endif
*/
int rfbMaxClientWait = 20000; /* time (ms) after which we decide client has int rfbMaxClientWait = 20000; /* time (ms) after which we decide client has
gone away - needed to stop us hanging */ gone away - needed to stop us hanging */
@ -111,7 +112,28 @@ rfbInitSockets(rfbScreenInfoPtr rfbScreen)
return; return;
} }
if(rfbScreen->rfbPort>0) { if(rfbScreen->autoPort) {
int i;
rfbLog("Autoprobing TCP port \n");
for (i = 5900; i < 6000; i++) {
if ((rfbScreen->rfbListenSock = ListenOnTCPPort(i)) >= 0) {
rfbScreen->rfbPort = i;
break;
}
}
if (i >= 6000) {
rfbLogPerror("Failure autoprobing");
exit(1);
}
rfbLog("Autoprobing selected port %d\n", rfbScreen->rfbPort);
FD_ZERO(&(rfbScreen->allFds));
FD_SET(rfbScreen->rfbListenSock, &(rfbScreen->allFds));
rfbScreen->maxFd = rfbScreen->rfbListenSock;
}
else if(rfbScreen->rfbPort>0) {
rfbLog("Listening for VNC connections on TCP port %d\n", rfbScreen->rfbPort); rfbLog("Listening for VNC connections on TCP port %d\n", rfbScreen->rfbPort);
if ((rfbScreen->rfbListenSock = ListenOnTCPPort(rfbScreen->rfbPort)) < 0) { if ((rfbScreen->rfbListenSock = ListenOnTCPPort(rfbScreen->rfbPort)) < 0) {
@ -204,7 +226,7 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr)); rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));
rfbNewClient(rfbScreen,sock); rfbNewClient(rfbScreen,sock);
FD_CLR(rfbScreen->rfbListenSock, &fds); FD_CLR(rfbScreen->rfbListenSock, &fds);
if (--nfds == 0) if (--nfds == 0)
return; return;
@ -248,6 +270,8 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
i = rfbGetClientIterator(rfbScreen); i = rfbGetClientIterator(rfbScreen);
while((cl = rfbClientIteratorNext(i))) { while((cl = rfbClientIteratorNext(i))) {
if (cl->onHold)
continue;
if (FD_ISSET(cl->sock, &fds) && FD_ISSET(cl->sock, &(rfbScreen->allFds))) if (FD_ISSET(cl->sock, &fds) && FD_ISSET(cl->sock, &(rfbScreen->allFds)))
rfbProcessClientMessage(cl); rfbProcessClientMessage(cl);
} }
@ -268,10 +292,12 @@ rfbCloseClient(cl)
rfbClientPtr cl; rfbClientPtr cl;
{ {
LOCK(cl->updateMutex); LOCK(cl->updateMutex);
FD_CLR(cl->sock,&(cl->screen->allFds)); if (cl->sock != -1) {
close(cl->sock); FD_CLR(cl->sock,&(cl->screen->allFds));
cl->sock = -1; close(cl->sock);
SIGNAL(cl->updateCond); cl->sock = -1;
}
TSIGNAL(cl->updateCond);
UNLOCK(cl->updateMutex); UNLOCK(cl->updateMutex);
} }
@ -360,7 +386,7 @@ ReadExact(cl, buf, len)
FD_SET(sock, &fds); FD_SET(sock, &fds);
tv.tv_sec = rfbMaxClientWait / 1000; tv.tv_sec = rfbMaxClientWait / 1000;
tv.tv_usec = (rfbMaxClientWait % 1000) * 1000; tv.tv_usec = (rfbMaxClientWait % 1000) * 1000;
n = select(sock+1, &fds, NULL, NULL, &tv); n = select(sock+1, &fds, NULL, &fds, &tv);
if (n < 0) { if (n < 0) {
rfbLogPerror("ReadExact: select"); rfbLogPerror("ReadExact: select");
return n; return n;

@ -24,7 +24,7 @@
* USA. * USA.
*/ */
//#include <stdio.h> /*#include <stdio.h>*/
#include "rfb.h" #include "rfb.h"
#ifdef WIN32 #ifdef WIN32
@ -35,7 +35,6 @@
#include <jpeglib.h> #include <jpeglib.h>
/* Note: The following constant should not be changed. */ /* Note: The following constant should not be changed. */
#define TIGHT_MIN_TO_COMPRESS 12 #define TIGHT_MIN_TO_COMPRESS 12

@ -259,8 +259,9 @@ rfbSetTranslateFunction(cl)
#endif #endif
(cl->screen->rfbServerFormat.bitsPerPixel != 32)) (cl->screen->rfbServerFormat.bitsPerPixel != 32))
{ {
rfbLog("%s: server bits per pixel not 8, 16 or 32\n", rfbLog("%s: server bits per pixel not 8, 16 or 32 (is %d)\n",
"rfbSetTranslateFunction"); "rfbSetTranslateFunction",
cl->screen->rfbServerFormat.bitsPerPixel);
rfbCloseClient(cl); rfbCloseClient(cl);
return FALSE; return FALSE;
} }

Loading…
Cancel
Save