From d3599be1b822b2afa3d27c2eca50c08edb9e5622 Mon Sep 17 00:00:00 2001
From: dscho <dscho>
Date: Wed, 22 Feb 2006 13:03:22 +0000
Subject: add functions to unregister extensions/security types

---
 ChangeLog                                          |  4 ++
 libvncserver/auth.c                                | 58 +++++++++++++++--
 libvncserver/main.c                                | 73 ++++++++++++++++++++--
 .../tightvnc-filetransfer/rfbtightserver.c         |  5 ++
 rfb/rfb.h                                          |  3 +
 5 files changed, 134 insertions(+), 9 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f352e35..c7c715f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2006-02-22  Rohit Kumar <rokumar@novell.com>
+	* auth.c, main.c, rfbtightserver.c, rfb.h: add methods to
+	  unregister extensions and security types.
+
 2006-02-20  Karl Runge <runge@karlrunge.com>
 	* main.c, cursor.c, tightvnc-filetransfer: fix some non-gcc
 	  compiler warnings.
diff --git a/libvncserver/auth.c b/libvncserver/auth.c
index e3a89eb..fd4c487 100755
--- a/libvncserver/auth.c
+++ b/libvncserver/auth.c
@@ -35,18 +35,68 @@
 
 static rfbSecurityHandler* securityHandlers = NULL;
 
+/*
+ * This method registers a list of new security types.  
+ * It avoids same security type getting registered multiple times. 
+ * The order is not preserved if multiple security types are
+ * registered at one-go.
+ */
 void
 rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
 {
-	rfbSecurityHandler* last = handler;
+	rfbSecurityHandler *head = securityHandlers, *next = NULL;
+
+	if(handler == NULL)
+		return;
 
-	while(last->next)
-		last = last->next;
+	next = handler->next;
 
-	last->next = securityHandlers;
+	while(head != NULL) {
+		if(head == handler) {
+			rfbRegisterSecurityHandler(next);
+			return;
+		}
+
+		head = head->next;
+	}
+
+	handler->next = securityHandlers;
 	securityHandlers = handler;
+
+	rfbRegisterSecurityHandler(next);
 }
 
+/*
+ * This method unregisters a list of security types. 
+ * These security types won't be available for any new
+ * client connection. 
+ */
+void
+rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
+{
+	rfbSecurityHandler *cur = NULL, *pre = NULL;
+
+	if(handler == NULL)
+		return;
+
+	if(securityHandlers == handler) {
+		securityHandlers = securityHandlers->next;
+		rfbUnregisterSecurityHandler(handler->next);
+		return;
+	}
+
+	cur = pre = securityHandlers;
+
+	while(cur) {
+		if(cur == handler) {
+			pre->next = cur->next;
+			break;
+		}
+		pre = cur;
+		cur = cur->next;
+	}
+	rfbUnregisterSecurityHandler(handler->next);
+}
 
 /*
  * Send the authentication challenge.
diff --git a/libvncserver/main.c b/libvncserver/main.c
index ada1a7a..bf14062 100644
--- a/libvncserver/main.c
+++ b/libvncserver/main.c
@@ -59,10 +59,21 @@ char rfbEndianTest = -1;
 
 static rfbProtocolExtension* rfbExtensionHead = NULL;
 
+/*
+ * This method registers a list of new extensions.  
+ * It avoids same extension getting registered multiple times. 
+ * The order is not preserved if multiple extensions are
+ * registered at one-go.
+ */
 void
 rfbRegisterProtocolExtension(rfbProtocolExtension* extension)
 {
-	rfbProtocolExtension* last;
+	rfbProtocolExtension *head = rfbExtensionHead, *next = NULL;
+
+	if(extension == NULL)
+		return;
+
+	next = extension->next;
 
 	if (! extMutex_initialized) {
 		INIT_MUTEX(extMutex);
@@ -70,14 +81,66 @@ rfbRegisterProtocolExtension(rfbProtocolExtension* extension)
 	}
 
 	LOCK(extMutex);
-	last = extension;
 
-	while(last->next)
-		last = last->next;
+	while(head != NULL) {
+		if(head == extension) {
+			UNLOCK(extMutex);
+			rfbRegisterProtocolExtension(next);
+			return;
+		}
+
+		head = head->next;
+	}
 
-	last->next = rfbExtensionHead;
+	extension->next = rfbExtensionHead;
 	rfbExtensionHead = extension;
+
+	UNLOCK(extMutex);
+	rfbRegisterProtocolExtension(next);
+}
+
+/*
+ * This method unregisters a list of extensions.  
+ * These extensions won't be available for any new
+ * client connection. 
+ */
+void
+rfbUnregisterProtocolExtension(rfbProtocolExtension* extension)
+{
+
+	rfbProtocolExtension *cur = NULL, *pre = NULL;
+
+	if(extension == NULL)
+		return;
+
+	if (! extMutex_initialized) {
+		INIT_MUTEX(extMutex);
+		extMutex_initialized = 1;
+	}
+
+	LOCK(extMutex);
+
+	if(rfbExtensionHead == extension) {
+		rfbExtensionHead = rfbExtensionHead->next;
+		UNLOCK(extMutex);
+		rfbUnregisterProtocolExtension(extension->next);
+		return;
+	}
+
+	cur = pre = rfbExtensionHead;
+
+	while(cur) {
+		if(cur == extension) {
+			pre->next = cur->next;
+			break;
+		}
+		pre = cur;
+		cur = cur->next;
+	}
+
 	UNLOCK(extMutex);
+
+	rfbUnregisterProtocolExtension(extension->next);
 }
 
 rfbProtocolExtension* rfbGetExtensionIterator()
diff --git a/libvncserver/tightvnc-filetransfer/rfbtightserver.c b/libvncserver/tightvnc-filetransfer/rfbtightserver.c
index 933025f..2acfa9c 100644
--- a/libvncserver/tightvnc-filetransfer/rfbtightserver.c
+++ b/libvncserver/tightvnc-filetransfer/rfbtightserver.c
@@ -506,4 +506,9 @@ void rfbRegisterTightVNCFileTransferExtension() {
 	rfbRegisterSecurityHandler(&tightVncSecurityHandler);
 }
 
+void 
+rfbUnregisterTightVNCFileTransferExtension() {
+	rfbUnregisterProtocolExtension(&tightVncFileTransferExtension);
+	rfbUnregisterSecurityHandler(&tightVncSecurityHandler);
+}
 
diff --git a/rfb/rfb.h b/rfb/rfb.h
index c2abb0e..a4d0b39 100644
--- a/rfb/rfb.h
+++ b/rfb/rfb.h
@@ -631,6 +631,7 @@ extern void rfbAuthNewClient(rfbClientPtr cl);
 extern void rfbProcessClientSecurityType(rfbClientPtr cl);
 extern void rfbAuthProcessClientMessage(rfbClientPtr cl);
 extern void rfbRegisterSecurityHandler(rfbSecurityHandler* handler);
+extern void rfbUnregisterSecurityHandler(rfbSecurityHandler* handler);
 
 /* rre.c */
 
@@ -792,6 +793,7 @@ void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion);
 void rfbDoNothingWithClient(rfbClientPtr cl);
 enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl);
 void rfbRegisterProtocolExtension(rfbProtocolExtension* extension);
+void rfbUnregisterProtocolExtension(rfbProtocolExtension* extension);
 struct _rfbProtocolExtension* rfbGetExtensionIterator();
 void rfbReleaseExtensionIterator();
 rfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension,
@@ -831,6 +833,7 @@ extern rfbBool rfbIsActive(rfbScreenInfoPtr screenInfo);
 
 /* TightVNC file transfer extension */
 void rfbRegisterTightVNCFileTransferExtension();
+void rfbUnregisterTightVNCFileTransferExtension(); 
 
 #endif
 
-- 
cgit v1.2.3

