Index: /trunk/FACT++/dim/README_v20.txt
===================================================================
--- /trunk/FACT++/dim/README_v20.txt	(revision 18919)
+++ /trunk/FACT++/dim/README_v20.txt	(revision 18920)
@@ -1,4 +1,4 @@
 
-                    DIM version 20r15 Release Notes
+                    DIM version 20r20 Release Notes
 
 Notes 1 and 2 for Unix Users only
@@ -17,10 +17,57 @@
 		Dns </dev/null >& dns.log &
 
-NOTE 3: The Version Number service provided by servers is now set to 2015.
+NOTE 3: The Version Number service provided by servers is now set to 2020.
+
+06/07/2017
+Changes for version 2020:
+    - All DIM log messages can now be caught by declaring an error_hlandler.
+    - Connect calls now use a non-blocking socket to avoit blocking for a long time (particularly in Windows).
+    - New re-designed version of webDid.
+    - Added conditional compilation settings for LABVIEWGSI/PHARLAP.
+
+
+20/01/2017
+Changes for version 2019:
+    - Changed slightly the definition of DIM constants in C++, they clashed with LHCb/ROOT software.
+    - A server didn't work properly when declaring the same server name to two different dnss.
+      Although this is still not allowed, because it would mean several services with the same name
+      in the same server (and couldn't resolve which one should be sent to which client), now
+      if the user declares the same server name a "-n" (where n is the dns instance number) will
+      be appended to the server name.
+    - Fixed a bug reported by Alice, whereby if a tcpip error (broken pipe) got received when
+      updating a service following a client request, the server would crash.
+    - Fixed a deadlock in C++ 
+
+
+30/06/2016
+Changes for version 2018:
+    - Removed the function do_dis_add_cmnd(), had became obsolete by do_dis_add_cmnd_dns().
+    - DIM now accepts servers to keep running even though they publish duplicated services:
+      - If all services are duplicated the server will exit like before
+      - If the server name is duplicated the server will also exit like before
+      - Otherwise the server will keep running providing only the non-duplicated services
+      - The server will print the name of each duplicated service to the logfile/stdout
+      - A DIM error handler can be installed by the user to detect or change this behaviour
+      - This new feature can only be used if both the Server and the DNS are using this new version
+        (otherwise the old behaviour will occur) 
+    - The DimBrowser class now accepts to browse over DIM Servers with no name 
+
+
+24/03/2016
+Changes for version 2017:
+    - Removed the function do_dis_add_service(), became obsolete by do_dis_add_service_dns().
+    - On Windows servers might not reconnect after DNS restart. Bug introduced in version v20r14 
+      (when the keepalive mechanism was introduced for TCPIP client connections). Fixed.
+
+
+04/12/2015
+Changes for version 2016:
+    - DIM had stopped working on MAC OS X, since v20r12 and the replacement of select() by poll().
+      This is now fixed.
+
 
 01/09/2015
 Changes for version 2015:
     - A DIM Server did not properly accept a DimServer::stop(), folowed by a DimServer::start(),
-      also DID didn't cope with the above, in particular if the server changed name - Fixed.
 
 
Index: /trunk/FACT++/dim/WebDID/did.js
===================================================================
--- /trunk/FACT++/dim/WebDID/did.js	(revision 18919)
+++ /trunk/FACT++/dim/WebDID/did.js	(revision 18920)
@@ -386,4 +386,5 @@
     {
 	serviceInfoArea.update("Updating - state "+HTTPPacket.readyState+"...");
+console.log("receiveing", HTTPPacket.readyState);
 	if ( HTTPPacket.readyState != 4 )
 		return; 
@@ -399,4 +400,5 @@
 //		{
 			serviceInfoArea.update(HTTPPacket.responseText);
+console.log("received answer", HTTPPacket.responseText);
 			serviceInfoArea.setVisible(1);
 			commandInfoArea.setVisible(0);
Index: /trunk/FACT++/dim/dim/dim.h
===================================================================
--- /trunk/FACT++/dim/dim/dim.h	(revision 18919)
+++ /trunk/FACT++/dim/dim/dim.h	(revision 18920)
@@ -14,9 +14,14 @@
 #include "dim_common.h"
 
-#define DIM_VERSION_NUMBER 2015
-
-
+#define DIM_VERSION_NUMBER 2020
+
+#ifdef LABVIEWGSI
+/*this is a hack, but we have to overcome the problem that LabVIEW uses Motorola endian on an Intel machine*/
+#define MY_LITTLE_ENDIAN	0x2
+#define MY_BIG_ENDIAN 		0x1
+#else
 #define MY_LITTLE_ENDIAN	0x1
 #define MY_BIG_ENDIAN 		0x2
+#endif
 
 #define VAX_FLOAT		0x10
@@ -163,5 +168,10 @@
 #define MAX_CONNS		1024
 #define ID_BLOCK		512
+#ifdef LABVIEWGSI
+/*changed buffer size to allow LabVIEW to connect to itself*/
+#define TCP_RCV_BUF_SIZE	/*16384*//*32768*//*65536*/262144
+#else
 #define TCP_RCV_BUF_SIZE	/*16384*//*32768*/65536
+#endif
 #define TCP_SND_BUF_SIZE	/*16384*//*32768*/65536
 #endif
@@ -205,4 +215,9 @@
 #define	TEST_WRITE_TAG		25		/* DTQ tag for test writes   */
 #define	WRITE_TMOUT			5		/* Interval to wait while writing.    */
+#ifndef WIN32
+#define	CONNECT_TMOUT		1		/* Interval to wait while connecting.    */
+#else
+#define	CONNECT_TMOUT		2		/* Interval to wait while connecting.    */
+#endif
 
 #define	OPN_MAGIC		0xc0dec0de	/* Magic value 1st packet    */
@@ -287,4 +302,5 @@
 	int size;
 	int type;
+	char dup_info[1];
 } DNS_DIS_PACKET;
 
Index: /trunk/FACT++/dim/dim/dim_common.h
===================================================================
--- /trunk/FACT++/dim/dim/dim_common.h	(revision 18919)
+++ /trunk/FACT++/dim/dim/dim_common.h	(revision 18920)
@@ -1,8 +1,23 @@
-#ifndef __COMMONDEFS
-#define __COMMONDEFS
+#ifndef __DIM_COMMONDEFS
+#define __DIM_COMMONDEFS
 
 /* Service type definition */
 
-#ifndef ONCE_ONLY
+#ifndef DIM_DEFINITIONS_DECLARED
+#define DIM_DEFINITIONS_DECLARED
+
+#ifdef __cplusplus
+static const int ONCE_ONLY=	0x01;
+static const int TIMED=		0x02;
+static const int MONITORED=	0x04;
+static const int COMMAND=	0x08;
+static const int DIM_DELETE=	0x10;
+static const int MONIT_ONLY=	0x20;
+static const int UPDATE=	0x40;
+static const int TIMED_ONLY=	0x80;
+static const int MONIT_FIRST=   0x100;
+static const int MAX_TYPE_DEF=  0x100;
+static const int STAMPED=       0x1000;
+#else
 #define ONCE_ONLY	0x01
 #define TIMED		0x02
@@ -16,4 +31,5 @@
 #define MAX_TYPE_DEF    0x100
 #define STAMPED       0x1000
+#endif
 
 typedef enum { SRC_NONE, SRC_DIS, SRC_DIC, SRC_DNS, SRC_DNA, SRC_USR }SRC_TYPES;
Index: /trunk/FACT++/dim/src/dic.c
===================================================================
--- /trunk/FACT++/dim/src/dic.c	(revision 18919)
+++ /trunk/FACT++/dim/src/dic.c	(revision 18920)
@@ -520,5 +520,6 @@
 	int once_only, size = 0;
 	register DIC_SERVICE *servp;
-	
+	char str[512];
+
 /*
 dim_print_date_time();
@@ -554,7 +555,11 @@
 			if((servp->pending == WAITING_DNS_UP) || (servp->pending == WAITING_DNS_ANSWER))
 			{
+				sprintf(str, "Client Sending Command: Command %s discarded, no DNS answer\n", servp->serv_name);
+				error_handler(0, DIM_ERROR, DIMDNSCNERR, str);
+/*
 				dim_print_date_time();
-				printf(" Client Sending Command: Command %s discarded, no DNS answer\n", servp->serv_name);
+				printf("Client Sending Command: Command %s discarded, no DNS answer\n", servp->serv_name);
 				fflush(stdout);
+*/
 			}
 /*
@@ -1894,4 +1899,5 @@
 	static int serv_packet_size = 0;
     int type, ret;
+	char str[256];
 
 	if( !serv_packet_size ) {
@@ -1912,8 +1918,7 @@
 	if(!ret)
 	{
-		dim_print_date_time();
-		printf(" Client Sending Service Request: Couldn't write to Conn %3d : Server %s@%s service %s\n",
+		sprintf(str, "Client Sending Service Request: Couldn't write to Conn %3d : Server %s@%s service %s\n",
 			conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node, servp->serv_name);
-		fflush(stdout);
+		error_handler(0, DIM_ERROR, DIMTCPWRTMO, str);
 	}
 	return(ret);
@@ -1961,4 +1966,5 @@
 	int ret;
 	CMNDCB_ITEM *itemp;
+	char str[256];
 
 	size = servp->fill_size;
@@ -2033,8 +2039,7 @@
 	if(!ret)
 	{
-		dim_print_date_time();
-		printf(" Client Sending Command: Couldn't write to Conn %3d : Server %s@%s\n",conn_id,
+		sprintf(str, "Client Sending Command: Couldn't write to Conn %3d : Server %s@%s\n", conn_id,
 			Net_conns[conn_id].task, Net_conns[conn_id].node);
-		fflush(stdout);
+		error_handler(0, DIM_ERROR, DIMTCPWRTMO, str);
 	}
 	return(ret);
Index: /trunk/FACT++/dim/src/diccpp.cxx
===================================================================
--- /trunk/FACT++/dim/src/diccpp.cxx	(revision 18919)
+++ /trunk/FACT++/dim/src/diccpp.cxx	(revision 18920)
@@ -987,6 +987,9 @@
 	ret = itsData[1]->getToken(currToken);
 	if(!ret) return 0;
-	server = currToken;
-	ret = itsData[1]->getToken(currToken);
+	if(!itsData[1]->cmpToken((char *)"@"))
+	{
+		server = currToken;
+		ret = itsData[1]->getToken(currToken);
+	}
 	if(!itsData[1]->cmpToken((char *)"@"))
 		return 0;
Index: /trunk/FACT++/dim/src/dim_thr.c
===================================================================
--- /trunk/FACT++/dim/src/dim_thr.c	(revision 18919)
+++ /trunk/FACT++/dim/src/dim_thr.c	(revision 18920)
@@ -736,5 +736,10 @@
 	else if(pclass == 2)
 		p = REALTIME_PRIORITY_CLASS;
+/*added by dietrich beck, GSI*/
+#ifdef PHARLAP
+	ret = 1;
+#else
 	ret = SetPriorityClass(hProc, p);
+#endif
 	if(ret)
 	  return 1;
@@ -755,6 +760,11 @@
 	hProc = GetCurrentProcess();
 
+/*added by dietrich beck, GSI*/
+#ifdef PHARLAP
+	ret = NORMAL_PRIORITY_CLASS;
+#else
 	ret = GetPriorityClass(hProc);
-	if(ret == 0)
+#endif
+	if (ret == 0)
 	  return 0;
 	if(ret == IDLE_PRIORITY_CLASS)
Index: /trunk/FACT++/dim/src/dis.c
===================================================================
--- /trunk/FACT++/dim/src/dis.c	(revision 18919)
+++ /trunk/FACT++/dim/src/dis.c	(revision 18920)
@@ -178,4 +178,8 @@
 								   void (*user_routine)(), dim_long tag, dim_long dnsid ) );
 _DIM_PROTO( static DIS_DNS_CONN *create_dns, (dim_long dnsid) );
+/*
+_DIM_PROTO( int do_dis_remove_service, (unsigned service_id, int do_stop_serving, void **dnsp ) );
+_DIM_PROTO( void do_dis_stop_serving_dns, (DIS_DNS_CONN *dnsp ) );
+*/
 
 void dis_set_debug_on()
@@ -324,11 +328,4 @@
 }
 
-static unsigned do_dis_add_service( char *name, char *type, void *address, int size, 
-								   void (*user_routine)(), dim_long tag )
-{
-	return do_dis_add_service_dns( name, type, address, size, 
-								   user_routine, tag, 0 );
-}
-
 #ifdef VxWorks
 void dis_destroy(int tid)
@@ -379,5 +376,5 @@
 	DISABLE_AST
 */
-	ret = do_dis_add_service( name, type, address, size, user_routine, tag);
+	ret = do_dis_add_service_dns( name, type, address, size, user_routine, tag, 0);
 #ifdef VxWorks
 	servp = (SERVICE *)id_get_ptr(ret, SRC_DIS);
@@ -489,9 +486,4 @@
 }
 
-static unsigned do_dis_add_cmnd( char *name, char *type, void (*user_routine)(), dim_long tag)
-{
-	return do_dis_add_cmnd_dns(name, type, user_routine, tag, 0);
-}
-
 unsigned dis_add_cmnd( char *name, char *type, void (*user_routine)(), dim_long tag ) 
 {
@@ -501,5 +493,5 @@
 	DISABLE_AST
 */
-	ret = do_dis_add_cmnd( name, type, user_routine, tag );
+	ret = do_dis_add_cmnd_dns( name, type, user_routine, tag, 0 );
 /*
 	ENABLE_AST
@@ -639,7 +631,66 @@
 }
 
+int decode_duplicated_info(char *info, char *sname)
+{
+	int n_dupl;
+/*
+	int first_service = 1;
+*/
+	unsigned service_id;
+	char *ptr;
+	SERVICE *servp;
+	char str[256];
+
+	ptr = strchr(info,' ');
+	if(ptr)
+	{
+		*ptr = '\0';
+		strcpy(sname, info);
+		ptr++;
+		sscanf(ptr,"%d",&n_dupl);
+	}
+	ptr = strchr(ptr,' ');
+	while(ptr)
+	{
+		ptr++;
+		sscanf(ptr,"%x",&service_id);
+		if(service_id)
+		{
+			service_id &= 0x0FFFFFFF;
+			servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
+			if(servp)
+			{
+				if((unsigned)servp->id == service_id)
+				{
+					servp->registered = -1;
+/*
+					if(first_service)
+					{
+						strcat(sname, " (ex: ");
+						strcat(sname, servp->name);
+						strcat(sname, ")");
+						first_service = 0;
+					}
+*/
+/*
+if(Debug_on)
+{
+*/
+					sprintf(str, "Service %s already declared\n", servp->name);
+					error_handler(0, DIM_WARNING, DIMDNSDUPLC, str, -1);
+				/*
+}
+*/
+				}
+			}
+		}
+		ptr = strchr(ptr,' ');
+	}
+	return(n_dupl);
+}
+
 void recv_dns_dis_rout( int conn_id, DNS_DIS_PACKET *packet, int size, int status )
 {
-	char str[128];
+	char str[MAX_NAME*2], dupl_server[MAX_NAME*2];
 	int dns_timr_time;
 	extern int rand_tmout(int, int);
@@ -649,5 +700,5 @@
 	extern void do_dis_stop_serving_dns(DIS_DNS_CONN *);
 	DIS_DNS_CONN *dnsp;
-	int type, exit_code;
+	int type, exit_code, severity, n_dupl;
 
 	if(size){}
@@ -709,12 +760,30 @@
 			break;
 		case DNS_DIS_KILL :
-			sprintf(str,
-				"%s: Some Services already known to DNS",
-				dnsp->task_name);
 			/*
 			exit(2);
 			*/
-			Serving = -1;
-			error_handler(0, DIM_FATAL, DIMDNSDUPLC, str, -1);
+			severity = DIM_FATAL;
+			if(size > DNS_DIS_HEADER)
+			{
+				n_dupl = decode_duplicated_info(packet->dup_info, dupl_server);
+				if(exit_code == 1)
+				{
+					Serving = -1;
+					sprintf(str, "%s: Server already declared by %s", dnsp->task_name, dupl_server);
+				}
+				else
+				{
+					severity = DIM_WARNING;
+					sprintf(str, "%s: %d Services already declared by %s", dnsp->task_name,
+						n_dupl, dupl_server);
+				}
+			}
+			else
+			{
+				Serving = -1;
+				sprintf(str, "%s: Some Services already known to DNS",
+						dnsp->task_name);
+			}
+			error_handler(0, severity, DIMDNSDUPLC, str, -1);
 			/*
 			do_dis_stop_serving_dns(dnsp);
@@ -850,5 +919,6 @@
 	n_services = 0;
 	tot_n_services = 0;
-	if( flag == NONE ) {
+	if( flag == NONE )
+	{
 		dis_dns_p->n_services = htovl(n_services);
 		dis_dns_p->size = htovl( DIS_DNS_HEADER + 
@@ -878,5 +948,8 @@
 		{
 			if(servp->dnsp == dnsp)
-				servp->registered  = 0;
+			{
+				if(servp->registered >= 0)
+					servp->registered = 0;
+			}
 		}
 	}
@@ -890,5 +963,12 @@
 		if( flag == MORE ) 
 		{
-			if( servp->registered )
+			if( servp->registered != 0)
+			{
+				continue;
+			}
+		}
+		else if( flag == ALL ) 
+		{
+			if( servp->registered < 0)
 			{
 				continue;
@@ -1095,9 +1175,11 @@
 	char str0[MAX_NAME], str1[MAX_NAME],str2[MAX_NAME],
 	  str3[MAX_NAME],str4[MAX_NAME];
-	char task_name_aux[MAX_TASK_NAME];
+	char task_name_aux[MAX_TASK_NAME], task_name[MAX_NAME];
 	extern int open_dns();
 	extern DIS_DNS_CONN *dis_find_dns(dim_long);
+	extern int dis_find_dns_task(dim_long, char *);
 	DIS_DNS_CONN *dnsp;
 	unsigned int more_ids[10] = {0};
+	int n;
 
 	dis_init();
@@ -1121,4 +1203,6 @@
 		dll_init( (DLL *) Client_head );
 	}
+	strncpy( task_name, task, (size_t)MAX_NAME );
+	task_name[MAX_NAME-1] = '\0';
 	if(dnsid == 0)
 	{
@@ -1127,4 +1211,8 @@
 	else if(!(dnsp = dis_find_dns(dnsid)))
 	{
+		if((n = dis_find_dns_task(dnsid, task)) > 0)
+		{
+			sprintf(task_name, "%s-%i", task, n);
+		}
 		dnsp = create_dns(dnsid);
 	}
@@ -1133,5 +1221,5 @@
 	if(Dis_first_time)
 	{
-		strncpy( task_name_aux, task, (size_t)MAX_TASK_NAME );
+		strncpy( task_name_aux, task_name, (size_t)MAX_TASK_NAME );
 		task_name_aux[MAX_TASK_NAME-1] = '\0';
 		Port_number = SEEK_PORT;
@@ -1153,11 +1241,15 @@
 		dnsp->dis_first_time = 0;
 
-		sprintf(str0, "%s/VERSION_NUMBER", task);
-		sprintf(str1, "%s/CLIENT_LIST", task);
-		sprintf(str2, "%s/SERVICE_LIST", task);
-		sprintf(str3, "%s/SET_EXIT_HANDLER", task);
-		sprintf(str4, "%s/EXIT", task);
-
-		more_ids[0] = do_dis_add_service_dns( str0, "L", &Version_number,
+		sprintf(str0, "%s/VERSION_NUMBER", task_name);
+		sprintf(str1, "%s/CLIENT_LIST", task_name);
+		sprintf(str2, "%s/SERVICE_LIST", task_name);
+		sprintf(str3, "%s/SET_EXIT_HANDLER", task_name);
+		sprintf(str4, "%s/EXIT", task_name);
+
+/*added by dietrich beck, GSI*/
+#ifdef LABVIEWGSI
+		Version_number = _swapl(Version_number); //need to swap this number, since we hacked MY_LITTLE_ENDIAN
+#endif
+		more_ids[0] = do_dis_add_service_dns(str0, "L", &Version_number,
 						sizeof(Version_number), 0, 0, dnsid );
 
@@ -1169,9 +1261,9 @@
 		more_ids[4] = do_dis_add_cmnd_dns( str4, "L:1", exit_handler, 0, dnsid );
 		more_ids[5] = 0;
-		strcpy( dnsp->task_name, task );
+		strcpy( dnsp->task_name, task_name );
 if(Debug_on)
 {
 dim_print_date_time();
- printf("start serving %s\n",task);
+ printf("start serving %s\n",task_name);
 }
 	}
@@ -1258,4 +1350,5 @@
 	int find_release_request();
 	DIS_DNS_CONN *dnsp;
+	int ret = 1;
 
 	if(size){}
@@ -1371,5 +1464,5 @@
 		if((type != MONIT_ONLY) && (type != UPDATE))
 		{
-			execute_service(newp->req_id);
+			ret = execute_service(newp->req_id);
 		}
 		if((type != MONIT_ONLY) && (type != MONIT_FIRST))
@@ -1383,5 +1476,5 @@
 			}
 		}
-		if(new_client)
+		if((new_client) && (ret != -1))
 		{
 			Last_client = conn_id;
@@ -1400,5 +1493,5 @@
 	register REQUEST *reqp;
 	register SERVICE *servp;
-	char str[80], def[MAX_NAME];
+	char str[256], def[MAX_NAME];
 	int conn_id, last_conn_id;
 	int *pkt_buffer, header_size, aux;
@@ -1410,4 +1503,5 @@
 #endif
 	FORMAT_STR format_data_cp[MAX_NAME/4];
+	int ret = 1;
 
 	reqp = (REQUEST *)id_get_ptr(req_id, SRC_DIS);
@@ -1519,5 +1613,5 @@
 			if(reqp->delay_delete > 1)
 			{
-				printf(" Server (Explicitly) Updating Service %s: Couldn't write to Conn %3d : Client %s@%s\n",
+				sprintf(str, "Server (Explicitly) Updating Service %s: Couldn't write to Conn %3d : Client %s@%s\n",
 					servp->name, conn_id,
 					Net_conns[conn_id].task, Net_conns[conn_id].node);
@@ -1525,9 +1619,9 @@
 			else
 			{
-				printf(" Server Updating Service %s: Couldn't write to Conn %3d : Client %s@%s\n",
+				sprintf(str, "Server Updating Service %s: Couldn't write to Conn %3d : Client %s@%s\n",
 					servp->name, conn_id,
 					Net_conns[conn_id].task, Net_conns[conn_id].node);
 			}
-			fflush(stdout);
+			error_handler(0, DIM_WARNING, DIMTCPWRTMO, str, -1);
 		}
 		if(reqp->delay_delete > 1)
@@ -1539,4 +1633,5 @@
 			reqp->delay_delete = 0;
 			release_conn(conn_id, 1, 0);
+			ret = -1;
 		}
 	}
@@ -1553,5 +1648,5 @@
 	if(reqp->delay_delete > 0)
 		reqp->delay_delete--;
-	return(1);
+	return(ret);
 }
 
@@ -1562,4 +1657,5 @@
 	static int packet_size = 0;
 	int service_id;
+	char str[256];
 
 	reqp = (REQUEST *)id_get_ptr(req_id, SRC_DIS);
@@ -1579,8 +1675,7 @@
 	if( !dna_write(reqp->conn_id, dis_packet, DIS_HEADER) ) 
 	{
-		dim_print_date_time();
-		printf(" Server Removing Service: Couldn't write to Conn %3d : Client %s@%s\n",
+		sprintf(str, "Server Removing Service: Couldn't write to Conn %3d : Client %s@%s\n",
 			reqp->conn_id, Net_conns[reqp->conn_id].task, Net_conns[reqp->conn_id].node);
-		fflush(stdout);
+		error_handler(0, DIM_WARNING, DIMTCPWRTMO, str, -1);
 		release_conn(reqp->conn_id, 0, 0);
 	}
@@ -2058,5 +2153,5 @@
 	static int packet_size = 0;
 	int conn_id;
-	char str[128];
+	char str[256];
 
 	DISABLE_AST
@@ -2098,8 +2193,7 @@
 		if( !dna_write_nowait(conn_id, dis_packet, size + DIS_HEADER) )
 		{
-			dim_print_date_time();
-			printf(" Server Sending Service: Couldn't write to Conn %3d : Client %s@%s\n",conn_id,
+			sprintf(str, "Server Sending Service: Couldn't write to Conn %3d : Client %s@%s\n",conn_id,
 				Net_conns[conn_id].task, Net_conns[conn_id].node);
-			fflush(stdout);
+			error_handler(0, DIM_WARNING, DIMTCPWRTMO, str, -1);
 			release_conn(conn_id, 1, 0);
 		}
@@ -2111,4 +2205,14 @@
 
 int dis_remove_service(unsigned service_id)
+{
+	int ret;
+	void *dnsp;
+	int do_dis_remove_service(unsigned, int , void **);
+
+	ret = do_dis_remove_service(service_id, 1, &dnsp);
+	return ret;
+}
+
+int do_dis_remove_service(unsigned service_id, int do_stop_serving, void **thednsp)
 {
 	register REQUEST *reqp, *auxp;
@@ -2197,10 +2301,20 @@
 		if(n_services == 5)
 		{
-			if(Dis_conn_id)
-			{
-				dna_close(Dis_conn_id);
-				Dis_conn_id = 0;
-			}
-			ENABLE_AST
+			if(do_stop_serving)
+			{
+				if(Dis_conn_id)
+				{
+					dna_close(Dis_conn_id);
+					Dis_conn_id = 0;
+				}
+				ENABLE_AST
+			}
+			else
+			{
+				*thednsp = dnsp;
+				ENABLE_AST
+				return -1;
+			}
+
 /*
 			dis_stop_serving();
@@ -2338,5 +2452,6 @@
 
 	dnsp = dis_find_dns(dnsid);
-	do_dis_stop_serving_dns(dnsp);
+	if(dnsp)
+		do_dis_stop_serving_dns(dnsp);
 }
 
@@ -2701,5 +2816,5 @@
 		dim_print_date_time();
 		dna_get_node_task(conn_id, node, task);
-		printf(" Couldn't write to client %s@%s, releasing connection %d\n",
+		printf("Couldn't write to client %s@%s, releasing connection %d\n",
 			task, node, conn_id);
 		fflush(stdout);
@@ -2987,5 +3102,5 @@
 			if(servp->dnsp != dnsp)
 				continue;
-			if(servp->registered)
+			if(servp->registered > 0)
 			{
 /*
@@ -3017,5 +3132,5 @@
 				buff_ptr += (int)strlen(buff_ptr);
 			}
-			else if(servp->registered < (Last_n_clients+1))
+			else if((servp->registered > 0) && (servp->registered < (Last_n_clients+1)))
 			{
 				if(!done)
@@ -3371,4 +3486,18 @@
 */
 	return dnsp;
+}
+
+int dis_find_dns_task(dim_long dnsid, char *task)
+{
+	DIS_DNS_CONN *dnsp;
+	int n = 0;
+
+	dnsp = (DIS_DNS_CONN *) DNS_head;
+	while ( (dnsp = (DIS_DNS_CONN *) dll_get_next( (DLL *) DNS_head, (DLL *) dnsp)))
+	{
+		if(!strcmp(dnsp->task_name, task))
+			n++;
+	}
+	return n;
 }
 
Index: /trunk/FACT++/dim/src/discpp.cxx
===================================================================
--- /trunk/FACT++/dim/src/discpp.cxx	(revision 18919)
+++ /trunk/FACT++/dim/src/discpp.cxx	(revision 18920)
@@ -18,4 +18,6 @@
 extern "C" {
 extern void dis_init();
+extern int do_dis_remove_service(unsigned service_id, int do_stop_serving, void **dnsp );
+extern void do_dis_stop_serving_dns(void *dnsp);
 
 static void user_routine( void *tagp, void **buf, int *size, int *first_time)
@@ -1001,4 +1003,7 @@
 DimService::~DimService()
 {
+	int ret = 0;
+	void *dnsp;
+
 	DISABLE_AST
 	if(itsName)
@@ -1009,7 +1014,11 @@
 //		id_free(itsTagId, SRC_DIS);
 	if(itsId)
-		dis_remove_service( itsId );
+		ret = do_dis_remove_service( itsId, 0, &dnsp );
 	itsId = 0;
 	ENABLE_AST
+	if(ret == -1)
+	{
+		do_dis_stop_serving_dns(dnsp);
+	}
 }
 
@@ -1487,4 +1496,7 @@
 DimCommand::~DimCommand()
 {
+	int ret;
+	void *dnsp;
+
 	DISABLE_AST
 	delete[] itsName;
@@ -1493,7 +1505,11 @@
 //		id_free(itsTagId, SRC_DIS);
 	if(itsId)
-		dis_remove_service( itsId );
+		ret = do_dis_remove_service( itsId, 0, &dnsp );
 	itsId = 0;
 	ENABLE_AST
+	if(ret == -1)
+	{
+		do_dis_stop_serving_dns(dnsp);
+	}
 }
 
@@ -1514,4 +1530,7 @@
 DimRpc::~DimRpc()
 {
+	int ret;
+	void *dnsp;
+
 	DISABLE_AST
 	delete[] itsName;
@@ -1521,10 +1540,14 @@
 //		id_free(itsTagId, SRC_DIS);
 	if(itsIdIn)
-		dis_remove_service( itsIdIn );
+		ret = do_dis_remove_service( itsIdIn, 0, &dnsp );
 	if(itsIdOut)
-		dis_remove_service( itsIdOut );
+		ret = do_dis_remove_service( itsIdOut, 0, &dnsp );
 	itsIdIn = 0;
 	itsIdOut = 0;
 	ENABLE_AST
+	if(ret == -1)
+	{
+		do_dis_stop_serving_dns(dnsp);
+	}
 }
 
Index: /trunk/FACT++/dim/src/dna.c
===================================================================
--- /trunk/FACT++/dim/src/dna.c	(revision 18919)
+++ /trunk/FACT++/dim/src/dna.c	(revision 18920)
@@ -16,4 +16,5 @@
 #define DNA
 #include <dim.h>
+#include <time.h>
 
 /* global definitions */
@@ -353,7 +354,9 @@
 	tcpip_code = dna_write_bytes(conn_id, &test_pkt, READ_HEADER_SIZE,0);
 	if(tcpip_failure(tcpip_code)) {
-		 /* Connection lost. Signal upper layer ? */
+/* Connection lost. Signal upper layer ? No -> creates a deadlock in the Timer Thread*/
+/*
 		if(dna_connp->read_ast)
 			dna_connp->read_ast(conn_id, NULL, 0, STA_DISC);
+*/
 		return;
 	}
@@ -624,5 +627,7 @@
 	time_t oldest;
 	int oldesti = 0;
+/*
 	extern time_t time();
+*/
 
 	if(type == 0)
@@ -822,8 +827,17 @@
 	if (tcpip_failure(tcpip_code))
 	{
+		if(src_type == SRC_DIS)
+			strcpy(src_type_str,"Server");
+		else if(src_type == SRC_DIC)
+			strcpy(src_type_str,"Client");
+		else
+			strcpy(src_type_str,"Unknown type");
 		dim_print_date_time();
-		printf(" Client Establishing Connection: Couldn't write to Conn %3d : Server %s@%s\n",conn_id,
-			Net_conns[conn_id].task, Net_conns[conn_id].node);
-		fflush(stdout);
+		sprintf(str," %s Establishing Connection: Couldn't write to Conn %3d : Server %s@%s\n",
+				src_type_str, conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node);
+		if (!strcmp(server_task, "DIM_DNS"))
+			dna_report_error(conn_id, tcpip_code, str, DIM_ERROR, DIMDNSCNERR);
+		else
+			dna_report_error(conn_id, tcpip_code, str, DIM_ERROR, DIMTCPCNERR);
 		dna_close(conn_id);
 		return(0);
@@ -841,6 +855,8 @@
 		    dna_report_error(conn_id, -1,
 				     "Write timeout, disconnecting from", DIM_ERROR, DIMTCPWRTMO);
-			if(!find_pend_conn(Net_conns[conn_id].node, Net_conns[conn_id].task, 0, 0, 1))
+			if (!find_pend_conn(Net_conns[conn_id].node, Net_conns[conn_id].task, 0, 0, 1))
+			{
 				ins_pend_conn(Net_conns[conn_id].node, Net_conns[conn_id].task, 0, 0, 1, time(NULL));
+			}
 		}
 		release_conn(conn_id);
Index: /trunk/FACT++/dim/src/dns.c
===================================================================
--- /trunk/FACT++/dim/src/dns.c	(revision 18919)
+++ /trunk/FACT++/dim/src/dns.c	(revision 18920)
@@ -116,5 +116,5 @@
 		{
 			dim_print_date_time();
-			printf(" Disconnect received - conn: %d to %s@%s\n", conn_id,
+			printf("Disconnect received - conn: %d to %s@%s\n", conn_id,
 				Net_conns[conn_id].task,Net_conns[conn_id].node );
 		}
@@ -126,5 +126,5 @@
 		{
 			dim_print_date_time();
-			printf(" Connection request received - conn: %d\n", conn_id);
+			printf("Connection request received - conn: %d\n", conn_id);
 		}
 		/* handle_conn( conn_id ); */
@@ -141,5 +141,5 @@
 		default:
 			dim_print_date_time();
-			printf(" conn: %d to %s@%s, Bad packet\n", conn_id,
+			printf("conn: %d to %s@%s, Bad packet\n", conn_id,
 				Net_conns[conn_id].task,Net_conns[conn_id].node );
 			printf("packet->size = %d\n", vtohl(packet->size));
@@ -155,5 +155,5 @@
 	default:	
 		dim_print_date_time();
-		printf( " - DIM panic: recv_rout(): Bad switch, exiting...\n");
+		printf( "- DIM panic: recv_rout(): Bad switch, exiting...\n");
 		abort();
 	}
@@ -172,4 +172,139 @@
 	}
 */
+}
+
+void create_service_entry( int conn_id, DIS_DNS_PACKET *packet, int i, int state)
+{
+	DNS_SERVICE *servp;
+	int name_too_long = 0;
+	char *ptrt;
+	void service_insert();
+
+	if((int)strlen(Dns_conns[conn_id].task_name) == MAX_TASK_NAME-4-1)
+		name_too_long = 1;
+	servp = (DNS_SERVICE *)malloc(sizeof(DNS_SERVICE));
+	if(name_too_long)
+	{
+		if(strstr(packet->services[i].service_name,"/CLIENT_LIST"))
+		{
+			strncpy(Dns_conns[conn_id].long_task_name, packet->services[i].service_name,
+				(size_t)MAX_NAME);
+			ptrt = strstr(Dns_conns[conn_id].long_task_name,"/CLIENT_LIST");
+			*ptrt = '\0';
+		}
+	}
+	strncpy( servp->serv_name,
+		packet->services[i].service_name,
+		(size_t)MAX_NAME );
+	strncpy( servp->serv_def,
+		packet->services[i].service_def,
+		(size_t)MAX_NAME );
+	servp->state = state;
+	servp->conn_id = conn_id;
+	servp->server_format = vtohl(packet->format);
+	servp->serv_id = vtohl(packet->services[i].service_id);
+	dll_insert_queue( (DLL *)
+		Dns_conns[conn_id].service_head, 
+		(DLL *) servp );
+	servp->node_head = (RED_NODE *) malloc(sizeof(NODE));
+	dll_init( (DLL *) servp->node_head );
+	servp->next = 0;
+	if(state == 1)
+	{
+		service_insert( &(servp->next) );
+		Dns_conns[conn_id].n_services++;
+	}
+} 
+
+int warn_server(int conn_id)
+{
+	DNS_SERVICE *servp;
+	DNS_DIS_PACKET *dis_packet;
+	int n_dupl, dupl_conn_id;
+	char vname[MAX_NAME], dupl_server[MAX_NAME];
+	int type, size, dupl_id, kill_anyway, ret;
+	char *ptr;
+		
+	ret = 1;
+	type = DNS_DIS_KILL;
+	n_dupl = 0;
+	strcpy(vname, Dns_conns[conn_id].task_name);
+	strcat(vname, "/VERSION_NUMBER");
+	dupl_id = 0;
+	kill_anyway = 0;
+	dupl_conn_id = Dns_conns[conn_id].already;
+	servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
+	while( (servp = (DNS_SERVICE *) dll_get_next(
+				(DLL *) Dns_conns[conn_id].service_head,
+				(DLL *) servp)) )
+	{
+		if(servp->state == -2)
+		{
+			if(!dupl_id)
+			{
+				dupl_id = servp->serv_id;
+				sprintf(dupl_server,"%s(%d)@%s:%d",
+					Dns_conns[dupl_conn_id].task_name,
+					Dns_conns[dupl_conn_id].pid,
+					Dns_conns[dupl_conn_id].node_name,
+					Dns_conns[dupl_conn_id].port);
+			}
+			if(!strcmp(servp->serv_name, vname))
+				kill_anyway = 1;
+			n_dupl++;
+		}
+	}
+/* allocate Header + space for <server_name>:<pid>@<node_name>:<port_number> + n duplicated + duplicated ids */
+	dis_packet = (DNS_DIS_PACKET *)malloc(DNS_DIS_HEADER + MAX_NAME*2 + (n_dupl+1)*10);
+	sprintf(dis_packet->dup_info, "%s %d", dupl_server, n_dupl);
+	ptr = dis_packet->dup_info + strlen(dis_packet->dup_info);
+	if(kill_anyway)
+	{
+		type |= (0x01 << (int)16) & (int)0xFFFF0000;
+		dim_print_date_time();
+printf("Server already declared by conn %d - %s@%s:%d (PID %d), Killing server conn %d - %s@%s:%d (PID %d) \n",
+			dupl_conn_id, 
+			Dns_conns[dupl_conn_id].task_name,
+			Dns_conns[dupl_conn_id].node_name,
+			Dns_conns[dupl_conn_id].port,
+			Dns_conns[dupl_conn_id].pid,
+			conn_id,
+			Dns_conns[conn_id].task_name,
+			Dns_conns[conn_id].node_name,
+			Dns_conns[conn_id].port,
+			Dns_conns[conn_id].pid);
+		fflush(stdout);
+	}
+	else
+	{
+		servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
+		while( (servp = (DNS_SERVICE *) dll_get_next(
+					(DLL *) Dns_conns[conn_id].service_head,
+					(DLL *) servp)) )
+		{
+			if(servp->state == -2)
+			{
+				dupl_id = servp->serv_id;
+				sprintf(ptr," %08X", dupl_id);
+				ptr += 9;
+			}
+		}
+	}
+	dis_packet->type = htovl(type);
+	size = DNS_DIS_HEADER + strlen(dis_packet->dup_info);
+/* Unfortunatelly the size is wrong, this is for backward compatibility on the server side (it tested the size)*/
+	dis_packet->size = htovl(DNS_DIS_HEADER);
+/*
+printf("Sendig packet %s\n", dis_packet->dup_info);
+*/
+	if( !dna_write_nowait(conn_id, dis_packet, size) )
+	{
+		dim_print_date_time();
+		printf("Kill Server: Couldn't write, releasing %d\n",conn_id);
+		fflush(stdout);
+		ret = 0;
+	}
+	free(dis_packet);
+	return ret;
 }
 
@@ -180,5 +315,5 @@
 	int i, service_id;
 	int n_services;
-	char *ptr, *ptr1, *ptrt;
+	char *ptr, *ptr1;
 	int found;
 	void do_update_did();
@@ -195,11 +330,14 @@
 #endif
 	int update_did = 0;
+/*
 	int name_too_long = 0;
+*/
 	int rem_only = 0;
+	int all_services_registered = -1;
 
 	Dns_conns[conn_id].validity = (int)time(NULL);
 	if( !Dns_conns[conn_id].service_head ) 
 	{
-
+		all_services_registered = 0;
 		if(vtohl(packet->n_services) > 0)
 		{
@@ -212,5 +350,5 @@
 	{
 			dim_print_date_time();
-			printf( " !!!! New Conn %3d : Server %s@%s (PID %d) registering %d services, to delete %d\n",
+			printf( "!!!! New Conn %3d : Server %s@%s (PID %d) registering %d services, to delete %d\n",
 				conn_id, packet->task_name,
 				packet->node_name, 
@@ -246,5 +384,5 @@
 	{
 			dim_print_date_time();
-			printf( " !!!! New Conn %3d : Server %s@%s (PID %d) registered %d services\n",
+			printf( "!!!! New Conn %3d : Server %s@%s (PID %d) registered %d services\n",
 				conn_id, Dns_conns[conn_id].task_name,
 				Dns_conns[conn_id].node_name, 
@@ -293,9 +431,9 @@
 				{
 					dim_print_date_time();
-					printf(" Stop Server: Couldn't write, releasing %d\n",conn_id);
+					printf("Stop Server: Couldn't write, releasing %d\n",conn_id);
 					fflush(stdout);
 				}
 				dim_print_date_time();
-				printf(" Connection from %s refused, stopping server %s\n",
+				printf("Connection from %s refused, stopping server %s\n",
 						Dns_conns[conn_id].node_name, 
 						Dns_conns[conn_id].task_name);
@@ -332,5 +470,5 @@
 				dna_set_test_write(conn_id, dim_get_keepalive_timeout());
 			dim_print_date_time();
-			printf( " Server %s out of error\n",
+			printf( "Server %s out of error\n",
 				Dns_conns[conn_id].task_name );
 			fflush(stdout);
@@ -339,6 +477,8 @@
 	}
 	n_services = vtohl(packet->n_services);
+/*
 	if((int)strlen(Dns_conns[conn_id].task_name) == MAX_TASK_NAME-4-1)
 		name_too_long = 1;
+*/
 	for( i = 0; i < n_services; i++ ) 
 	{
@@ -347,5 +487,5 @@
 	{
 			dim_print_date_time();
-			printf( " Conn %3d : Server %s@%s (PID %d) registered %s\n",
+			printf( "Conn %3d : Server %s@%s (PID %d) registered %s\n",
 				conn_id, Dns_conns[conn_id].task_name,
 				Dns_conns[conn_id].node_name, 
@@ -359,4 +499,5 @@
 			if(!strcmp(packet->services[i].service_name, "DUMMY_UPDATE_PACKET"))
 			{
+				all_services_registered = 1;
 				do_inform_clients(conn_id);
 				break;
@@ -378,9 +519,9 @@
 					{
 						dim_print_date_time();
-						printf(" Couldn't write, releasing %d\n",servp->conn_id);
+						printf("Couldn't write, releasing %d\n",servp->conn_id);
 						fflush(stdout);
 					}
 					dim_print_date_time();
-					printf(" Service %s already declared, killing server %s\n",
+					printf("Service %s already declared, killing server %s\n",
 						servp->serv_name, Dns_conns[servp->conn_id].task_name);
 					fflush(stdout);
@@ -395,5 +536,5 @@
 					{
 						dim_print_date_time();
-printf(" Service %s already declared by conn %d - %s@%s:%d (PID %d), Redeclared by conn %d - %s@%s:%d (PID %d)(same server) - Closing both conns %d %d\n",
+printf("Service %s already declared by conn %d - %s@%s:%d (PID %d), Redeclared by conn %d - %s@%s:%d (PID %d)(same server) - Closing both conns %d %d\n",
 							servp->serv_name, servp->conn_id, 
 							Dns_conns[servp->conn_id].task_name,
@@ -418,6 +559,7 @@
 					else
 					{
-						Dns_conns[conn_id].already = 1;
-
+						Dns_conns[conn_id].already = servp->conn_id;
+						create_service_entry( conn_id, packet, i, -2);			
+/*DUPL
 						if( !dna_write_nowait(conn_id, &dis_packet, DNS_DIS_HEADER) )
 						{
@@ -426,6 +568,7 @@
 							fflush(stdout);
 						}
+*/
 						dim_print_date_time();
-printf(" Service %s already declared by conn %d - %s@%s:%d (PID %d), killing server conn %d - %s@%s:%d (PID %d) \n",
+printf("Service %s already declared by conn %d - %s@%s:%d (PID %d), Warning server conn %d - %s@%s:%d (PID %d) \n",
 							servp->serv_name, servp->conn_id, 
 							Dns_conns[servp->conn_id].task_name,
@@ -439,8 +582,10 @@
 							Dns_conns[conn_id].pid);
 						fflush(stdout);
-
+/*DUPL
 						release_conn(conn_id);
-
 						return(0);
+*/
+						if((!all_services_registered) && (n_services < MAX_REGISTRATION_UNIT))
+							all_services_registered = 1;
 					}
 #ifdef VMS
@@ -481,5 +626,4 @@
 						dll_remove((DLL *) servp);
 						service_remove(&(servp->next));
-						Curr_n_services--;
 						free(servp);
 						Dns_conns[conn_id].n_services--;
@@ -489,5 +633,5 @@
 							{
 								dim_print_date_time();
-								printf( " Conn %3d : Server %s@%s unregistered All services, releasing it.\n",
+								printf("Conn %3d : Server %s@%s unregistered All services, releasing it.\n",
 									conn_id, Dns_conns[conn_id].task_name,
 									Dns_conns[conn_id].node_name );
@@ -521,34 +665,14 @@
 		if(!(servp = service_exists(packet->services[i].service_name)))
 		{
-			servp = (DNS_SERVICE *)malloc(sizeof(DNS_SERVICE));
-			if(name_too_long)
-			{
-				if(strstr(packet->services[i].service_name,"/CLIENT_LIST"))
-				{
-					strncpy(Dns_conns[conn_id].long_task_name, packet->services[i].service_name,
-						(size_t)MAX_NAME);
-					ptrt = strstr(Dns_conns[conn_id].long_task_name,"/CLIENT_LIST");
-					*ptrt = '\0';
-				}
-			}
-			strncpy( servp->serv_name,
-				packet->services[i].service_name,
-				(size_t)MAX_NAME );
-			strncpy( servp->serv_def,
-				packet->services[i].service_def,
-				(size_t)MAX_NAME );
-			servp->state = 1;
-			servp->conn_id = conn_id;
-			servp->server_format = vtohl(packet->format);
-			servp->serv_id = vtohl(packet->services[i].service_id);
-			dll_insert_queue( (DLL *)
-					  Dns_conns[conn_id].service_head, 
-					  (DLL *) servp );
-			Dns_conns[conn_id].n_services++;
-			service_insert( &(servp->next) );
-			servp->node_head = (RED_NODE *) malloc(sizeof(NODE));
-			dll_init( (DLL *) servp->node_head );
-			Curr_n_services++;
+			create_service_entry( conn_id, packet, i, 1);			
 		} 
+	}
+	if((vtohl(packet->n_services) != 0) && Dns_conns[conn_id].already && all_services_registered)
+	{
+/*
+		dim_print_date_time();
+printf("Services already declared Warning server\n");
+*/
+		warn_server(conn_id);
 	}
 	if(update_did)
@@ -559,5 +683,5 @@
 		{
 			dim_print_date_time();
-			printf( " Conn %3d : Server %s@%s (PID %d) registered %d services\n",
+			printf("Conn %3d : Server %s@%s (PID %d) registered %d services\n",
 				conn_id, Dns_conns[conn_id].task_name,
 				Dns_conns[conn_id].node_name, 
@@ -620,5 +744,5 @@
 		{
 			dim_print_date_time();
-			printf(" Server %s (%s@%s) has been set in error\n",
+			printf("Server %s (%s@%s) has been set in error\n",
 				Dns_conns[conn_id].task_name, Net_conns[conn_id].task, Net_conns[conn_id].node);
 			fflush(stdout);
@@ -639,5 +763,5 @@
 		{
 			dim_print_date_time();
-			printf(" Conn %3d : Server %s@%s Registration Requested\n",
+			printf("Conn %3d : Server %s@%s Registration Requested\n",
 				conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node);
 			fflush(stdout);
@@ -647,5 +771,5 @@
 		{
 			dim_print_date_time();
-			printf(" Server Validity: Couldn't write, releasing Conn %3d : Server %s@%s\n",conn_id,
+			printf("Server Validity: Couldn't write, releasing Conn %3d : Server %s@%s\n",conn_id,
 				Net_conns[conn_id].task, Net_conns[conn_id].node);
 			fflush(stdout);
@@ -676,5 +800,5 @@
 	{
 		dim_print_date_time();
-		printf(" Conn %3d : Client %s@%s requested %s\n",
+		printf("Conn %3d : Client %s@%s requested %s\n",
 			conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node,
 			serv_regp->service_name);
@@ -720,5 +844,5 @@
 			dic_packet.size = htovl(DNS_DIC_HEADER);
 			dim_print_date_time();
-			printf(" Connection from %s refused, stopping client pid=%s\n",
+			printf("Connection from %s refused, stopping client pid=%s\n",
 					Net_conns[conn_id].node,
 					Net_conns[conn_id].task);
@@ -727,5 +851,5 @@
 			{
 				dim_print_date_time();
-				printf(" Stop Client: Couldn't write, releasing Conn %3d : Client %s@%s\n",conn_id,
+				printf("Stop Client: Couldn't write, releasing Conn %3d : Client %s@%s\n",conn_id,
 					Net_conns[conn_id].task,
 					Net_conns[conn_id].node);
@@ -773,5 +897,4 @@
 				}
 				service_remove(&(servp->next));
-				Curr_n_services--;
 				free(servp);
 			}
@@ -815,5 +938,4 @@
 				}
 				service_remove(&(servp->next));
-				Curr_n_services--;
 				free(servp);
 			}
@@ -850,5 +972,4 @@
 		servp->conn_id = 0;
 		service_insert(&(servp->next));
-		Curr_n_services++;
 		servp->node_head = (RED_NODE *)malloc(sizeof(NODE));
 		dll_init( (DLL *) servp->node_head );
@@ -930,5 +1051,5 @@
 	{
 		dim_print_date_time();
-		printf(" Client Request: Couldn't write, releasing Conn %3d : Client %s@%s\n",conn_id,
+		printf("Client Request: Couldn't write, releasing Conn %3d : Client %s@%s\n",conn_id,
 					Net_conns[conn_id].task,
 					Net_conns[conn_id].node);
@@ -962,5 +1083,8 @@
 				(DLL *) servp)) )
 	{
+/* DUPL
 		if( servp->state != -1 ) 
+*/
+		if( servp->state > -1 ) 
 		{
 			if( !dll_empty((DLL *) servp->node_head)) 
@@ -1014,5 +1138,5 @@
 		{
 			dim_print_date_time();
-			printf(" Inform Client: Couldn't write, releasing Conn %3d : Client %s@%s\n",nodep->conn_id,
+			printf("Inform Client: Couldn't write, releasing Conn %3d : Client %s@%s\n",nodep->conn_id,
 					Net_conns[nodep->conn_id].task,
 					Net_conns[nodep->conn_id].node);
@@ -1063,5 +1187,5 @@
 					{
 						dim_print_date_time();
-						printf(" Releasing client on conn %d - %s@%s\n",
+						printf("Releasing client on conn %d - %s@%s\n",
 							i, Net_conns[i].task, Net_conns[i].node);
 						fflush(stdout);
@@ -1088,5 +1212,5 @@
 		{
 			dim_print_date_time();
-			printf( " Conn %3d : Server %s@%s died\n",
+			printf("Conn %3d : Server %s@%s died\n",
 				conn_id, Dns_conns[conn_id].task_name,
 				Dns_conns[conn_id].node_name);
@@ -1098,5 +1222,5 @@
 			{
 				dim_print_date_time();
-				printf( " Conn %3d : Server %s@%s died\n",
+				printf("Conn %3d : Server %s@%s died\n",
 					conn_id, Dns_conns[conn_id].task_name,
 					Dns_conns[conn_id].node_name);
@@ -1119,5 +1243,4 @@
 			{
 				service_remove(&(servp->next));
-				Curr_n_services--;
 				old_servp = servp;
 				servp = servp->server_prev;
@@ -1152,5 +1275,5 @@
 		{
 			dim_print_date_time();
-			printf(" Conn %3d : Client %s@%s died\n",
+			printf("Conn %3d : Client %s@%s died\n",
 				conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node);
 			fflush(stdout);
@@ -1172,5 +1295,4 @@
 				{
 					service_remove(&(servp->next));
-					Curr_n_services--;
 					free( servp );
 				}
@@ -1187,5 +1309,5 @@
 		{
 			dim_print_date_time();
-			printf(" Conn %3d : Undefined Type %s@%s died\n",
+			printf("Conn %3d : Undefined Type %s@%s died\n",
 				conn_id, Net_conns[conn_id].task,
 				Net_conns[conn_id].node);
@@ -1281,4 +1403,6 @@
 						    (DLL *) servp)) )
 	{
+		if(servp->state == -2)
+			continue;
 		strncpy(dns_service_info->name, servp->serv_name, (size_t)MAX_NAME); 
 		dns_service_info->status = htovl(1);
@@ -1448,5 +1572,5 @@
 	get_node_name(node);
 	dim_print_date_time();
-	printf(" DNS version %d starting up on %s\n",DIM_VERSION_NUMBER, node); 
+	printf("DNS version %d starting up on %s\n",DIM_VERSION_NUMBER, node); 
 	fflush(stdout);
 
@@ -1506,5 +1630,5 @@
 
 	dim_print_date_time();
-	printf(" Connection Statistics :\n");
+	printf("Connection Statistics :\n");
 	for(i = 0; i< Curr_N_Conns; i++)
 	{
@@ -1595,5 +1719,5 @@
 				type |= (soft_code << (int)16) & (int)0xFFFF0000;
 				dim_print_date_time();
-				printf(" Killing server %s@%s with exit code %d\n",
+				printf("Killing server %s@%s with exit code %d\n",
 					Dns_conns[i].task_name, Dns_conns[i].node_name, soft_code);
 			}
@@ -1601,5 +1725,5 @@
 			{
 				dim_print_date_time();
-				printf(" Killing server %s@%s\n",
+				printf("Killing server %s@%s\n",
 					Dns_conns[i].task_name, Dns_conns[i].node_name);
 			}
@@ -1609,5 +1733,5 @@
 			{
 				dim_print_date_time();
-				printf(" Kill Server: Couldn't write, releasing %d\n",i);
+				printf("Kill Server: Couldn't write, releasing %d\n",i);
 				fflush(stdout);
 				release_conn(i);
@@ -1636,4 +1760,5 @@
 	dll_insert_queue((DLL *) Service_hash_table[index], 
 			 (DLL *) servp);
+	Curr_n_services++;
 }
 
@@ -1642,6 +1767,12 @@
 {
 	if( servp->node_head )
+	{
 		free( servp->node_head );
-	dll_remove( (DLL *) servp );
+	}
+	if(servp->next)
+	{
+		dll_remove( (DLL *) servp );
+		Curr_n_services--;
+	}
 }
 
@@ -1834,5 +1965,5 @@
 		dim_print_date_time();
 		conn_id = dis_get_conn_id();
-		printf(" Got Browse Request <%s> from conn: %d %s@%s\n", buffer, conn_id,
+		printf("Got Browse Request <%s> from conn: %d %s@%s\n", buffer, conn_id,
 			Net_conns[conn_id].task,Net_conns[conn_id].node);
 	}
@@ -1842,5 +1973,5 @@
 		dim_print_date_time();
 		conn_id = dis_get_conn_id();
-		printf(" Browse Request <%s> found %d services\n", buffer, n);
+		printf("Browse Request <%s> found %d services\n", buffer, n);
 	}
 	if(!Rpc_info_size)
Index: /trunk/FACT++/dim/src/examples/test_server.c
===================================================================
--- /trunk/FACT++/dim/src/examples/test_server.c	(revision 18919)
+++ /trunk/FACT++/dim/src/examples/test_server.c	(revision 18920)
@@ -67,4 +67,5 @@
 	char aux[80];
 	char name[84]/*, name1[132]*/;
+	char srvname[64];
 /*
 	int on = 0;
@@ -93,4 +94,7 @@
 	printf("result = %d\n", status); 
 */
+	dim_print_date_time();
+	printf("Dim Server Starting up...\n");
+	fflush(stdout);
 	if(argc){}
 	new_dns = dim_get_env_var("EXTRA_DNS_NODE", extra_dns, sizeof(extra_dns));
@@ -107,7 +111,10 @@
 	dis_add_client_exit_handler(client_exited);
 
+	strcpy(srvname, argv[1]);
+	if(!strcmp(srvname,"xx1"))
+		strcpy(srvname,"xx");
 	for(i = 0; i< 10; i++)
 	{
-		sprintf(str[i],"%s/Service_%03d",argv[1],i);
+		sprintf(str[i],"%s/Service_%03d",srvname,i);
 		dis_add_service( str[i], "C", str[i], (int)strlen(str[i])+1, 
 			(void *)0, 0 );
@@ -123,9 +130,15 @@
 	strcpy(t.str,"hello world");
 
-	sprintf(aux,"%s/TEST_SWAP",argv[1]);
+	sprintf(aux,"%s/TEST_SWAP",srvname);
 	id = dis_add_service( aux, "l:3;d:1;s:1;c:1;s:1;f:1;c:20", &t, sizeof(t), 
 		(void *)0, 0 );
+	if(!strcmp(argv[1],"xx1"))
+	{
+		sprintf(aux,"%s/TEST_SWAP1",srvname);
+		id = dis_add_service( aux, "l:3;d:1;s:1;c:1;s:1;f:1;c:20", &t, sizeof(t), 
+			(void *)0, 0 );
+	}
 	if(id){}
-	sprintf(aux,"%s/TEST_CMD",argv[1]);
+	sprintf(aux,"%s/TEST_CMD",srvname);
 	dis_add_cmnd(aux,"l:3;d:1;s:1;c:1;s:1;f:1;c:20",cmnd_rout, 0);
 
Index: /trunk/FACT++/dim/src/examples/test_server.cxx
===================================================================
--- /trunk/FACT++/dim/src/examples/test_server.cxx	(revision 18919)
+++ /trunk/FACT++/dim/src/examples/test_server.cxx	(revision 18920)
@@ -137,8 +137,10 @@
 //	delete dim;
 
+	dis_set_debug_on();
 	DimServer::start("TEST");
 	extraDns = DimUtil::getEnvVar((char *)"EXTRA_DNS_NODE");
 	if(extraDns)
-		newDns = new DimServerDns(extraDns, 0, (char *)"new_TEST");
+		newDns = new DimServerDns(extraDns, 0, (char *)"TEST");
+//		newDns = new DimServerDns(extraDns, 0, (char *)"new_TEST");
 
 //	int i, arr[15000];
@@ -156,5 +158,6 @@
 	if(extraDns)
 	{
-		new_servint = new DimService(newDns, "new_TEST/INTVAL",ival);
+//		new_servint = new DimService(newDns, "new_TEST/INTVAL",ival);
+		new_servint = new DimService(newDns, "TEST/new_INTVAL",ival);
 	}
 
Index: /trunk/FACT++/dim/src/tcpip.c
===================================================================
--- /trunk/FACT++/dim/src/tcpip.c	(revision 18919)
+++ /trunk/FACT++/dim/src/tcpip.c	(revision 18920)
@@ -16,5 +16,13 @@
 #ifdef WIN32
 #define FD_SETSIZE      16384
-#define poll(pfd,nfds,timeout)	WSAPoll(pfd,nfds,timeout)
+#endif
+
+#include <stdio.h>
+#include <time.h>
+#define DIMLIB
+#include <dim.h>
+
+#ifdef WIN32
+//#define poll(pfd,nfds,timeout)	WSAPoll(pfd,nfds,timeout)
 #define ioctl ioctlsocket
 
@@ -26,5 +34,7 @@
 #define EADDRNOTAVAIL WSAEADDRNOTAVAIL
 #define EWOULDBLOCK WSAEWOULDBLOCK
+#define EINPROGRESS WSAEINPROGRESS
 #define ECONNREFUSED WSAECONNREFUSED
+#define ETIMEDOUT WSAETIMEDOUT
 #define HOST_NOT_FOUND	WSAHOST_NOT_FOUND
 #define NO_DATA	WSANO_DATA
@@ -80,9 +90,4 @@
 #define MY_FD_ISSET(fd, set)	FD_ISSET(fd, set)
 #endif
-
-#include <stdio.h>
-#include <time.h>
-#define DIMLIB
-#include <dim.h>
 
 #define ushort unsigned short
@@ -813,15 +818,17 @@
     fd_set	rfds;
     int	conn_id, ret, selret, count;
+#ifndef __linux__
 	struct timeval	timeout;
+#endif
 
 	if(num){}
 	do
 	{
-		timeout.tv_sec = 0;		/* Don't wait, just poll */
-		timeout.tv_usec = 0;
 		list_to_fds( &rfds );
 #ifdef __linux__
 		selret = poll(Pollfds, Pollfd_size, 0);
 #else
+		timeout.tv_sec = 0;		/* Don't wait, just poll */
+		timeout.tv_usec = 0;
 		selret = select(FD_SETSIZE, &rfds, NULL, NULL, &timeout);
 #endif
@@ -890,7 +897,7 @@
 #endif
 		if(ret <= 0)
-		  {
-		    printf("poll returned %d, errno %d\n", ret, errno);
-		  }
+		{
+		    printf("poll/select returned %d, errno %d\n", ret, errno);
+		}
 		if(ret > 0)
 		{
@@ -1023,5 +1030,5 @@
 	int host_addr;
 #endif
-	int path, val, ret_code, ret;
+	int path, val, ret_code, ret, retcon, selret;
 	int a,b,c,d;
 /* Fix for gcc 4.6 "dereferencing type-punned pointer will break strict-aliasing rules"?!*/
@@ -1029,4 +1036,13 @@
 	unsigned char *ipaddr = ipaddr_buff;
 	int host_number = 0;
+	int tcpip_would_block();
+#ifdef __linux__
+	struct pollfd pollitem;
+#else
+	struct timeval	timeout;
+	fd_set rfds, wfds, efds;
+#endif
+	int so_error = ETIMEDOUT;
+	int so_error_len = sizeof(so_error);
 
     dim_tcpip_init(0);
@@ -1161,7 +1177,8 @@
 #endif
 	sockname.sin_port = htons((ushort) port); /* port number to send to */
-	while((ret = connect(path, (struct sockaddr*)&sockname, sizeof(sockname))) == -1 )
-	{
-		if(errno != EINTR)
+	/*
+	while ((ret = connect(path, (struct sockaddr*)&sockname, sizeof(sockname))) == -1)
+	{
+		if (errno != EINTR)
 		{
 			closesock(path);
@@ -1169,5 +1186,50 @@
 		}
 	}
-	strcpy( Net_conns[conn_id].node, node );
+	*/
+	set_non_blocking(path);
+	retcon = connect(path, (struct sockaddr*)&sockname, sizeof(sockname));
+#ifndef WIN32
+	ret = errno;
+#else
+	ret = WSAGetLastError();
+#endif
+	set_blocking(path);
+	if (retcon == -1)
+	{
+		if (tcpip_would_block(ret))
+		{
+#ifdef __linux__
+			pollitem.fd = path;
+			pollitem.events = POLLIN | POLLOUT | POLLERR;
+			pollitem.revents = 0;
+			selret = poll(&pollitem, 1, CONNECT_TMOUT * 1000);
+#else
+			timeout.tv_sec = CONNECT_TMOUT;
+			timeout.tv_usec = 0;
+			FD_ZERO(&wfds);
+			FD_SET(path, &wfds);
+			FD_ZERO(&rfds);
+			FD_SET(path, &rfds);
+			FD_ZERO(&efds);
+			FD_SET(path, &efds);
+			selret = select(FD_SETSIZE, &rfds, &wfds, &efds, &timeout);
+#endif
+			if (selret > 0)
+			{
+				getsockopt(path, SOL_SOCKET, SO_ERROR, (void *)&so_error, &so_error_len);
+			}
+		}
+		if (so_error != 0)
+		{
+#ifndef WIN32
+			errno = so_error;
+#else
+			WSASetLastError(so_error);
+#endif
+			closesock(path);
+			return(0);
+		}
+	}
+	strcpy(Net_conns[conn_id].node, node);
 	strcpy( Net_conns[conn_id].task, task );
 	Net_conns[conn_id].channel = path;
@@ -1547,5 +1609,7 @@
    if(code == EWOULDBLOCK)
 		return(1);
-    return(0);
+   else if (code == EINPROGRESS)
+	   return(1);
+   return(0);
 }
 
Index: /trunk/FACT++/dim/src/utilities.c
===================================================================
--- /trunk/FACT++/dim/src/utilities.c	(revision 18919)
+++ /trunk/FACT++/dim/src/utilities.c	(revision 18920)
@@ -19,4 +19,23 @@
 #define DIMLIB
 #include <dim.h>
+
+/*added by dietrich beck, GSI*/
+#ifdef PHARLAP
+#define getenv(x) getenv2(x)
+char* getenv2(envname)
+char* envname;
+{
+	char* buff;
+	int ml;
+
+	buff = (char*)malloc(200);
+	ml = GetEnvironmentVariable(envname, buff, 200);
+
+	if (ml == 0){
+		buff = NULL;
+	}
+	return buff;
+}
+#endif
 
 int get_proc_name(char *proc_name)
Index: /trunk/FACT++/dim/src/webDid/webDid.c
===================================================================
--- /trunk/FACT++/dim/src/webDid/webDid.c	(revision 18919)
+++ /trunk/FACT++/dim/src/webDid/webDid.c	(revision 18920)
@@ -6,8 +6,12 @@
 #include <dis.h>
 
-extern int WebDID_Debug;
+int WebDID_Debug = 1;
+int IsWebDID = 1;
 
 typedef struct item{
     struct item *next;
+	int id;
+	/* must be here */
+	char *service_format_ptr;
 	DNS_SERVER_INFO server;
 	DNS_SERVICE_INFO *service_ptr;
@@ -16,4 +20,6 @@
 	int busy;
 	int isSMI;
+//	char *servicelistp;
+	char **service_format_ptrp;
 }SERVER;
 
@@ -27,4 +33,30 @@
 }NODE;
 NODE *Node_head = (NODE *)0;
+
+typedef struct req_ent {
+	struct req_ent *next;
+	struct req_ent *prev;
+	int conn_id;
+//	int service_id;
+//	int req_id;
+//	int type;
+//	struct serv *service_ptr;
+	int timeout;
+//	int format;
+//	int first_time;
+//	int delay_delete;
+//	int to_delete;
+	TIMR_ENT *timr_ent;
+	void *nolink;
+	int nolinksize;
+	struct reqp_ent *reqpp;
+	struct sitem *servicep;
+} REQUEST;
+
+typedef struct reqp_ent {
+	struct reqp_ent *next;
+	struct reqp_ent *prev;
+	REQUEST *reqp;
+} REQUEST_PTR;
 
 typedef struct sitem{
@@ -43,6 +75,11 @@
 	time_t last_updated;
 	int n_browsers;
-}CURR_SERVICE;
-CURR_SERVICE *Curr_service_head = (CURR_SERVICE *)0;
+	int formatted;
+//	void *nolink;
+//	int nolinksize;
+	REQUEST *request_head;
+	int is_nolink;
+}SERVICE;
+SERVICE *Curr_service_head = (SERVICE *)0;
 
 typedef struct objstate{
@@ -62,4 +99,6 @@
     struct bitem *next;
 	int id;
+	/* must be here */
+	char *service_format_ptr;
 	int subscribe;
 	time_t last_subscribed;
@@ -71,5 +110,5 @@
 	int n_servers;
 	int n_nodes;
-	CURR_SERVICE *servicep;
+	SERVICE *servicep;
 	char *JSONBuffer;
 	int JSONBufferSize;
@@ -78,5 +117,5 @@
 	char pattern[256];
 	char curr_command[MAX_NAME];
-	char *service_format_ptr;
+//	char *service_format_ptr;
 	int isSMI;
 	int n_domains;
@@ -85,4 +124,6 @@
 	int curr_smidomain_nobjs;
 	OBJSTATE *smidomainp;
+	int formatted;
+	REQUEST_PTR *requestp_head;
 }BROWSER;
 BROWSER *Browser_head = (BROWSER *)0;
@@ -106,5 +147,6 @@
 int N_services = 0;	
 static char no_link = -1;
-static char no_link_str[5] = "DEAD";
+//static char no_link_str[5] = "DEAD";
+static char no_link_str[26] = "__DIM_SERVICE_NOT_THERE__";
 int no_link_int = -1;
 FILE	*fptr;
@@ -147,8 +189,16 @@
 	}
 	sprintf(icon_title,"DID %s",dns_node);
-dim_print_date_time();
-printf("webDid Starting up on %s\n\t serving %s\n", local_node, Title);
+	if (IsWebDID)
+	{
+		dim_print_date_time();
+		printf("webDid Starting up on %s\n\t serving %s\n", local_node, Title);
+	}
+	else
+	{
+		dim_print_date_time();
+		printf("webDim Starting up on %s\n\t serving %s\n", local_node, Title);
+	}
 	Timer_q = dtq_create();
-	dic_info_service("DIS_DNS/SERVER_INFO",MONITORED,0,0,0,update_servers,0,
+	dic_info_service((const char *)"DIS_DNS/SERVER_INFO",MONITORED,0,0,0,(void (*)(int *,void *,int *))update_servers,0,
 						&no_link,1);
 	return 1;
@@ -187,17 +237,71 @@
 }
 
-int find_server_service_pattern(SERVER *servp, char *pattern)
+int find_server_service_pattern(SERVER *servp, char *pattern, char **bufptr)
 {
 	DNS_SERVICE_INFO *servicep;
 	int n_services, i;
 	int n_found = 0;
+	char *ptr, str[256], *sptr, *sformat, *stype;
+	int type, index;
+	char *addJSONChildStart();
+	char *addJSONChildEnd();
+	int doall = 0, doit = 0;
 
 	servicep = servp->service_ptr;
 	n_services = servp->server.n_services;
-	for(i = 0; i < n_services; i++)
-	{
-		if(strstr(servicep->name, pattern))
+	if (!strcmp(pattern, "*"))
+	{
+		doall = 1;
+	}
+	for (i = 0; i < n_services; i++)
+	{
+		sptr = (char *)servp->service_format_ptrp[i];
+		if (!sptr)
+			break;
+		if (!doall)
+		{
+			doit = 0;
+//			if (strstr(servicep->name, pattern))
+//			if (sptr)
+//			{
+//				if (strstr(servicep->name, pattern))
+				if (strstr(sptr, pattern))
+				{
+					doit = 1;
+				}
+//			}
+		}
+		if (doall || doit)
 		{
 			n_found++;
+			if(bufptr)
+			{
+/*
+				type = servicep->type;
+				if (type < 0xff)
+					printf("problem %s %d", servicep->name, servicep->type);
+				index = type;
+				type &= 0x000000FF;
+				index = (index >> 16) & 0xFFFF;
+				index--;
+				sptr = (char *)servp->service_format_ptrp[index];
+				ptr = *bufptr;
+				sprintf(str, "name: \"%s\", format: \"%s\", type: %d", servicep->name,
+                    (char *)sptr + strlen((const char *)sptr)+1, type);
+*/
+				ptr = *bufptr;
+				sformat = (char *)sptr + strlen((const char *)sptr) + 1;
+				stype = (char *)sformat + strlen((const char *)sformat) + 1;
+				if (*stype = '\n')
+					type = 0;
+				else if (*stype == 'C')
+					type = 1;
+				else if (*stype == 'R')
+					type = 2;
+				sprintf(str, "name: \"%s\", format: \"%s\", type: %d", sptr, sformat, type);
+				ptr = addJSONChildStart(ptr, str, 0);
+				ptr = addJSONChildEnd(ptr, 1);
+				*bufptr = ptr;
+			}
 		}
 		servicep++;
@@ -206,5 +310,5 @@
 }
 
-int find_service_pattern(NODE *nodep, SERVER *servpp, char *pattern, int *n_servers)
+int find_service_pattern(NODE *nodep, SERVER *servpp, char *pattern, int *n_servers, char **ptr)
 {
   SERVER *servp;
@@ -217,5 +321,5 @@
 	while( (servp = (SERVER *)sll_get_next((SLL *)servp)) )
 	{
-		if((ret = find_server_service_pattern(servp, pattern)))
+		if((ret = find_server_service_pattern(servp, pattern, ptr)))
 		{
 			n_found += ret;
@@ -226,5 +330,5 @@
   else
   {
-	if((ret = find_server_service_pattern(servpp, pattern)))
+	if((ret = find_server_service_pattern(servpp, pattern, ptr)))
 	{
 		n_found += ret;
@@ -236,10 +340,10 @@
 }
 
-CURR_SERVICE *find_curr_service(char *service)
-{
-  CURR_SERVICE *servicep;
+SERVICE *find_curr_service(char *service)
+{
+  SERVICE *servicep;
 
   servicep = Curr_service_head ;
-  while( (servicep = (CURR_SERVICE *)sll_get_next((SLL *)servicep)) )
+  while( (servicep = (SERVICE *)sll_get_next((SLL *)servicep)) )
   {
       if(!strcmp(servicep->name,service))
@@ -248,5 +352,5 @@
 	  }
   }
-  return ((CURR_SERVICE *)0);
+  return ((SERVICE *)0);
 }
 
@@ -285,5 +389,5 @@
 {
   BROWSER *browserp;
-  int prepareJSONTree();
+  int prepareJSONTree(char *, BROWSER *);
 
   browserp = Browser_head;
@@ -291,5 +395,5 @@
   {
 	  if(browserp->pattern[0] != '\0')
-		  prepareJSONTree(browserp);
+		  prepareJSONTree("",browserp);
   }
 }
@@ -311,4 +415,5 @@
 int prepareJSONTree();
 int prepareJSONHeader();
+void got_update_services();
 
 	if(tag){}
@@ -379,7 +484,10 @@
 			strcpy(servp->name,sname);
 			servp->next = 0;
+			servp->id = 0;
 			servp->busy = 0;
 			servp->server.n_services = 0;
 			servp->service_ptr = 0;
+			servp->service_format_ptr = 0;
+			servp->service_format_ptrp = 0;
 			servp->isSMI = 0;
 			if(strstr(sname,"_SMI"))
@@ -407,5 +515,15 @@
 			servp->service_ptr = 0;
 		}
-		if(n_services != -1)
+		if (servp->service_format_ptr)
+		{
+			free(servp->service_format_ptr);
+			servp->service_format_ptr = 0;
+		}
+		if (servp->service_format_ptrp)
+		{
+			free(servp->service_format_ptrp);
+			servp->service_format_ptrp = 0;
+		}
+		if (n_services != -1)
 		{
 			service_size = n_services*(int)sizeof(DNS_SERVICE_INFO);
@@ -413,4 +531,8 @@
 			memcpy(servp->service_ptr, buffer->services, (size_t)service_size);
 			N_services += n_services;
+			sprintf(str, "%s/SERVICE_LIST", sname);
+//			printf("subscribe update_servers %s %d\n", sname, n_services);
+			dic_info_service(str, ONCE_ONLY, 20, 0, 0,
+				got_update_services, (dim_long)servp, "None", 5);
 		}
 		servp->busy = 1;
@@ -419,17 +541,18 @@
 	{
 	  if(servp)
-	    {
+	  {
 		N_servers--;
 		if(servp->server.n_services != -1)
-		  {
-			N_services -= servp->server.n_services;
-		  }
+		{
+		    N_services -= servp->server.n_services;
+		}
 		servp->server.n_services = 0;
 		servp->busy = -1;
 		servp->isSMI = 0;
-	    }
+	  }
 	}
 	if(JSONHeader[0])
 	  prepareJSONHeader();
+//	printf("update_servers %d %d %d\n", N_nodes, N_servers, N_services);
 }
 
@@ -437,11 +560,131 @@
 {
 	BROWSER *browserp;
+	SERVER *servp;
+	DNS_SERVICE_INFO *servicep;
+	int i, j, n_services, index = 0, type;
+	char *ptr, *ptre, *ptr1, tmp[MAX_NAME], *sptr;
 
 	if(size){}
 	browserp = (BROWSER *)*tag;
-	if(browserp->service_format_ptr)
-		free(browserp->service_format_ptr);
-	browserp->service_format_ptr = (char *)malloc(strlen(buffer)+1);
-	strcpy(browserp->service_format_ptr, buffer);
+	if (browserp)
+	{
+		if (browserp->service_format_ptr)
+			free(browserp->service_format_ptr);
+		browserp->service_format_ptr = (char *)malloc(strlen(buffer) + 1);
+		strcpy(browserp->service_format_ptr, buffer);
+	}
+	if (browserp->id == 0)
+	{
+		servp = (SERVER *)browserp;
+		n_services = servp->server.n_services;
+		if (servp->service_format_ptrp)
+			free(servp->service_format_ptrp);
+		servp->service_format_ptrp = (char **)malloc(n_services*sizeof(char *));
+		memset(servp->service_format_ptrp, 0, (size_t)n_services*sizeof(char *));
+		ptr = servp->service_format_ptr;
+		servicep = servp->service_ptr;
+		for (i = 0; i < n_services; i++)
+		{
+			servicep->type &= 0x000000FF;
+			servicep++;
+			servp->service_format_ptrp[index++] = ptr;
+			ptre = strchr(ptr, '\n');
+			ptr1 = strchr(ptr, '|');
+			if(ptr1)
+			{
+				*ptr1 = '\0';
+				ptr1++;
+				ptr1 = strchr(ptr1, '|');
+				if (ptr1)
+					*ptr1 = '\0';
+			}
+			ptr = ptre;
+			if (!ptr)
+			{
+				break;
+				if (!(*ptr))
+					break;
+			}
+			ptr++;
+			if (!(*ptr))
+				break;
+		}
+/*
+		for (i = 0; i < n_services; i++)
+		{
+			if (!servp->service_format_ptrp[i])
+				break;
+			servicep = servp->service_ptr;
+			for (j = 0; j < n_services; j++)
+			{
+				if (servicep->type < 0xFF)
+				{
+					if ((strstr(servicep->name, "/RpcIn")) || (strstr(servicep->name, "/RpcOut")))
+					{
+						strcpy(tmp, servicep->name);
+						if ((ptr = strstr(tmp, "/RpcIn")))
+							*ptr = '\0';
+						if ((ptr = strstr(tmp, "/RpcOut")))
+							*ptr = '\0';
+						if (!strcmp(tmp, servp->service_format_ptrp[i]))
+						{
+							servicep->type |= ((i + 1) << 16);
+							break;
+						}
+					}
+					if (!strcmp(servicep->name, servp->service_format_ptrp[i]))
+					{
+						servicep->type |= ((i+1) << 16);
+						break;
+					}
+				}
+//				printf("%s %08x\n",servicep->name, servicep->type);
+//				if (servicep->type == 0)
+//					break;
+				servicep++;
+			}
+		}
+*/
+/*
+		servicep = servp->service_ptr;
+		for (i = 0; i < n_services; i++)
+		{
+			for (j = 0; j < n_services; j++)
+			{
+				if (!servp->service_format_ptrp[j])
+					break;
+				if ((strstr(servicep->name, "/RpcIn")) || (strstr(servicep->name, "/RpcOut")))
+				{
+					strcpy(tmp, servicep->name);
+					if ((ptr = strstr(tmp, "/RpcIn")))
+						*ptr = '\0';
+					if ((ptr = strstr(tmp, "/RpcOut")))
+						*ptr = '\0';
+					if (!strcmp(tmp, servp->service_format_ptrp[j]))
+					{
+						servicep->type |= ((j + 1) << 16);
+						break;
+					}
+				}
+				if (!strcmp(servicep->name, servp->service_format_ptrp[j]))
+				{
+					servicep->type |= ((j + 1) << 16);
+					break;
+				}
+			}
+				//				if (servicep->type == 0)
+				//					break;
+			type = servicep->type;
+			index = type;
+			type &= 0x000000FF;
+			index = (index >> 16) & 0xFFFF;
+			index--;
+			sptr = (char *)servp->service_format_ptrp[index];
+			printf("%s %08x %s\n", servicep->name, servicep->type, (char *)sptr + strlen((const char *)sptr) + 1);
+			servicep++;
+		}
+*/
+	}
+//	printf("got_update_services %s\n", buffer);
 }
 
@@ -454,5 +697,5 @@
 	BROWSER *browserp;
 	char *prepareJSONServiceList();
-	BROWSER *create_browser();
+	BROWSER *create_browser(int);
 
 	if(!(browserp = find_browser(browser)))
@@ -610,5 +853,5 @@
 }
 
-int delete_curr_service(CURR_SERVICE *servicep)
+int delete_curr_service(SERVICE *servicep)
 {
 
@@ -620,4 +863,6 @@
 	if(servicep->buffer_str_size)
 		free(servicep->buffer_str);
+//	if (servicep->nolink)
+//		free(servicep->nolink);
 	sll_remove((SLL *)Curr_service_head, (SLL *)servicep);
 	free(servicep);
@@ -625,8 +870,21 @@
 }
 
+int close_browser(int browser)
+{
+	BROWSER *browserp;
+
+	if ((browserp = find_browser(browser)))
+		delete_browser(browserp);
+	return 1;
+}
 int delete_browser(BROWSER *browserp)
 {
-	CURR_SERVICE *servicep;
-
+	SERVICE *servicep;
+	int i;
+
+	release_all_requests(browserp);
+	if (browserp->requestp_head)
+		free(browserp->requestp_head);
+	/*
 	if((servicep = browserp->servicep))
 	{
@@ -635,4 +893,5 @@
 			delete_curr_service(servicep);
 	}
+*/
 	if(browserp->service_format_ptr)
 		free(browserp->service_format_ptr);
@@ -679,5 +938,5 @@
 	browserp->n_servers = 0;
 	browserp->n_services = 0;
-	browserp->servicep = 0;
+//	browserp->servicep = 0;
 	browserp->JSONBuffer = 0;
 	browserp->JSONBufferSize = 0;
@@ -689,6 +948,9 @@
 	browserp->curr_smidomain[0] = '\0';
 	browserp->smidomainp = 0;
-	sll_insert_queue((SLL *)Browser_head,(SLL *)browserp);
-	dtq_start_timer(10, check_browser, browserp);
+	browserp->requestp_head = (REQUEST_PTR *)malloc(sizeof(REQUEST_PTR));
+	dll_init((DLL *)(browserp->requestp_head));
+	sll_insert_queue((SLL *)Browser_head, (SLL *)browserp);
+	if(IsWebDID)
+	    dtq_start_timer(10, check_browser, browserp);
 	return browserp;
 }
@@ -716,16 +978,127 @@
 }
 
-int update_service_data(char *service, int conn_id, int subscribe, int req, int browser, int force)
-{
-	CURR_SERVICE *servicep;
+REQUEST *create_request(int conn_id, SERVICE *servicep, int timeout, void *nolink, int nolinksize)
+{
+	REQUEST *newp;
+
+	newp = (REQUEST *)malloc(sizeof(REQUEST));
+	newp->servicep = servicep;
+	newp->timeout = timeout;
+	newp->conn_id = conn_id;
+//	newp->first_time = 1;
+//	newp->delay_delete = 0;
+//	newp->to_delete = 0;
+	newp->timr_ent = 0;
+	newp->reqpp = 0;
+	newp->nolink = 0;
+	newp->nolinksize = 0;
+	if (nolinksize)
+	{
+		newp->nolink = malloc(nolinksize);
+		newp->nolinksize = nolinksize;
+		memcpy(newp->nolink, nolink, nolinksize);
+	}
+	dll_insert_queue((DLL *)servicep->request_head, (DLL *)newp);
+	return newp;
+}
+
+REQUEST_PTR *create_requestp(REQUEST *reqp, BROWSER *browserp)
+{
+	REQUEST_PTR *reqpp;
+
+	reqpp = (REQUEST_PTR *)malloc(sizeof(REQUEST_PTR));
+	reqpp->reqp = reqp;
+	reqp->reqpp = reqpp;
+	dll_insert_queue((DLL *)browserp->requestp_head, (DLL *)reqpp);
+	return reqpp;
+}
+
+int release_request(REQUEST_PTR *reqpp)
+{
+	REQUEST *reqp;
+	SERVICE *servicep;
+
+	reqp = reqpp->reqp;
+	if (reqp)
+	{
+		servicep = reqp->servicep;
+		dll_remove((DLL *)reqp);
+	}
+	if (reqpp)
+		dll_remove((DLL *)reqpp);
+	if (reqp->nolink)
+		free(reqp->nolink);
+	//	if (reqp->timr_ent)
+//		dtq_rem_entry(Dis_timer_q, reqp->timr_ent);
+//	id_free(reqp->req_id, SRC_DIS);
+	servicep->n_browsers--;
+	if (dll_empty((DLL *)servicep->request_head))
+	{
+//		if (!servicep->n_browsers)
+//		{
+			free(servicep->request_head);
+			delete_curr_service(servicep);
+//		}
+	}
+	if (reqp)
+		free(reqp);
+	if (reqpp)
+		free(reqpp);
+	return 1;
+}
+
+int release_all_requests(BROWSER *browserp)
+{
+	REQUEST_PTR *reqpp, *auxp;
+	int release_request();
+
+	if (browserp)
+	{
+		reqpp = browserp->requestp_head;
+		while ((reqpp = (REQUEST_PTR *)dll_get_next((DLL *)browserp->requestp_head,
+			(DLL *)reqpp)))
+		{
+			auxp = reqpp->prev;
+			release_request(reqpp);
+			reqpp = auxp;
+		}
+	}
+	return 1;
+}
+
+REQUEST_PTR *find_request(SERVICE* servicep, int conn_id)
+{
+	REQUEST_PTR *reqpp;
+	REQUEST *reqp;
+
+	if (servicep)
+	{
+		reqp = servicep->request_head;
+		while ((reqp = (REQUEST *)dll_get_next((DLL *)servicep->request_head,
+			(DLL *)reqp)))
+		{
+			if (reqp->conn_id == conn_id)
+				return reqp->reqpp;
+		}
+	}
+	return (REQUEST_PTR *)0;
+}
+
+int update_service_data(char *service, int conn_id, int subscribe, int req, int browser, int force, 
+	int formatted, void *nolink, int nolinksize)
+{
+	SERVICE *servicep;
 	time_t tsecs;
 	void recv_service_info();
 	extern void sendData();
 	BROWSER *browserp;
+	int i;
+	REQUEST *reqp;
+	REQUEST_PTR *reqpp;
 
 	if(req){}
 	if(!Curr_service_head)
 	{
-		Curr_service_head = (CURR_SERVICE *)malloc(sizeof(CURR_SERVICE));
+		Curr_service_head = (SERVICE *)malloc(sizeof(SERVICE));
 		sll_init((SLL *)Curr_service_head);
 	}
@@ -737,13 +1110,30 @@
 		return 1;
 	}
-	if((servicep = browserp->servicep))
-	{
-		servicep->n_browsers--;
-		if(!servicep->n_browsers)
-			delete_curr_service(servicep);
+	browserp->formatted = formatted;
+	if(IsWebDID)
+	{
+/*
+		if ((servicep = browserp->servicep))
+		{
+			servicep->n_browsers--;
+			if (!servicep->n_browsers)
+				delete_curr_service(servicep);
+		}
+*/
+		release_all_requests(browserp);
+	}
+	if (subscribe == -2)
+	{
+		if ((servicep = find_curr_service(service)))
+		{
+			reqpp = find_request(servicep, conn_id);
+			if (reqpp)
+			    release_request(reqpp);
+		}
+		return 1;
 	}
 	if(!(servicep = find_curr_service(service)))
 	{
-		servicep = (CURR_SERVICE *)malloc(sizeof(CURR_SERVICE));
+		servicep = (SERVICE *)malloc(sizeof(SERVICE));
 		strcpy(servicep->name,service);
 		servicep->conn_id = conn_id;
@@ -760,7 +1150,13 @@
 		servicep->last_subscribed = tsecs;
 		servicep->n_browsers = 0;
+		servicep->formatted = formatted;
+		servicep->request_head = (REQUEST *)malloc(sizeof(REQUEST));
+		servicep->is_nolink = 0;
+		dll_init((DLL *)(servicep->request_head));
+		reqp = create_request(conn_id, servicep, subscribe, nolink, nolinksize);
+		reqpp = create_requestp(reqp, browserp);
 		sll_insert_queue((SLL *)Curr_service_head,(SLL *)servicep);
-		servicep->sid = (int)dic_info_service_stamped( service, MONITORED, subscribe, 0, 0,
-			recv_service_info, servicep, &no_link_int, 4);
+		servicep->sid = (int)dic_info_service_stamped(service, MONITORED, 0, 0, 0,
+			recv_service_info, servicep, no_link_str, strlen(no_link_str));
 	}
 	else
@@ -768,11 +1164,22 @@
 		if(servicep->size)
 		{
-			if((servicep->timestamp > browserp->last_updated) || (force))
-			{
-				sendData(conn_id, servicep->buffer_str, 4);
+			reqp = create_request(conn_id, servicep, subscribe, nolink, nolinksize);
+			reqpp = create_requestp(reqp, browserp);
+			if ((servicep->timestamp > browserp->last_updated) || (force))
+			{
+				if(browserp->formatted)
+					sendData(conn_id, servicep->buffer_str, 4);
+				else
+				{
+					if (servicep->is_nolink)
+						sendData(conn_id, reqp->nolink, 11);
+					else
+						sendData(conn_id, servicep->buffer, 11);
+//					sendData(conn_id, servicep->buffer, 11);
+				}
 			}
 			else
 			{
-				sendData(conn_id, "", 4);
+                sendData(conn_id, "", 4);
 			}
 			browserp->last_updated = servicep->timestamp;
@@ -781,5 +1188,5 @@
 	if(force)
 	{
-		browserp->servicep = servicep;
+//   		browserp->servicep = servicep;
 		servicep->n_browsers++;
 	}
@@ -789,5 +1196,5 @@
 int check_browser_changes(char *service, int conn_id, int subscribe, int req, int browser, int force)
 {
-	CURR_SERVICE *servicep;
+	SERVICE *servicep;
 	time_t tsecs;
 	void recv_service_info();
@@ -803,5 +1210,5 @@
 	if(!Curr_service_head)
 	{
-		Curr_service_head = (CURR_SERVICE *)malloc(sizeof(CURR_SERVICE));
+		Curr_service_head = (SERVICE *)malloc(sizeof(SERVICE));
 		sll_init((SLL *)Curr_service_head);
 	}
@@ -873,6 +1280,7 @@
 	void print_service_formatted();
 	extern void sendData();
-	CURR_SERVICE *servicep;
+	SERVICE *servicep;
 	time_t tsecs;
+	REQUEST *reqp, *auxp;
 
 	servicep = *tag;
@@ -897,6 +1305,10 @@
 	strcpy(Curr_service_name, servicep->name);
 	get_curr_service_format();
-	if((*size == 4 ) && (*buffer == -1))
-	{
+//	if ((*size == servicep->nolinksize) && (!memcmp(buffer, servicep->nolink, servicep->nolinksize)))
+//	if ((*size == 4) && (*buffer == -1))
+	servicep->is_nolink = 0;
+	if ((*size == strlen(no_link_str)) && (!memcmp(buffer, no_link_str, strlen(no_link_str))))
+    {
+		servicep->is_nolink = 1;
 		sprintf(Service_content_str,
 			"Service %s Not Available", Curr_service_name);
@@ -906,13 +1318,54 @@
 		print_service_formatted(servicep, buffer, *size);
 	}
-	if(servicep->last_updated == 0)
-	{
-		sendData(conn_id, Service_content_str, 4);
+if(WebDID_Debug)
+	printf("service updated - %s,  conn_id %d\n", Curr_service_name, conn_id);
+
+    if (IsWebDID)
+    {
+	    if (servicep->last_updated == 0)
+	    {
+		    if (servicep->formatted)
+			    sendData(conn_id, Service_content_str, 4);
+		    else
+			    sendData(conn_id, servicep->buffer, 11);
+		    tsecs = time((time_t *)0);
+		    servicep->last_updated = tsecs;
+	    }
+    }
+	else
+	{
 		tsecs = time((time_t *)0);
 		servicep->last_updated = tsecs;
-	}
-}
-
-void print_service_formatted(CURR_SERVICE *servicep, void *buff, int size)
+		reqp = servicep->request_head;
+		while ((reqp = (REQUEST *)dll_get_next((DLL *)servicep->request_head,
+			(DLL *)reqp)))
+		{
+/*
+			if (servicep->buffer_size < reqp->nolinksize)
+			{
+				if (servicep->buffer_size)
+					free(servicep->buffer);
+				servicep->buffer = malloc((size_t)reqp->nolinksize);
+				servicep->buffer_size = reqp->nolinksize;
+			}
+			memcpy(servicep->buffer, (char *)reqp->nolink, (size_t)reqp->nolinksize);
+			servicep->size = *size;
+*/
+			if (servicep->is_nolink)
+				sendData(reqp->conn_id, reqp->nolink, 11);
+			else
+      			sendData(reqp->conn_id, servicep->buffer, 11);
+			if (reqp->timeout == -1)
+			{
+// May delete servicep...
+				auxp = reqp->prev;
+				release_request(reqp->reqpp);
+				reqp = auxp;
+			}
+		}
+	}
+}
+
+void print_service_formatted(SERVICE *servicep, void *buff, int size)
 {
 char type;
@@ -1463,4 +1916,27 @@
 }
 
+char *getJSONDimBuffer(char *node, int browser)
+{
+	BROWSER *browserp;
+	int prepareJSONDimTree();
+
+	if (browser)
+	{
+		if ((browserp = find_browser(browser)))
+		{
+			if (browserp->pattern[0] != '\0')
+			{
+				prepareJSONDimTree(node, browserp);
+				return(browserp->JSONBuffer);
+			}
+			browserp->n_services = 0;
+			browserp->n_servers = 0;
+			browserp->n_nodes = 0;
+		}
+	}
+	prepareJSONDimTree(node, 0);
+	return(JSONBuffer);
+}
+
 char *getJSONHeader(int isSMI)
 {
@@ -1550,5 +2026,5 @@
 		if(selective)
 		{
-			if(!(ret = find_service_pattern(nodep, 0, browserp->pattern, &tot_n_servers)))
+			if(!(ret = find_service_pattern(nodep, 0, browserp->pattern, &tot_n_servers, 0)))
 			{
 				nodep->match = 0;
@@ -1609,5 +2085,5 @@
 			if(selective)
 			{
-				if(!(ret = find_service_pattern(nodep, servp, browserp->pattern, 0)))
+				if(!(ret = find_service_pattern(nodep, servp, browserp->pattern, 0, 0)))
 				{
 					servp->match = 0;
@@ -1714,5 +2190,5 @@
 		if(selective)
 		{
-			if(!(ret = find_service_pattern(nodep, 0, pattern, &tot_n_servers)))
+			if(!(ret = find_service_pattern(nodep, 0, pattern, &tot_n_servers, 0)))
 			{
 				nodep->match = 0;
@@ -1773,5 +2249,5 @@
 			if(selective)
 			{
-				if(!(ret = find_service_pattern(nodep, servp, pattern, 0)))
+				if(!(ret = find_service_pattern(nodep, servp, pattern, 0, 0)))
 				{
 					servp->match = 0;
@@ -1814,4 +2290,168 @@
 	*/
 printf("%s\n",browserp->JSONSmiBuffer);
+	return(1);
+}
+
+int prepareJSONDimTree(char *node, BROWSER *browserp)
+{
+	char *ptr;
+	NODE *nodep;
+	SERVER *servp;
+	char str[256], aux[128];
+	int selective = 0;
+	int n_nodes, tot_n_nodes;
+	int n_servers, tot_n_servers;
+	int ret, n_found = 0;
+
+	if (browserp)
+	{
+		if (browserp->pattern[0] != '\0')
+			selective = 1;
+		else
+			return(0);
+	}
+	if (!selective)
+	{
+		if (JSONBufferSize == 0)
+		{
+			JSONBuffer = malloc((size_t)(N_nodes * 128 + N_servers * 128));
+		}
+		else if (JSONBufferSize < N_nodes * 128 + N_servers * 128)
+		{
+			free(JSONBuffer);
+			JSONBuffer = malloc((size_t)(N_nodes * 128 + N_servers * 128));
+		}
+		ptr = JSONBuffer;
+	}
+	else
+	{
+		if (browserp->JSONBufferSize == 0)
+		{
+			browserp->JSONBuffer = malloc((size_t)(N_services * (128*2)));
+		}
+		else if (browserp->JSONBufferSize < (N_services * (128 * 2)))
+		{
+			free(browserp->JSONBuffer);
+			browserp->JSONBuffer = malloc((size_t)(N_services * (128 * 2)));
+		}
+		ptr = browserp->JSONBuffer;
+	}
+	*ptr = '\0';
+	if (!strcmp(node, "src"))
+	{
+		ptr = addJSONStart(ptr);
+		ptr = addJSONNodeStart(ptr, "services");
+//		sprintf(str, "text: \"%s\", id: \"Nodes\", expanded: false", Title);
+//		ptr = addJSONChildStart(ptr, str, 1);
+//		ptr = addJSONNodeStart(ptr, "children");
+		nodep = Node_head;
+		tot_n_nodes = 0;
+		while ((nodep = (NODE *)sll_get_next((SLL *)nodep)))
+		{
+//			nodep->match = 1;
+			if (selective)
+			{
+				if (!(ret = find_service_pattern(nodep, 0, browserp->pattern, &tot_n_servers, &ptr)))
+				{
+//					nodep->match = 0;
+					continue;
+				}
+				else
+				{
+					n_found += ret;
+				}
+			}
+			tot_n_nodes++;
+		}
+		if(n_found)
+		{
+			ptr--;
+			*(ptr-1) = ' ';
+		}
+		/*
+		n_nodes = 0;
+		nodep = Node_head;
+		while ((nodep = (NODE *)sll_get_next((SLL *)nodep)))
+		{
+			if (!nodep->match)
+				continue;
+			getNodeLabel(nodep->name, aux);
+			sprintf(str, "text: \"%s\", id: \"%s\", qtip: \"%s\"",
+				aux, nodep->name, nodep->name);
+			ptr = addJSONChildStart(ptr, str, 0);
+			n_nodes++;
+			if (WebDID_Debug)
+				printf("adding %s %d %d\n", nodep->name, n_nodes, tot_n_nodes);
+			if (n_nodes < tot_n_nodes)
+				ptr = addJSONChildEnd(ptr, 1);
+			else
+				ptr = addJSONChildEnd(ptr, 0);
+		}
+        */
+//		ptr = addJSONNodeEnd(ptr);
+//		ptr = addJSONChildEnd(ptr, 0);
+		ptr = addJSONNodeEnd(ptr);
+		ptr = addJSONEnd(ptr);
+		if (selective)
+		{
+			browserp->n_services = n_found;
+			browserp->n_servers = tot_n_servers;
+			browserp->n_nodes = tot_n_nodes;
+		}
+	}
+	else
+	{
+		if ((nodep = find_node(node)))
+		{
+			ptr = addJSONStart(ptr);
+			ptr = addJSONNodeStart(ptr, "children");
+			servp = nodep->server_head;
+			tot_n_servers = 0;
+			while ((servp = (SERVER *)sll_get_next((SLL *)servp)))
+			{
+				servp->match = 1;
+				if (servp->busy != 1)
+				{
+					servp->match = 0;
+					continue;
+				}
+				if (selective)
+				{
+					if (!(ret = find_service_pattern(nodep, servp, browserp->pattern, 0, 0)))
+					{
+						servp->match = 0;
+						continue;
+					}
+					else
+					{
+						n_found += ret;
+					}
+				}
+				tot_n_servers++;
+			}
+			n_servers = 0;
+			servp = nodep->server_head;
+			while ((servp = (SERVER *)sll_get_next((SLL *)servp)))
+			{
+				if (!servp->match)
+					continue;
+				sprintf(str, "text: \"%s\", id: \"%d\", leaf: true, icon: \"server.png\"", servp->name, servp->server.pid);
+				ptr = addJSONChildStart(ptr, str, 0);
+				n_servers++;
+				if (n_servers < tot_n_servers)
+					ptr = addJSONChildEnd(ptr, 1);
+				else
+					ptr = addJSONChildEnd(ptr, 0);
+			}
+			ptr = addJSONNodeEnd(ptr);
+			ptr = addJSONEnd(ptr);
+		}
+	}
+	/*
+	if(!selective)
+	printf(" Nodes&Servers %s\n",JSONBuffer);
+	else
+	printf(" Nodes&Servers %s\n",browserp->JSONBuffer);
+	*/
 	return(1);
 }
@@ -1871,5 +2511,5 @@
 	if(selective)
 	{
-		n_found = find_server_service_pattern(servp, browserp->pattern);
+		n_found = find_server_service_pattern(servp, browserp->pattern, 0);
 	}
 	ptr = JSONServices;
Index: /trunk/FACT++/dim/src/webDid/webServer.c
===================================================================
--- /trunk/FACT++/dim/src/webDid/webServer.c	(revision 18919)
+++ /trunk/FACT++/dim/src/webDid/webServer.c	(revision 18920)
@@ -5,5 +5,6 @@
 #include <fcntl.h>
 
-int WebDID_Debug = 0;
+extern int WebDID_Debug;
+extern int IsWebDID;
 
 #define BUFSIZE 8096
@@ -83,5 +84,5 @@
 }
 
-int getParameters(char *buffer, char (*pars)[], char *ptrs[])
+int getParameters(char *buffer, char (*pars)[], char *ptrs[], int nmandatory)
 {
 	char *ptr, *parptr;
@@ -106,5 +107,5 @@
 	for(i = 0; ptrs[i]; i++)
 	{
-	        if((ptr = strchr(ptrs[i],'&')))
+	    if((ptr = strchr(ptrs[i],'&')))
 			*ptr = '\0';
 		while((ptr = strchr(ptrs[i],'%')))
@@ -121,8 +122,14 @@
 		}
 	}
-	if(found == n)
-		return 1;
-	else
-		return 0;
+	if(nmandatory == -1)
+	{
+		if(found == n)
+			return 1;
+	}
+	else if(found >= nmandatory)
+	{
+		return found;
+	}
+	return 0;
 }
 
@@ -136,5 +143,5 @@
 	strcpy(pars[1],"browser=");
 	pars[2][0] = '\0';
-	ret = getParameters(buffer, pars, ptrs);
+	ret = getParameters(buffer, pars, ptrs, -1);
 	if(!ret)
 		return 0;
@@ -158,5 +165,5 @@
 	strcpy(pars[3],"browser=");
 	pars[4][0] = '\0';
-	ret = getParameters(buffer, pars, ptrs);
+	ret = getParameters(buffer, pars, ptrs, -1);
 	if(!ret)
 		return 0;
@@ -181,5 +188,5 @@
 	strcpy(pars[3],"force=");
 	pars[4][0] = '\0';
-	ret = getParameters(buffer, pars, ptrs);
+	ret = getParameters(buffer, pars, ptrs, -1);
 	if(!ret)
 		return 0;
@@ -190,4 +197,70 @@
 if(WebDID_Debug)
 printf("\nparse service pars - service %s %d %d %d\n\n",service, *req, *browser, *force);
+	return 1;
+}
+
+int getServiceParametersDim(char *buffer, char *service, void *nolink, int *nolinksize, int *update)
+{
+	char pars[10][32];
+	char *ptrs[10];
+	int ret;
+	char nolinkstr[MAX_NAME] = { '\0' }, updatestr[10] = { '\0' };
+	char servicestr[MAX_NAME];
+
+	strcpy(pars[0], "service=");
+	strcpy(pars[1], "nolink=");
+	strcpy(pars[2], "update=");
+	pars[3][0] = '\0';
+	ret = getParameters(buffer, pars, ptrs, 1);
+	if (!ret)
+		return 0;
+	strcpy(servicestr, ptrs[0]);
+	if (ptrs[1])
+	    strcpy(nolinkstr, ptrs[1]);
+	if (ptrs[2])
+	    strcpy(updatestr, ptrs[2]);
+//	sscanf(ptrs[1], "%d", req);
+//	sscanf(ptrs[2], "%d", browser);
+//	sscanf(ptrs[3], "%d", force);
+	if (servicestr[0] == '"')
+	{
+		strcpy((char *)service, &servicestr[1]);
+		((char *)service)[strlen(servicestr) - 2] = '\0';
+	}
+	else
+	{
+		strcpy(service, ptrs[0]);
+	}
+	if ((nolink) && (nolinksize))
+	{
+		if(nolinkstr[0] != '\0')
+		{
+			if (nolinkstr[0] == '"')
+			{
+				strcpy((char *)nolink, &nolinkstr[1]);
+				((char *)nolink)[strlen(nolinkstr) - 2] = '\0';
+				*nolinksize = strlen(nolinkstr) - 2 + 1;
+			}
+			else
+			{
+				sscanf(nolinkstr, "%d", (int *)nolink);
+				*nolinksize = sizeof(int);
+			}
+		}
+		else
+		{
+			*((int *)nolink) = -1;
+			*nolinksize = sizeof(int);
+		}
+	}
+	if (update)
+	{
+		if (updatestr[0] != '\0')
+		{
+			sscanf(updatestr, "%d", (int *)update);
+		}
+	}
+	if (WebDID_Debug)
+		printf("\nparse service pars - service %s %s %s\n\n", service, nolinkstr, updatestr);
 	return 1;
 }
@@ -238,5 +311,5 @@
 }
 
-void sendData(int conn_id, char *buffer, int type)
+void sendData(int conn_id, char *buffer, int type, int oper)
 {
 	static char date_buffer[128];
@@ -250,6 +323,11 @@
 	extern char *getJSONHeader();
 	extern char *getJSONBuffer();
+	extern char *getJSONDimBuffer();
 	char datatype[128];
 	char *conv_buffer;
+	int conv_size = 0;
+	char nolink[MAX_NAME];
+	int nolinksize;
+	int update;
 
 	conv_buffer = buffer;
@@ -287,5 +365,5 @@
 		else
 		{
-			update_service_data(service, conn_id, 0, req, browser, force);
+			update_service_data(service, conn_id, 0, req, browser, force, 1, 0, 0);
 			return;
 		}
@@ -296,4 +374,30 @@
 if(WebDID_Debug)
 		printf("%s\n",ptr);
+		strcpy(datatype,"text/html");
+	}
+	else if(type == 10)
+	{
+		ret = getServiceParametersDim(conv_buffer, service, nolink, &nolinksize, &update);
+		if(!ret)
+		{
+			strcpy(snd_data_buffer,"{}");
+			ptr = snd_data_buffer;
+		}
+		else
+		{
+			if (oper == 0)
+				update = -1;
+			else if (oper == -1)
+				update = -2;
+			update_service_data(service, conn_id, update, 0, conn_id, 1, 0, nolink, nolinksize);
+			return;
+		}
+	}
+	else if(type == 11)
+	{
+		ptr = conv_buffer;
+if(WebDID_Debug)
+		printf("%s\n",ptr);
+//		strcpy(datatype,"application/octet-stream");
 		strcpy(datatype,"text/html");
 	}
@@ -330,8 +434,29 @@
 		}
 	}
-	getTime(date_buffer);
-	(void)sprintf(snd_buffer,"HTTP/1.1 200 OK\r\nDate: %s\r\nServer: DID/19.7\r\nContent-Length: %d\r\nContent-Type: %s\r\nConnection: close\r\n\r\n",
-		      date_buffer, (int)strlen(ptr), datatype);
-    (void)web_write(conn_id,snd_buffer,(int)strlen(snd_buffer));
+	else if (type == 12)
+	{
+		ret = getServiceParametersDim(conv_buffer, service, 0, 0, 0);
+		if (!ret)
+		{
+			strcpy(snd_data_buffer, "{}");
+			ptr = snd_data_buffer;
+		}
+		else
+		{
+			find_services(service, conn_id, conn_id, 1);
+			ptr = getJSONDimBuffer("src", conn_id);
+		}
+	}
+	if (IsWebDID)
+	{
+		getTime(date_buffer);
+/*
+		(void)sprintf(snd_buffer, "HTTP/1.1 200 OK\r\nDate: %s\r\nServer: DID/19.7\r\nContent-Length: %d\r\nContent-Type: %s\r\nKeep-Alive: timeout=1000\r\nConnection: keep-alive\r\n\r\n",
+			date_buffer, (int)strlen(ptr), datatype);
+*/
+		(void)sprintf(snd_buffer, "HTTP/1.1 200 OK\r\nDate: %s\r\nServer: DID/19.7\r\nContent-Length: %d\r\nContent-Type: %s\r\nConnection: close\r\n\r\n",
+			date_buffer, (int)strlen(ptr), datatype);
+		(void)web_write(conn_id, snd_buffer, (int)strlen(snd_buffer));
+	}
 if(WebDID_Debug)
 	printf("SENDING DATA to conn %d:\n%s\n",conn_id, snd_buffer);
@@ -391,5 +516,5 @@
 		else
 		{
-			update_service_data(service, conn_id, 0, req, browser, force);
+			update_service_data(service, conn_id, 0, req, browser, force, 0, 0);
 			return;
 		}
@@ -434,8 +559,11 @@
 		}
 	}
-	getTime(date_buffer);
-	(void)sprintf(snd_buffer,"HTTP/1.1 200 OK\r\nDate: %s\r\nServer: DID/19.7\r\nContent-Length: %d\r\nContent-Type: %s\r\nConnection: close\r\n\r\n",
-		      date_buffer, (int)strlen(ptr), datatype);
-    (void)web_write(conn_id,snd_buffer,(int)strlen(snd_buffer));
+	if (IsWebDID)
+	{
+		getTime(date_buffer);
+		(void)sprintf(snd_buffer, "HTTP/1.1 200 OK\r\nDate: %s\r\nServer: DID/19.7\r\nContent-Length: %d\r\nContent-Type: %s\r\nConnection: close\r\n\r\n",
+			date_buffer, (int)strlen(ptr), datatype);
+		(void)web_write(conn_id, snd_buffer, (int)strlen(snd_buffer));
+	}
 if(WebDID_Debug)
 	printf("SENDING DATA to conn %d:\n%s\n",conn_id, snd_buffer);
@@ -453,4 +581,6 @@
         static char snd_buffer[BUFSIZE+1]; /* static so zero filled */
 		static char date_buffer[128];
+		char *ptr;
+		int operation = 0;
 
 
@@ -462,10 +592,12 @@
 if(WebDID_Debug)
 printf("Got %s\n", buffer);
-        if( strncmp(buffer,"GET ",4) && strncmp(buffer,"get ",4) )
-		{
-                log_it(SORRY,"Only simple GET operation supported",buffer,conn_id);
-				return;
-		}
-
+        if (IsWebDID)
+        {
+	        if (strncmp(buffer, "GET ", 4) && strncmp(buffer, "get ", 4))
+	        {
+		        log_it(SORRY, "Only simple GET operation supported", buffer, conn_id);
+		        return;
+	        }
+        }
         for(i=4;i<BUFSIZE;i++) 
 		{ /* null terminate after the second space to ignore extra stuff */
@@ -479,5 +611,5 @@
 if(WebDID_Debug)
 printf("Got 1 %s\n", buffer);
-       for(j=0;j<i-1;j++)      /* check for illegal parent directory use .. */
+        for(j=0;j<i-1;j++)      /* check for illegal parent directory use .. */
 		{
                 if(buffer[j] == '.' && buffer[j+1] == '.')
@@ -516,46 +648,74 @@
 		printf("SENDING to conn %d:\n%s\n",conn_id, snd_buffer);
 */
+		ptr = &buffer[5];
+		if (!IsWebDID)
+		{
+			if (!strncmp(&buffer[0], "GET", 3) || !strncmp(&buffer[0], "get", 3))
+			{
+				operation = 0;
+			}
+			if (!strncmp(&buffer[0], "SUBSCRIBE", 9) || !strncmp(&buffer[0], "subscribe", 9))
+			{
+				operation = 1;
+				ptr = &buffer[11];
+			}
+			if (!strncmp(&buffer[0], "UNSUBSCRIBE", 11) || !strncmp(&buffer[0], "unsubscribe", 11))
+			{
+				operation = -1;
+				ptr = &buffer[13];
+			}
+		}
 		if(fstr == 0)
 		{
 if(WebDID_Debug)
 printf("Got %s\n", buffer);
-			if(!strncmp(&buffer[5],"didHeader",9))
-			{
-				sendData(conn_id, &buffer[5], 0);
-				return;
-			}
-			else if(!strncmp(&buffer[5],"didData",7))
-			{
-				sendData(conn_id, &buffer[5], 1);
-				return;
-			}
-			else if(!strncmp(&buffer[5],"didServices",11))
-			{
-				sendData(conn_id, &buffer[5], 2);
-				return;
-			}
-			else if(!strncmp(&buffer[5],"didServiceData",14))
-			{
-				sendData(conn_id, &buffer[5], 3);
-				return;
-			}
-			else if(!strncmp(&buffer[5],"didPoll",7))
-			{
-				sendData(conn_id, &buffer[5], 5);
-				return;
-			}
-			else if(!strncmp(&buffer[5],"didQuery",8))
-			{
-				sendData(conn_id, &buffer[5], 6);
-				return;
-			}
-			else if(!strncmp(&buffer[5],"smiData",7))
-			{
-				sendSmiData(conn_id, &buffer[5], 1);
-				return;
-			}
-			else if(!strncmp(&buffer[5],"smiObjects",10))
-			{
-				sendSmiData(conn_id, &buffer[5], 2);
+            if (!strncmp(ptr, "didHeader", 9))
+			{
+				sendData(conn_id, ptr, 0, 0);
+				return;
+			}
+			else if (!strncmp(ptr, "didData", 7))
+			{
+				sendData(conn_id, ptr, 1, 0);
+				return;
+			}
+			else if (!strncmp(ptr, "didServices", 11))
+			{
+				sendData(conn_id, ptr, 2, 0);
+				return;
+			}
+			else if (!strncmp(ptr, "didServiceData", 14))
+			{
+				sendData(conn_id, ptr, 3, 0);
+				return;
+			}
+			else if (!strncmp(ptr, "dimService", 10))
+			{
+				sendData(conn_id, ptr, 10, operation);
+				return;
+			}
+			else if (!strncmp(ptr, "didPoll", 7))
+			{
+				sendData(conn_id, ptr, 5, 0);
+				return;
+			}
+			else if (!strncmp(ptr, "didQuery", 8))
+			{
+				sendData(conn_id, ptr, 6, 0);
+				return;
+			}
+			else if (!strncmp(ptr, "dimBrowser", 10))
+			{
+				sendData(conn_id, ptr, 12, 0);
+				return;
+			}
+			else if (!strncmp(ptr, "smiData", 7))
+			{
+				sendSmiData(conn_id, ptr, 1);
+				return;
+			}
+			else if (!strncmp(ptr, "smiObjects", 10))
+			{
+				sendSmiData(conn_id, ptr, 2);
 				return;
 			}
@@ -635,4 +795,6 @@
 static void handler( int conn_id, char *packet, int size, int status )
 {
+	int close_browser();
+
 	switch(status)
 	{
@@ -644,5 +806,6 @@
 				Net_conns[conn_id].task,Net_conns[conn_id].node );
 }
-			web_close(conn_id);
+            close_browser(conn_id);
+            web_close(conn_id);
 		break;
 	case STA_CONN:     /* connection received */
@@ -707,6 +870,6 @@
 		*ptr = '\0';
 	}
-	chdir(currwd);
-        log_it(LOG,"webDid starting",argv[1],getpid());
+//	chdir(currwd);
+        log_it(LOG,"webDim starting",argv[1],getpid());
         /* setup the network socket */
 		proto = 1;
@@ -714,6 +877,14 @@
 		get_node_name(dns_node);
 		did_init(dns_node, DNS_PORT);
-		if(!web_open_server("DID",handler, &proto, &port, error_handler))
-			return(0);
+		if(IsWebDID)
+		{
+			if (!web_open_server("DID", handler, &proto, &port, error_handler))
+				return(0);
+		}
+		else
+		{
+			if (!web_open_server("DimClient", handler, &proto, &port, error_handler))
+				return(0);
+		}
 /*
 		ret = matchString("hello world","*ll*");
