Index: /trunk/FACT++/dim/README_v19.txt
===================================================================
--- /trunk/FACT++/dim/README_v19.txt	(revision 13994)
+++ /trunk/FACT++/dim/README_v19.txt	(revision 13995)
@@ -1,4 +1,4 @@
 
-                    DIM version 19.31 Release Notes
+                    DIM version 19.35 Release Notes
 
 Notes 1 and 2 for Unix Users only
@@ -17,5 +17,42 @@
 		Dns </dev/null >& dns.log &
 
-NOTE 3: The Version Number service provided by servers is now set to 1931.
+NOTE 3: The Version Number service provided by servers is now set to 1935.
+
+24/05/2012
+Changes for version 19.35:
+    - Fixed the DimInfo() default constructor, now if the default constructor is called, it doesn't cause the 
+      destructor to crash anymore.
+    - Made available to DimInfo, DimStampedInfo, DimUpdatedInfo and DimCurrentInfo the method: 
+      	- void subscribe(char *name, void *nolink, int nolinksize, int time, DimInfoHandler *handler)
+      Like this the default constructor can be called and then this method called later to subscribe
+      whenever needed.
+    - The behaviour of a giving a null pointer and size 0 as "no link" parameters was not completely
+      defined. The user could get back either a null pointer or an "invalid" pointer in the callbacks.
+      This is now well-defined: 
+        - If null pointer and size 0 is used at subscribe, the user will get null pointer and size 0 in the callback.
+        - If a negative size is passed at subscribe the callback is not called at all.
+
+
+03/05/2012
+Changes for version 19.34:
+    - Changed back to dna_write_nowait() the message that the server sends to the client when removing
+      a service. This was causing clients not to reconnect ever again when the server removed services.
+      (because the client would get the info much before the DNS, so it would keep trying to reconnect
+      and failing even though the service or even the server didn't exist anymore, without asking the DNS)
+    - Changed the client in order to avoid the behaviour above, i.e. if sending the service request fails it
+      asks the DNS again.
+
+
+23/04/2012
+Changes for version 19.33:
+    - A bug was introduced in v19r30. When trying to retry immediately, a dtq_start_timer(0)
+      was used (like for dna_write). This is not possible because the callback is not protected 
+      by a DIM lock. Fixed. (in v19r32)
+    - Small tidy up in dic.c and protecting the move_to_xxx functions.
+    - When a server received an unsubscribe from the last subscribed service of a client it was closing the
+      connection to the client, this is not good because there could be commands being sent. In any case
+      it should be up to the client to close the connection - Fixed.
+    - dim_send_command now accepts a "-i" argument to send integer data (default is string)
+
 
 30/03/2012
@@ -25,4 +62,5 @@
       as dna_write_nowait as it will mingle the packets.
     - Removed more compiler warnings.
+
 
 14/03/2012
Index: /trunk/FACT++/dim/dim/dic.hxx
===================================================================
--- /trunk/FACT++/dim/dim/dic.hxx	(revision 13994)
+++ /trunk/FACT++/dim/dim/dic.hxx	(revision 13995)
@@ -34,5 +34,6 @@
 	DimInfoHandler *itsHandler;
 
-	DimInfo(){};
+	DimInfo()
+		{ subscribe((char *)0, 0, (void *)0, 0, 0); };
 	DimInfo(const char *name, int nolink) 
 		{ subscribe((char *)name, 0, &nolink, sizeof(int), 0); };
@@ -116,4 +117,7 @@
 	int getTimestampMillisecs();
 	char *getFormat();
+	void subscribe(char *name, void *nolink, int nolinksize, int time, 
+		DimInfoHandler *handler) 
+		{ subscribe((char *)name, time, nolink, nolinksize, handler); };
 
 protected :
@@ -122,5 +126,5 @@
 	int itsTime;
 	int itsType;
-	int itsTagId;
+//	int itsTagId;
 	char *itsFormat;
 	void *itsNolinkBuf;
@@ -192,4 +196,7 @@
 
 	virtual ~DimStampedInfo();
+	void subscribe(char *name, void *nolink, int nolinksize, int time, 
+		DimInfoHandler *handler) 
+		{ subscribe((char *)name, time, nolink, nolinksize, handler); };
 private :
 	void doIt();
@@ -261,4 +268,8 @@
 
 	virtual ~DimUpdatedInfo();
+	void subscribe(char *name, void *nolink, int nolinksize, int time, 
+		DimInfoHandler *handler) 
+		{ subscribe((char *)name, time, nolink, nolinksize, handler); };
+
 private :
 	void doIt();
@@ -283,7 +294,9 @@
 	int itsDataSize;
 	int itsSize;
-	int itsTagId;
+//	int itsTagId;
 	int wakeUp;
 
+	DimCurrentInfo(){
+		subscribe((char *)0, 0, (void *)0, 0); };
 	DimCurrentInfo(const char *name, int nolink) { 
 		subscribe((char *)name, 0, &nolink, sizeof(int)); };
@@ -326,4 +339,6 @@
 	char *getString()  { return (char *)getData(); } ;
 	int getSize()  { getData(); return itsSize; } ;
+	void subscribe(char *name, void *nolink, int nolinksize, int time) 
+		{ subscribe((char *)name, time, nolink, nolinksize); };
 
 private :
@@ -337,5 +352,5 @@
 public :
 	int itsId;
-	int itsTagId;
+//	int itsTagId;
 	int itsInit;
 	void *itsData;
Index: /trunk/FACT++/dim/dim/dim.h
===================================================================
--- /trunk/FACT++/dim/dim/dim.h	(revision 13994)
+++ /trunk/FACT++/dim/dim/dim.h	(revision 13995)
@@ -14,5 +14,6 @@
 #include "dim_common.h"
 
-#define DIM_VERSION_NUMBER 1931
+#define DIM_VERSION_NUMBER 1935
+
 
 #define MY_LITTLE_ENDIAN	0x1
Index: /trunk/FACT++/dim/src/conn_handler.c
===================================================================
--- /trunk/FACT++/dim/src/conn_handler.c	(revision 13994)
+++ /trunk/FACT++/dim/src/conn_handler.c	(revision 13995)
@@ -188,5 +188,5 @@
 	DISABLE_AST
 
-	if(id >= Curr_N_Ids)
+	if((id >= Curr_N_Ids) || (id <= 0))
 	{
 		ENABLE_AST
Index: /trunk/FACT++/dim/src/dic.c
===================================================================
--- /trunk/FACT++/dim/src/dic.c	(revision 13994)
+++ /trunk/FACT++/dim/src/dic.c	(revision 13995)
@@ -189,6 +189,8 @@
 				service_tmout( servp->serv_id );
 			}
+/*
 			servp->pending = WAITING_DNS_UP;
 			servp->conn_id = 0;
+*/
 			auxp = servp->prev;
 			move_to_notok_service( servp );
@@ -243,6 +245,8 @@
 				{
 					service_tmout( servp->serv_id );
+/*
 					servp->pending = WAITING_DNS_UP;
 					servp->conn_id = 0;
+*/
 					move_to_notok_service( servp );
 				}
@@ -553,5 +557,8 @@
 	if(servp->type == ONCE_ONLY)
 		once_only = 1;
+/*
 	if( servp->fill_address )
+*/
+	if( servp->fill_size >= 0 )
 	{
 		size = servp->fill_size;
@@ -748,7 +755,12 @@
 			if( (conn_id = servp->conn_id) ) 
 			{
-				free( servp->fill_address );
-				fillp = (int *)malloc(serv_size);
-				memcpy( (char *)fillp, (char *)serv_address, serv_size );
+				if(servp->fill_size > 0)
+					free( servp->fill_address );
+				fillp = 0;
+				if(serv_size > 0)
+				{
+					fillp = (int *)malloc(serv_size);
+					memcpy( (char *)fillp, (char *)serv_address, serv_size );
+				}
 				servp->fill_address = fillp;
 				servp->fill_size = serv_size;
@@ -802,6 +814,10 @@
 	newp->user_routine = routine;
 	newp->tag = tag;
-	fillp = (int *)malloc(fill_size);
-	memcpy( (char *) fillp, (char *) fill_addr, fill_size );
+	fillp = 0;
+	if(fill_size > 0)
+	{
+		fillp = (int *)malloc(fill_size);
+		memcpy( (char *) fillp, (char *) fill_addr, fill_size );
+	}
 	newp->fill_address = fillp;
 	newp->fill_size = fill_size;
@@ -867,7 +883,12 @@
 	servp->user_routine = routine;
 	servp->tag = tag;
-	free( servp->fill_address );
-	fillp = (int *)malloc(fill_size);
-	memcpy( (char *) fillp, (char *) fill_addr, fill_size );
+	if(servp->fill_size > 0)
+		free( servp->fill_address );
+	fillp = 0;
+	if(fill_size > 0)
+	{
+		fillp = (int *)malloc(fill_size);
+		memcpy( (char *) fillp, (char *) fill_addr, fill_size );
+	}
 	servp->fill_address = fillp;
 	servp->fill_size = fill_size;
@@ -1082,5 +1103,6 @@
 	if(servicep->type != COMMAND)
 */
-	free( servicep->fill_address );
+	if(servicep->fill_size > 0)
+		free( servicep->fill_address );
 	if(strstr(servicep->serv_name,"/RpcOut"))
 	{
@@ -1492,4 +1514,7 @@
 			if(tmout > 120)
 				tmout = 120;
+/* Can not be 0, the callback of dtq_start_timer(0) is not protected */
+			if(tmout == 0)
+				tmout = 1;
 			dtq_start_timer(tmout, retry_bad_connection, (long)bad_connp);
 			if(( servp->type == COMMAND )||( servp->type == ONCE_ONLY ))
@@ -1555,6 +1580,8 @@
 				 	(DLL *) servp)) )
 	{
+/*
 		servp->pending = WAITING_DNS_UP;
 		servp->conn_id = 0;
+*/
 		auxp = servp->prev;
 		move_to_notok_service( servp );
@@ -1571,4 +1598,8 @@
 	if(Dic_conns[conn_id].service_head)
 	{
+		DISABLE_AST
+/*
+printf("move_to_ok %s\n",servp->serv_name);
+*/
 		servp->pending = NOT_PENDING;
 		servp->tmout_done = 0;
@@ -1576,4 +1607,5 @@
 		dll_insert_queue( (DLL *) Dic_conns[conn_id].service_head,
 			  (DLL *) servp );
+		ENABLE_AST
 	}
 }
@@ -1581,7 +1613,12 @@
 void move_to_bad_service( DIC_SERVICE *servp, DIC_BAD_CONNECTION *bad_connp)
 {
+	DISABLE_AST
+/*
+printf("move_to_bad %s\n",servp->serv_name);
+*/
 	servp->pending = WAITING_DNS_UP;
 	dll_remove( (DLL *) servp );
 	dll_insert_queue( (DLL *) bad_connp->conn.service_head, (DLL *) servp );
+	ENABLE_AST
 }
 
@@ -1590,4 +1627,8 @@
 /*
 	if(servp->pending != WAITING_CMND_ANSWER)
+*/
+	DISABLE_AST
+/*
+printf("move_to_cmnd %s\n",servp->serv_name);
 */
 	servp->pending = NOT_PENDING;
@@ -1595,11 +1636,18 @@
 	dll_remove( (DLL *) servp );
 	dll_insert_queue( (DLL *) Cmnd_head, (DLL *) servp );
+	ENABLE_AST
 }
 
 void move_to_notok_service(DIC_SERVICE *servp )
 {
-
+	DISABLE_AST
+/*
+printf("move_to_notok %s\n",servp->serv_name);
+*/
+	servp->pending = WAITING_DNS_UP;
+	servp->conn_id = 0;
 	dll_remove( (DLL *) servp );
 	dll_insert_queue( (DLL *) Service_pend_head, (DLL *) servp );
+	ENABLE_AST
 }
 
@@ -1806,4 +1854,21 @@
 				move_to_ok_service( servp, conn_id );
 		}
+		else
+		{
+			if( servp->type == ONCE_ONLY ) 
+			{
+				servp->pending = WAITING_DNS_UP;
+				dic_release_service( servp->serv_id );
+			}
+			else
+			{
+				servp->pending = WAITING_DNS_UP;
+				servp->conn_id = 0;
+/*
+				release_conn(conn_id);
+*/
+				request_dns_info(0);
+			}
+		}
 	}
 	return(ret);
@@ -1834,6 +1899,6 @@
 	{
 		dim_print_date_time();
-		printf(" Client Sending Service Request: Couldn't write to Conn %3d : Server %s@%s\n",
-			conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node);
+		printf(" 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);
 	}
@@ -1884,4 +1949,7 @@
 
 	size = servp->fill_size;
+
+	if(size < 0)
+		return(1);
 
 	if( !cmnd_packet_size ) {
Index: /trunk/FACT++/dim/src/diccpp.cxx
===================================================================
--- /trunk/FACT++/dim/src/diccpp.cxx	(revision 13994)
+++ /trunk/FACT++/dim/src/diccpp.cxx	(revision 13995)
@@ -142,15 +142,24 @@
 {
 	itsId = 0;
-//	itsTagId = 0;
 	itsData = 0;
 	itsFormat = 0;
 	itsHandler = handler;
+	itsDataSize = 0;
+	itsSize = 0;
+	itsNolinkBuf = 0;
+	itsNolinkSize = 0;
+	itsName = 0;
+	if(!name)
+	{
+		return;
+	}
 	itsName = new char[strlen(name)+1];
 	strcpy(itsName,name);
-	itsDataSize = 0;
-	itsSize = 0;
-	itsNolinkBuf = new char[nolinksize];
-	itsNolinkSize = nolinksize;
-	memcpy(itsNolinkBuf, nolink, nolinksize);
+	if(nolinksize > 0)
+	{
+		itsNolinkBuf = new char[nolinksize];
+		itsNolinkSize = nolinksize;
+		memcpy(itsNolinkBuf, nolink, nolinksize);
+	}
 	if(!time)
 	{
@@ -176,9 +185,12 @@
 //	if(itsTagId)
 //		id_free(itsTagId, SRC_DIC);
-	dic_release_service(itsId);
-	delete[] (char *)itsNolinkBuf;
+	if(itsId)
+		dic_release_service(itsId);
+	if(itsNolinkSize)
+		delete[] (char *)itsNolinkBuf;
 	if(itsDataSize)
 		delete[] (char *)itsData;
-	delete[] itsName;
+	if(itsName)
+		delete[] itsName;
 	if(itsFormat)
 		delete[] itsFormat;
@@ -215,12 +227,24 @@
 {
 	itsId = 0;
+	itsData = 0;
 	itsFormat = 0;
 	itsHandler = handler;
+	itsDataSize = 0;
+	itsSize = 0;
+	itsNolinkBuf = 0;
+	itsNolinkSize = 0;
+	itsName = 0;
+	if(!name)
+	{
+		return;
+	}
 	itsName = new char[strlen(name)+1];
 	strcpy(itsName,name);
-	itsDataSize = 0;
-	itsNolinkBuf = new char[nolinksize];
-	itsNolinkSize = nolinksize;
-	memcpy(itsNolinkBuf, nolink, nolinksize);
+	if(nolinksize > 0)
+	{
+		itsNolinkBuf = new char[nolinksize];
+		itsNolinkSize = nolinksize;
+		memcpy(itsNolinkBuf, nolink, nolinksize);
+	}
 	if(!time)
 	{
@@ -261,12 +285,24 @@
 {
 	itsId = 0;
+	itsData = 0;
 	itsFormat = 0;
 	itsHandler = handler;
+	itsDataSize = 0;
+	itsSize = 0;
+	itsNolinkBuf = 0;
+	itsNolinkSize = 0;
+	itsName = 0;
+	if(!name)
+	{
+		return;
+	}
 	itsName = new char[strlen(name)+1];
 	strcpy(itsName,name);
-	itsDataSize = 0;
-	itsNolinkBuf = new char[nolinksize];
-	itsNolinkSize = nolinksize;
-	memcpy(itsNolinkBuf, nolink, nolinksize);
+	if(nolinksize > 0)
+	{
+		itsNolinkBuf = new char[nolinksize];
+		itsNolinkSize = nolinksize;
+		memcpy(itsNolinkBuf, nolink, nolinksize);
+	}
 	if(!time)
 	{
@@ -325,14 +361,29 @@
 
 //	itsTagId = 0;
+//	itsId = 0;
+	itsData = 0;
+//	itsFormat = 0;
+//	itsHandler = handler;
+	itsDataSize = 0;
+	itsSize = 0;
+	itsNolinkBuf = 0;
+	itsNolinkSize = 0;
+	itsName = 0;
+	if(!name)
+	{
+		return;
+	}
+	itsName = new char[strlen(name)+1];
+	strcpy(itsName,name);
+	if(nolinksize > 0)
+	{
+		itsNolinkBuf = new char[nolinksize];
+		itsNolinkSize = nolinksize;
+		memcpy(itsNolinkBuf, nolink, nolinksize);
+	}
 	if(!time)
 		timeout = 10;
 	else
 		timeout = time;
-	itsName = new char[strlen(name)+1];
-	strcpy(itsName,name);
-	itsDataSize = 0;
-	itsNolinkBuf = new char[nolinksize];
-	itsNolinkSize = nolinksize;
-	memcpy(itsNolinkBuf, nolink, nolinksize);
 	wakeUp = 0;
 //	itsTagId = id_get((void *)this, SRC_DIC);
@@ -345,4 +396,15 @@
 DimCurrentInfo::~DimCurrentInfo()
 {
+//	if(itsId)
+//		dic_release_service(itsId);
+	if(itsNolinkSize)
+		delete[] (char *)itsNolinkBuf;
+	if(itsDataSize)
+		delete[] (char *)itsData;
+	if(itsName)
+		delete[] itsName;
+//	if(itsFormat)
+//		delete[] itsFormat;
+/*
 	delete[] (char *)itsNolinkBuf;
 
@@ -352,4 +414,5 @@
 		delete[] (char *)itsData;
 	delete[] itsName;
+*/
 }
 
Index: /trunk/FACT++/dim/src/dis.c
===================================================================
--- /trunk/FACT++/dim/src/dis.c	(revision 13994)
+++ /trunk/FACT++/dim/src/dis.c	(revision 13995)
@@ -1560,5 +1560,9 @@
 	dis_packet->service_id = htovl(service_id);
 	dis_packet->size = htovl(DIS_HEADER);
+/*
 	if( !dna_write_nowait(reqp->conn_id, dis_packet, DIS_HEADER) ) 
+Has to be dna_write otherwise the client gets the message much before the DNS
+*/
+	if( !dna_write(reqp->conn_id, dis_packet, DIS_HEADER) ) 
 	{
 		dim_print_date_time();
@@ -2620,8 +2624,10 @@
 			}
 		}
+/* The client should close the connection (there may be commands)
 		if( dll_empty((DLL *)clip->requestp_head) ) 
 		{
 			release_conn( conn_id, 0, 0 );
 		}
+*/
 	}
 	ENABLE_AST
Index: /trunk/FACT++/dim/src/tcpip.c
===================================================================
--- /trunk/FACT++/dim/src/tcpip.c	(revision 13994)
+++ /trunk/FACT++/dim/src/tcpip.c	(revision 13995)
@@ -1312,4 +1312,12 @@
 	ret = WSAGetLastError();
 #endif
+/*
+	if((wrote == -1) && (!tcpip_would_block(ret)))
+	{
+	dna_report_error(conn_id, 0,
+			"Writing (non-blocking) to", DIM_ERROR, DIMTCPWRRTY);
+printf("Writing %d, ret = %d\n", size, ret);
+	}
+*/
 	set_blocking(Net_conns[conn_id].channel);
 	if(wrote == -1)
@@ -1327,4 +1335,8 @@
 				if( wrote == -1 ) 
 				{
+/*
+		dna_report_error(conn_id, 0,
+			"Writing to", DIM_ERROR, DIMTCPWRRTY);
+*/
 					return(0);
 				}
@@ -1333,4 +1345,8 @@
 		else
 		{
+/*
+dna_report_error(conn_id, 0,
+			"Writing (non-blocking) to", DIM_ERROR, DIMTCPWRRTY);
+*/
 			return(0);
 		}
Index: /trunk/FACT++/dim/src/util/dim_send_command.c
===================================================================
--- /trunk/FACT++/dim/src/util/dim_send_command.c	(revision 13994)
+++ /trunk/FACT++/dim/src/util/dim_send_command.c	(revision 13995)
@@ -74,4 +74,5 @@
 int silent = 0;
 char data[1024] = {'\0'};
+int data_int, data_int_flag = 0;
 char dns_node[128], *ptr;
 int dns_port = 0;
@@ -95,4 +96,8 @@
 			silent = 1;
 		}
+		else if(!strcmp(argv[i],"-i"))
+		{
+			data_int_flag = 1;
+		}
 		else
 		{
@@ -102,5 +107,7 @@
 			}
 			else if(!data[0])
+			{
 				strcpy(data,argv[i]);
+			}
 		}
 	}
@@ -116,10 +123,18 @@
 	{
 		printf("dim_send_command: Insufficient parameters\n");
-		printf("usage: dim_send_command <cmnd_name> [<data>] [-dns <dns_node>] [-s]\n");
+		printf("usage: dim_send_command <cmnd_name> [<data>] [-dns <dns_node>] [-s] [-i]\n");
 		exit(0);
 	}
 	if(!data[0])
 		data[0] = '\0';
-	dic_cmnd_callback(str,data,strlen(data)+1, rout, silent);
+	if(data_int_flag)
+	{
+		sscanf(data,"%d",&data_int);
+		dic_cmnd_callback(str,&data_int,sizeof(int), rout, silent);
+	}
+	else
+	{
+		dic_cmnd_callback(str,data,strlen(data)+1, rout, silent);
+	}
 	while(!received)
 	  dim_wait();
