summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--libvncserver/cargs.c25
-rw-r--r--libvncserver/main.c38
-rw-r--r--libvncserver/rfbserver.c43
-rwxr-xr-xlibvncserver/sockets.c7
-rw-r--r--rfb/rfb.h31
6 files changed, 140 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 42e21a6..17a6187 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-09-27 Rohit Kumar <rokumar@novell.com>
+ * libvncserver/{cargs,sockets,main,rfbserver}.c,
+ rfb/rfb.h: Provide a generic means to extend the RFB
+ protocol: rfbRegisterProtocolExtension(extension). This
+ deprecates the current (very limited) option to override
+ rfbScreenInfoPtr->processCustomClientMessage(client).
+
2005-09-26 Rohit Kumar <rokumar@novell.com>
* libvncserver/{auth,main,rfbserver}.c, rfb/{rfb,rfbproto}.h:
support VNC protocol version 3.7. This allows to add security
diff --git a/libvncserver/cargs.c b/libvncserver/cargs.c
index d0e3309..10926a9 100644
--- a/libvncserver/cargs.c
+++ b/libvncserver/cargs.c
@@ -19,6 +19,8 @@ extern int rfbStringToAddr(char *str, in_addr_t *iface);
void
rfbUsage(void)
{
+ rfbProtocolExtension* extension;
+
fprintf(stderr, "-rfbport port TCP port for RFB protocol\n");
fprintf(stderr, "-rfbwait time max time in ms to wait for RFB client\n");
fprintf(stderr, "-rfbauth passwd-file use authentication on RFB protocol\n"
@@ -40,6 +42,11 @@ rfbUsage(void)
fprintf(stderr, "-progressive height enable progressive updating for slow links\n");
fprintf(stderr, "-listen ipaddr listen for connections only on network interface with\n");
fprintf(stderr, " addr ipaddr. '-listen localhost' and hostname work too.\n");
+
+ for(extension=rfbGetExtensionIterator();extension;extension=extension->next)
+ if(extension->usage)
+ extension->usage();
+ rfbReleaseExtensionIterator();
}
/* purges COUNT arguments from ARGV at POSITION and decrements ARGC.
@@ -138,9 +145,21 @@ rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[])
return FALSE;
}
} else {
- i++;
- i1=i;
- continue;
+ rfbProtocolExtension* extension;
+ int handled=0;
+
+ for(extension=rfbGetExtensionIterator();handled==0 && extension;
+ extension=extension->next)
+ if(extension->processArgument)
+ handled = extension->processArgument(argv + i);
+ rfbReleaseExtensionIterator();
+
+ if(handled==0) {
+ i++;
+ i1=i;
+ continue;
+ }
+ i+=handled-1;
}
/* we just remove the processed arguments from the list */
rfbPurgeArguments(argc,&i1,i-i1+1,argv);
diff --git a/libvncserver/main.c b/libvncserver/main.c
index a9161ce..905bb83 100644
--- a/libvncserver/main.c
+++ b/libvncserver/main.c
@@ -40,6 +40,7 @@
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
static MUTEX(logMutex);
+static MUTEX(extMutex);
#endif
static int rfbEnableLogging=1;
@@ -50,6 +51,43 @@ char rfbEndianTest = 0;
char rfbEndianTest = -1;
#endif
+/*
+ * Protocol extensions
+ */
+
+static rfbProtocolExtension* rfbExtensionHead = NULL;
+
+void
+rfbRegisterProtocolExtension(rfbProtocolExtension* extension)
+{
+ rfbProtocolExtension* last;
+
+ LOCK(extMutex);
+ last = extension;
+
+ while(last->next)
+ last = last->next;
+
+ last->next = rfbExtensionHead;
+ rfbExtensionHead = extension;
+ UNLOCK(extMutex);
+}
+
+rfbProtocolExtension* rfbGetExtensionIterator()
+{
+ LOCK(extMutex);
+ return rfbExtensionHead;
+}
+
+void rfbReleaseExtensionIterator()
+{
+ UNLOCK(extMutex);
+}
+
+/*
+ * Logging
+ */
+
void rfbLogEnable(int enabled) {
rfbEnableLogging=enabled;
}
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index 1f71a18..730c789 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -3,6 +3,7 @@
*/
/*
+ * Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin
* Copyright (C) 2002 RealVNC Ltd.
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
@@ -347,6 +348,8 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
cl->progressiveSliceY = 0;
+ cl->extensions = NULL;
+
sprintf(pv,rfbProtocolVersionFormat,rfbProtocolMajorVersion,
rfbProtocolMinorVersion);
@@ -603,6 +606,7 @@ rfbProcessClientInitMessage(rfbClientPtr cl)
int len, n;
rfbClientIteratorPtr iterator;
rfbClientPtr otherCl;
+ rfbProtocolExtension* extension;
if ((n = rfbReadExact(cl, (char *)&ci,sz_rfbClientInitMsg)) <= 0) {
if (n == 0)
@@ -613,7 +617,7 @@ rfbProcessClientInitMessage(rfbClientPtr cl)
return;
}
- memset(buf,0,256);
+ memset(buf,0,sizeof(buf));
si->framebufferWidth = Swap16IfLE(cl->screen->width);
si->framebufferHeight = Swap16IfLE(cl->screen->height);
@@ -632,6 +636,19 @@ rfbProcessClientInitMessage(rfbClientPtr cl)
return;
}
+ for(extension=rfbGetExtensionIterator();extension;extension=extension->next)
+ if(extension->init) {
+ void* data;
+ if(extension->init(cl, &data)) {
+ rfbExtensionData* extensionData=calloc(sizeof(rfbExtensionData),1);
+ extensionData->extension=extension;
+ extensionData->data=data;
+ extensionData->next=cl->extensions;
+ cl->extensions=extensionData;
+ }
+ }
+ rfbReleaseExtensionIterator();
+
cl->state = RFB_NORMAL;
if (!cl->reverseConnection &&
@@ -1046,15 +1063,27 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
default:
+ {
+ rfbExtensionData* extension;
+
+ for(extension=cl->extensions; extension; extension=extension->next)
+ if(extension->extension->handleMessage &&
+ extension->extension->handleMessage(cl, extension->data, msg))
+ return;
- if(cl->screen->processCustomClientMessage(cl,msg.type))
+ if(cl->screen->processCustomClientMessage(cl,msg.type)) {
+ rfbLog("Warning: this program uses processCustomClientMessage, "
+ "which is deprecated.\n"
+ "Please use rfbRegisterProtocolExtension instead.\n");
return;
+ }
- rfbLog("rfbProcessClientNormalMessage: unknown message type %d\n",
- msg.type);
- rfbLog(" ... closing connection\n");
- rfbCloseClient(cl);
- return;
+ rfbLog("rfbProcessClientNormalMessage: unknown message type %d\n",
+ msg.type);
+ rfbLog(" ... closing connection\n");
+ rfbCloseClient(cl);
+ return;
+ }
}
}
diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c
index 24a787d..44843c2 100755
--- a/libvncserver/sockets.c
+++ b/libvncserver/sockets.c
@@ -19,6 +19,7 @@
*/
/*
+ * Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* All Rights Reserved.
@@ -344,6 +345,12 @@ rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen)
void
rfbCloseClient(rfbClientPtr cl)
{
+ rfbExtensionData* extension;
+
+ for(extension=cl->extensions; extension; extension=extension->next)
+ if(extension->extension->close)
+ extension->extension->close(cl, extension->data);
+
LOCK(cl->updateMutex);
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
if (cl->sock != -1)
diff --git a/rfb/rfb.h b/rfb/rfb.h
index 4254016..bac805c 100644
--- a/rfb/rfb.h
+++ b/rfb/rfb.h
@@ -145,7 +145,7 @@ typedef struct {
} rfbColourMap;
/*
- * Security handling (RFB protocol version 3.7
+ * Security handling (RFB protocol version 3.7)
*/
typedef struct _rfbSecurity {
@@ -154,6 +154,29 @@ typedef struct _rfbSecurity {
struct _rfbSecurity* next;
} rfbSecurityHandler;
+/*
+ * Protocol extension handling.
+ */
+
+typedef struct _rfbProtocolExtension {
+ /* returns TRUE if extension should be activated */
+ rfbBool (*init)(struct _rfbClientRec* client, void** data);
+ /* returns TRUE if message was handled */
+ rfbBool (*handleMessage)(struct _rfbClientRec* client,
+ void* data,
+ rfbClientToServerMsg message);
+ void (*close)(struct _rfbClientRec* client, void* data);
+ void (*usage)(void);
+ /* processArguments returns the number of handled arguments */
+ int (*processArgument)(char *argv[]);
+ struct _rfbProtocolExtension* next;
+} rfbProtocolExtension;
+
+typedef struct _rfbExtensionData {
+ rfbProtocolExtension* extension;
+ void* data;
+ struct _rfbExtensionData* next;
+} rfbExtensionData;
/*
* Per-screen (framebuffer) structure. There can be as many as you wish,
@@ -481,6 +504,8 @@ typedef struct _rfbClientRec {
/* if progressive updating is on, this variable holds the current
* y coordinate of the progressive slice. */
int progressiveSliceY;
+
+ rfbExtensionData* extensions;
} rfbClientRec, *rfbClientPtr;
/*
@@ -760,6 +785,10 @@ void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y
void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion);
void rfbDoNothingWithClient(rfbClientPtr cl);
enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl);
+void rfbRegisterProtocolExtension(rfbProtocolExtension* extension);
+struct _rfbProtocolExtension* rfbGetExtensionIterator();
+void rfbReleaseExtensionIterator();
+rfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension);
/* to check against plain passwords */
rfbBool rfbCheckPasswordByList(rfbClientPtr cl,const char* response,int len);
OpenPOWER on IntegriCloud