diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9564a59
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+build/
+scripts/StartServer
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..f96d84e
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,36 @@
+cmake_minimum_required(VERSION 2.6)
+
+PROJECT(DDServer)
+
+configure_file (
+ "${CMAKE_SOURCE_DIR}/scripts/StartServer.in"
+ "${CMAKE_SOURCE_DIR}/scripts/StartServer"
+)
+
+set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/build/${CMAKE_BUILD_TYPE}/bin/)
+set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/build/${CMAKE_BUILD_TYPE}/lib/)
+
+if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+  #64 bits
+  set(CMAKE_C_FLAGS_DEBUG "-ggdb -DLINUX -Dlinux -m64 -march=core2 -fPIC -D_REENTRANT -pthread")
+  set(CMAKE_C_FLAGS_RELEASE "-DLINUX -Dlinux -m64 -march=core2 -fPIC -D_REENTRANT -pthread")
+else( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+  #32 bits
+  set(CMAKE_C_FLAGS_DEBUG "-ggdb -DLINUX -march=i686 -fPIC -Dlinux -D_REENTRANT -malign-double -pthread")
+  set(CMAKE_C_FLAGS_DEBUG "-DLINUX -march=i686 -fPIC -Dlinux -D_REENTRANT -malign-double -pthread")
+endif( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
+
+find_package( Threads REQUIRED )
+find_package( CRYPT REQUIRED )
+find_package( NetCDF REQUIRED )
+
+MESSAGE( STATUS "Build DDServer Project" )
+add_subdirectory(src/CLIENT)
+add_subdirectory(src/SERVER)
+
+install(FILES "scripts/StartServer" DESTINATION . PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+install(DIRECTORY "src/INCLUDE/" DESTINATION include)
+
+SET(CMAKE_VERBOSE_MAKEFILE ON)
diff --git a/README b/README
new file mode 100644
index 0000000..c6ede39
--- /dev/null
+++ b/README
@@ -0,0 +1,20 @@
+1. Set NETCDF_ROOT to use a specific netcdf installation directory :
+> export NETCDF_ROOT="/home/benjamin/AMDA-GIT/AMDA_COTS/netcdf/install"
+
+2. Make the build directory :
+> cmake -E make_directory build
+
+3. Configure the build. Set CMAKE_BUILD_TYPE to Debug or Release to configure the build type. Set CMAKE_INSTALL_PREFIX to configure the install directory :
+> cmake -E chdir build cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/home/benjamin/DDServer ..
+
+4. Build DDServer :
+> cmake --build build
+
+5. Install DDServer :
+> make -C build install VERBOSE=1
+
+6. Configure DDServer :
+In the install directory, open "StartServer" and set DDPATH and DDBASE.
+
+7. Run DDServer:
+> ./StartServer
diff --git a/cmake/modules/FindCRYPT.cmake b/cmake/modules/FindCRYPT.cmake
new file mode 100644
index 0000000..b1580cf
--- /dev/null
+++ b/cmake/modules/FindCRYPT.cmake
@@ -0,0 +1,32 @@
+FIND_PATH(CRYPT_INCLUDE_DIR crypt.h
+  /usr/local/include/crypt
+  /usr/local/include
+  /usr/include/crypt
+  /usr/include
+)
+
+SET(CRYPT_NAMES crypt)
+
+FIND_LIBRARY(CRYPT_LIBRARY
+  NAMES ${CRYPT_NAMES}
+  PATHS /usr/lib /usr/local/lib
+)
+
+IF(CRYPT_INCLUDE_DIR AND CRYPT_LIBRARY)
+  SET(CRYPT_FOUND TRUE)
+  SET(CRYPT_LIBRARIES ${CRYPT_LIBRARY} )
+ELSE(CRYPT_INCLUDE_DIR AND CRYPT_LIBRARY)
+  SET(CRYPT_FOUND FALSE)
+  SET(CRYPT_LIBRARIES)
+ENDIF(CRYPT_INCLUDE_DIR AND CRYPT_LIBRARY)
+
+IF(NOT CRYPT_FOUND)
+  IF(CRYPT_FIND_REQUIRED)
+    MESSAGE(FATAL_ERROR "crypt library and headers required.")
+  ENDIF(CRYPT_FIND_REQUIRED)
+ENDIF(NOT CRYPT_FOUND)
+
+MARK_AS_ADVANCED(
+  CRYPT_LIBRARY
+  CRYPT_INCLUDE_DIR
+)
diff --git a/cmake/modules/FindNetCDF.cmake b/cmake/modules/FindNetCDF.cmake
new file mode 100644
index 0000000..2c7c7c5
--- /dev/null
+++ b/cmake/modules/FindNetCDF.cmake
@@ -0,0 +1,24 @@
+FIND_PATH(NETCDFINCLUDE_DIR netcdf.h
+  HINTS
+    $ENV{NETCDF_ROOT}/include
+    ${NETCDF_ROOT}/include
+)
+mark_as_advanced(NETCDFINCLUDE_DIR)
+
+find_library(NETCDFLIBRARY 
+    NAMES netcdf
+    HINTS
+        $ENV{NETCDF_ROOT}
+        ${NETCDF_ROOT}
+    PATH_SUFFIXES lib
+)
+mark_as_advanced(NETCDFLIBRARY)
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(NetCdf DEFAULT_MSG NETCDFLIBRARY NETCDFINCLUDE_DIR)
+
+if(NETCDF_FOUND)
+    set(NETCDFINCLUDE_DIRS ${NETCDFINCLUDE_DIR})
+    set(NETCDFLIBRARIES ${NETCDFLIBRARY})
+endif()
+
diff --git a/scripts/StartServer.in b/scripts/StartServer.in
new file mode 100755
index 0000000..edbb3a0
--- /dev/null
+++ b/scripts/StartServer.in
@@ -0,0 +1,13 @@
+#!/bin/bash
+#-------------------------------------------------------------------
+#                    StartServer
+#-------------------------------------------------------------------
+DDBASE=@CMAKE_INSTALL_PREFIX@/DDBASE/DATA
+DDPATH=@CMAKE_INSTALL_PREFIX@/DDBASE
+DDLIB=@CMAKE_INSTALL_PREFIX@/lib
+DDBASEBIN=@CMAKE_INSTALL_PREFIX@/bin
+LD_LIBRARY_PATH=$DDLIB/:/usr/local/lib64/
+export DDBASE DDPATH DDBASEBIN DDLIB LD_LIBRARY_PATH
+
+#$DDBASEBIN/DD_Server 1>/dev/null 2>/dev/null&
+$DDBASEBIN/DD_Server -V
diff --git a/src/CLIENT/CMakeLists.txt b/src/CLIENT/CMakeLists.txt
new file mode 100644
index 0000000..ec237a6
--- /dev/null
+++ b/src/CLIENT/CMakeLists.txt
@@ -0,0 +1,22 @@
+
+PROJECT(DDClient)
+
+include_directories(
+  ${CMAKE_HOME_DIRECTORY}/src/INCLUDE/
+)
+
+#Library configuration
+file(
+	GLOB_RECURSE
+	source_files
+	./*
+)
+
+ADD_LIBRARY( DDClient SHARED ${source_files} )
+
+target_link_libraries(
+	DDClient
+	${CMAKE_THREAD_LIBS_INIT}
+)
+
+install (TARGETS DDClient DESTINATION lib)
diff --git a/src/CLIENT/DD_client.c b/src/CLIENT/DD_client.c
new file mode 100755
index 0000000..59286ab
--- /dev/null
+++ b/src/CLIENT/DD_client.c
@@ -0,0 +1,931 @@
+/* $Id: DD_client.c,v 1.4 2012/10/18 09:25:58 budnik Exp $ */
+/*==============================================================
+ *                  DD SYSTEM
+ *                 DD_client.c
+ *                    V.6.0
+ * List of changes:
+ * November 1995, Version 1.0
+ * August 1999 :Access security system was installed by Alexandr Grigoriev (v3.0)
+ * October 22, 2002 - Communication ideology  is changed (V.4.0)
+ * Oct 29, 2002 - Add DD_GetVersion() and some bags are corrected (V.4.1)
+ * May 1, 2003 - Network error is developped. (The header receiving is changed): V.4.2
+ * Nov 18, 2004 - Cach error is fixed.
+ * Jun 17, 2007 - Fedorov, V.4.5 Create new VI and Update data requests
+ * Sep 24, 2007 - Fedorov, V.4.6 Processing of return of Get_Data
+ * Dec 03, 2007 - Budnik,  V.4.7 There may be several sessions with DD Server inside ONE
+ *                               Client session. Keep UserHost & UserName
+ * Oct 18, 2012  - Knizhnikova, V.4.8 new DD_SetTimeInfo() function
+ * Dec 15, 2012  - Fedorov, V.6.0. DD_GetMultiData(). Request structure is very changed, CurrentData is not a global structure
+ *===============================================================*/
+
+#include <unistd.h>
+#include "DD.h"
+#include "DD_comm.h"
+#include "DD_Access.h"
+#include <stdio.h>
+#include <string.h>
+
+#define VERSION "V.6.0"
+
+/*------------------ GLOBAL STATIC VARIABLES --------------------------*/
+int SocketID = -1;                                /* Global socket id for this communication session */
+char UserName[USRLENGTH]="\0";                    /* string for user name  */
+char UserHost[MAXHOSTLENGTH] = "\0";              /* IP of user's host in a string form */
+int  UserID;                                      /* ID of user at the user's host */
+extern int errno;
+
+/*================== FUNCTIONS =================================*/
+/*----------------------- GET User Host-------------------------------*/
+int GetUserHost()
+{
+   char HostName[HOSTNAMELENGTH];
+   struct hostent *Host;
+   unsigned int HostAddress;
+   int userid;
+   static unsigned int m1 = 0X000000FF;
+   static unsigned int m2 = 0X0000FF00;
+   static unsigned int m3 = 0X00FF0000;
+   static unsigned int m4 = 0XFF000000;
+   unsigned int b1,b2,b3,b4;
+
+   userid = getuid();   /* Get a client user  ID */
+
+/* UserHost can be set by extern WEB function in case of WEB communicatio,
+ * or it should be defined as local host if DD_client is installed at USER
+ * computer
+ */
+   if(UserHost[0] == '\0')
+   {
+     gethostname(HostName,HOSTNAMELENGTH);  /* Get a client host name */
+
+      if((Host = gethostbyname(HostName)) == NULL) return NOHOST;
+      HostAddress = *((unsigned int *)Host->h_addr_list[0]);
+
+      b1 = HostAddress & m1;
+      b2 = (HostAddress & m2) >> 8;
+      b3 = (HostAddress & m3) >> 16;
+      b4 = (HostAddress & m4) >> 24;
+
+      sprintf(UserHost,"%03u.%03u.%03u.%03u\0",b1,b2,b3,b4);
+   }
+   return userid;
+}
+/*-------------------------------------------------------------------*/
+
+/*------------------ MAKE_CONNECTION ---------------------------*/
+/*
+ * The function returns opened socket, ready to read and write
+ */
+int GetSocket()
+/*
+ * Connect with remote server, and returns socket ID
+ * In case of error return error number according DD_comm.h
+ */
+{
+/*-------- Variables for resource file -----------------*/
+   char rname[PATHLENGTH];      /* name of res file */
+   char line[PATHLENGTH];
+   char *path;
+   FILE *resfile;       /* resource file */
+   char *pline;
+
+/*---------- Variables for network ---------------------*/
+   static struct hostent *Host;        /* name & internet (32b) address for
+                                   remout hosts (see netdb.h) */
+    static char RemSerName[PATHLENGTH];        /* name of remote server */
+
+    struct servent *serv;     /* pointer to static structure of
+                                port number of registrated service */
+
+   static struct sockaddr_in IntAFAddr;    /* structure of internet address of type AF_INET
+                                       see <netinet/in.h>
+                                       to get name of socket we should
+                                       to convert pointer to this structure
+                                       to pointer to "srtruct sockaddr" where
+                                       all fields are  "char array". */
+
+   int AFAddrLen = sizeof(struct sockaddr_in); /* size of internet address, <netinet/in.h>  18 bytes*/
+   int ScAddrLen = sizeof(struct sockaddr);    /* size of socket address,   <sys/socket.h>  18 bytes*/
+
+   int cc,i;
+   int arg = 0;
+   int normaddr;
+/*
+ *---------- Getting socket and its address ---------------------*/
+/*---------------- HOST and PORT ------------------------------*/
+   if((path = getenv("DDPATH")) == NULL)
+   {
+      strcpy(rname,"DD.res");
+   }
+   else
+   {
+      strcpy(rname,path);
+      strcat(rname, "/DD.res");
+   }
+/*
+   (void *)strcpy(rname,"./DD.res");
+*/
+   if((resfile = fopen(rname,"r")) == NULL)
+   {
+      fprintf(stderr,"No resource file, sorry\n");
+      exit(1);
+   }
+
+   pline = fgets(RemSerName, PATHLENGTH-1, resfile);
+   pline = fgets(line, PATHLENGTH-1, resfile);
+   fclose(resfile);
+
+   RemSerName[strlen(RemSerName)-1] = '\0';
+   sscanf(line,"%d",&(normaddr));
+
+   IntAFAddr.sin_port = htons((uint16_t)normaddr); /* Conversion of the port number to
+                                                      universal net form */
+/*---------------- END of FILE READING --------------------------*/
+/*
+ *------- Trying to open socket with this address and name ---------
+ */
+   if((Host = gethostbyname(RemSerName)) == NULL)  /* Get address and other information by
+                                                     host name, see netdb.h  */
+   {
+      fprintf(stderr,"Server %s not found\n",RemSerName);
+      return(-1);
+   }
+
+   if((SocketID = socket(AF_INET,SOCK_STREAM,PROTOCOL)) < 0)
+   {
+      perror("Socket:"); return(-1);
+   }
+
+/* Filling full internet address for socket "name"
+ * this address will be used to get communication point */
+
+   IntAFAddr.sin_family = Host->h_addrtype;
+   memcpy(&IntAFAddr.sin_addr.s_addr,Host->h_addr_list[0],Host->h_length);
+
+   /* Connection to server socket on remote computer */
+   if(connect(SocketID,(struct sockaddr *)&IntAFAddr,AFAddrLen) < 0)
+         { perror("connect"); return(-1); }
+
+/*
+ * Get Host name and Host ID for security application
+ */
+   if((UserID = GetUserHost()) < 0) return(NOHOST);
+
+   return SocketID;
+}
+/*------------------- end of GetSocket ---------------------*/
+
+/*==================== Receive From Net ======================*/
+/*
+ * Smart buffered receiver
+ */
+int ReceiveFromNet(char *buf, int PacketSize)
+{
+   int CurLength = 0;
+   int i,cc;
+   do
+   {
+      i = 0;
+      while(((cc = recv(SocketID,buf+ CurLength,PacketSize - CurLength,0)) < 0) && (i < TRY)) i++;
+      if(cc < 0) return -1;
+      CurLength = CurLength + cc;
+   } while(CurLength < PacketSize);
+   return 1;
+}
+
+/*------------------ Open Virtual Instrument -----------------------*/
+/*
+ * If no connection, connect to server, then try to order data set and return
+ * ID if OK or ErrorNumber if not
+ */
+int DD_SetVariable(char *InstrName)
+{
+   static caddr_t buff = NULL;
+   static XDR xdrs;
+   int InstrID; /* Instrumnet ID to return */
+   int cc,i;
+   int Request = OPENINSREQ;
+   int hostlen,userlen;
+   char *PUserHost = UserHost, *PUserName = UserName;
+   /* We need this because XDR works with adresses of pointers */
+
+/* If there is no connection, try to get it */
+   if(SocketID < 0)
+       if((SocketID = GetSocket()) < 0) return(NOCONNECTION);
+
+/* Encoding request by XDR to buf */
+/* Buffer and stream allocation */
+   buff = (caddr_t)malloc(REQUESTLENGTH);
+
+   xdrmem_create(&xdrs, buff, REQUESTLENGTH, XDR_ENCODE);
+
+   xdr_int(&xdrs,&Request);
+   xdr_string(&xdrs, &InstrName, strlen(InstrName));
+
+/* Send Open Virtual Instrument request */
+
+   if((cc = send(SocketID,buff,REQUESTLENGTH,0)) < 0)
+   {
+      perror("DD_SetVariable:");
+      free(buff);
+      xdr_destroy(&xdrs);
+      return(REQSENDERR);
+   }
+   xdrmem_create(&xdrs, buff, REQUESTLENGTH, XDR_FREE);
+
+/*--------  preparation an authorization request ----------------*/
+   if(UserName[0] == '\0') strcpy(UserName,NONAME);
+   hostlen = strlen(UserHost);
+   userlen = strlen(UserName);
+
+   xdrmem_create(&xdrs, buff,REQUESTLENGTH, XDR_ENCODE);
+
+   xdr_int(&xdrs,&UserID);
+   xdr_string(&xdrs, &PUserHost, hostlen);
+   xdr_string(&xdrs, &PUserName, userlen);
+/* fprintf(stderr,"userid %d host %s DD_name %s\n",UserID,UserHost,UserName); */
+
+/* Send request */
+   if((cc = send(SocketID,buff,REQUESTLENGTH,0)) < 0)
+   {
+      perror("DD_Set_Variable:");
+      free(buff);
+      xdr_destroy(&xdrs);
+      return(REQSENDERR);
+   }
+
+   free(buff);
+   xdr_destroy(&xdrs);
+
+/* Get reply */
+   buff = (caddr_t)malloc(REPLYLENGTH);
+/*
+   i=0;
+   while(((cc = recv(SocketID,buff,REPLYLENGTH,0)) < 0) && (i < TRY)) i++;
+*/
+   if((cc = ReceiveFromNet(buff, REPLYLENGTH)) < 0)
+   {
+      perror("DD_SET_Variable:");
+      free(buff);
+      return(REPLYRECERR);
+   }
+
+   xdrmem_create(&xdrs, buff, REPLYLENGTH, XDR_DECODE);
+   xdr_int(&xdrs,&InstrID);
+
+/* Free all */
+   free(buff);
+   xdr_destroy(&xdrs);
+
+   return InstrID;
+}
+
+/*----------------------- DD_GetInform -----------------------------*/
+/*
+ * Returns "OK" if OK, fill DD_Data structure
+ * Return negative value if error
+ */
+
+int DD_GetInform(int VarID,char *AttrName,DD_data_t **data)
+{
+   static void *v = NULL;
+   static DD_data_t idd = {DD_CHAR, 0, NULL,1, &v};
+   static caddr_t buf = NULL;
+   static XDR xdrs;
+   int id;
+   int cc;
+   int length;
+   int op = DATAINFOREQ;
+   int type;               /* type of information or error */
+   int DimNumbers;
+   int PacketSize;
+   int CurLength;
+   int i;
+   u_int count;
+   u_int MaxNumber;
+
+/*------------------- Empty static data ------------------------*/
+   if(idd.Dimensions != NULL)
+   {
+      free(idd.Dimensions);
+      idd.Dimensions = NULL;
+   }
+   if(idd.Variables[0] != NULL)
+   {
+      free(idd.Variables[0]);
+      idd.Variables[0] = NULL;
+   }
+
+/*------------------ Check the Name length -----------------------*/
+   if(strlen(AttrName) > MAXVARLENGTH) length = MAXVARLENGTH;
+   else length = strlen(AttrName);
+
+/*----------- Allocation of memory and stream --------------------*/
+   buf = (caddr_t)malloc(REQUESTLENGTH);
+   xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE);
+
+/*------------------- Encoding the request ----------------------*/
+   xdr_int(&xdrs,&op);
+   xdr_int(&xdrs,&VarID);
+   xdr_string(&xdrs, &AttrName, length);
+
+/*------------------------ Send request ---------------------------*/
+   if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0)
+   {
+      perror("DD_GetInform:");
+      free(buf);
+      xdr_destroy(&xdrs);
+      return(REQSENDERR);
+   }
+   free(buf);
+   xdr_destroy(&xdrs);
+
+/*------------------------ Get reply header ------------------------*/
+
+   buf = (caddr_t)malloc(REPLYLENGTH);
+/*
+   i=0;
+   while(((cc = recv(SocketID,buf,REPLYLENGTH,0)) < 0) && (i < TRY)) i++;
+   if(cc < 0)
+*/
+   if((cc = ReceiveFromNet(buf, REPLYLENGTH)) < 0)
+   {
+      perror("DD_GetInform:");
+      free(buf);
+      return(REPLYRECERR);
+   }
+
+   xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE);
+   xdr_int(&xdrs,&type);
+   if(type < 0)
+   {
+      free(buf);
+      xdr_destroy(&xdrs);
+      return(type);
+   }
+   xdr_int(&xdrs,&DimNumbers);
+   xdr_int(&xdrs,&PacketSize);
+   free(buf);
+   xdr_destroy(&xdrs);
+
+   idd.DimNumber = DimNumbers;
+   idd.type = type;
+
+/*---------------------------- Get Data Packet ----------------------*/
+   if(PacketSize > 0) buf = (caddr_t)malloc(PacketSize);
+   else return(REPLYRECERR);
+
+   if((cc = ReceiveFromNet(buf, PacketSize)) < 0)
+   {
+      perror("DD_GetInform:");
+      free(buf);
+      return(REPLYRECERR);
+   }
+
+/*--------------------- Decoding data packet ------------------------*/
+   if(DimNumbers > 0)
+   {
+/*----------- Memory allocation and xdr creating -----------------*/
+      xdrmem_create(&xdrs, buf, (u_int)PacketSize, XDR_DECODE);
+
+/*----------------- Dimensions decoding -------------------------*/
+      if(idd.Dimensions !=NULL) free(idd.Dimensions);
+      idd.Dimensions = (int *)malloc(DimNumbers*sizeof(int));
+
+      xdr_array(&xdrs, (caddr_t *)&(idd.Dimensions),
+                       &count,
+                       (u_int )DimNumbers,
+                       unixlen[DD_INT],
+                       (xdrproc_t)xdr_int);
+
+      count = 1;
+      for(i=0; i < DimNumbers;i++)
+         count = count*idd.Dimensions[i];
+      MaxNumber = count;
+   }
+   else
+   {
+      free(buf);
+      return(REPLYRECERR);
+   }
+
+/*---------------- Allocate memory for Variables and decoding ------------------*/
+   if(idd.Variables[0] != NULL) free(idd.Variables[0]);
+   idd.Variables[0] = (int *)malloc(unixlen[type] * MaxNumber);
+
+   xdr_array(&xdrs,((caddr_t*)(&idd.Variables[0])),&count,
+             MaxNumber, unixlen[type], (xdrproc_t)ConvFunc[type]);
+
+/*-------------------------- Free all ------------------------------*/
+   free(buf);
+   xdr_destroy(&xdrs);
+
+   *data = &idd;
+   return OK;
+}
+
+/*====================================================
+ *          DD_SetTime()
+ *====================================================*/
+/*-----------------------------------------------------
+ * VarID - ID of Data Set
+ * Time - string in DD type
+ * Returns 1 if OK and negative in case of err
+ *---------------------------------------------------*/
+
+int DD_SetTime(int VarID,char *Time)
+{
+   static caddr_t buf = NULL;
+   static XDR xdrs;
+   static int op = TIMESETREQ;
+   int type;
+   int cc,i;
+   int DoneFlag = 0;
+
+   while(DoneFlag == 0)
+   {
+/* Allocatein memory and stream */
+   buf = (caddr_t)malloc(REQUESTLENGTH);
+   xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE);
+
+/* Encoding the request */
+   xdr_int(&xdrs,&op);
+   xdr_int(&xdrs,&VarID);
+   xdr_string(&xdrs, &Time, TIMELENGTH);
+
+/* Send request */
+   if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0)
+   {
+      perror("DD_SetTime:");
+      free(buf);
+      xdr_destroy(&xdrs);
+      return(REQSENDERR);
+   }
+   free(buf);
+   xdr_destroy(&xdrs);
+
+/* Get reply header */
+
+   buf = (caddr_t)malloc(REPLYLENGTH);
+   if((cc = ReceiveFromNet(buf, REPLYLENGTH)) < 0)
+   {
+      perror("DD_SetTime:");
+      free(buf);
+      return(REPLYRECERR);
+   }
+
+   xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE);
+   xdr_int(&xdrs,&type);
+
+   free(buf);
+   xdr_destroy(&xdrs);
+
+   if(type < 0)
+   {
+      if(type == CACHTOOREC) sleep((unsigned )(FILEACCMARG));
+      else return type;
+   }
+   else DoneFlag = 1;
+   }
+   return 1 ;
+}
+
+/*==================================================================
+ *                DD_SetTimeInfo()
+ *=================================================================*/
+/*----------------------------------------------------------
+ * VarID - ID of Data Set
+ * Time - string in DD type
+ * RealTime - double : time value pointer points to
+ * Returns 1 if OK and negative in case of err
+ *----------------------------------------------------------*/
+
+int DD_SetTimeInfo(int VarID, char *Time, double *RealTime)
+{
+    int err;
+    static char TimeInt[17] =  "0000000000001000\0";
+    DD_data_t *data;
+
+    err = DD_SetTime(VarID, Time);
+    if (err < 1) return err;
+
+    err = DD_GetData(VarID, "Time", TimeInt, &data);
+    if (err < 0) return err;
+    if (data->VarNumber < 1) return OUTOFTIME;
+
+    *RealTime = DD_Time2Double((char *)data->Variables[0]);
+
+   return 1 ;
+}
+
+/*=========================================================
+ *                 DD_GetData()
+ * Just an interface to the DD_GetMultiData()
+ *========================================================*/
+int DD_GetData(int VarID, char *VarName, char *TimeInt, DD_data_t **data)
+{
+   char *xxx=VarName;
+   int err;
+   err = DD_GetMultiData(VarID, 1, &xxx, TimeInt, data, 1);
+   return err;
+}
+/*=========================================================
+ *                 DD_GetMultiData()
+ *========================================================*/
+/*---------------------------------------------------------
+ * VarID - ID of open virtual instrument
+ * VarSize - the size of the array names
+ * VarNames - araay of the variables names
+ * TimeInt - Time interval in DD_time style
+ * data - returned data
+ * Return values:
+ *    positives:
+ *    MOREDELAY - call this function again after delay
+ *    MOREDATA - call this function again to complete request
+ *    OK       - all data received
+ *    negative value - error (see DD.h)
+ *---------------------------------------------------------*/
+
+int DD_GetMultiData(int VarID,size_t VarSize, char **VarNames,char *TimeInt,DD_data_t **data, int BackFlag)
+{
+   static DD_data_t *CurrentData = NULL; /* Data records array to keep until the next call */
+   static size_t OldVarSize = 0;
+   static caddr_t buf = NULL;
+   static XDR xdrs;
+   static int LastPacketFlag = OK;
+   int id;
+   int cc;
+   int *NameLength = NULL; /* Array of lengths */
+   int XDRStrLen;          /* xdr length of a string */
+   int XDRReqlength;  // Length in bytes the XDR stream
+   int op = DATAGETREQ;
+   int type;  /* type of information or error */
+   int DimNumbers;
+   int PacketSize;
+   int CurLength;
+   u_int count, MaxSize;
+   int i;
+
+   /* Empty static data */
+   for(id = 0; id < OldVarSize; id++)
+   {
+      if(CurrentData[id].Dimensions != NULL)
+      {
+	 free(CurrentData[id].Dimensions);
+	 CurrentData[id].Dimensions = NULL;
+      }
+      if(CurrentData[id].Variables != NULL)
+      {
+	 for(i = 0; i< CurrentData[id].VarNumber; i++)
+	    free(CurrentData[id].Variables[i]);
+	 free(CurrentData[id].Variables);
+	 CurrentData[id].Variables = NULL;
+      }
+   }
+   free(CurrentData);
+
+   /*--------------------------------------
+    * Create a new Current Data empty array
+    *-------------------------------------*/
+   OldVarSize = VarSize;
+   CurrentData = (DD_data_t *)malloc(sizeof(DD_data_t)*VarSize);
+   for(id = 0; id < VarSize; id++)
+   {
+      CurrentData[id].Dimensions = NULL;
+      CurrentData[id].Variables = NULL;
+      CurrentData[id].DimNumber = 0;
+      CurrentData[id].VarNumber = 0;
+      CurrentData[id].type = 0;
+   }
+   /*--------------------------------------------------------------
+      * The follows request preparation and send is performed only
+      * if the priveous data packed is completely received
+      *--------------------------------------------------------------*/
+   if((LastPacketFlag == OK) || (LastPacketFlag == MOREDELAY))
+   {
+      /*---------------------------------------
+       * Preparation of the array the name lengths
+       * Note that the names are cut down to the MAXVARLENGTH
+       * Calculation the packet size
+       *---------------------------------------*/
+      NameLength = (int *)malloc(sizeof(int)*VarSize);
+      XDRReqlength = 8; /* the length of the first+last arguments */
+      for(id = 0; id < VarSize; id++)
+      {
+	 if(strlen(VarNames[id]) > MAXVARLENGTH) NameLength[id] = MAXVARLENGTH;
+	 else NameLength[id] = strlen(VarNames[id]);
+	 XDRStrLen = (NameLength[id] / 4) * 4;
+	 if((NameLength[id] % 4) > 0) XDRStrLen += 4;
+	 XDRReqlength += XDRStrLen + 4; // String length + 4 bytes length coding
+	 //fprintf(stderr,"Variable %s, length %d, total %d\n",VarNames[id],XDRStrLen,XDRReqlength);
+      }
+      /*--------------------------------
+       * The first packet of the request of the standard size
+       * Allocation corresponding memory and stream
+       *------------------------------*/
+      buf = (caddr_t)malloc(REQUESTLENGTH);
+      xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE);
+
+      /* Encoding the request */
+      xdr_int(&xdrs,&op);
+      xdr_int(&xdrs,&VarID);
+      xdr_string(&xdrs,&TimeInt,TIMELENGTH);
+      xdr_int(&xdrs,&XDRReqlength);
+
+      /* Send the first request */
+      if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0)
+      {
+	 perror("DD_GetData: First Request");
+	 free(buf);
+	 xdr_destroy(&xdrs);
+	 return(REQSENDERR);
+      }
+      free(buf);
+      xdr_destroy(&xdrs);
+
+      /*--------------------------------
+       * The Second packet of XDRReqlength size
+       * Allocation corresponding memory and stream
+       *------------------------------*/
+      buf = (caddr_t)malloc(XDRReqlength);
+      xdrmem_create(&xdrs, buf, XDRReqlength, XDR_ENCODE);
+      xdr_int(&xdrs,(int *)(&VarSize));
+      for(id = 0; id < VarSize; id++) xdr_string(&xdrs, &VarNames[id], NameLength[id]);
+      xdr_int(&xdrs,&BackFlag);
+
+      /* Send the second request */
+      if((cc = send(SocketID,buf,XDRReqlength,0)) < 0)
+      {
+	 perror("DD_GetData:Second Packet");
+	 free(buf);
+	 xdr_destroy(&xdrs);
+	 return(REQSENDERR);
+      }
+      free(buf);
+      xdr_destroy(&xdrs);
+   }
+
+   /*-----------------------------------------------------------
+    * Get the VarSize reply headers and VarSize data
+    *----------------------------------------------------------*/
+   for(id = 0; id < VarSize; id++)
+   {
+      /*-------------------
+       * The header
+       *-----------------*/
+      buf = (caddr_t)malloc(REPLYLENGTH);
+      if((cc = ReceiveFromNet(buf, REPLYLENGTH)) < 0)
+      {
+	 perror("DD_GetData:Error while header receive");
+	 free(buf);
+	 return(REPLYRECERR);
+      }
+
+      xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE);
+      xdr_int(&xdrs,&type);
+      xdr_int(&xdrs,&DimNumbers);
+      xdr_int(&xdrs,&PacketSize);
+      free(buf);
+      xdr_destroy(&xdrs);
+
+      if((type < 0) && (type != NOVAR))  /* Server returns unrecoverable error */
+      {
+	 fprintf(stderr,"DD_GetData: Server returns %d, unrecovable error\n",type);
+	 return type;
+      }
+
+      /*----------- Header is received ----------------------*/
+      CurrentData[id].DimNumber = DimNumbers - 1;
+      CurrentData[id].type = type;
+
+      /*--------------- Receive Data Packet ------------------------------*/
+      if(PacketSize > 0) buf = (caddr_t)malloc(PacketSize);
+      else return(REPLYRECERR);
+      if((cc = ReceiveFromNet(buf, PacketSize)) < 0)
+      {
+	 perror("DD_GetData: Error while data packet receive");
+	 free(buf);
+	 return(REPLYRECERR);
+      }
+      /*----------------- Decoding data packet --------------------*/
+      if(DimNumbers > 1)
+      {
+	 xdrmem_create(&xdrs, buf, (u_int)PacketSize, XDR_DECODE);
+	 count = DimNumbers-1;
+	 /* allocation memory for dimensions */
+	 CurrentData[id].Dimensions = (int *)malloc((DimNumbers-1)*sizeof(int));
+
+	 xdr_int(&xdrs,&LastPacketFlag);        /* Last Paket Indicatort*/
+	 xdr_int(&xdrs,&CurrentData[id].VarNumber); /* Variables number */
+
+	 if(LastPacketFlag > 2)
+	 {
+	    LastPacketFlag = OK;
+	    CurrentData[id].VarNumber = 0;
+	    free(buf);
+	    return(REPLYRECERR);
+	 }
+
+	 /*----- Decoding dimensions array -------------------*/
+	 xdr_array(&xdrs, (caddr_t *)&(CurrentData[id].Dimensions),
+		     &count,
+		     (u_int )DimNumbers-1,
+		     unixlen[DD_INT],
+		     (xdrproc_t)xdr_int);
+
+	 count = 1;
+	 for(i=0; i < DimNumbers-1;i++)
+	 {
+	    count = count*CurrentData[id].Dimensions[i];
+	 }
+	 MaxSize = count;
+      }
+      else
+      {
+	 if(type != NOVAR)
+	 {
+	    free(buf);
+	    return(REPLYRECERR);
+	 }
+	 else
+	 {
+	    CurrentData[id].VarNumber = 0;
+	 }
+      }
+
+      /*---------- Decoding variables -------------------------*/
+      if(CurrentData[id].VarNumber != 0) CurrentData[id].Variables = (void *)malloc(CurrentData[id].VarNumber*sizeof(void *));
+      else CurrentData[id].Variables = NULL;
+
+      for(i = 0; i < CurrentData[id].VarNumber; i++)
+      {
+	 CurrentData[id].Variables[i] = (void *)malloc(unixlen[type]*MaxSize);
+	 count = MaxSize;
+	 xdr_array(&xdrs,(caddr_t *)(&(CurrentData[id].Variables[i])),&count,MaxSize,unixlen[type], (xdrproc_t)ConvFunc[type]);
+      }
+
+      /* Free all */
+      free(buf);
+      xdr_destroy(&xdrs);
+   }
+   *data = CurrentData;
+   return(LastPacketFlag);
+}
+/*===================================================================*/
+
+/*-------------------------- DD_CLOSE --------------------------------*/
+/*
+ *
+ * VarID - entry point of ID table
+ * Returns 1 if OK or negative err
+ * Close Socket if no VarID more ( this information supplyed by server )
+ */
+
+int DD_Close(int VarID)
+{
+   static caddr_t buf = NULL;
+   static XDR xdrs;
+   static int op = CLOSEINSREQ;
+   int RemainedID;                 /* Server returns number of remained ID */
+   int cc,i;
+/* Allocatein memory and stream */
+   buf = (caddr_t)malloc(REQUESTLENGTH);
+   xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE);
+
+/* Encoding the request */
+   xdr_int(&xdrs,&op);
+   xdr_int(&xdrs,&VarID);
+
+/* Send request */
+   if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0)
+   {
+      perror("DD_Close:");
+      free(buf);
+      xdr_destroy(&xdrs);
+      return(REQSENDERR);
+   }
+   free(buf);
+   xdr_destroy(&xdrs);
+
+/* Get reply header */
+
+   buf = (caddr_t)malloc(REPLYLENGTH);
+/*
+   i = 0;
+   while(((cc = recv(SocketID,buf,REPLYLENGTH,0)) < 0) && (i < TRY)) i++;
+   if(cc < 0)
+*/
+   if((cc = ReceiveFromNet(buf, REPLYLENGTH)) < 0)
+   {
+      perror("DD_Close:");
+      free(buf);
+      return(REPLYRECERR);
+   }
+
+   xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE);
+   xdr_int(&xdrs,&RemainedID);
+   if(RemainedID< 0)
+   {
+      free(buf);
+      xdr_destroy(&xdrs);
+      return(RemainedID);
+   }
+   free(buf);
+   xdr_destroy(&xdrs);
+
+   if(RemainedID == 0)
+   {
+     shutdown(SocketID,2);
+     close(SocketID);
+     SocketID = -1;
+/*
+       UserHost[0] = '\0';
+       UserName[0] = '\0';
+*/
+   }
+
+   return(1);
+}
+/*------------------------------------------------------------------------------*/
+
+/*=============== DATABASE UPDATE FUNCTIONS ====================================*/
+/*------------------ DD_AddDataSet() -------------------------------------------*/
+int DD_AddDataSet(char *DataSetName, char *RemSetID, char *BaseName)
+{
+   static caddr_t buf = NULL;
+   static XDR xdrs;
+   static int op = ADDVIREQ;
+   int Err;                      /* Server returns OK or NOEXEC */
+   int cc,i,length;
+   int CloseFlag = 0;
+
+/* If there is no connection, try to get it */
+   if(SocketID < 0)
+   {
+       if((SocketID = GetSocket()) < 0) return(NOCONNECTION);
+       CloseFlag = 1; // To close Connection at the end
+   }
+
+/* Allocatein memory and stream */
+   buf = (caddr_t)malloc(REQUESTLENGTH);
+   xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE);
+
+/* Encoding the request */
+   xdr_int(&xdrs,&op);
+
+/* Coding DataSetName */
+      if((length = strlen(DataSetName)) > MAXSETLENGTH) length = MAXSETLENGTH;
+      xdr_string(&xdrs, &DataSetName, length);
+/* Coding RemSetID */
+      if((length = strlen(RemSetID)) > MAXVARLENGTH) length = MAXVARLENGTH;
+      xdr_string(&xdrs,   &RemSetID, length);
+/* Coding BaseName */
+      if((length = strlen(BaseName)) > MAXVARLENGTH) length = MAXVARLENGTH;
+      xdr_string(&xdrs, &BaseName, length);
+
+/* Send request */
+   if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0)
+   {
+      perror("DD_AddDataSet:");
+      free(buf);
+      xdr_destroy(&xdrs);
+      return(REQSENDERR);
+   }
+   free(buf);
+   xdr_destroy(&xdrs);
+
+/* Get reply header */
+   buf = (caddr_t)malloc(REPLYLENGTH);
+   if((cc = ReceiveFromNet(buf, REPLYLENGTH)) < 0)
+   {
+      perror("DD_AddDataSet:");
+      free(buf);
+      return(REPLYRECERR);
+   }
+
+   xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE);
+   xdr_int(&xdrs,&Err);
+
+   if(CloseFlag)  // Close everything if function established connection
+   {
+     shutdown(SocketID,2);
+     close(SocketID);
+     SocketID = -1;
+/*   Session with DD Server was closed, but User Session continues !!!!! */
+  /*   UserHost[0] = '\0';
+       UserName[0] = '\0';  */
+   }
+   return Err;
+}
+/*-----------------------------------------------------------------------------*/
+
+/*---------------------- DD GET VERSION ---------------------------------------*/
+char *DD_GetVersion()
+/*
+ * return static pointer to internal string with the DDLIB-SERVER package version
+ */
+{
+    static char Version[] = VERSION;
+    return (char *)Version;
+}
+/*------------------------- End Library -------------------------------*/
diff --git a/src/CLIENT/DD_time.c b/src/CLIENT/DD_time.c
new file mode 100755
index 0000000..946432a
--- /dev/null
+++ b/src/CLIENT/DD_time.c
@@ -0,0 +1,321 @@
+/* ===================================================================
+ * Name          : DD_time.c
+ * Version:      : 4.1
+ * Author        : Andrey Fedorov
+ * Institution   : IRAP/UPS/CNRS Toulouse
+ * Modifications list:
+ *    Oct 5, 2002:    V.3.0, New functions   DD_Time2Double   and  Double2DD_Time were added.
+ *    March 26, 2010: V.3.1  YEARS up to 2025
+ *    May 17, 2011:    V.4.0 Fedorov, completely revised version.
+ *                           There is no more confuse between Time and Time Interval
+ *   Sept 05, 2011: V.4.1  SetIntNew =>  arg TimeKind => to work with 1970-1973 : BR
+ *==================================================================*/
+
+#include "DD_time.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+#define YEARS 56
+#define STARTYEAR 1970
+
+/*---- Static array of days shift from Jan-1-1970 -------*/
+/*                    1970    1971    1972    1973    1974    1975    1976
+ *                    1977    1978    1979    1980    1981    1982    1983
+ *                    1984    1985    1986    1987    1988    1989    1990
+ *                    1991    1992    1993    1994    1995    1996    1997
+ *                    1998    1999    2000    2001    2002    2003    2004
+ *                    2005    2006    2007    2008    2009    2010    2011
+ *                    2012    2013    2014    2015    2016    2017    2018
+ *                    2019    2020    2021    2022    2023    2024    2025
+ */
+static double
+      YearDays[YEARS] = {   0.0,   365.0,   730.0,  1096.0,  1461.0,  1826.0,  2191.0,
+                         2557.0,  2922.0,  3287.0,  3652.0,  4018.0,  4383.0,  4748.0,
+                         5113.0,  5479.0,  5844.0,  6209.0,  6574.0,  6940.0,  7305.0,
+                         7670.0,  8035.0,  8401.0,  8766.0,  9131.0,  9496.0,  9862.0,
+                        10227.0, 10592.0, 10957.0, 11323.0, 11688.0, 12053.0, 12418.0,
+                        12784.0, 13149.0, 13514.0, 13879.0, 14245.0, 14610.0, 14975.0,
+                        15340.0, 15706.0, 16071.0, 16436.0, 16801.0, 17167.0, 17532.0,
+                        17897.0, 18262.0, 18628.0, 18993.0, 19358.0, 19723.0, 20089.0};
+
+/*-------------------------------------------------------------
+ * DAY_OF_YEAR = monthday[*][month-1]+day_of_month -1
+ *------------------------------------------------------------*/
+static int monthday[2][12] =
+{
+{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
+{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
+};
+
+/*------------------------------------------------------------
+ * Global static Flag to show the current state of the time
+ * processor. Is it Time interval (0), or DD Time (1)
+ *----------------------------------------------------------*/
+static int TimeFlag = 1;
+/*================== INTERNAL FUNCTION ====================*/
+/*-------------------- SetInt ----------------------------*/
+void SetInt(dd_tmstr_t *UT)
+{
+  SetIntNew(UT,DD_TM_UNKNOWN);
+}
+
+void SetIntNew(dd_tmstr_t *UT,t_DDTimeKind timeKind) /* Fill int values of dd_tmstr_t */
+/* If the double times field of UT structure is defined,
+ * this function fills remains fields of Year, day .... separately
+ */
+{
+   static double msofday = 24.0*60.0*60.0;
+   static double msofhour = 60.0*60.0;
+   static double msofmin = 60.0;
+   long daynumber;
+   double msrest;
+   int i;
+
+   daynumber = (long)(UT->times / msofday);
+   for(i=0;i<YEARS;i++) if(daynumber < (long)YearDays[i]) break;
+   i--;
+
+   switch(timeKind)
+   {
+     case DD_TM_DATE :
+     {
+       //it's a date
+       UT->year = i+1970;
+       UT->day = (int)(daynumber - (long)YearDays[i]);
+       break;
+     }
+     case DD_TM_TIME_INTERVAL :
+     {
+       //it's a time interval
+       UT->year = 0;
+       UT->day =  (int)(daynumber);
+       break;
+     }
+     default :
+       //compatibility mode
+       if(i > 3)
+       {
+         UT->year = i+1970;
+         UT->day = (int)(daynumber - (long)YearDays[i]);
+       }
+       else
+       {
+         UT->year = 0;
+         UT->day =  (int)(daynumber);
+       }
+       break;
+   }
+
+   msrest = UT->times - (double)daynumber * msofday;
+   UT->hour = (int)(msrest / msofhour);
+   msrest -= (double)(UT->hour)*msofhour;
+   UT->min = (int)(msrest / msofmin);
+   msrest -= (double)(UT->min)*msofmin;
+   UT->sec = (int)(msrest);
+   UT->msec = (int)((msrest - (double)(UT->sec))*1000.0);
+   return;
+}
+
+/*---------------- end of SetInt -----------------------*/
+ 
+/*-------------------------------------------------------
+ *                 SetDouble()
+ * Returns the double value of seconds since  1 Jan 1970
+ * The calculations are made from already filled dd_tmstr_t.
+ * If UT->year
+ *------------------------------------------------------*/
+void SetDouble(dd_tmstr_t *UT)
+{
+ static double SecInMls = 1.0/1000.0;
+ static double SecImMin = 60.0;
+ static double SecInHour = 60.0*60.0;
+ static double SecInDay = 60.0*60.0*24.0;
+ if(UT->year >= STARTYEAR)     // This is DD Time !
+ UT->times =          (double)UT->msec*SecInMls  +
+                      (double)UT->sec +
+                      (double)UT->min*SecImMin +
+                      (double)UT->hour*SecInHour +
+                      (double)UT->day*SecInDay +
+                      YearDays[(UT->year - 1970)]*SecInDay;
+ else if(UT->year < STARTYEAR) // This is Time Interval
+ UT->times =            (double)UT->msec*SecInMls  +
+                        (double)UT->sec +
+                        (double)UT->min*SecImMin +
+                        (double)UT->hour*SecInHour +
+                        (double)UT->day*SecInDay +
+                        YearDays[UT->year]*SecInDay;
+ else
+ UT->times =            0.0;
+ return;
+}
+/*----------------- end of SetDouble ---------------------*/
+
+/*=================== PUBLIC FUNCTIONS ==================*/
+/*-------------------   DD_Time2Double  --------------------*/
+double DD_Time2Double(dd_time_t  UTstring)
+{
+   static dd_tmstr_t UT;
+   static char year[5] = "0000\0";
+   static char  day[4] = "000\0";
+   static char   hour[3]= "00\0";
+   static char min[3] = "00\0";
+   static char  sec[3]= "00\0";
+   static char  msec[4] = "000\0";
+
+   strncpy(year,UTstring,4);
+   strncpy(day,UTstring+4,3);
+   strncpy(hour,UTstring+7,2);
+   strncpy(min,UTstring+9,2);
+   strncpy(sec,UTstring+11,2);
+   strncpy(msec,UTstring+13,3);
+
+   sscanf(year,"%d",&(UT.year));
+   sscanf(day,"%d",&(UT.day));
+   sscanf(min,"%d",&(UT.min));
+   sscanf(hour,"%d",&(UT.hour));
+   sscanf(sec,"%d",&(UT.sec));
+   sscanf(msec,"%d",&(UT.msec));
+   if(UT.year < STARTYEAR) TimeFlag = 0; // Time Inetrval
+
+   SetDouble(&UT);
+   return UT.times;
+}
+/*------------------------------------------------------*/
+
+/*-------------------   Double2DD_Time  ---------------------*/
+ char *Double2DD_Time(double Time)
+ {
+    static dd_time_t UTstring;
+    dd_tmstr_t  UT;
+
+    UT.times =   Time;
+    SetInt(&UT);
+    sprintf(UTstring,"%04d%03d%02d%02d%02d%03d",(UT.year),(UT.day),(UT.hour), (UT.min), (UT.sec),(UT.msec));
+    return &(UTstring[0]);
+ }
+/*------------------------------------------------------------*/
+
+/*================== BACKUP COMPABILITY FUNCTIONS =================*/
+/*-----------------------------------------------------------------
+ *                  ReadTime()
+ * Reads a standard DD time string as an argument
+ * and converts it into dd_tmstr_t structure.
+ * Function returns the pointer to the internal startic structure dd_tmstr_t.
+ * Function redefines TimeFlag.
+ *----------------------------------------------------------------*/
+dd_tmstr_t *ReadTime(char *UTstring)
+{
+   static dd_tmstr_t UT;
+   static char year[5] = "0000\0";
+   static char  day[4] = "000\0";
+   static char   hour[3]= "00\0";
+   static char min[3] = "00\0";
+   static char  sec[3]= "00\0";
+   static char  msec[4] = "000\0";
+
+   strncpy(year,UTstring,4);
+   strncpy(day,UTstring+4,3);
+   strncpy(hour,UTstring+7,2);
+   strncpy(min,UTstring+9,2);
+   strncpy(sec,UTstring+11,2);
+   strncpy(msec,UTstring+13,3);
+
+   sscanf(year,"%d",&(UT.year));
+   sscanf(day,"%d",&(UT.day));
+   sscanf(min,"%d",&(UT.min));
+   sscanf(hour,"%d",&(UT.hour));
+   sscanf(sec,"%d",&(UT.sec));
+   sscanf(msec,"%d",&(UT.msec));
+
+   if(UT.year < STARTYEAR) TimeFlag = 0; // Time Inetrval
+
+   SetDouble(&UT);
+   return(&UT);
+}
+/*-------------------- end of ReadTime ------------------------*/
+
+/*---------------------- Write Time ---------------------------*/
+/* Function Write time convert use only double times field
+ * of dd_tmstr_t structure to print time in DD style
+ * in internal static string. The integer fields redefined.
+ * Function return string pointer.
+ */
+
+char *WriteTime(dd_tmstr_t *UT)
+{
+   static dd_time_t UTstring;
+
+   SetInt(UT);
+   sprintf(UTstring,"%04d%03d%02d%02d%02d%03d",(UT->year),(UT->day),(UT->hour),
+                                         (UT->min), (UT->sec),(UT->msec));
+   return(UTstring);
+}
+/*------------------- end of WriteTime -------------------*/
+
+void WriteFmtTime(dd_tmstr_t *UT,char *UTstring)
+{
+   SetInt(UT);
+   sprintf(UTstring,"%04d:%03d:%02d:%02d:%02d",(UT->year),(UT->day),(UT->hour),
+                                               (UT->min), (UT->sec));
+}
+/*------------------- end of WriteFmtTime -------------------*/
+
+/*=========================================================
+ *    Functions for DECODERs
+ * These functions make conversion from/to DD double/DD_time_structure and
+ * a integer array as follows:
+ * {Year, Month, Day_Of_Month, Hour, Min, Sec, Mls}
+ *========================================================*/
+/*--------------------------------------------------------
+ *              UT2double()
+ * Fille the DD_time_structure with double fild from the
+ * integer array (see the section header)
+ *-------------------------------------------------------*/
+dd_tmstr_t *UT2double(unsigned *ut)
+/* Fill the standard structure with double too using as
+ * argument 7 int length array in Gavrilova Passport Standard
+ */
+{
+static dd_tmstr_t UT;
+int visocos;
+
+if(ut[0]%4 == 0) visocos = 1; else visocos = 0;
+UT.year = ut[0];
+UT.day = monthday[visocos][ut[1] - 1]+ut[2] - 1;
+UT.hour = ut[3];
+UT.min = ut[4];
+UT.sec = ut[5];
+UT.msec = ut[6];
+
+SetDouble(&UT);
+return(&UT);
+}
+/*-------------------------------------------------------*/
+/*-------------------------------------------------------
+ *           Double2UT()
+ * Converts Standard DD double time to interger array (see
+ * the section header)
+ *--------------------------------------------------------*/
+unsigned *Double2UT(double t)
+{
+   static unsigned UT[7];
+   dd_tmstr_t tm;
+   int i,visocos;
+
+   tm.times = t;
+   SetInt(&tm);
+   if(tm.year % 4 == 0) visocos = 1; else visocos = 0;
+   i = 0;
+   while((i < 12) && (tm.day >= monthday[visocos][i])) i++;
+   UT[0] = tm.year;
+   UT[1] = i;
+   UT[2] = tm.day +1 - monthday[visocos][i-1];
+   UT[3] = tm.hour;
+   UT[4] = tm.min;
+   UT[5] = tm.sec;
+   UT[6] = tm.msec;
+
+   return( (unsigned *)UT);
+}
+/*=======================================================================*/
diff --git a/src/INCLUDE/DD.h b/src/INCLUDE/DD.h
new file mode 100755
index 0000000..7ce65d8
--- /dev/null
+++ b/src/INCLUDE/DD.h
@@ -0,0 +1,135 @@
+/*=================================================================================================
+ *                  DD SYSTEM
+ *                    DD.h
+ * Version:           6.0
+ * Description: The public header to use DD library libDD.a
+ * List of changes:
+ *       Apr. 17, 2002  Fedorov, - New error constant to interrupt the
+ *       transmission if data dimensions are changed from file
+ *       to file
+ *       Nov 18, 2004 - V.4.2 - Fedorov, New errors for CACH manipulating
+ *       Jun 17, 2007 - V.4.6  Fedorov New requestes and external executables
+ *       Aug 02, 2007 - V.4.7  Fedorov Modification of call external executables
+ *       Sep 24, 2007 - V.5.0  Fedorov New status of Get Data: MOREDELAY
+ *       May 21, 2008 - V.5.1  Fedorov New Status of SetTime: CTIMEISSHIFTED
+ *       Oct 18, 2012 - V.5.2  Knizhnikova New DD_SetTimeInfo() function
+ *=================================================================================================*/
+
+#include "DD_time.h"
+
+typedef struct { int type;        /* Type of variable in netcdf style */
+                 int DimNumber;   /* number of dimensions */
+                 int *Dimensions; /* Dimensions array
+                                   * fastest change is last */
+                 int VarNumber;   /* Dimension of variable array */
+                 void **Variables;/* Variables array pointer
+                                   * It is static array refreshed
+                                   * each call
+                                   */
+               } DD_data_t;
+
+/*------------------- FUNCTIONS ---------------------------*/
+
+extern int DD_SetVariable(char *VarName);
+/*
+ * VarName - full name of variable <project>:<instrument>:<Variable>
+ * Returns VarID or negative in case of error (see bellow)
+ */
+
+extern int DD_GetInform(int VarID,char *AttrName, DD_data_t **data);
+/*
+ * VarID    - Variable ID from DD_SetVariable
+ * AttrName - name of attribute ( defined by konvention )
+ * data - address of data structure
+ * Returns 1 if OK and negative value in case of error (see bellow)
+ */
+
+extern int DD_SetTime(int VarID, char *Time);
+/*
+ * VarID    - Variable ID from DD_SetVariable
+ * Time - string defined in DD_time.h
+ * Returns 1 if OK and negative value in case of error (see bellow)
+ */
+
+extern int DD_SetTimeInfo(int VarID, char *Time, double *RealTime);
+/*
+ * VarID    - Variable ID from DD_SetVariable
+ * Time - string defined in DD_time.h
+ * RealTime - time pointer was set to
+ * Returns 1 if OK and negative value in case of error (see bellow)
+ */
+
+extern int DD_GetMultiData(int VarID, size_t VarSize, char **VarNames, char *TimeInt, DD_data_t **data, int BackFlag);
+/*
+ * VarID    - Variable ID from DD_SetVariable
+ * VarSize  - number of variables to return
+ * VarNames  - the array of Names of the requested Variable
+ * TimeInt  - String of Time interval in DD_time style
+ * data -     Data structures array
+ * BackFlag - 0 - pointer is at the lasy position, 1 - pointer returns to the start point
+ * Returns 1 if OK and negative value in case of error (see bellow)
+ */
+
+/* ----------------------------------------
+ * This function below just call  DD_GetMultiData
+ * for backup
+ *---------------------------------------*/
+extern int DD_GetData(int VarID, char *VarName, char *TimeInt, DD_data_t **data);
+
+extern int DD_MovePoint(int VarID, int RecordNumber);
+/*
+ *  VarID    - Open virtual instrument ID
+ * int RecordNumber - +/- records to move
+ * Move pointer in the open instrument and return 1 or negative if error
+ */
+
+extern int DD_Close(int VarID);
+/*
+ * VarID    - Variable ID from DD_SetVariable
+ * Returns 1 if OK and negative value in case of error (see bellow)
+ */
+
+extern char *DD_GetVersion();
+/*
+ * return static pointer to internal string with the DDLIB-SERVER package version
+ */
+
+/*----------- Data Update functions -----------------------------------*/
+extern int DD_AddDataSet(char *DataSetName, char *RemSetID, char *BaseName);
+/*
+ * Request for new VI. See ../DOC/TECHDOC/DDServFunct.html
+ */
+
+/*--------------------- CONSTANTS -----------------------------------------*/
+#define MOREDATA      1  /* There is data, but we have to call GetData again right now*/
+#define MOREDELAY     2  /* There is data, but we have to call GetData again after delay */
+#define OK            0  /* It is last data packet */
+#define NOCONNECTION -1
+#define TOOMANYREQ   -2
+#define REQSENDERR   -3
+#define REPLYRECERR  -4
+#define NOID         -5
+#define NOREFFILE    -6
+#define NOTIMESFILE  -7
+#define NOINFOFILE   -8
+#define NOVAR        -9
+#define OUTOFTIME    -10
+#define CACHERR       -11 /* The error occured when program manipulated the cach */
+#define CACHTOOREC    -33 /* Off files in the CASH are created less then 5 sec ago */
+#define WAITEXTCALL   -34 /* Server Waits external call finish */
+#define TRYAGAIN      -35 /* Times file is locked. This request should be repeated again */
+#define NODATAATTIME  -36 /* Requested time is inside NODATA time interval */
+#define GAPISSMALL    -37 /* Gap is too small to call external archive */
+#define CTIMEISSHIFTED -38 /* The request was in NoData interval, try again with time at the end */
+#define DATAFILEERR   -12 /* The error while manipulate with data file */
+#define ENVIRERROR -13    /* Error in Environments */
+#define NOPOINTER  -14    /* The pointer points nowhere, SetTime were failed */
+#define INTSERERR  -15    /* Server internal error */
+#define TIMEINEMPTY -16   /* No data for specified time interval */
+#define NOEXEC      -17   /* No executable */
+
+#define DD_SHORT 4
+#define DD_INT     1
+#define DD_FLOAT   2
+#define DD_DOUBLE 3
+#define DD_CHAR   0
diff --git a/src/INCLUDE/DD_Access.h b/src/INCLUDE/DD_Access.h
new file mode 100755
index 0000000..a1d3b10
--- /dev/null
+++ b/src/INCLUDE/DD_Access.h
@@ -0,0 +1,93 @@
+/* ======================================================
+ *
+ *           DD_Access.h
+ *           V.2.0
+ *      Last revision: Oct 7, 2002
+ *     List  of revisions: 1997 - version 1.0
+ *     Oct 7, 2002 - version 2.0 (update a little )
+ */
+
+#define MAXHOSTLENGTH   16  /*  IP-address:  "255.255.255.255\0"  */
+#define USRLENGTH       21      /*  Length of UserName:  + \0  */
+#define TICKETLENGTH    9    /*  Length of passwd: 8 + \0  */
+#define HOSTNAMELENGTH  120 /* Length of the user host name */
+#define USERCASHLEN     100  /*  Size of user_ticket.nc file must be 300  */
+#define NONAME          "no_name\0" /* Name of user in case of non-WEB connection */
+#define ACCINSTR        "iball:acc:all"    /* Instrument which watch the  access */
+#define TICKET_PATH     "/ACC/user_ticket.nc"
+#define USERREFNAME     "/ACC/user_info.nc"
+#define LOGFILE         "/ACC/login.log"
+
+/*------------ Errors of   ACCESS ---------------------*/
+#define NOPERMISSION     -100
+#define NOHOST           -101
+#define NOUSERSFILE      -102
+
+/*--------------- Extern global variables -------------------*/
+extern  char UserName[USRLENGTH]; /* defined in DD_client.c */
+extern  char UserHost[MAXHOSTLENGTH]; /* defined in DD_client.c */
+extern  int  UserID;                  /* defined in  DD_client.c   */
+
+/*--------------- Extern Functions ---------------------------*/
+extern int  FillStruct  (int argc, void **argv);
+/* This function used to set up the host address from IDL (when WWW access used)
+ * Arguments allocation is as follows:
+ *  UserName - 0
+ *  UserHost  - 1
+ *  Location: DD_idl.c -> DD_idl.so
+*/
+
+extern int GetTicket(int UID, char *HostName, int DD_user_id);
+/* Description: This function find the user data in user_cash.nc
+ *              If O'k rewrite the line with new time.
+ *              In case of a new user, remove the first line with 
+ *              older time data then a current time + 4.5 hours.
+                *
+                Takes 3 arguments: UserId (id in the romote host)
+                                   Remote host address(string,like "193.232.6.60\0")
+                                   DD_user_id(can see in user_info.nc)
+                                  
+                Returns 0 if O'k or NOPERMISSIONS, or ERROR
+                
+                If DD_log_name equal NULL searching for UserId, IP-address
+                If DD_log_name nonequal NULL searching for IP-address,DD_log_name*
+                *
+ */
+extern int CheckTicket(char *NameUsr, char *Ticket);
+/* Description: This function check if user exosts
+ *              in user_info.nc file. Returns DD_id if O'k. 
+ *              It returns NOPERMISSION or other errors
+ */
+      
+extern int ShowTicket(int userid, char *hostname, char *DD_name);
+/*
+ * Show if user has authorisation to work
+ */
+
+extern int LoginRequest(char *UserPasswd, char *UserLogin, char *HostName);
+/* Description: Library function for client-server using.  
+ *              Send ID, Password,UserLogin, and host to server.
+ *              Compares the information with your {id,hostname and other}.
+ *              Returns 0 if O'k, or a negative value in case 
+ *              of "NOPERMISSION" or error.
+ *
+ */
+extern int SetUser(int UserID, char *HostName, char *LogName);
+/* Description: Library function for client-server using.
+ *              Send UserID, HostName to server.
+ *              Compares the information with your {id,hostname}.
+ *              Returns 1 if O'k, or a NOPERMISSION, or error number
+ */
+
+extern int CheckID(char *NameUsr);
+/* Description: This function check the user name in user_info.nc file. 
+ *              Returns DD_id if exists. 
+ *              It returns NOPERMISSION or other errors
+ */
+
+extern void Put2Log(int UID, char *Host, char *LogName, int error);
+/* Description: This function logs a user's ID, IP-address of a local host,
+ *              login name and permission information into log file. 
+ *              
+ */
+      
diff --git a/src/INCLUDE/DD_comm.h b/src/INCLUDE/DD_comm.h
new file mode 100755
index 0000000..bc0cef2
--- /dev/null
+++ b/src/INCLUDE/DD_comm.h
@@ -0,0 +1,383 @@
+/*=================================================================================
+ *               DD SYSTEM base package
+ *              DD_Server DD_Client library
+ *                  DD_comm.h
+ *                   V. 6.0
+ * Changes listing:
+ *      Feb 27 1995 - V 1.0
+ *      13 Apr. 2002 - changed for NetCDF 3.3
+ *      03 Oct. 2002 - v.4.0  Fedorov, communication ideology is changed
+ *      Oct 31, 2002 - V.4.1  Fedorov, UserName, UserHost and UserID transferred into DD_Access.h
+ *      May 7, 2003  - V.4.2  Fedorov, The Cash structure is changed (flag of open file )
+ *      June 17, 2003 - V.4.3  Fedorov, The Maximal Packet Size is changed
+ *      Nov 18, 2004 - V.4.4  Fedorov,  Some changes
+ *      Aug 17, 2005 - V.4.5  Fedorov,  Cach Time constant is changed
+ *      Jun 17, 2007 - V.4.6  Fedorov, New requestes and external executables
+ *      Aug 01, 2007 - V.4.7  Fedorov, Cache length = 20, New DD_Var_t structure
+ *      Sep 20, 2007 - V.5.0  Fedorov, Update Time Info library now in the separate file
+ *      Sep 23, 2007 - V.5.1  Fedorov, New interface of SetTime
+ *      Sep 25, 2007 - V.5.2  Fedorov, Individual minimal gap
+ *      Oct 08, 2007 - V.5.3  Budnik,  php createVI.php <baseID> <remSetID> <ddSetID>
+ *      Jan 25, 2008 - V.5.3.1 Budnik, min data gap = 1 day!!!!
+ *      May 22, 2008 - V.5.4 Fedorov, DD_Var_t has a LockStartTime value
+ *      May 27, 2008 - V.5.5 Fedorov, Maximal tracnsmition buffer
+ *      Sep 19, 2008 - V.5.6 MAXVARLENGTH=64 REQUESTLENGTH 184
+ *      Dec 15, 2012 - V.6.0 New multiparam Get_MultiData() function
+ *===================================================================================*/
+
+#include <stdio.h>
+#include <sys/errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+#include "DD_Access.h"
+
+#ifdef SOLARIS
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>      /* internet stile addres */
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/rpc.h>
+#endif /* SOLARIS */
+
+#ifdef HPUX
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/un.h>
+#include <rpc/xdr.h>
+#include <rpc/rpc.h>
+#endif
+
+#ifdef OSF1
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <rpc/xdr.h>
+#endif /* OSF1 */
+
+#ifdef LINUX
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#endif /* LINUX */
+
+#ifdef SUNOS
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <rpc/xdr.h>
+#endif /* SUNOS */
+
+/*----------------- Defenitions of request and server replies --------------------*/
+/* 1. Data manipulation requests  */
+#define OPENINSREQ  0     /* Open virtual instrument    */
+#define DATAINFOREQ 1     /* Request of constant info */
+#define TIMESETREQ  2     /* Position of pointer by StartTime*/
+#define DATAGETREQ  3     /* Data request by time interval */
+#define CLOSEINSREQ 4     /* Request to close virtual instrument */
+#define MOVPOINTREQ 5     /* Move the pointer od data request*/
+#define ADDVIREQ    6     /*  Add New virtual instrument */
+
+/*  2. Security requests */
+#define GETTICKETREQ 10
+#define SHOWTICKETREQ 11
+
+/*-------- Some constants ------------------*/
+#define EMPTY       0     /* Filler of the trailer */
+#define FILEACCMARG 1     /* The minimum time from the last access to remove this file */
+
+/*------------ Important lengths and pathes ----------------*/
+#define PROTOCOL        0     /* protocol TCP  */
+#define REPLYLENGTH    12     /* Length of header of reply packet */
+#define REQUESTLENGTH 196     /* Length of request packets MAXSETLENGTH + 2*MAXVARLENGTH + 16 */
+#define MAXVARLENGTH   64     /* Length (with \0) of Variable Name */
+#define MAXSETLENGTH   52     /* Max Length of VI name */
+#define PATHLENGTH    128     /* Length of complete path */
+#define MAXFILENAME    32     /* The maximal length of the data file (info, cach, times as well)*/
+#define REFNAME "/refer.nc"   /* path name for databse  refer file */
+#define CASHLEN 20            /* Length of cash array */
+#define TRY 100               /* How many tymes to ask the socket */
+#define MAXPACKSIZE  5000000  /* Maximal size of one packet of transmission in bytes */
+#define MAXCOMMANDL   300     /* Command in system() maximal length
+/*-------------------------------------------------
+ * XDR length to calcolate the total len
+ *-------------------------------------------------*/
+#define XDRINTLEN 4
+#define XDRFLOATLEN 4
+#define XDRDOUBLELEN 8
+// String length is counted as 4B + N + r (to completed to 4 bytes)
+
+/*------------ List of External Call of DD_Server and ERRORS -------------------*/
+#define ADDDATASETCALL "php %s/createVI.php %s %s %s"        /* Format to call to create new VI */
+#define GETNEWDATACALL "php %s/getData%s.php  %s %s %s %s &"  /* Format to call to get new data  */
+#define NOPHP     32512
+#define NOSCRIPT  256
+#define PHPOK     0
+
+/*------ Constant to understand data availabilities -------------------------------*/
+#define GLOBSTARTNAME "GlobalStart"
+#define GLOBSTOPNAME "GlobalStop"
+#define SAMPLNAME "MinSampling"
+#define REMARCHNAME "DataBaseID"
+#define REMINSTNAME "DataSetID"
+#define MINGAP    86400.0 /*Seconds. The minimal time gap to set up the flag DATAGAP */
+#define REQTIMEINT 86400.0 /* One day, +/- of request time interval */
+#define ISOTIMEF  "%4u%*1c%2u%*1c%2u%*1c%2u%*1c%2u%*1c%2u%*1c%3u" /* Format to READ time in ISO format */
+#define ISOTIMEP  "%04u-%02u-%02uT%02u:%02u:%02u.%03uZ" /* Format to PRINT time in ISO format */
+#define NODATASTR "NODATA"
+#define DIRLOCK "LOCK"
+
+#define QUANTOFFSET 0.01
+/*------------- More internal specifications -----------------------*/
+/*
+ *   See ../DOC/TECHDOC/DDGenProt.html (lyx)
+ */
+
+/* Reply variables:
+ * Error - negative value described in DD.h
+ * Type - int (see DD.h)
+ * Dim_Number - int ( the dimension (vector, matrix, cube, etc) ov the variable)
+ * Data_Size - int (the size of the data packet in bytes)
+ * RemID     - int (number of virtual instruments still open in this session)
+ * Dim       - int (the particular dimension )
+ * LastPacketFlag - int ( == OK in this packet is last, or MOREDATA)
+ * Data - array of Type of Dim X Dim X....X Dim size
+ *                         --------------------
+ *                             Dim_Number
+ * DataPacket:
+ *
+ * <LastPacketFlag>             |
+ * <Dim>    |                   |
+ * <.....>  |  Dim_Number       |  Data_Size bytes
+ * <Dim>    |                   |
+ * <data>                       |
+ * .....  | only for real data  |
+ * <data> |                     |
+ *
+ * Note is the value is scalar - the Dim = 0 (???)
+ */
+
+/* REPLY SPECIFICATION
+ *
+ * Reply consists Header 12 bytes length and Data Block
+ *
+ * on Open Virtual instrument:
+ * <OPENINSREQ><ID/Eroor><EMPTY><EMPTY>
+ * on Constant Info request:
+ * <DATAINFOREQ><Type/Error><Dim_Number><Data_Size><DataPacket>
+ * on Set pointer by StartTime:
+ * <SETTIMEREQ><EMPTY/Error><EMPTY><EMPTY>
+ * on Get Data by TimeInt :
+ * <DATAGETREQ><Type/Error><Dim_Numbers><Data_Size><LastRecordFlag><DataPacket>
+ * on Move pointer with records number
+ * <MOVPOINTREQ><EMPTY/Error><EMPTY><EMPTY>
+ * on Close Virtual Instrument
+ * <CLOSEINSREQ><RemID/Error><EMPTY><EMPTY>
+ */
+
+/*-------------------- TYPEDEF ---------------------------*/
+typedef struct { char names[CASHLEN][MAXSETLENGTH];
+                 long times[CASHLEN];
+                 int FileOpen[CASHLEN];    /* 1 if file is open */
+                 int ID;                   /* ID of open cach file */
+                 int nameID;               /* ID of names array */
+                 int timeID;               /* ID of times array */
+                 int fopenID;              /* ID of fopen flag */
+               } DD_cash_t;      /* The structure holding cash informaton
+                                  * of particular virtual instrument DataBase
+                                  */
+
+/*
+ * This structure corresponds to ONE requested variable
+ * of some Virtual instrument
+ */
+typedef struct { char  InstrName[MAXSETLENGTH]; /* Virtual Instrument Name */
+                 char path[PATHLENGTH]; /* Path to directory of open virtual instrument */
+                 /*---------------------------------------
+		  *              Cache part
+		  *--------------------------------------*/
+                 DD_cash_t Cash;        /* Cash holder */
+                 int CurrCushN;         /* Current cash pointer */
+                 /*--------------------------------------
+		  *  This is the part of open data file and corresponding data set
+		  *-------------------------------------*/
+                 int ncID;              /* ID of open nc_file */
+                 size_t nc_rec;         /* the current record number nc_file */
+                 size_t Maxnc_rec;      /* Maximum of records number in in the current nc file */
+                 DD_data_t *VarData;    /* Static pointer. Variables Holder */
+		 size_t ParamSize;      /* Number or requested variables to save */
+                 /*---------------------------------------------
+		  *    This is part of times file of given VI
+		  *--------------------------------------------*/
+                 char TimesFileName[PATHLENGTH];
+                 double SDTime;         /* Requested Start Time in double form */
+                 double FDTime;         /* Requested Stop Time in double form */
+                 double CDTime;         /* Current Time in double form */
+                 int tmID;              /* ID of "times" file of this  virtual instrument*/
+                 int NameID;            /* ID of FileName variable in times file */
+                 int StartID;           /* ID of Start variable in times file */
+                 int StopID;            /* ID of Stop variable in times file */
+                 size_t TimeRecNumber;  /* Current Record number in the "times" file */
+                 size_t MaxTimeRecNum;  /* Maximum records number in the "times" file */
+                 int RValidMin;      /* Minimal record with valid data */
+                 int RValidMax;      /* Maximal record with valid data */
+                 double MinValidTime;
+                 double MaxValidTime;   /* Start of RValidMin, and stop of RValidMax */
+                 int CurrRmin;       /* Sure that looking time is greater than stop; -1 if NOT */
+                 int CurrRmax;       /* Sure that looking time is less than start; -1 if NOT */
+                 /*------- Working with external Data Base ------------------------------*/
+                 int VILocked;       /* Flag to show that request to remote database has been sent */
+                 time_t LockStartTime; /* Value to calculate a time elapsed from lock made by THIS VI */
+                 /*---------- This is the part of Info file of given VI -----------------*/
+                 int attrID;            /* ID of constant information nc_file */
+                 char AttrName[PATHLENGTH]; /* Name of constant information file */
+                 DD_data_t AttrData;    /* Dimensions of Attributes */
+                 /*---- Part concerning External call ------------------*/
+                 double MinGap;         /* The minimal gap between two files */
+                 double GlobalStart;    /* The principal begin of data */
+                 double GlobalStop;     /* The principal end of data */
+                 char BaseName[MAXSETLENGTH]; /* The name of external data archive */
+                 char RemSetID[MAXSETLENGTH]; /* The name of VI in exterval archiving */
+                 int ExtCallAllowed; /* 1 If Server can call external archiving */
+                 /*------------ Flow Control -----------------------------*/
+                 int LastPacketFlag;  /* OK - request is completed,
+                                       * MOREDATA - one or several blocks expected,
+                                       * MOREDELAY - wait, system is blocked */
+                 int LastFileStatus;    /* The file status after the last SetNewFile */
+                 int NewFile;           /* 1 if File was changed, VI has to be refreshed*/
+                 int NewFileWasOpen;    /* 1 if the original position of pointer
+                                          * (in data file, times file) was lost after open
+                                          * a new data file */
+              } DD_Var_t;
+
+/*---------------- Usefull enumerations ---------------------*/
+enum SearchRet {REACHLEFT, REACHRIGHT, OKLEFT, OKRIGHT};
+  /*
+   * enumerate of the status of time inteval searching
+   * NOONEDATA - no data at al in this VI
+   * INSIDE - CTime is inside valid data interval (tolerance is MINGAP)
+   * DATAATRIGHT, DATAATLEFT - Valid interval is on the right/left from CTime
+   */
+enum SearchIntRet {NOONEDATA, INSIDE, DATAATRIGHT, DATAATLEFT, IDLE};
+
+/* Return function IsTimesLocked */
+enum LockStatus {NOLOCK, LOCKED, LOCKREMOVED};
+
+
+/*------------------ Function for Server ---------------------*/
+extern int OpenInstr(char *InstrName);
+/*
+ * Open Virtual instrument by name and returns the ID
+ * Returns negative value in case of error (see DD.h)or OK
+ */
+extern int GetAttribute(int ID, char *Name);
+/*
+ * Variable - address of structure with variable description
+ * Name - name of attribute
+ * Returns OK or an error (see DD.h)
+ */
+extern int GetMultiData(int ID, int VarSize, char **VarNames, char *TimeInterval, int BackFlag);
+/*
+ * VarSize - size of the array of Names
+ * Names - array of strings with names of requested variables,
+ * TimeInterval - Time in DD_time.h style
+ * Returns  negative value in case of error (see bellow)
+ * Returnes MOREDATA if "there is more data", and OK if data is finished.
+ */
+
+extern int SetTime(DD_Var_t *D, double CTime);
+/*#################################################################
+ *                      SET TIME
+ * Set time and try to open appropriate data file. If not try to
+ * call external archive
+ * D - address of VI holder
+ * Time -  Time in DD_time.h style
+ * Return:
+ * OK
+ * NOID - call with uncorrect VI holder
+ * OUTOFTIME - Requested time is out of General time limitation
+ * WAITEXTCALL - Server sent request to external archive
+ * TRYAGAIN - VI is blocked by call to external database
+ * NODATAATTIME - request time is inside NODATA time interval
+ * some return of SetNewFile(); see ...
+ *#################################################################*/
+
+extern int CloseID(int ID);
+/* ID - integer identificator of opened Data Set
+ * Returns number of remained IDs of this communication seasson
+ * in case of 0 the server closes this comminication session
+ */
+
+int SetNewFile(DD_Var_t *D, int N);
+/*
+ * Function tries to get new data for the gap beetween files, or just
+ * open a new data file according to offset N referring to current position in the times file.
+ * The current position changed if file is succesefully open.
+ * Return values:
+ * OK
+ * OUTOFTIME - next interval exceeeds GlobalStart/Stop
+ * TIMEINEMPTY - next interval marked as "NODATA"
+ * TRYAGAIN - the VI is blocked while new data is arriving
+ * WAITEXTCALL - new data is requested
+ * CACHTOOREC - now free space in the CACH
+ * CHACHERR - unrecovable error in CACH
+ * DATAFILEERR - unrecovable error in data file
+ */
+
+size_t MaxRecord(int ncID);
+/*
+ * Inspect all variables and dimensions of the file (exept Time associated) and
+ * returm maximal record number to transmit
+ */
+/*------------------ Global constants ----------------------------------*/
+static u_int xdrlen[] = {4,4,4,8,4};
+static size_t unixlen[] = {sizeof(char),sizeof(int),sizeof(float),sizeof(double),sizeof(short)};
+static  bool_t ( *ConvFunc[5])() = {xdr_char, xdr_int, xdr_float, xdr_double, xdr_short};
+
+/*------------------ Global data variable for entire  session --------------------*/
+extern   DD_Var_t **DD_Var ; /* Actually this variable is implimented
+                                                * in DD_GetData.c . The dimension of this array is defined
+                                                * by sysconf(_SC_OPEN_MAX)*/
+extern size_t MaxIDNumber;        /* Size of DD_Var array. Defined actually in  DD_GetData.c  */
+
+/*
+ * Fuctions prototypes in ExtDataRequest.c file
+ */
+/*======================================================================
+ *                IsTimesLocked
+ * Return 1 if there is LOCK in the VI directory
+ *======================================================================*/
+extern int IsTimesLocked(DD_Var_t *DD_Var);
+
+/*======================================================================
+ *                ExtDataRequest
+ *  Return folowing values:
+ *  OK - request is accepted SERVER has to wait when LOCK file is gone
+ *  NOEXEC - error in external executable
+ *  NODATAATTIME - time corresponds to the NODATA interval
+ *  GAPISSMALL - Time is inside too small gap
+ *======================================================================*/
+extern int ExtDataRequest(DD_Var_t *DD_Var, double CurrTime);
+
+/*=======================================================================
+ *                UpdateTimeInfo.c
+ *  int SearchLeft(DD_Var_t *DD_VarL, size_t Rmin, size_t Rmax)
+ *  int SearchRight(DD_Var_t *DD_VarL, size_t Rmin, size_t Rmax)
+ *  Search the next to the left(right) non-empty time interval
+ *  DD_VarL - common data structure corresponding to THIS open VI
+ *  Rmin, Rmax - start points
+ *
+ *  int UpdateTimeInfo(DD_Var_t *DD_VarL)
+ *  Function reopen "times" file and update all time constants
+ *======================================================================*/
+extern int SearchLeft(DD_Var_t *DD_VarL, size_t Rmin, size_t Rmax);
+extern int SearchRight(DD_Var_t *DD_VarL, size_t Rmin, size_t Rmax);
+extern int UpdateTimeInfo(DD_Var_t *DD_VarL);
+
diff --git a/src/INCLUDE/DD_time.h b/src/INCLUDE/DD_time.h
new file mode 100755
index 0000000..51c4720
--- /dev/null
+++ b/src/INCLUDE/DD_time.h
@@ -0,0 +1,59 @@
+/* This is header file for working with DD time */
+/*                       V.4.1                  */
+/* name:        DD_time.h 
+ * Author:      Andrey Fredorov
+ * Institution: IKI RAN
+ * Date:        21-Feb-1995
+ * Last update  Sept 05, 2011
+ * 	     Sept 05, 2011: V.3.2  SetIntNew =>  arg TimeKind => to work with 1970-1973 : BR
+ */
+
+#define TIMELENGTH 17
+
+typedef char dd_time_t[TIMELENGTH]; /* YYYYDDDHHMMSSMLS */
+
+/* ---------------- Functions prototypes  ----------------------*/
+extern   double DD_Time2Double(dd_time_t  DD_Time);
+/* Convert string to double and return.
+ * Return negative value in case of error string format
+ */
+extern char *Double2DD_Time(double Time);
+/* Convert double Time value into string form and return pointer to static string
+ * allocated INSIDE the library.    Thus the value is renoveted each function call.
+ */
+
+/*---------------- Backup compability with V.3.0 and earlier ----------*/
+typedef struct { double times;  /* time sec from 1970 */
+                 int year;
+                 int day;
+                 int hour;
+                 int min;
+                 int sec;
+                 int msec;
+               } dd_tmstr_t ;
+
+
+extern dd_tmstr_t *ReadTime(char *UT); /* Read time from sring and fill static
+                                          * structure defined IN function.
+                                          * Returns pointer of strusture */
+extern char *WriteTime(dd_tmstr_t *UT); /* Get pointer of time structure
+                                           * and convert it into string
+                                           * Function returns pointer of
+                                           * internal string */
+
+extern void WriteFmtTime(dd_tmstr_t *UT,char *UTstring);
+
+extern void SetDouble(dd_tmstr_t *UT); /* Fill double value of dd_tmstr_t */
+
+typedef enum {DD_TM_UNKNOWN, DD_TM_TIME_INTERVAL, DD_TM_DATE} t_DDTimeKind; 
+
+extern void SetInt(dd_tmstr_t *UT); /* Fill int values of dd_tmstr_t */
+extern void SetIntNew(dd_tmstr_t *UT,t_DDTimeKind timeKind);
+
+/*------- Functions for DECODERS ------------------------
+ *These functions works with with Gavrilova's UT representation  */
+extern dd_tmstr_t *UT2double(unsigned *UT); /* Set standard time
+                                             * structure and return
+                                             * its pointer
+                                             */
+extern unsigned *Double2UT(double Time); /*Converts Double to Gavrilova array */
diff --git a/src/SERVER/CMakeLists.txt b/src/SERVER/CMakeLists.txt
new file mode 100644
index 0000000..8084f6c
--- /dev/null
+++ b/src/SERVER/CMakeLists.txt
@@ -0,0 +1,26 @@
+
+PROJECT(DDServer)
+
+include_directories(
+  ${CMAKE_HOME_DIRECTORY}/src/INCLUDE/
+  ${NETCDFINCLUDE_DIR}
+)
+
+#Configuration de l'exécutable
+file(
+        GLOB_RECURSE
+        source_files
+        ./*
+)
+  
+ADD_EXECUTABLE (DDServer ${source_files} )
+
+target_link_libraries(
+  DDServer
+  ${CMAKE_THREAD_LIBS_INIT}
+  DDClient
+  ${NETCDFLIBRARY}
+  ${CRYPT_LIBRARY}
+)
+
+install (TARGETS DDServer DESTINATION bin)
diff --git a/src/SERVER/DD_Access_sr.c b/src/SERVER/DD_Access_sr.c
new file mode 100644
index 0000000..1ae7e5f
--- /dev/null
+++ b/src/SERVER/DD_Access_sr.c
@@ -0,0 +1,655 @@
+/*
+ *-------------------- DD_ACCESS -------------------------------
+ *
+ * name:         DD_Access.c V4.0
+ * author:       Alexander Grigoriev , Andrei Fedorov
+ * Insitution:   IKI RAN lab.546 aug@afed.iki.rssi.ru
+  * Description: Set of function for access to DD system
+  *   Last revision:   Oct 10, 2002
+ *  List of revisions:
+ *                  March    1999  V1.0
+ *                 20 Oct 1999 ; ShowTicket was corrected.   V2.0
+ *                28 Oct 1999 ; Added LOGINS,ddcheck         V3.0
+  *               Oct 10, 2002 - revised by A. Fedorov       V 4.0
+ */
+/*#define _XOPEN_SOURCE*/  /* for crypt function */
+
+#define _XOPEN_SOURCE
+#include <unistd.h>
+#include <time.h>
+#include <DD.h>
+#include <netcdf.h>
+#include <DD_comm.h>
+#include <DD_Access.h>
+
+/*=========== Global Variables ===============================*/
+  size_t CashStart[2]={0L,0L};
+  size_t CashCount[2]={1, MAXHOSTLENGTH};
+  size_t CashCountInt[2]={1, 1};
+  extern int Verbose;
+  
+/*############################################################################*/
+
+/*----------------GETTICKET------------------------------------*/
+
+/* Description: This function find the user data in user_cash.nc
+ *              If O'k rewrite the line with new time.
+ *              In case of a new user, remove the first line with 
+ *              older time data then a current time + 4.5 hours.
+                *
+                Take 3 arguments: UserId, 
+                                  IP-address(string,like "193.232.6.60\0") 
+                                  DD_user_id(can see in user_info.nc)
+                                  
+                Returns 0 if O'k or NOPERMISSION  if error
+                
+                If DD_log_name equal NULL searching for UserId, IP-address
+                If DD_log_name nonequal NULL searching for IP-address,DD_log_name*
+                *
+ */
+
+int GetTicket(int UID, char *HostName, int DD_user_id)
+  {
+    char *ddbase;
+    char refname[PATHLENGTH];
+    int TicketID, Comp=1, Flag,OldFlag=0, Find=0, dltt;
+    int CurIDID,HostID,TimeID, DD_id_ID;   /* Variable IDs in the NC ticket file */
+    int TimeFinish;
+    int Clock;
+    char CurHostName[MAXHOSTLENGTH];
+    int CurID, CurTime,DD_id, MemTime,OldestStart;  /* Values to read and write to ticket file */
+    size_t CurCashStart[2]={0,0};
+    size_t HostCount[2] = {1,MAXHOSTLENGTH};
+    int ACCESS = NOPERMISSION;
+    int status; /* Return value of any  NC routine */
+    
+    if(Verbose) fprintf(stderr,"GetTicket: UID = %d, HostName <%s>, DD_user_id = <%d> is going to work\n",UID, HostName,DD_user_id); 
+
+/*------------- OpenUserNC ---------------------------------*/
+
+   if((ddbase = getenv("DDBASE")) == NULL)
+   {
+      if(Verbose) fprintf(stderr,"GETTICKET:  No DDBASE environment.\n");
+      return(ENVIRERROR);
+   }
+   strcpy(refname,ddbase);
+   strcat(refname,TICKET_PATH);
+   if(Verbose) fprintf(stderr,"GETTICKET: TICKET_PATH is %s \n",refname);
+
+   if((status = nc_open(refname, NC_WRITE,&TicketID))  !=  NC_NOERR)
+   {
+      if(Verbose) fprintf(stderr,"GETTICKET:  %s\n", nc_strerror(status));
+      return(NOUSERSFILE);
+   }
+
+/*------------------ Working with -------------------------------*/
+     
+   status = nc_inq_varid(TicketID,"id",&CurIDID);
+   status = nc_inq_varid(TicketID,"host",&HostID);
+   status = nc_inq_varid(TicketID,"time",&TimeID);
+   status = nc_inq_varid(TicketID,"DD_id",&DD_id_ID);
+   status = nc_sync(TicketID);
+
+   Clock = (int)time(NULL);
+ 
+ //  TimeFinish = Clock+16200;  // 4.5 hours
+   TimeFinish = Clock+172800;  // 48 hours
+   HostName[strlen(HostName)] = '\0';
+   CashStart[0]=0;
+   OldestStart = 0;
+ 
+   do
+   {
+     status = nc_get_var1_int(TicketID, CurIDID, CashStart,&CurID);
+     nc_get_var1_int(TicketID, DD_id_ID, CashStart,&DD_id);
+     nc_get_vara_text(TicketID, HostID,CashStart,HostCount,CurHostName);
+     nc_get_var1_int(TicketID, TimeID,CashStart,&CurTime);
+
+     if(CashStart[0] == 0) MemTime=CurTime;
+   
+     Comp=strcmp(CurHostName,HostName);
+       
+     if((CurID == UID)&&(Comp == 0)&&(DD_id == DD_user_id))
+     {
+        CurCashStart[0]=CashStart[0];
+        Find = 1;
+     }
+     dltt = (CurTime - MemTime);
+     
+     if((dltt < 0) && (CurHostName[0] != '\0'))
+     {
+        OldestStart=CashStart[0]; 
+        MemTime = CurTime; 
+     }
+
+     CashStart[0]++;
+   }
+   while((Find != 1) && (CurHostName[0] != '\0') && (CashStart[0] < USERCASHLEN));
+
+   if(Verbose) fprintf(stderr,"FINISH TIME : %ld\n",TimeFinish);
+  
+   CashStart[0]--;
+  
+   if(MemTime < Clock) {
+   OldFlag = 1;
+   }
+    if(Find == 1)
+   {
+     nc_put_var1_int(TicketID,TimeID,CurCashStart,&TimeFinish);
+     if(Verbose) fprintf(stderr,"User: ID = %d, DD_id = %d, HostName <%s> continue work.\n ",UID,DD_user_id,HostName); 
+     ACCESS = 0;
+   }
+   else
+   if(OldFlag == 1)
+   {
+      CashStart[0]=OldestStart;
+
+      nc_put_var1_int(TicketID,CurIDID, CashStart,&UID);
+      nc_put_var1_int(TicketID,DD_id_ID, CashStart,&DD_user_id);
+      nc_put_vara_text(TicketID,HostID,CashStart,HostCount,HostName);
+      nc_put_var1_int(TicketID,TimeID,CashStart,&TimeFinish);
+      if(Verbose) fprintf(stderr,"User: ID = %d, DD_id = %d, \n HostName <%s> started work.\n ",UID,DD_user_id,HostName); 
+      ACCESS = 0;
+   }
+   else
+   if((CashStart[0]<USERCASHLEN) && (CurHostName[0] == '\0'))
+   {
+      nc_put_var1_int(TicketID,CurIDID, CashStart,&UID);
+      nc_put_var1_int(TicketID,DD_id_ID, CashStart,&DD_user_id);
+      nc_put_vara_text(TicketID,HostID,CashStart,HostCount,HostName);
+      nc_put_var1_int(TicketID,TimeID,CashStart,&TimeFinish);
+      if(Verbose) fprintf(stderr,"User: ID = %d, DD_id = %d, \n HostName <%s> started work.\n ",UID,DD_user_id,HostName); 
+      ACCESS = 0;
+   } 
+   else {fprintf(stderr,"Too many members!\n");ACCESS = NOPERMISSION;}
+  
+ 
+   /*if((CurID == UID)&&(Comp == 0)) fprintf(stderr,"Exists...\n");*/
+  
+   nc_sync(TicketID);
+   nc_close(TicketID);
+      
+return((int)ACCESS);     
+}      
+
+/*############################################################################*/
+
+/*-------------------CHECK TICKET-----------------------*/ 
+
+/* Description: This function check the user for accessability
+ *              in user_info.nc file. Returns DD_id if O'k. 
+ *              Returns NOPERMISSION in case of unaccessability, neagative value (DD_access.h)
+ *              in case of error.
+ */
+      
+int CheckTicket(char *NameUsr, char *Ticket)
+{
+   int i=0;
+   int DD_id;
+   int Right = NOPERMISSION;
+   char salt[2],newkey[USRLENGTH];
+  
+   int UsrRefID;  /* ID of reference file which consists description of all users */
+   char *ddbase;
+   char refname[PATHLENGTH];
+  
+   int UserDimID,UserLenDimID,PasLenDimID;   /* ID of dimensions in NC file */
+   int MemID, PasID;                                              /* ID of variables in NC file */
+   size_t MaxRecords, UserLength, PasswdLength;   /* Dimensions */
+   size_t start[2] = {0,0}, UserCount[2] = {1,0}, PasswdCount[2] = {1,0};
+   static char UserDimName[] = "user", UserLenDimName[] = "UserLength";  /* Dimensions names */
+   static char PasLenDimName[] = "PasswdLength";                                       /* Dimensions names */
+   static char MemName[] = "member", PasName[] = "passwd";                      /* Variable Names */
+   char PasChar[USRLENGTH],MemChar[USRLENGTH];
+    int status;   /* Return of any NC call */
+
+/*------------- Open User reference NC ---------------------------------*/
+   if((ddbase = getenv("DDBASE")) == NULL)
+   {
+      if(Verbose) fprintf(stderr,"CHECKTICKET:  No DDBASE environment.\n");
+      return(ENVIRERROR);
+   }
+   strcpy(refname,ddbase);
+   strcat(refname,USERREFNAME);
+   if(Verbose) fprintf(stderr," CHECHTICKET: PATH is %s \n",refname);
+// sleep(40);
+   if((status = nc_open(refname, NC_WRITE,&UsrRefID))  !=  NC_NOERR)
+   {
+      if(Verbose) fprintf(stderr,"CHECHTICKET:  %s\n", nc_strerror(status));
+      return(NOUSERSFILE);
+   }
+
+/*------------------ Define all dimensions -------------------------------*/
+
+   status = nc_inq_dimid(UsrRefID,UserDimName,&UserDimID);
+   status = nc_inq_dimlen(UsrRefID, UserDimID,  &MaxRecords);
+   status = nc_inq_dimid(UsrRefID,UserLenDimName,&UserLenDimID);
+   status = nc_inq_dimlen(UsrRefID, UserLenDimID,  &UserLength);
+   UserCount[1] = UserLength;
+   status = nc_inq_dimid(UsrRefID,PasLenDimName,&PasLenDimID);
+   status = nc_inq_dimlen(UsrRefID, PasLenDimID,  &PasswdLength);
+   PasswdCount[1] = PasswdLength;
+
+/*fprintf(stderr,"CheckTicket:Rec: %d %d %d\n",MaxRecords,UserLength,PasswdLength);*/
+  
+/*------------------ Define all variables ID -------------------------------*/
+   status = nc_inq_varid(UsrRefID, MemName,&MemID);
+   status = nc_inq_varid(UsrRefID, PasName,&PasID);
+    
+  
+   for(i=0;i<MaxRecords;i++)
+   {
+      start[0]=(size_t)i;
+      nc_get_vara_text(UsrRefID, MemID, start,UserCount, MemChar);
+
+      if(strcmp(MemChar,NameUsr)==0)
+      {
+         nc_get_vara_text(UsrRefID, PasID, start, PasswdCount, PasChar);
+
+         /*fprintf(stderr,"Your dd_id is %u\n",i);*/
+         DD_id = i;
+         Ticket[strlen(Ticket)]='\0';
+         NameUsr[strlen(NameUsr)]='\0';
+         newkey[PasswdLength-1]='\0';
+       
+         strncpy(salt,PasChar,2);
+
+         strcpy(newkey,(char *)crypt(Ticket,salt));
+
+         if(strcmp(PasChar,newkey) == 0) 
+         {
+            if(Verbose) fprintf(stderr,"User %s is logged in\n",NameUsr);
+            Right = DD_id;
+         }
+         else
+         {
+            if(Verbose) fprintf(stderr,"for user %s permission denied.\n",NameUsr);
+            Right = NOPERMISSION;
+         }
+      }
+   }
+   nc_close(UsrRefID);
+return((int)Right); 
+}
+
+/*       
+ *-------------------- SHOW TICKET -------------------------------*/
+/* 
+ * Description: Library function. Used by DD_Server. It reads the 
+ *              content of user_ticket.nc file. Compares the information
+ *              with your {id,hostname,DD_id,time}.
+ *  If id and hostname(IP_address) and DD_id exists in table of registarated
+ *  users, check the working time. If one has any time for work, returns 0,
+ *  or a negative value "NOPERMISSION".
+ *   It IS DD_Check !
+ */
+  
+int ShowTicket(int userID, char *hostname, char *DD_name)
+  {
+    char *ddbase;
+    char refname[PATHLENGTH];
+    int TicketID;    /* Ticket file ID */
+    int Comp=1, Time_is=0, Find=0;
+    int CurIDID,HostID,TimeID, DD_id_ID;   /* NC variables ID */
+    time_t Clock; 
+    char CurHostName[MAXHOSTLENGTH];
+    int CurID, CurTime, RefTime, DD_id;   /* Variables */
+    size_t CurCashStart[2]={0,0};
+    size_t HostCount[2] = {1,MAXHOSTLENGTH};
+    int ServerReply = NOPERMISSION;
+    int DD_user_id = -1;
+    int status;   /* Return of any NC call */
+
+   hostname[strlen(hostname)]='\0';
+   DD_name[strlen(DD_name)]='\0';
+   if((strcmp(DD_name,NONAME))!=0) DD_user_id = CheckID(DD_name);
+ 
+/*------------- OpenUserNC ---------------------------------*/
+
+   if((ddbase = getenv("DDBASE")) == NULL)
+   {
+      if(Verbose) fprintf(stderr,"SHOWTICKET:  No DDBASE environment.\n");
+      return(ENVIRERROR);
+   }
+   strcpy(refname,ddbase);
+   strcat(refname,TICKET_PATH);
+   if(Verbose) fprintf(stderr,"SHOWTICKET: TICKET_PATH is %s \n",refname);
+
+   if((status = nc_open(refname, NC_WRITE,&TicketID))  !=  NC_NOERR)
+   {
+      if(Verbose) fprintf(stderr,"SHOWTICKET:  %s\n", nc_strerror(status));
+      return(NOUSERSFILE);
+   }
+
+/*------------------Info about source.file-------------------------------*/
+   status = nc_inq_varid(TicketID,"id",&CurIDID);
+   status = nc_inq_varid(TicketID,"host",&HostID);
+   status = nc_inq_varid(TicketID,"time",&TimeID);
+   status = nc_inq_varid(TicketID,"DD_id",&DD_id_ID);
+
+   nc_sync(TicketID);
+   CashStart[0]=0;
+
+  do
+   {
+     status = nc_get_var1_int(TicketID, CurIDID, CashStart,&CurID);
+     status = nc_get_var1_int(TicketID, DD_id_ID, CashStart,&DD_id);
+     status = nc_get_vara_text(TicketID, HostID,CashStart,HostCount,CurHostName);
+     status = nc_get_var1_int(TicketID, TimeID,CashStart,&CurTime);
+ 
+     Comp=strcmp(CurHostName,hostname);
+     if((strcmp(DD_name,NONAME)) == 0) DD_user_id = DD_id;
+
+     if((CurID == userID) && (Comp == 0) && (DD_id == DD_user_id))
+     {
+        RefTime = CurTime;
+        CurCashStart[0]=CashStart[0];
+        Find = 1;
+     }
+
+     CashStart[0]++;
+   }
+   while((CurHostName[0] != '\0') && (CashStart[0] < USERCASHLEN));
+
+   if(Find == 1)
+   {
+     CashStart[0]=CurCashStart[0];
+     status = nc_get_var1_int(TicketID, CurIDID, CashStart,&CurID);
+     status = nc_get_var1_int(TicketID, DD_id_ID, CashStart,&DD_id);
+     status = nc_get_vara_text(TicketID, HostID,CashStart,HostCount,CurHostName);
+     status = nc_get_var1_int(TicketID, TimeID,CashStart,&CurTime);
+     if((strcmp(DD_name,NONAME))==0)  DD_user_id = (int)DD_id;
+   }
+   CashStart[0]--;
+      
+   Clock=(int)time(NULL);
+
+   if(CurTime > Clock) Time_is = 1;
+
+   if((Find == 1) && (Time_is == 1))
+   {
+     fprintf(stderr,"User: ID = %d, DD_id = %d, host %s, timework=%d, is connected. \n",CurID,DD_user_id,hostname,Time_is);   
+     ServerReply = 0;
+   }
+   else {
+
+         fprintf(stderr,"User: ID = %d, DD_id = %d, host %s, timework=%d, Permission denied!. \n",CurID,DD_user_id,hostname,Time_is);   
+         ServerReply=NOPERMISSION;
+         }
+  
+   nc_sync(TicketID);
+   nc_close(TicketID);
+   return ServerReply;
+}      
+
+/*       
+ *------------------------ SETUSER -------------------------------*/
+/* 
+ * Description: Library function for client-server using.  
+ *              Send ID, HostName to server.
+ *              Compares the information with your {id,hostname}.
+ *              Returns 1 if O'k, or a negative value in case 
+ *              of "NOPERMISSION".
+ *
+ */
+int SetUser(int UserID, char *HostName, char *LogName)
+{
+
+   int SocketID = -1; /* Global socket id for this communication session */
+   static DD_data_t dd = {DD_CHAR,0,NULL,0,NULL};
+   static caddr_t buf = NULL;
+   static XDR xdrs;
+   int cc,i, hostlen, ticketlen, userlen;
+   int op = SHOWTICKETREQ;
+   int SHOW_ACCESS;
+   
+   SHOW_ACCESS = NOPERMISSION;
+ /*  fprintf(stderr,"after CLIENT int SetUser: SocketID = %d\n",SocketID);
+   fprintf(stderr,"after CLIENT int SetUser: User = %d  Host %s\n",UserID,HostName);
+ */  
+
+/*------------------CONNECTION to SERVER---------------------------*/
+/*
+ * If no connection, connect to server, try to order data set and return
+ * ID if OK or ErrorNumber if not
+ */
+
+
+ /*  fprintf(stderr,"Try to connect Server\n");*/
+/* If there is no connection, try to get it */
+   if(SocketID < 0)
+       if((SocketID = GetSocket()) < 0) return(NOCONNECTION);
+ /*  fprintf(stderr,"Server3 connected\n");*/
+   
+   
+/*---------------------REQUEST TO SERVER-----------------------------*/
+
+/* Check the HostName length */
+   if(strlen(HostName) > MAXHOSTLENGTH) hostlen = MAXHOSTLENGTH;
+   else hostlen = strlen(HostName);
+   if(strlen(LogName) > USRLENGTH) userlen = USRLENGTH;
+   else userlen = strlen(LogName);
+
+/* Allocation memory and stream */
+   buf = (caddr_t)malloc(REQUESTLENGTH);
+   xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE);
+
+/* Encoding the request */
+   xdr_int(&xdrs,&op);
+   xdr_int(&xdrs,&UserID);
+   xdr_string(&xdrs, &HostName, hostlen);
+   xdr_string(&xdrs, &LogName, userlen);
+/* fprintf(stderr,"UserID, HostName  just more : %d %s\n",UserID,HostName);*/
+/* Send request */
+   if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0)
+   {
+      perror("DD_GetTicket:");
+      free(buf);
+      xdr_destroy(&xdrs);
+      return(REQSENDERR);
+   }
+   free(buf);
+   xdr_destroy(&xdrs);
+
+/* Get reply header */
+
+   buf = (caddr_t)malloc(REPLYLENGTH);
+   i =0;
+   while(((cc = recv(SocketID,buf,REPLYLENGTH,0)) < 0) && (i < TRY)) i++;
+   if(cc < 0)
+   {
+      perror("DD_SetUser:");
+      free(buf);
+      return(REPLYRECERR);
+   }
+
+   xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE);
+   xdr_int(&xdrs,&SHOW_ACCESS);
+
+   free(buf);
+   xdr_destroy(&xdrs);
+   shutdown(SocketID,2);
+   close(SocketID);
+   /*SocketID = -1;*/
+/*  fprintf(stderr,"SetUser,End; UserID, HostName  just more : %d %s\n",UserID,HostName);
+  fprintf(stderr,"SHOW_ACCES %d \n",SHOW_ACCESS);
+*/ 
+ if(Verbose) fprintf(stderr,"SetUser: ACCES = %d \n",SHOW_ACCESS);
+
+return((int)SHOW_ACCESS);
+}
+
+/*############################################################################*/
+
+/*-------------------CHECK ID-----------------------*/ 
+
+/* Description: This function check the user name in user_info.nc file. 
+ *              Returns DD_id if exists. 
+ *              Returns OK, or NOPERMISSION, or an ERROR
+ */
+      
+int CheckID(char *NameUsr)
+{
+   int i=0,Find=0;
+   int DD_id = NOPERMISSION;
+  
+   int UsrRefID;   /* ID of NC file */
+   char *ddbase;
+   char refname[PATHLENGTH];
+   int UserDimID,UserLenDimID;    /* Dimennsions ID */
+   int MemID;                                    /* Variable ID */
+   size_t MaxRecords, UserLength;   /* Dimensions */
+   size_t start[2]= {0,0};
+   size_t UserCount[2] = {1,0};
+   char UserDimName[] = "user", UserLenDimName[] = "UserLength";   /*   Dimensions names */
+   char MemName[] = "member";                                      /* Variable name */
+   char MemChar[USRLENGTH];
+   int status;
+ 
+/*------------- Open User Reference file ---------------------------------*/
+   if((ddbase = getenv("DDBASE")) == NULL)
+   {
+      if(Verbose) fprintf(stderr,"CHECKID:  No DDBASE environment.\n");
+      return(ENVIRERROR);
+   }
+   strcpy(refname,ddbase);
+   strcat(refname,USERREFNAME);
+   if(Verbose) fprintf(stderr," CHECKID: PATH is %s \n",refname);
+
+   if((status = nc_open(refname, NC_WRITE,&UsrRefID))  !=  NC_NOERR)
+   {
+      if(Verbose) fprintf(stderr,"CHECKID:  %s\n", nc_strerror(status));
+      return(NOUSERSFILE);
+   }
+
+/*------------------ Define all dimensions -------------------------------*/
+
+   status = nc_inq_dimid(UsrRefID,UserDimName,&UserDimID);
+   status = nc_inq_dimlen(UsrRefID, UserDimID,  &MaxRecords);
+   status = nc_inq_dimid(UsrRefID,UserLenDimName,&UserLenDimID);
+   status = nc_inq_dimlen(UsrRefID, UserLenDimID,  &UserLength);
+   UserCount[1] = UserLength;
+
+/*fprintf(stderr,"CheckTicket:Rec: %d %d %d\n",MaxRecords,UserLength,PasswdLength);*/
+
+/*------------------ Define all variables ID -------------------------------*/
+   status = nc_inq_varid(UsrRefID, MemName,&MemID);
+
+   while((i<MaxRecords) && (Find != 1))
+   {
+      start[0]=i;
+      status = nc_get_vara_text(UsrRefID, MemID, start,UserCount,MemChar);
+      if(strcmp(MemChar,NameUsr)==0) {DD_id = i;Find=1;}
+      i++;
+   }
+   nc_close(UsrRefID);
+   return(DD_id);
+}
+
+/*----------------Put into LOG file------------------------------------*/
+
+/* Description: This function requires ID of local host, IP-address of 
+*               local host and Login Name.      
+*
+*/
+
+void Put2Log(int UID, char *Host, char *LogName, int error)
+  {
+    FILE *log;
+    time_t Clock; 
+    char *ddbase;
+    char refname[PATHLENGTH], right[]="   normal    \0",noright[]="no permission\0";
+
+   if((ddbase = getenv("DDBASE")) == NULL)
+   {
+      fprintf(stderr,"No DDBASE info. Check your profile... \n");
+      return;
+   }
+   strcpy(refname,ddbase);
+   strcat(refname,LOGFILE);
+   if(Verbose) fprintf(stderr,"LOG file: %s \n",refname);
+   if((log = fopen(refname, "a")) == NULL)
+   {
+      fprintf(stderr,"Error in opening log file. \n");
+      return;
+   }
+
+   Clock=time(NULL);
+   
+   if(error>=0) 
+   fprintf(log,"%s\t%s\t%u  %s\t%s",Host,LogName,UID,right,ctime(&Clock));
+   else fprintf(log,"%s\t%s\t%u  %s\t%s",Host,LogName,UID,noright,ctime(&Clock));
+
+   fclose(log);
+ 
+   return;
+ }
+   
+/*---------------------LOGINS----------------------------------*/
+
+/* Description: This function uses by ddcheck */
+/*              Compare two passwords  */
+  
+int LOGINS(char *password)
+{
+  char salt[3],newkey[13];
+  char pas[80];
+  char PName[]="Administrator password: ";
+  int ACCESS_ = 0;
+
+/*--------------Password----------------------------*/
+  
+   strncpy(salt,password,2);
+   salt[2]='\0';
+   strcpy(pas,getpass(PName));
+   pas[strlen(pas)] = '\0';
+   strcpy(newkey,(char *)crypt(pas,salt));
+   newkey[strlen(newkey)] = '\0';
+   if(strcmp(newkey, password) == 0) ACCESS_=1;
+
+   return ACCESS_;
+}
+
+/*---------------------DDCHECK----------------------------------*/
+
+/* Description: This function check user for dd administrator access to DD_System
+*               Require only dd password from you.
+*               Returns 0 if o'k or -1 in case of unaccessability.
+*
+*/
+  
+int ddcheck()
+{
+  int FL=1,coun,i;
+  char lines[256],ref[40];
+  FILE *files;
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+   files=fopen("/etc/passwd","r");
+   while(FL != 0)
+   { 
+     if(fgets(lines, 255, files) != NULL)
+     {
+       coun=(strlen(lines)-strlen(strchr(lines,':')));
+       strncpy(ref,lines,coun);
+       ref[(strlen(lines)-strlen(strchr(lines,':')))]='\0';
+       if(strcmp(ref,"dd") == 0)
+       {
+         coun=(strlen(&(lines[0])+3)-strlen(strchr(&(lines[0])+3,':')));
+         strncpy(ref,&lines[0]+3,coun);
+         ref[coun]='\0';
+         i=LOGINS(ref);
+       }
+
+     }
+     else FL=0;
+   }
+  fclose(files);
+  if(i == 0) return(-1);
+  return(0);
+}
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+
+
diff --git a/src/SERVER/DD_GetData.c b/src/SERVER/DD_GetData.c
new file mode 100755
index 0000000..f06c055
--- /dev/null
+++ b/src/SERVER/DD_GetData.c
@@ -0,0 +1,1415 @@
+/*=====================================================================
+ *                DD SYSTEM base package
+ *                  DD_Server library
+ *                    DD_GetData.c
+ *                     V. 6.1
+ * author:         Andrey Fedorov
+ *
+ * Last revision:
+ *      May 19 1997: Version 1.0
+ *      25 February 1999 by A.Grigoriev
+ *      DD_GetData was updated.      V.2.0
+ *      Methods of search in SetTime are changed.
+ *      April 12, 2002: NETCDF lib is changed    V.3.0
+ *      Oct 10, 2002   Communication prorocol is changed. V 4.0
+ *      Oct 24, 2002  New calculation of thremaximum record size V. 4.1
+ *      work with NC files is now in file ncfileop.c
+ *      May 7, 2003 : V 4.2 Cash work improoved (ncfileop.c also)
+ *      Jan 6, 2004: V 4.3 Error in ID closing is fixed
+ *      Jan 21, 2004: V.4.4 Error in free memory fixed,
+ *                    Server can path several new files, and then return
+ *      Aug 12, 2004: V.4.5 New verbatim in the CLOSEID
+ *      Nov 18, 2004: V.4.6 Accomodation of new ncfileop.c
+ *      Mar 15, 2007 V.4.7 Fixed cash bag
+ *      Jul 10, 2007 V.5.0  According to Server protocol 4.5.1
+ *                          If "times" has "NODATA" string as name of the file, return "NOTIME"
+ *                          New format of VI name (see DDGenProt.lyx)
+ *      Aug 02, 2007 V.5.1  Add WAITEXTCALL flag and LOCK file to GetData routines
+ *                          Also global time limits
+ *      Sep 20, 2007 V.5.2  Refrech time limits after database update, database update after Get_Data call
+ *      Sep 23, 2007 V.5.3  Fedorov, New interface for SetTime()
+ *      Sep 24, 2007 V.5.4  Fedorov, Get_Data return is changed
+ *      Sep 25, 2007 V.5.5  Fedorov, Variable minimal gap
+ *      Feb 22, 2008, V.5.6 SetTime bug corrected -> nc_get,,,(...StartID...) not VarL->StartID !!!!
+ *      Mar 06, 2008, V.5.7 SetTime bug corrected ->
+ *      May 03, 2008, V.5.8 GlobalTime limits
+ *      May 06, 2008  V.5.9 Fedorov, Max Records number processing
+ *      May 15, 2008  V.5.10 Fedorov, NoData interval processing. Just go to the next correct data interval.
+ *      May 19, 2008  V.5.11 Fedorov, One record data interval. Time is interpreted as scalar
+ *      May 21, 2008  V.5.12 Fedorov, No data processing
+ *      Apr 11, 2009  V.5.13 Fedorov, Out of global limits
+ *      Apr 13, 2009  V.5.20 Fedorov, Reset of the pointer is in a spectal function
+ *      Apr 13, 2009  V.5.21 Fedorov, Set time between the last record and Stop time
+ *      Dec  8, 2012  V.6.0  Fedorov, New call to get the data structure, New multiparam call
+ *      Jan 11, 2013  V.6.1  Knizhnikova, Fedorov, SlobalStart check, If there is NOVAR, set the corresponding data constants to send the corresponding packet.
+ *=====================================================================*/
+#include <netcdf.h>
+#include "DD.h"
+#include "DD_comm.h"
+
+/*------------------ GLOBAL VARIABLES --------------------------*/
+
+DD_Var_t **DD_Var ;  /* Common for entire server session , all files */
+size_t  MaxIDNumber; /* The size of  DD_Var  array. Defined when new DD_Server session starts*/
+
+extern int Verbose;
+extern LocalOrigSync(DD_Var_t *Local, DD_Var_t *Orig);
+
+/*#################################################################*/
+/*----------------------- OpenInstr -------------------------------*/
+/*#################################################################*/
+/*
+ * Open Virtual instrument by VInstrName  and return ID.
+ * Make entry point of DD_Var table
+ * Fill General attributes fron the INFO file
+ */
+int OpenInstr(char *VInstrName)
+{
+   char refname[PATHLENGTH]; /* full name of the reference file */
+   char *ddbase;              /* Environment variable DDBASE (path to the DDBASE ROOT)*/
+   char RInstrName[MAXSETLENGTH]; /* Requested virtual instrument name */
+   int id;                        /* ID of open Virtual Instrument */
+   int refID,nameID;    /* ID of reference file and Var in */
+   static size_t RefStart[2] = {0,0};
+   static size_t RefCount[2] = {4,PATHLENGTH};
+   static char RefVar[4][PATHLENGTH];
+   int len, status;
+   char *VirInstrP;  //Pointer to some  part of virtual instrument
+   unsigned UT[7];   // Buffer array to decode global time
+   dd_tmstr_t *GTimeP;   // Buffer structure to decode global time
+
+  /** sleep(60); **/
+
+   if(Verbose)
+    {
+       fprintf(stderr,"OpenInstr(%s): begin\n",VInstrName);
+    }
+/* Converting original name to the name in database */
+   strcpy(RInstrName,VInstrName);
+   VirInstrP = (char *)RInstrName;
+   while((VirInstrP = strchr(VirInstrP,':')) != NULL) *VirInstrP = '_';
+
+/* Is this name in DD_Var structure ? */
+   for(id = 0; id < MaxIDNumber; id++)
+   {
+      if(DD_Var[id] != NULL)
+         if(strcmp(RInstrName, DD_Var[id]->InstrName) == 0)
+         {
+           if(Verbose) fprintf(stderr,"OpenInstr(%s): VI is already open with ID = %d\n",VInstrName,id);
+           return(id);
+         }
+   }
+   if(Verbose) fprintf(stderr,"OpenInstr(%s): No such VI in DD_Var array. Create New Entry.\n",VInstrName);
+
+/* Is the empty space in DD_Var table */
+   id =0;
+   while((DD_Var[id] != NULL) && (id < MaxIDNumber)) id++;
+   if(id >= MaxIDNumber)
+   {
+      if(Verbose) fprintf(stderr,"OpenInstr(%s): No Room in DD_Var table\n",VInstrName);
+      return(TOOMANYREQ);      /* No room */
+   }
+/**
+   if(Verbose) fprintf(stderr,"OpenInstr(%s): There is empty plase at %d\n",VInstrName,id);
+**/
+/* Open reference NC file */
+   if((ddbase = getenv("DDBASE")) == NULL) return(NOREFFILE);
+   strcpy(refname,ddbase);
+   strcat(refname,REFNAME);
+
+   status = nc_open(refname, NC_NOWRITE|NC_SHARE,&refID);
+   if(status != NC_NOERR)
+   {
+     if(Verbose) fprintf(stderr,"OpentInstr(%s): open file %s, message: %s\n",VInstrName,refname,nc_strerror(status));
+     return(NOREFFILE);
+   }
+
+   status = nc_inq_varid(refID,RInstrName,&nameID);
+   if(status != NC_NOERR)
+   {
+      if(Verbose) fprintf(stderr,"OpentInstr(%s): read %s, message: %s\n",VInstrName,RInstrName, nc_strerror(status));
+      return(NOVAR);
+   }
+
+   status = nc_get_vara_text(refID,nameID,RefStart,RefCount,(char *)RefVar);
+   if(status != NC_NOERR)
+   {
+      if(Verbose) fprintf(stderr,"OpentInstr(%s): %s\n",VInstrName,nc_strerror(status));
+      return(NOVAR);
+   }
+
+   len = strcspn(RefVar[1]," "); RefVar[1][len] = '\0';
+   len = strcspn(RefVar[2]," "); RefVar[2][len] = '\0';
+   len = strcspn(RefVar[0]," "); RefVar[0][len] = '\0';
+   len = strcspn(RefVar[3]," "); RefVar[3][len] = '\0';
+   status = nc_close(refID);
+
+/* Create VI holder*/
+   DD_Var[id] = (DD_Var_t *)malloc(sizeof(DD_Var_t));
+
+/* Init Values  */
+   strcpy(DD_Var[id]->InstrName,RInstrName);
+   DD_Var[id]->VarData = NULL;
+   DD_Var[id]->ParamSize = 0;
+   DD_Var[id]->AttrData.Dimensions = NULL;
+   DD_Var[id]->AttrData.Variables = NULL;
+   DD_Var[id]->ncID = -1;
+   DD_Var[id]->Maxnc_rec = 0;
+   strcpy(DD_Var[id]->path, RefVar[0]);
+
+   /*----- Init control Flags ---------------*/
+   DD_Var[id]->LastPacketFlag = OK;
+   DD_Var[id]->NewFile = 0;
+   DD_Var[id]->NewFileWasOpen = 0;
+/* ----------------------------------------------------------------
+ * Open and init "Times" file
+ * -----------------------------------------------------------------*/
+   DD_Var[id]->VILocked = 0;
+   DD_Var[id]->tmID = -1;
+   strcpy(DD_Var[id]->TimesFileName,RefVar[1]);
+   if((status = UpdateTimeInfo(DD_Var[id])) < 0) return status;
+
+/* ----------------------------------------------------------------
+ * Open "Info" file
+ * -----------------------------------------------------------------*/
+/* Attention: Constant information file open and close by request in GetAttribute() */
+   strcpy(DD_Var[id]->AttrName,RefVar[2]);
+   DD_Var[id]->attrID = -1;
+   /*
+    * Important to make NULL all variables
+    */
+    DD_Var[id]->AttrData.Dimensions = NULL;
+    DD_Var[id]->AttrData.Variables = NULL;
+/**
+    if(Verbose) fprintf(stderr,"OpentInstr(%s): ID = %d, Atributes are resetted\n",VInstrName,id);
+**/
+/* ----------------------------------------------------------------
+ * Open "CACHE" file
+ * -----------------------------------------------------------------*/
+   status = nc_open(RefVar[3],NC_WRITE|NC_SHARE,&(DD_Var[id]->Cash.ID));     /* Cach file */
+   if(status != NC_NOERR)
+   {
+      if(Verbose) fprintf(stderr,"OpentInstr(): open cash %s, message:%s\n",RefVar[3], nc_strerror(status));
+      return(CACHERR);
+   }
+   status = nc_inq_varid(DD_Var[id]->Cash.ID,"name",&(DD_Var[id]->Cash.nameID));
+   status = nc_inq_varid(DD_Var[id]->Cash.ID,"time",&(DD_Var[id]->Cash.timeID));
+   status = nc_inq_varid(DD_Var[id]->Cash.ID,"fopen",&(DD_Var[id]->Cash.fopenID));
+   DD_Var[id]->CurrCushN = -1;
+
+   if(status != NC_NOERR)
+   {
+      if(Verbose) fprintf(stderr,"OpentInstr(): %s\n",nc_strerror(status));
+      return(CACHERR);
+   }
+/**
+   if(Verbose) fprintf(stderr,"OpentInstr(%s): ID = %d, Cache is open\n",VInstrName,id);
+**/
+/* ----------------------------------------------------------------
+ * Read Global timing and minimal gap from INFO file
+ * -----------------------------------------------------------------*/
+   if((status = GetAttribute(id, GLOBSTARTNAME)) < 0) DD_Var[id]->GlobalStart = 0.0;
+   else
+   {
+      sscanf((char *)((DD_Var[id]->AttrData).Variables[0]), ISOTIMEF, &UT[0],&UT[1],&UT[2],&UT[3],&UT[4],&UT[5],&UT[6]);
+      SetDouble(GTimeP = UT2double(UT));
+      DD_Var[id]->GlobalStart = GTimeP->times;
+   }
+   if((status = GetAttribute(id, GLOBSTOPNAME)) < 0) DD_Var[id]->GlobalStop = 1.0e11;
+   else
+   {
+      sscanf((char *)((DD_Var[id]->AttrData).Variables[0]), ISOTIMEF, &UT[0],&UT[1],&UT[2],&UT[3],&UT[4],&UT[5],&UT[6]);
+      SetDouble(GTimeP = UT2double(UT));
+      DD_Var[id]->GlobalStop = GTimeP->times;
+   }
+   if((status = GetAttribute(id, SAMPLNAME)) < 0) DD_Var[id]->MinGap = MINGAP;
+   else
+   {
+      DD_Var[id]->MinGap = *((double *)((DD_Var[id]->AttrData).Variables[0])) * 5.0;
+      if(DD_Var[id]->MinGap < MINGAP) DD_Var[id]->MinGap = MINGAP;
+   }
+/* ----------------------------------------------------------------
+ * Read External archiving info
+ * -----------------------------------------------------------------*/
+   DD_Var[id]->ExtCallAllowed = 0;
+   if((status = GetAttribute(id, REMARCHNAME)) < 0)
+   {
+      if(Verbose) fprintf(stderr,"OpentInstr(%s):RemBase:GetAttribute(%s): %s\n", VInstrName,REMARCHNAME, nc_strerror(status));
+      DD_Var[id]->ExtCallAllowed = 0;
+      DD_Var[id]->BaseName[0] = '\0';
+      DD_Var[id]->RemSetID[0] = '\0';
+   }
+   else
+   {
+     strcpy(DD_Var[id]->BaseName,(DD_Var[id]->AttrData).Variables[0]);
+     if((status = GetAttribute(id, REMINSTNAME)) < 0)
+     {
+        DD_Var[id]->ExtCallAllowed = 0;
+        if(Verbose) fprintf(stderr,"OpentInstr(%s):RemInstr: %s\n",VInstrName,nc_strerror(status));
+     }
+     else
+     {
+        DD_Var[id]->ExtCallAllowed = 1;
+        strcpy(DD_Var[id]->RemSetID,(DD_Var[id]->AttrData).Variables[0]);
+     }
+   }
+
+   if(Verbose) fprintf(stderr,"OpentInstr(%s): GStart: %f GStop: %f\n",VInstrName,DD_Var[id]->GlobalStart,DD_Var[id]->GlobalStop);
+   if(Verbose) fprintf(stderr,"OpentInstr(%s): RemBase: %s RemInstr: %s\n",VInstrName,DD_Var[id]->BaseName,DD_Var[id]->RemSetID);
+
+
+   if(Verbose) fprintf(stderr,"DD_GetData:OpentInstr: New ID = %d\n",id);
+   return(id);
+}
+/*-------------------------------------------------------------------------------*/
+
+/*###########################################################*/
+/*------------------- CLOSEID -------------------------------*/
+/*###########################################################*/
+int CloseID(int ID)
+/*
+ * Closes this ID and return number of IDs remained in use
+ */
+
+{
+   size_t CashStart[2] = {0L,0L};
+   size_t CashCount[2] = {1L,MAXFILENAME};
+   int status;
+   int i,il, count = 0;
+/* Is this ID */
+   if(Verbose) fprintf(stderr,"CloseID(%d)\n",ID);
+   if(ID >= MaxIDNumber) return(1);    /* Everythig is OK */
+   if(DD_Var[ID] != NULL)
+   {
+/**
+       if(Verbose) fprintf(stderr,"CloseID(%d): ID exists, start termination\n",ID);
+**/
+/*------ Close all netCDF files -----*/
+      if(DD_Var[ID]->ncID >= 0)
+      {
+         status = nc_close(DD_Var[ID]->ncID);
+         DD_Var[ID]->ncID = -1;
+         /**
+         if(Verbose) fprintf(stderr,"CloseID(%d): Data File is closed\n",ID);
+         **/
+      }
+      if(DD_Var[ID]->Cash.ID >= 0)
+      {
+         status = nc_close(DD_Var[ID]->Cash.ID);
+         DD_Var[ID]->Cash.ID = -1;
+         if(Verbose)
+         {
+           if(DD_Var[ID]->CurrCushN >= 0)
+             fprintf(stderr,"CloseID(%d): File %s, N %d closed\n",ID, &(DD_Var[ID]->Cash.names[DD_Var[ID]->CurrCushN][0]),DD_Var[ID]->CurrCushN);
+           else fprintf(stderr,"CloseID(%d): cash closed\n",ID);
+         }
+      }
+      if(DD_Var[ID]->attrID >= 0)
+      {
+         status = nc_close(DD_Var[ID]->attrID);
+         DD_Var[ID]->attrID = -1;
+         /**
+         if(Verbose) fprintf(stderr,"CloseID(%d): Info File is closed\n",ID);
+         **/
+      }
+      if(DD_Var[ID]->tmID >= 0)
+      {
+         status = nc_close(DD_Var[ID]->tmID);
+         DD_Var[ID]->tmID = -1;
+         /**
+         if(Verbose) fprintf(stderr,"CloseID(%d): Times File is closed\n",ID);
+         **/
+      }
+
+/*==========================================================
+ *      FREE MEMORY Variable Data
+ *==========================================================*/
+      for(il = 0; il < DD_Var[ID]->ParamSize; il++)
+      {
+	 for(i = 0; i < DD_Var[ID]->VarData[il].VarNumber; i++)
+	 {
+	    if (Verbose) fprintf(stderr,"CloseID(%d): %d, ptr %p\n",ID,i,DD_Var[ID]->VarData[il].Variables[i]);
+	    free(DD_Var[ID]->VarData[il].Variables[i]);
+	    DD_Var[ID]->VarData[il].VarNumber = 0;
+	 }
+	 free(DD_Var[ID]->VarData[il].Dimensions);
+      }
+      if(DD_Var[ID]->ParamSize > 0) free(DD_Var[ID]->VarData);
+
+/**
+         if(Verbose) fprintf(stderr,"CloseID(%d): Free VarData\n",ID);
+**/
+
+      if(DD_Var[ID]->AttrData.Variables != NULL)
+      {
+/**
+         if (Verbose)
+          fprintf(stderr,"CloseID(%d): Free AttrData.Variables[0] = %p\n",ID,DD_Var[ID]->AttrData.Variables[0]);
+**/
+         if (DD_Var[ID]->AttrData.Variables[0] != NULL)
+         {
+            free(DD_Var[ID]->AttrData.Variables[0]);
+            DD_Var[ID]->AttrData.Variables[0] = NULL;
+         }
+      }
+
+      free(DD_Var[ID]);
+      DD_Var[ID] = NULL;
+      if(Verbose) fprintf(stderr,"CloseID(%d): Free DD_Var\n",ID);
+   }
+
+/* Count determination */
+   for(i = 0; i < MaxIDNumber; i++) if(DD_Var[i] != NULL) count++;
+
+   return(count);
+}
+
+/*###########################################################*/
+/*------------------ GETATTRIBUTE ---------------------------*/
+/*###########################################################*/
+int GetAttribute(int ID, char *VarName)
+/*
+ * Get information variable by ID and variable
+ * name. Fill Variable structure
+ */
+
+{
+  int VarID;          /* ID of requested Variable */
+  static size_t DimArray[NC_MAX_DIMS];
+  static int  IntDimArray[NC_MAX_DIMS];
+  static int  DimIDArray[NC_MAX_DIMS];
+  static size_t start[NC_MAX_DIMS];
+  static void *CommonAttrPnt = NULL;    /* Pointer to the Atributes for ALL ID's */
+  static nc_type type;
+  size_t count = 1;
+  int i, status;
+
+/* Check the ID */
+  if(DD_Var[ID] == NULL) return(NOID);
+
+  if(Verbose) fprintf(stderr,"GetAttribute(%d): Name = %s\n",ID,VarName);
+
+/* Free memory for data */
+  if(DD_Var[ID]->AttrData.Dimensions == NULL)
+     DD_Var[ID]->AttrData.Dimensions = (int *)IntDimArray;
+
+  if(DD_Var[ID]->AttrData.Variables == NULL)
+     DD_Var[ID]->AttrData.Variables = &CommonAttrPnt; /* Static pointer -> Variables[0] */
+  if(DD_Var[ID]->AttrData.Variables[0] != NULL)       /* Only one variable exists (no time) */
+  {
+/**/
+     if (Verbose) fprintf(stderr,"GetAttribute(%d):Free AttrData.Variables[0] = %p\n", ID,DD_Var[ID]->AttrData.Variables[0]);
+/**/
+     free(DD_Var[ID]->AttrData.Variables[0]);
+     DD_Var[ID]->AttrData.Variables[0] = NULL;
+  }
+
+/* Try to open constant information data */
+   status = nc_open(DD_Var[ID]->AttrName,NC_NOWRITE,&(DD_Var[ID]->attrID));   /* Constant information */
+   if(status!= NC_NOERR)
+   {
+      if(Verbose) fprintf(stderr,"GetAttribute(%d): %s\n",ID,nc_strerror(status));
+      return(NOINFOFILE);
+   }
+/* Get ID for queired variable. If not return */
+  status = nc_inq_varid(DD_Var[ID]->attrID,VarName,&VarID);
+  if(status != NC_NOERR)
+  {
+     if(Verbose) fprintf(stderr,"GetAttribute(%d): %s\n",ID,nc_strerror(status));
+     return(NOVAR);
+  }
+
+/* Get invormation about queried variable */
+  status = nc_inq_vartype(DD_Var[ID]->attrID,VarID,&type);                                                          /* Type of variable */
+  status = nc_inq_varndims(DD_Var[ID]->attrID,VarID,&(DD_Var[ID]->AttrData.DimNumber));    /* Number of dimansions */
+  status = nc_inq_vardimid(DD_Var[ID]->attrID,VarID,DimIDArray);                                                 /* Array of dimensions IDs */
+  if(status != NC_NOERR)
+  {
+     if(Verbose) fprintf(stderr,"GETATTR: %s\n",nc_strerror(status));
+     return(NOVAR);
+  }
+
+  if(DD_Var[ID]->AttrData.DimNumber == 0)
+  {
+     DD_Var[ID]->AttrData.DimNumber = 1;
+     DimArray[0] = 1;
+     IntDimArray[0] = 1;
+  }
+  else
+    for(i = 0; i < DD_Var[ID]->AttrData.DimNumber; i++)
+    {
+       status = nc_inq_dimlen( DD_Var[ID]->attrID,DimIDArray[i],&(DimArray[i]));            /* Dimensions values */
+       if(status != NC_NOERR)
+       {
+           if(Verbose) fprintf(stderr,"GETATTR: %s\n",nc_strerror(status));
+           return(NOVAR);
+       }
+       IntDimArray[i] =  (int)DimArray[i];
+    }
+
+
+/* Define type of variable */
+  switch(type)
+  {
+    case NC_DOUBLE: DD_Var[ID]->AttrData.type = DD_DOUBLE; break;
+    case NC_CHAR:   DD_Var[ID]->AttrData.type = DD_CHAR;   break;
+    case NC_FLOAT:  DD_Var[ID]->AttrData.type = DD_FLOAT;  break;
+    case NC_SHORT:  DD_Var[ID]->AttrData.type = DD_SHORT;  break;
+    case NC_INT:    DD_Var[ID]->AttrData.type = DD_INT;
+  }
+
+/* Setting Dimensions attributes to get data */
+  for(i = 0; i < DD_Var[ID]->AttrData.DimNumber; i++) count = count * DimArray[i];
+
+/* Alocating memory for data */
+  DD_Var[ID]->AttrData.Variables[0] = (void *)malloc(unixlen[DD_Var[ID]->AttrData.type]*count);
+
+/*
+   if (Verbose)
+       fprintf(stderr,"Malloc DD_Var[%d]->AttrData.Variables[0] = %p\n",ID,DD_Var[ID]->AttrData.Variables[0]);
+*/
+
+  switch(type)
+  {
+    case NC_DOUBLE: status = nc_get_vara_double(DD_Var[ID]->attrID,VarID,start,DimArray,(double *)DD_Var[ID]->AttrData.Variables[0]);
+                    if (status != NC_NOERR)
+                    {
+                        if(Verbose) fprintf(stderr,"GETATTR: %s\n",nc_strerror(status));
+                        return(NOVAR);
+                    }
+                    break;
+    case NC_CHAR:  status = nc_get_vara_text(DD_Var[ID]->attrID,VarID,start,DimArray,(char *)DD_Var[ID]->AttrData.Variables[0]);
+                    if (status != NC_NOERR)
+                    {
+                        if(Verbose) fprintf(stderr,"GETATTR: %s\n",nc_strerror(status));
+                        return(NOVAR);
+                    }
+                    break;
+    case NC_FLOAT:  status = nc_get_vara_float(DD_Var[ID]->attrID,VarID,start,DimArray,(float *)DD_Var[ID]->AttrData.Variables[0]);
+                    if (status != NC_NOERR)
+                    {
+                        if(Verbose) fprintf(stderr,"GETATTR: %s\n",nc_strerror(status));
+                        return(NOVAR);
+                    }
+                    break;
+    case NC_SHORT: status = nc_get_vara_short(DD_Var[ID]->attrID,VarID,start,DimArray,(short *)DD_Var[ID]->AttrData.Variables[0]);
+                    if (status != NC_NOERR)
+                    {
+                        if(Verbose) fprintf(stderr,"GETATTR: %s\n",nc_strerror(status));
+                        return(NOVAR);
+                    }
+                    break;
+    case NC_INT:   status = nc_get_vara_long(DD_Var[ID]->attrID,VarID,start,DimArray,(long *)DD_Var[ID]->AttrData.Variables[0]);
+                    if (status != NC_NOERR)
+                    {
+                        if(Verbose) fprintf(stderr,"GETATTR: %s\n",nc_strerror(status));
+                        return(NOVAR);
+                    }
+  }
+  if(DD_Var[ID]->attrID >= 0) nc_close(DD_Var[ID]->attrID);
+  DD_Var[ID]->attrID = -1;
+  return(1);
+}
+/*--------------------------------------------------------------*/
+
+/*##############################################################
+ *#                GetMultiData()                              #
+/*##############################################################*/
+ int GetMultiData(int ID, int VarSize, char **VarNames, char *TimeInt, int BackFlag)
+/*
+ * Create static DD_data_t variables array and return its pointer.
+ * After open a new file the function refreshes variable dimensions
+ * Data are returned by portions until end of requested interval.
+ * Return MOREDATA or OK, or error value.
+ * If requsted variable is "Time", then it converts into "double" form.
+ * The rool of this routine: DO NOT CALL SetNewFile if VI is locked,
+ * If VI have been locked and then have been releesed, Times has to be updated and
+ * SetTime has to be redone.
+ */
+{
+   static int *VarID = NULL;                 /* IDs of requested Parameters of this VI */
+   static char TimeStr[TIMELENGTH];
+   static char TimeName[] = "Time";
+   static int TimeID;
+   //static size_t DimArray[NC_MAX_DIMS];
+   static size_t **DimArrayS  = NULL;         /* Several Dimensions arrays */
+   size_t *DimArray;                          /* Local Dimension Array (for the specific parameter */
+   static int DimIDArray[NC_MAX_DIMS];
+   static nc_type type;
+   static size_t start[NC_MAX_DIMS];
+   static size_t TimeCount[2] = {1,TIMELENGTH};
+   static size_t TimeStart[2] = {0,0};
+   static int Scalar = 0; /* indicator of scalar value */
+   static int String = 0; /* indicator of single (not timed) string March 9 1997 */
+   static int TimeTypeValue = 0; /* indicator of time type value */
+   static size_t RecordSize;   /* Size of one record in terms of variables of specified type */
+   static size_t *PacketSize=NULL;   /* Packets sizes of one record (of specified variable) */
+   static size_t RecordNumber; /* Variable maximal number of records in one packet */
+   int i,il;
+   int DimNumber;
+   int err2,status;
+   int CurrncID;
+
+   /*-------------------------------------------------------------
+   * Following variables subsitute fields in DD_Var to save a time
+   *------------------------------------------------------------*/
+   static DD_Var_t Local;
+
+   /** sleep(60); **/
+  /**  if(Verbose)
+   {
+      for(il = 0; il < VarSize; il++)
+	 fprintf(stderr,"GetMultiData(ID=%d), VarName=%s,Timeint=%s)\n",ID,VarNames[il],TimeInt);
+      fprintf(stderr,"GeMultitData(ID=%d) LastPacket: %d FileStatus: %d NewFile: %d NFWasOpen: %d\n",ID,
+                              DD_Var[ID]->LastPacketFlag,
+                              DD_Var[ID]->LastFileStatus,
+                              DD_Var[ID]->NewFile,
+                              DD_Var[ID]->NewFileWasOpen);
+      fprintf(stderr,"GetMultiData(ID=%d), DD_Var[ID]->VarData = %p\n",ID,DD_Var[ID]->VarData);
+   }
+  **/
+   /* Check the ID and reset the variable number*/
+   if(DD_Var[ID] == NULL) return(NOID);
+   //if(FirstFlag) { DD_Var[ID]->ParamSize = 0; FirstFlag = 0;}
+
+   /* sleep(30); */ /* To give possibility to start gdb */
+
+   /*===================================================
+    * Free data from the previous requests
+    * BUT the data dimensions are not removed YET
+    * Probably we have just fill new portion of the same data
+    *==================================================*/
+   for(il = 0; il < DD_Var[ID]->ParamSize; il++)
+   {
+      for(i = 0; i < DD_Var[ID]->VarData[il].VarNumber; i++)
+      {
+	 //if (Verbose) fprintf(stderr," FREE ID = %d, il = %d, i = %d ptr %p\n",ID,il,i,DD_Var[ID]->VarData[il].Variables[i]);
+	 free(DD_Var[ID]->VarData[il].Variables[i]);
+	 DD_Var[ID]->VarData[il].VarNumber = 0;
+      }
+   }
+
+   /*============================================================================
+   *###### Check if we need to refresh entire information about parameters #####
+   *###### We have to renovate ALL if previous request been finished or    #####
+   *###### new file was open during previous entry                         #####
+   *============================================================================*/
+  if((DD_Var[ID]->LastPacketFlag == OK) || DD_Var[ID]->NewFile) // Request been finished or
+                                                                // System was trying to open new file
+  {
+     if(DD_Var[ID]->ncID < 0) return NOPOINTER; /* Time has been not set */
+     if(Verbose) fprintf(stderr,"GetMultiData(%d): Parameters Info should be updated\n", ID);
+      /** sleep(60); **/
+      /*---------------------------------------------------------------------
+      * Look if the LastFileStatus has an error
+      *--------------------------------------------------------------------*/
+     switch(DD_Var[ID]->LastFileStatus)
+     {
+        case OK: break;   /* Data file was open succesfully */
+        case CACHTOOREC:  /* There was no free place in the CACH */
+        case TRYAGAIN:    /* VI was blocked */
+        case WAITEXTCALL: /* New data was requested at external database */
+           if(Verbose) fprintf(stderr,"GetData(%d): There was WAITEXTCALL, I am trying again\n",ID);
+           /* We have to check if VI is unlocked */
+           switch(IsTimesLocked(&Local))
+           {
+             case NOLOCK: break;
+             case LOCKED:
+                    if(Verbose) fprintf(stderr,"GetData(%d): Data base is still locked\n",ID);
+                      DD_Var[ID]->VILocked = Local.VILocked;
+                      return MOREDELAY; break;
+             case LOCKREMOVED: UpdateTimeInfo(&Local);
+                               LocalOrigSync(&Local,DD_Var[ID]);
+                               SetTime(&Local,Local.CDTime); /* Return to the original status */
+                              if(Verbose) fprintf(stderr,"GetData(%d):Lock Was removed, SetTime again",ID);
+           }
+           switch(DD_Var[ID]->LastFileStatus = SetNewFile(&Local,1)) /* Only LOCAL work in our case !*/
+           {
+              case OK: break;   /* New file is open, go on */
+              case CACHTOOREC:  /* There was no free place in the CACH */
+              case TRYAGAIN:    /* VI was blocked */
+              case WAITEXTCALL: /* New data was requested */
+                  DD_Var[ID]->VILocked = Local.VILocked; /* Tell Original holder that it is locked */
+                  DD_Var[ID]->NewFile = 1;
+                  DD_Var[ID]->NewFileWasOpen = 1;
+                  DD_Var[ID]->LastPacketFlag = MOREDELAY;
+                 if(Verbose) fprintf(stderr,"GetData(%d): We have to waite again: %d\n",ID,status);
+                 return MOREDELAY;
+                 break;
+              case OUTOFTIME:
+               if(Verbose) fprintf(stderr,"GetData(%d): OUTOFTIME while requested new file %d\n",ID,status);
+               DD_Var[ID]->LastFileStatus = OUTOFTIME;
+               DD_Var[ID]->LastPacketFlag = OK;  /* Just to show that this request is completed */
+               return DD_Var[ID]->LastFileStatus;
+               break;
+              default:
+               if(Verbose) fprintf(stderr,"GetData(%d): Unrecoverable error: %d\n",ID,status);
+               DD_Var[ID]->LastPacketFlag = OK;  /* Just to show that this request is completed */
+               return DD_Var[ID]->LastFileStatus;
+           }
+           break;
+         case OUTOFTIME: // Nothing to do with this request. New set time is needed
+            if(Verbose) fprintf(stderr,"GetData(%d): Previous call gave OUTOFTIME, return\n",ID);
+            return DD_Var[ID]->LastFileStatus;
+            break;
+         default:  /* The error is unrecoverable */
+            if(Verbose) fprintf(stderr,"GetData(%d): Unrecoverable error: %d\n",ID,status);
+            return DD_Var[ID]->LastFileStatus;
+     }
+
+      /*-----------------------------------------------------------------------------
+       *    Data file is open. It is time to refresh information about parameters
+       *----------------------------------------------------------------------------*/
+      for(il = 0; il < DD_Var[ID]->ParamSize; il++) // Free existing dimensions
+      {
+	 if(DD_Var[ID]->VarData[il].Dimensions != NULL) {free(DD_Var[ID]->VarData[il].Dimensions); DD_Var[ID]->VarData[il].Dimensions = NULL;}
+	 if(DimArrayS[il] != NULL) {free(DimArrayS[il]); DimArrayS[il] = NULL;}
+      }
+      if(DD_Var[ID]->ParamSize > 0)
+      {
+	 if(DD_Var[ID]->VarData != NULL) { free(DD_Var[ID]->VarData); DD_Var[ID]->VarData = NULL;}
+	 free(VarID);
+	 free(PacketSize);
+	 free(DimArrayS);
+      }
+      DD_Var[ID]->ParamSize = (size_t)VarSize;
+      /*--------------------------------------------
+      * Create a new holder according to the parameters number
+      *--------------------------------------------*/
+      DD_Var[ID]->VarData = (DD_data_t *)malloc(sizeof(DD_data_t) * VarSize);
+      VarID = (int *)malloc(sizeof(int) * VarSize);
+      PacketSize = (size_t *)malloc(sizeof(size_t) * VarSize);
+      DimArrayS = (size_t **)malloc(sizeof(size_t *) * VarSize);
+      for(il = 0; il < DD_Var[ID]->ParamSize; il++) DimArrayS[il] = NULL;
+
+      /*----------------------------------------------------
+       * Decide which ncID we are  using
+       *---------------------------------------------------*/
+      if(DD_Var[ID]->NewFile == 1) CurrncID = Local.ncID;
+      else  CurrncID = DD_Var[ID]->ncID;
+
+      /*------------------------------------------------
+       * Calculation what number of records
+       * of the maximaly sized variable we can transmit
+       *-----------------------------------------------*/
+      RecordNumber = MaxRecord(CurrncID);
+      if(RecordNumber <= 0)
+      {
+	 if(Verbose) fprintf(stderr,"GetMultiData(%d): Error in calculation of records number\n",ID);
+	 return(INTSERERR);
+      }
+
+      /*---------------------------------------------
+       * Define time ID
+       *--------------------------------------------*/
+      status = nc_inq_varid(CurrncID,TimeName,&TimeID);
+      /*------------------------------------------------------------------------------------------
+      *      Reseting VarNumber  and create a new local data structure
+      *      Also we need to set Time limit constants
+      *------------------------------------------------------------------------------------------*/
+      if(DD_Var[ID]->LastPacketFlag == OK)  /* Very new request, after SetTime() */
+      {
+	 TimeStart[0] = DD_Var[ID]->nc_rec;
+	 status = nc_get_vara_text(DD_Var[ID]->ncID,TimeID,TimeStart,TimeCount,TimeStr);
+	 DD_Var[ID]->CDTime = DD_Time2Double(TimeStr); /* Current time of record */
+	 DD_Var[ID]->SDTime = DD_Var[ID]->CDTime; /* Start time of record */
+	 DD_Var[ID]->FDTime = DD_Var[ID]->SDTime + DD_Time2Double(TimeInt);
+      }
+
+      DD_Var[ID]->NewFile = 0;  /* Forget that it was new file */
+
+      /*--------------------------------------------------
+       * Get Dimensions and allocate memory for all
+       * requested parameters
+       *-------------------------------------------------*/
+      for(il = 0; il < VarSize; il++)
+      {
+	 DD_Var[ID]->VarData[il].VarNumber = 0;
+	 status = nc_inq_varid(CurrncID,VarNames[il],&(VarID[il]));
+	 if (status != NC_NOERR)
+	 {
+	    if(Verbose)
+	    {
+	       fprintf(stderr,"MultiData(%d): NCDF message: %s\n",ID,nc_strerror(status));
+	       fprintf(stderr,"MultiData(%d): Parameter %s not found\n",ID,VarNames[il]);
+	    }
+	    VarID[il] = NOVAR; /* NOVAR */
+	 }
+         /*--------------------------------------------------------
+	  * Get dimensions number and its type
+	  *------------------------------------------------------*/
+	 if(VarID[il] != NOVAR)
+	 {
+	    DimArrayS[il] = (size_t *)malloc(sizeof(size_t) * NC_MAX_DIMS);
+	    DimArray = DimArrayS[il]; // Just a local pointer
+	    status = nc_inq_vartype(CurrncID,VarID[il],&type);
+	    status = nc_inq_varndims(CurrncID,VarID[il],&DimNumber);
+	    //if(Verbose) fprintf(stderr,"GetMultiData(%d): Dimensions(%d) number = %d\n",ID,il,DimNumber);
+
+	    status = nc_inq_vardimid(CurrncID,VarID[il],DimIDArray);
+	    if(DimNumber == 0)
+	    {
+	       DD_Var[ID]->VarData[il].DimNumber = 1;
+	       DimArray[1] = 1;
+	       Scalar = 1;    // For one parameter call only
+	    }
+	    else                    /* Filling the array of Dimensions */
+	    {
+	       for(i = 0; i < DimNumber; i++) status = nc_inq_dimlen(CurrncID,DimIDArray[i],&(DimArray[i]));
+	    }
+
+	    /*--------------- Several special trucks for single variables (without time) ---------*/
+	    if((DimArray[0]<2) && (DimIDArray[0] != 0)) Scalar = 1; /* If the first dimension is not TIME and lenrgth is 1 or 0 */
+	    if((type == NC_CHAR) && (DimNumber < 2)) String = 1;
+	    if(String == 0) DimArray[0] = 1; else DimArray[1] = DimArray[0];
+	    if((String == 0) && (DimNumber == 1)) { DimArray[1] = 1; DimNumber = 2;}
+	    if(DimNumber > 1) DD_Var[ID]->VarData[il].DimNumber = DimNumber -1;
+	    else DD_Var[ID]->VarData[il].DimNumber = 1;
+
+	    /*----------------------------------------------------------
+	    * Create dimensions, and fill the dimensions array
+	    *--------------------------------------------------------*/
+	    DD_Var[ID]->VarData[il].Dimensions = (int *)malloc(sizeof(int)*DimNumber);
+	    for(i = 0; i < DD_Var[ID]->VarData[il].DimNumber; i++)
+	    {
+	       (DD_Var[ID]->VarData[il].Dimensions)[i] = (int)DimArray[i+1];
+	       //if(Verbose) fprintf(stderr,"GetMultiData(%d): Dimensions(%d): dim[%d] = %d\n",ID,il,i,(int)DimArray[i+1]);
+	    }
+
+	    /*---------------------------------------------------------------------
+	    *   Set Variable type
+	    *-------------------------------------------------------------------*/
+	    switch(type)
+	    {
+	       case NC_DOUBLE: DD_Var[ID]->VarData[il].type = DD_DOUBLE; break;
+	       case NC_CHAR:   DD_Var[ID]->VarData[il].type = DD_CHAR;   break;
+	       case NC_FLOAT:  DD_Var[ID]->VarData[il].type = DD_FLOAT;  break;
+	       case NC_SHORT:  DD_Var[ID]->VarData[il].type = DD_SHORT;  break;
+	       case NC_INT:    DD_Var[ID]->VarData[il].type = DD_INT;    break;
+	       case NC_BYTE:   DD_Var[ID]->VarData[il].type = DD_CHAR;   break;
+	       default:        DD_Var[ID]->VarData[il].type = DD_CHAR;
+	    }
+
+	    /*-------------------------------------------------------------------------
+	    * Calculate the corresponding record size,
+	    * an allocate memory to fit the RecordNumber records
+	    *------------------------------------------------------------------------*/
+	    RecordSize = 1;
+	    for(i = 1; i < DimNumber; i++)
+	    {
+		  RecordSize = RecordSize * DimArray[i];
+		  start[i] = 0;
+	    }
+	    if(String == 1) RecordSize = DimArray[0];  /* March 9 1997 */
+	    PacketSize[il] = RecordSize*unixlen[DD_Var[ID]->VarData[il].type];
+
+	    DD_Var[ID]->VarData[il].Variables = (void **)malloc(sizeof(void *) * RecordNumber);
+	    /*
+	       if (Verbose)
+		  fprintf(stderr," Malloc: DD_Var[%d]->VarData[%d].Variables = %p\n",ID, il, DD_Var[ID]->VarData[il].Variables);
+	    */
+	 }
+	 else
+	 {
+	    DD_Var[ID]->VarData[il].type = NOVAR; /* To indicate absence of this variable */
+	    PacketSize[il] = 0;
+	    DD_Var[ID]->VarData[il].DimNumber = 0;
+	    DD_Var[ID]->VarData[il].VarNumber = 0;
+	    PacketSize[il] = 0;
+	 }
+      } /* FOR il */
+
+      /*-------------------------------------------
+       * Create a Local structure
+       *------------------------------------------- */
+      if(DD_Var[ID]->LastPacketFlag == OK)  /* Very new request, after SetTime() */
+      {
+	 memcpy((void *)&Local, (void *)DD_Var[ID], sizeof(DD_Var_t)); /*--- Local structure if it is new request */
+	 //if(Verbose) fprintf(stderr,"GetData(%d): DD_Var[ID] -> Local\n",ID);
+      }
+      if(Verbose) fprintf(stderr,"GetMultiData(ID=%d), Created Local, DD_Var[ID]->VarData = %p\n",ID,DD_Var[ID]->VarData);
+   }
+   /*#######################################################################*/
+   /*        End of refresh information about variable in case of new file
+   *        or new request                                   */
+   /*#######################################################################*/
+
+   /*=================================================================
+   * GET DATA
+   *=================================================================*/
+   if ((Scalar == 1) || (String == 1)) DD_Var[ID]->LastPacketFlag = OK;
+   else DD_Var[ID]->LastPacketFlag = MOREDATA;
+
+   /*===========================================================
+    *  The loop to get data until time or file finish
+    *===========================================================*/
+   do
+   {
+      /*----------------------------------------
+       *   Get memory for each variable
+       *-----------------------------------------*/
+      for(il = 0; il < VarSize; il++)
+      {
+         if( DD_Var[ID]->VarData[il].type >= 0)
+	 {
+	    DD_Var[ID]->VarData[il].Variables[DD_Var[ID]->VarData[il].VarNumber] = (void *)malloc(PacketSize[il]);
+	    /*
+	    if (Verbose)
+	       fprintf(stderr,"Malloc: DD_Var[%d]->VarData[%d].Variables[%d] = %p, Size = %d\n",ID, il,
+		     DD_Var[ID]->VarData[il].VarNumber,
+		     DD_Var[ID]->VarData[il].Variables[DD_Var[ID]->VarData[il].VarNumber],
+		     PacketSize[il]);
+	    */
+	 }
+      }
+      if((Scalar == 1) || (String == 1))
+      {
+         start[0] = 0;
+      }
+      else  /* Setup start and looking for a time limit */
+      {
+
+         /*---------- Define START from LOCAL struct and read current Time ----------*/
+         start[0] = Local.nc_rec;
+         TimeStart[0] = Local.nc_rec;
+         status = nc_get_vara_text(Local.ncID,TimeID,TimeStart,TimeCount,TimeStr);
+	 Local.CDTime = DD_Time2Double(TimeStr); /* Current time of record */
+         //fprintf(stderr,"GetData(%d): Start %f Current %f Stop %f\n",ID,Local.SDTime,Local.CDTime,Local.FDTime);
+
+         //-------------- Check if we have to return by time --------------
+         if(Local.CDTime > Local.FDTime) /* Return by time. All problem will path to the next GetData */
+         {
+            /* If new file was open we have to return to original file */
+            if(Verbose) fprintf(stderr,"GetData(%d): Stop By Time\n",ID);
+            SetOriginPointer(&Local, ID);
+            /*------- Free reserved for nothing last array -------------*/
+	    for(il = 0; il < VarSize; il++)
+	    {
+               if(DD_Var[ID]->VarData[il].type >= 0)
+	       {
+		  free(DD_Var[ID]->VarData[il].Variables[DD_Var[ID]->VarData[il].VarNumber]);
+		  /*
+		  if (Verbose)
+		     fprintf(stderr,"Free: DD_Var[%d]->VarData[%d].Variables[%d], Pntr %p\n",ID, il, DD_Var[ID]->VarData[il].VarNumber,  DD_Var[ID]->VarData[il].Variables[DD_Var[ID]->VarData[il].VarNumber]);
+		  */
+	       }
+	    }
+            return OK;
+         } //--------- End return by time ---------------
+      }
+
+      /*-------------------------------------------------------
+       * Get Data according to its type
+       *-------------------------------------------------------*/
+      for(il = 0; il < VarSize; il++)
+      {
+         if( DD_Var[ID]->VarData[il].type >= 0)
+	 {
+	    DimArray = DimArrayS[il];
+	    /* 
+	    if(Verbose)
+	    {
+	       for (i = 0; i < DD_Var[ID]->VarData[il].DimNumber+1; i++)
+		  fprintf(stderr,"GetMultiData(%d): Variable[%d], Dimension[%d] DimSize = %d\n", ID, il, i,DimArray[i]);
+	       fprintf(stderr,"VarID[%d] = %d, type = %d\n",il, VarID[il],DD_Var[ID]->VarData[il].type);
+	    }
+	     */
+	    switch(DD_Var[ID]->VarData[il].type)
+	    {
+	    case DD_DOUBLE: status = nc_get_vara_double(Local.ncID, VarID[il],  start,  DimArray,
+							 (double *)DD_Var[ID]->VarData[il].Variables[DD_Var[ID]->VarData[il].VarNumber]);
+		  break;
+	    case DD_INT: status = nc_get_vara_int(Local.ncID, VarID[il],  start,  DimArray,
+						   (int *)DD_Var[ID]->VarData[il].Variables[DD_Var[ID]->VarData[il].VarNumber]);
+		  break;
+	    case DD_FLOAT: status = nc_get_vara_float(Local.ncID, VarID[il],  start,  DimArray,
+						      (float *)DD_Var[ID]->VarData[il].Variables[DD_Var[ID]->VarData[il].VarNumber]);
+		//  if(Verbose) fprintf(stderr,"(Variable[%d])[0] = %f\n",il,((float *)DD_Var[ID]->VarData[il].Variables[DD_Var[ID]->VarData[il].VarNumber])[0]);
+		  break;
+	    case DD_SHORT: status = nc_get_vara_short(Local.ncID, VarID[il],  start,  DimArray,
+						      (short *)DD_Var[ID]->VarData[il].Variables[DD_Var[ID]->VarData[il].VarNumber]);
+		  break;
+	    case DD_CHAR: status = nc_get_vara_text(Local.ncID, VarID[il],  start,  DimArray,
+						      (char *)DD_Var[ID]->VarData[il].Variables[DD_Var[ID]->VarData[il].VarNumber]);
+	    }  /* End of switch */
+	    DD_Var[ID]->VarData[il].VarNumber++;
+	 } /* if not NOVAR */
+      } /* for il */
+      /*------ Return immediately if it is just one record ------------*/
+      if ((Scalar == 1) || (String == 1)) return OK;
+
+      /*---- Now we have to decide if we opVarNamesen a new file to continue ------------*/
+      if(DD_Var[ID]->LastPacketFlag == MOREDATA) /* Timed variable (no scalar) */
+      {
+	 Local.nc_rec++;
+
+          /*======================================================================
+           * The next procedure runs if the current file is finished and we have
+           * to open a new file (or look for external data source
+           *=====================================================================*/
+          if(Local.nc_rec > Local.Maxnc_rec - 1)
+          {
+             if(Verbose) fprintf(stderr,"GetData(%d): Stop By EOF\n",ID);
+             /* Before open new file we have to check the LOCK status */
+             switch(IsTimesLocked(&Local))
+             {
+               case NOLOCK: break;
+               case LOCKED: DD_Var[ID]->LastFileStatus = TRYAGAIN;
+                            DD_Var[ID]->VILocked = Local.VILocked; /* Tell Original holder that it is locked */
+                            DD_Var[ID]->NewFile = 1;
+                            DD_Var[ID]->NewFileWasOpen = 1;
+                            return MOREDELAY; break;
+               case LOCKREMOVED: UpdateTimeInfo(&Local);
+                                 LocalOrigSync(&Local,DD_Var[ID]);
+                                 SetTime(&Local,Local.CDTime); /* Return to the original status */
+             }
+             switch(DD_Var[ID]->LastFileStatus = SetNewFile(&Local,1))
+             {
+                case OK:         // Everything is OK
+                  DD_Var[ID]->LastPacketFlag = MOREDATA;
+                  DD_Var[ID]->NewFile = 1;         // We have to reset all variables
+                  DD_Var[ID]->NewFileWasOpen = 1;
+		  if(Verbose) fprintf(stderr,"GetMultiData(ID=%d), Retun by EOF, MOREDATA, DD_Var[ID]->VarData = %p\n",ID,DD_Var[ID]->VarData);
+                  return MOREDATA;
+                case TRYAGAIN:   // just wait and try again
+                  if(Verbose) fprintf(stderr,"GetData(%d): Open New File return TRYAGAIN\n",ID);
+                  DD_Var[ID]->NewFile = 1;
+                  DD_Var[ID]->NewFileWasOpen = 1;
+                  DD_Var[ID]->LastPacketFlag = MOREDELAY;
+                  DD_Var[ID]->VILocked = Local.VILocked; /* Tell Original holder that it is locked */
+                  return  MOREDELAY;
+                case WAITEXTCALL:   // just wait and try again
+                  if(Verbose) fprintf(stderr,"GetData(%d): Open New File returned WAITEXTCALL\n",ID);
+                  DD_Var[ID]->VILocked = Local.VILocked; /* Tell Original holder that it is locked */
+                  DD_Var[ID]->NewFile = 1;
+                  DD_Var[ID]->NewFileWasOpen = 1;
+                  DD_Var[ID]->LastPacketFlag = MOREDELAY;
+                  return  MOREDELAY;
+                case CACHTOOREC:   // just wait and try again
+                  if(Verbose) fprintf(stderr,"GetData(%d): Open New File returned CACHTOOREC\n",ID);
+                  DD_Var[ID]->NewFile = 1;
+                  DD_Var[ID]->NewFileWasOpen = 1;
+                  DD_Var[ID]->LastPacketFlag = MOREDELAY;
+                  return  MOREDELAY;
+                case OUTOFTIME:   // Return data as the last packet (as well as it was finished by time
+                  if(Verbose) fprintf(stderr,"GetData(%d): New file is out of time\n",ID);
+                  SetOriginPointer(&Local, ID);
+                  DD_Var[ID]->LastPacketFlag = OK;
+                  DD_Var[ID]->NewFile = 1;
+                  return  OK;
+                  break;
+                default:              // Unrecoverable error in the database or out of time
+                  if(Verbose) fprintf(stderr,"GetData(%d): Unrecoverable error in the new file\n",ID);
+                  Local.nc_rec--;
+                  DD_Var[ID]->LastPacketFlag = OK;
+                  DD_Var[ID]->NewFile = 0;
+                  return  DD_Var[ID]->LastFileStatus;
+             }
+          } /* End of file finish processing */
+
+          if(DD_Var[ID]->VarData[0].VarNumber >= RecordNumber) /* Packet size exceeded */
+          {
+             DD_Var[ID]->LastPacketFlag = MOREDATA;
+             return  MOREDATA;
+          }
+       } /* End of check of status */
+   } while(1);
+
+   return OK;
+}
+/*-----------------------------------------------------------------*/
+
+/*#################################################################
+ *                      SET TIME
+ * Set time and try to open appropriate data file. If not try to
+ * call external archive
+ * Return:
+ * NOID - call with uncorrect VI holder
+ * OUTOFTIME - Requested time is out of General time limitation
+ * WAITEXTCALL - Server sent request to external archive
+ * TRYAGAIN - VI is blocked by call to external database
+ * NODATAATTIME - request time is inside NODATA time interval
+ * some return of SetNewFile(); see ...
+ *#################################################################*/
+
+int SetTime(DD_Var_t *DD_VarL, double VCTime)
+{
+  char Name[MAXSETLENGTH];  /* Name of data nc file */
+  char FullName[PATHLENGTH]; /* Full name of nc file */
+  char StartTime[TIMELENGTH];
+  char StopTime[TIMELENGTH];
+  static char StartName[] =  "StartTime";
+  static char StopName[] =   "StopTime";
+  static char TimeName[] = "Time";
+  int StartID,StopID,TimeID;
+  size_t Rmin,Rmax,RLeft,RRight;   /* Limits of record num */
+  double dt, TestTime,MinTime,MaxTime;
+  dd_tmstr_t *tt;
+  int More;                       /* InsideFlag - we are inside good time interval */
+                                  /* NoDataFlag - we in the time record marked "NODATA" */
+  char TimeIntName[MAXSETLENGTH]; /* File name associated with the given time interval */
+
+  static size_t start[2] = {0,0};
+  static size_t TimeCount[2] = {1,TIMELENGTH};
+  static size_t FileCount[2] = {1,MAXFILENAME};
+  static void *p;
+  static double CTime = 0.0;  /* Real working requested time */
+  int status;
+  int SearchStatus;           /* Status at the end of interval search */
+  int ExternalReqStatus;      /* Status at return of extenal call */
+
+/* Check the ID */
+/** sleep(40); **/
+
+  if(Verbose) fprintf(stderr,"SetTime(%f): Start\n",VCTime);
+  if(DD_VarL == NULL) return(NOID);
+
+/*===========================================================
+ * Set CTime if need
+ *===========================================================*/
+  if(VCTime > 0)
+  {
+    CTime = VCTime;
+    if(Verbose) fprintf(stderr,"SetTime(%f): CTime is from argument\n",CTime);
+  }
+  else if(Verbose) fprintf(stderr,"SetTime(%f): CTime is from saved value\n",CTime);
+
+/*----------------------------------------------------
+ * Check if is out of Global Time Limits
+ * If the requested time is out of Global Time Limit, the time is reset to the
+ * correct time interval
+ *----------------------------------------------------*/
+  if (CTime <= DD_VarL->GlobalStart) CTime = DD_VarL->GlobalStart +  QUANTOFFSET;
+  if (CTime > DD_VarL->GlobalStop) return OUTOFTIME;
+
+/*
+ * Check if this VI is not blocked by this or another server
+ */
+ switch(IsTimesLocked(DD_VarL))
+ {
+    case NOLOCK: break;
+    case LOCKED: return TRYAGAIN; break;
+    case LOCKREMOVED: UpdateTimeInfo(DD_VarL);
+ }
+
+/*
+ * If Ctime out of valid interval, we can try to get new data in external archive
+ */
+ if((DD_VarL->MinValidTime > CTime)||(DD_VarL->MaxValidTime < CTime))
+ {
+    if(Verbose) fprintf(stderr,"SetTime(): Start Time is out of current data interval\n");
+    if(DD_VarL->ExtCallAllowed)
+    {
+       switch(ExternalReqStatus = ExtDataRequest(DD_VarL,CTime))
+       {
+          case OK:       return WAITEXTCALL;         /* Request is gone */
+          case NOEXEC:   break;                      /* Call is impossible */
+          case NODATAATTIME:  return NODATAATTIME;   /* CTime in side NODATA interval */
+          case GAPISSMALL: break;                    /* Out of data, but gap is too small */
+          case OUTOFTIME: return OUTOFTIME;
+          default:       return OUTOFTIME;
+       }
+    } else return OUTOFTIME;
+ }
+
+/*
+ * Now we know that CTime SURE in between Tmin and TMax
+ * We start from the middle of the maximal valid interval
+ */
+  Rmin = (size_t)DD_VarL->RValidMin;
+  Rmax = (size_t)DD_VarL->RValidMax;
+  More = 1;
+  while(More)
+  {
+     DD_VarL->TimeRecNumber = (Rmin + Rmax)/2;
+     SearchRight(DD_VarL,Rmin,Rmax); /*--- Go right up to valid interval */
+     start[0] = DD_VarL->TimeRecNumber;
+     status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->StartID,start,TimeCount,StartTime);
+     TestTime = DD_Time2Double(StartTime);
+
+     if(CTime > TestTime) // StartTime(R) < CTime
+     {
+         status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->StopID,start,TimeCount,StopTime);
+         TestTime = DD_Time2Double(StopTime);
+         if(TestTime >= CTime) /* CTime is really inside this interval */
+         {
+            More = 0;
+            SearchStatus = INSIDE;
+         }
+        else                  /* CTime is at the right of the R */
+        {
+          RLeft = DD_VarL->TimeRecNumber;
+          DD_VarL->TimeRecNumber++;
+          SearchRight(DD_VarL,Rmin,Rmax);    /*R shift right up to the next valid interval */
+          start[0] = DD_VarL->TimeRecNumber;
+          status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->StopID,start,TimeCount,StopTime);
+          TestTime = DD_Time2Double(StopTime);
+          if(TestTime >= CTime)                 /* CTime is between Stop(R)-1 and Stop(R) */
+          {
+             More = 0;
+             DD_VarL->CurrRmin = (int)RLeft;
+             DD_VarL->CurrRmax = (int)DD_VarL->TimeRecNumber;
+             /*--- Test if it is inside interval ------*/
+             status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->StartID,start,TimeCount,StartTime);
+             TestTime = DD_Time2Double(StartTime);
+             if(TestTime < CTime) SearchStatus = INSIDE;
+             else SearchStatus = DATAATRIGHT;  /* Ctime is inbetween the valid intervals */
+          }
+          else                                 /* CTime is on the right from the Stop(R) */
+          {
+             Rmin = DD_VarL->TimeRecNumber;
+             More = 1;
+          }
+        }  /* else of  CTime is at the right of the R */
+     }
+     else /* StartTime(R) > CTime */
+     {
+        RRight = DD_VarL->TimeRecNumber;
+        DD_VarL->TimeRecNumber--;
+        SearchLeft(DD_VarL,Rmin,Rmax);    /*R shift left down to the next valid interval */
+        start[0] = DD_VarL->TimeRecNumber;
+        status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->StartID,start,TimeCount,StartTime);
+        TestTime = DD_Time2Double(StartTime);
+        if(CTime > TestTime) // CTime is inbetween Start(R) and Start(RRight)
+        {
+           More = 0;
+           DD_VarL->CurrRmax = (int)RRight;
+           DD_VarL->CurrRmin = (int)DD_VarL->TimeRecNumber;
+           /*--- Test if it is inside interval ------*/
+           status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->StopID,start,TimeCount,StopTime);
+           TestTime = DD_Time2Double(StopTime);
+           if(TestTime > CTime) SearchStatus = INSIDE;
+           else  /* Ctime is inbetween the valid intervals */
+           {
+             DD_VarL->TimeRecNumber++; /* Return to the right interval */
+             SearchStatus = DATAATRIGHT; /* Ctime is inbetween the valid intervals */
+           }
+        }
+        else /* CTime is to the left from Start(R) */
+        {
+           Rmax = DD_VarL->TimeRecNumber;
+           More =1;
+        }
+     } // else  StartTime(R) > CTime
+  } // while(More);
+/*------------------------------------------------------------------------------*/
+  if(Verbose) fprintf(stderr,"SetTime(): Search Status is %d\n",SearchStatus);
+
+/*-----------------------------------------------------------------------
+ * Now we check if we can and need to require new data in external archive
+ *-----------------------------------------------------------------------*/
+  if((SearchStatus != INSIDE)&&(DD_VarL->ExtCallAllowed))
+  {
+      switch(ExternalReqStatus = ExtDataRequest(DD_VarL,CTime))
+      {
+          case OK:       return WAITEXTCALL;         /* Request is gone */
+          case NOEXEC:   return NODATAATTIME;       /* Call is impossible */
+          case NODATAATTIME:
+            start[0] = DD_VarL->TimeRecNumber;
+            status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->StopID,start,TimeCount,StopTime);
+            CTime = DD_Time2Double(StopTime) + 0.001;
+            if(Verbose) fprintf(stderr,"SetTime(): There was NO Data intreval, CTime is scrolled to %f\n",CTime);
+            return CTIMEISSHIFTED;
+          case GAPISSMALL:    DD_VarL->TimeRecNumber = DD_VarL->CurrRmax; break;                    /* Out of data, but gap is too small */
+          case OUTOFTIME: return OUTOFTIME; break;
+          default:       return OUTOFTIME;
+      }
+  }
+
+/* Get the file Name and open file */
+  if(Verbose) fprintf(stderr,"SetTime(): File found: %d\n",DD_VarL->TimeRecNumber);
+  if((status = SetNewFile(DD_VarL,0)) < 0) return status;
+
+/*=====================================================================
+ * Fit the CTime inside data file
+ *=====================================================================*/
+/* Get MinTime and MaxTime */
+  status =  nc_inq_varid(DD_VarL->ncID,StartName, &StartID);
+  status =  nc_inq_varid(DD_VarL->ncID,StopName,  &StopID);
+  status =  nc_inq_varid(DD_VarL->ncID,TimeName,  &TimeID);
+
+  if (status != NC_NOERR)
+  {
+     if(Verbose) fprintf(stderr,"SetTime(): %s\n",nc_strerror(status));
+     return(DATAFILEERR);
+  }
+
+  start[0] = 0;
+
+
+  status = nc_get_vara_text(DD_VarL->ncID, StartID, start,&TimeCount[1],StartTime);
+  MinTime = DD_Time2Double(StartTime);
+  status = nc_get_vara_text(DD_VarL->ncID, StopID, start,&TimeCount[1],StopTime);
+  MaxTime = DD_Time2Double(StopTime);
+
+
+/* circle of finding of time */
+   More = 1;
+   Rmin = 0; Rmax = DD_VarL->Maxnc_rec - 1;
+
+   do
+   {
+      start[0] = (Rmin + Rmax)/2;
+      if(start[0] < Rmin) { DD_VarL->nc_rec = Rmin; More = 0;}
+      if(start[0] > Rmax) { DD_VarL->nc_rec = Rmax; More = 0;}
+      if(More > 0)
+      {
+         status = nc_get_vara_text(DD_VarL->ncID, TimeID,start,TimeCount,StartTime);
+         TestTime = DD_Time2Double(StartTime);
+
+         if(CTime >= TestTime)
+         {
+//            if(start[0] +1 >= DD_VarL->Maxnc_rec) return(OUTOFTIME);
+            if(start[0] +1 >= DD_VarL->Maxnc_rec) // We are in the gap between the last record
+                                                  // and the StopTime of this file
+            {
+               if(Verbose) fprintf(stderr,"SetTime(): The gap between the last record and stop time\n");
+               if((status = SetNewFile(DD_VarL,1)) < 0) return status;
+               DD_VarL->nc_rec = 0;
+               More = 0;
+               if(Verbose) fprintf(stderr,"SetTime(): Pointer is set as %s, TimesRecord %d FileRecord %d\n",StartTime,DD_VarL->TimeRecNumber, DD_VarL->nc_rec);
+               return 1;
+            }
+            start[0]++;
+            status = nc_get_vara_text(DD_VarL->ncID, TimeID,start,TimeCount,StartTime);
+            TestTime = DD_Time2Double(StartTime);
+            if(CTime <= TestTime)
+            {
+               DD_VarL->nc_rec = start[0];
+               More = 0;
+            }
+            else
+            {
+               MinTime = TestTime;
+               Rmin = start[0];
+               More = 1;
+            }
+         }
+         else
+         {
+             if(start[0] <= Rmin)   /*  25 Feb 1999  */
+             {
+                  DD_VarL->nc_rec = Rmin;
+                 More = 0;
+             }
+             else
+             {
+                 start[0]--;
+                 status = nc_get_vara_text(DD_VarL->ncID, TimeID,start,TimeCount,StartTime);
+                 TestTime = DD_Time2Double(StartTime);
+                 if(CTime >= TestTime)
+                 {
+                     DD_VarL->nc_rec = start[0] +1;
+                     More = 0;
+                 }
+                else
+                {
+                    MaxTime = TestTime;
+                    Rmax = start[0];
+                    More = 1;
+                 }
+              }
+            }
+         }
+         if(MaxTime - MinTime < 0.0001)
+         {
+         DD_VarL->nc_rec = start[0];
+         More = 0;
+         }
+     } while(More == 1);
+    if(Verbose) fprintf(stderr,"SetTime(): Pointer is set as %s, TimesRecord %d FileRecord %d\n",StartTime,DD_VarL->TimeRecNumber, DD_VarL->nc_rec);
+
+  return(1);
+}
+/*======================================================================================*/
+
+/*--------------------------------------------------------------------------------------*/
+/* If There was TimeUpdate in one VI, vi have to update all other values in another VI */
+/*--------------------------------------------------------------------------------------*/
+int LocalOrigSync(DD_Var_t *Local, DD_Var_t *Orig)
+{
+   Orig->tmID = Local->tmID;
+   Orig->NameID = Local->NameID;
+   Orig->StartID = Local->StartID;
+   Orig->StopID = Local->StopID;
+   Orig->RValidMin = Local->RValidMin;
+   Orig->RValidMax = Local->RValidMax;
+   Orig->MinValidTime = Local->MinValidTime;
+   Orig->MaxValidTime = Local->MaxValidTime;
+   Orig->CurrRmin = -1;
+   Orig->CurrRmax = -1;
+   Orig->VILocked = Local->VILocked;
+   return 1;
+}
+
+/*--------------------------------------------------------------------------------------*/
+/* Recovering of the original pointer                                                   */
+/*--------------------------------------------------------------------------------------*/
+int SetOriginPointer(DD_Var_t *LocalVI, int ID)
+{
+   if(DD_Var[ID]->NewFileWasOpen)
+   {
+      switch(IsTimesLocked(LocalVI))
+      {
+         case NOLOCK: break;
+         case LOCKED: DD_Var[ID]->LastFileStatus = TRYAGAIN;
+                     DD_Var[ID]->LastPacketFlag = MOREDELAY;
+                     DD_Var[ID]->VILocked = LocalVI->VILocked; /* Tell Original holder that it is locked */
+                     DD_Var[ID]->NewFile = 0;
+                     DD_Var[ID]->NewFileWasOpen = 1;
+                     return MOREDELAY; break;
+         case LOCKREMOVED: UpdateTimeInfo(LocalVI);
+                           LocalOrigSync(LocalVI,DD_Var[ID]);
+                           SetTime(DD_Var[ID],DD_Var[ID]->SDTime); /* Return to the original status */
+                           DD_Var[ID]->LastPacketFlag = OK;
+                           DD_Var[ID]->NewFileWasOpen = 0;
+                           DD_Var[ID]->NewFile = 0;
+                           DD_Var[ID]->LastFileStatus = OK; /* Total reset */
+                           return OK;
+      }
+      /* If VI is not locked, try to set new file */
+      switch(DD_Var[ID]->LastFileStatus = SetNewFile(DD_Var[ID],0))
+      {
+         case OK:         // Everything is OK
+         DD_Var[ID]->LastPacketFlag = OK;
+         DD_Var[ID]->NewFile = 0;         // We have to reset all variables
+         DD_Var[ID]->NewFileWasOpen = 0;
+         return OK;
+         case TRYAGAIN:   // just wait and try again
+         if(Verbose) fprintf(stderr,"GetData(%d): Reset to Origin return TRYAGAIN\n",ID);
+         DD_Var[ID]->NewFile = 0;
+         DD_Var[ID]->NewFileWasOpen = 1;
+         DD_Var[ID]->LastPacketFlag = MOREDELAY;
+         DD_Var[ID]->VILocked = LocalVI->VILocked; /* Tell Original holder that it is locked */
+         return  MOREDELAY;
+         case WAITEXTCALL:   // just wait and try again
+         if(Verbose) fprintf(stderr,"GetData(%d): Reset to Origin return WAITEXTCALL\n",ID);
+         DD_Var[ID]->VILocked = LocalVI->VILocked; /* Tell Original holder that it is locked */
+         DD_Var[ID]->NewFile = 0;
+         DD_Var[ID]->NewFileWasOpen = 1;
+         DD_Var[ID]->LastPacketFlag = MOREDELAY;
+         return  MOREDELAY;
+         case CACHTOOREC:   // just wait and try again
+         if(Verbose) fprintf(stderr,"GetData(%d):  Reset to Origin returnCACHTOOREC\n",ID);
+         DD_Var[ID]->NewFile = 0;
+         DD_Var[ID]->NewFileWasOpen = 1;
+         DD_Var[ID]->LastPacketFlag = MOREDELAY;
+         return  MOREDELAY;
+         case OUTOFTIME:       // An accident when we were trying to return to original file
+         default:              // Unrecoverable error in the database or out of time
+         if(Verbose) fprintf(stderr,"GetData(%d):  Reset to origin: Unrecovararable errorn (including OUT OF TIME)\n",ID);
+         DD_Var[ID]->LastPacketFlag = OK;
+         DD_Var[ID]->NewFile = 0;
+         DD_Var[ID]->NewFileWasOpen = 1;
+         return  DD_Var[ID]->LastFileStatus;
+      }
+   }
+   /* If we did not transfer to new file, we can just reset all */
+   DD_Var[ID]->VILocked = LocalVI->VILocked; /* Tell Original the locking state */
+   DD_Var[ID]->LastPacketFlag = OK;
+   DD_Var[ID]->NewFileWasOpen = 0;
+   DD_Var[ID]->NewFile = 0;
+   DD_Var[ID]->LastFileStatus = OK;
+
+}
+/*######################################################################################*/
diff --git a/src/SERVER/DD_Server.c b/src/SERVER/DD_Server.c
new file mode 100644
index 0000000..5da9054
--- /dev/null
+++ b/src/SERVER/DD_Server.c
@@ -0,0 +1,701 @@
+/*==============================================================
+ *                  DD SYSTEM
+ *                 DD_Server.c
+ *                   V. 6.0
+ *
+ * Description:
+ *
+ * See ../DOC/TECHDOC/DDServFunct.html for complete information
+ *
+ * List of revisions:
+ *     September, 1995     - Fedorov, First realisation:  V 1.0
+ *     Oct 1997            - Fedorov, Acces security    V 3.0
+ *     Sep 4, 2002         - Fedorov, Some changes   V 3.5
+ *     Oct 28, 2002        - Fedorov, Communication ideology is changed V 4.1
+ *     May 1, 2003         - Fedorov, The buffered send is added V.4.2
+ *     Jul 16, 2004        - Fedorov, Check the buffer state V.4.3
+ *     March 15, 2007      - Fedorov, V.5.0 Bug in cach, Fedorov
+ *     March 24, 2007      - Fedorov, V.5.2 Bug in free memory
+ *     Jun 17, 2007        - Fedorov, V.5.5 Create new VI and Fill data via external calls
+ *     Jun 20, 2007        - Fedorov, V.5.51 Adjust to createVI**.php
+ *     Sep 23, 2007        - Fedorov, V.5.6 SetTime has another interface
+ *     Sep 24, 2007        - Fedorov, V.5.6 New Get_Data processing
+ *     May 21, 2008        - Fedorov, V.5.7 Try SetTime several times
+ *     Apr 12, 2009        - Fedorov, V.5.8 Correct procession of OUTOFTIME
+ *     Nov 18, 2012        - Fedorov, V.6.0 New call to get the variable info
+ *===============================================================*/
+#include "DD_Access.h"
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "DD.h"
+#include "DD_comm.h"
+
+/*-------------- Global definitions ------------------------*/
+extern int errno;
+int Verbose;                 /* Verbose mode (variable for all subroutines)*/
+static int err;              /* Common error for this file */
+static fd_set rfds;          // For function select to look
+static struct timeval tv;    // if send can be done
+
+
+/*--------------------- SET_LISTENER ------------------------*/
+/* function returns socket ID  of listener or -1 as ERROR   */
+
+int SetListener()
+{
+/*-------- Variables for resource file -----------------*/
+   char rname[PATHLENGTH];      /* name of res file */
+   char line[PATHLENGTH];
+   char *path;
+   FILE *resfile;       /* resource file */
+
+/*---------- Variables for network ---------------------*/
+   static struct hostent *Host;        /* name & internet (32b) address for
+                                          remote hosts (see netdb.h) */
+   static char RemSerName[PATHLENGTH]; /* name of remote server */
+
+   static struct sockaddr_in IntAFAddr; /* structure of internet address of type AF_INET
+                                       see <netinet/in.h>
+                                       to get name of socket we should
+                                       to convert pointer to this structure
+                                       to pointer to "srtruct sockaddr" where
+                                       all fields are  "char array". */
+
+   int SocketID;               /* socket ID (use as well file ID) */
+
+   int cc,i,j;
+   int arg = 0;
+
+/*
+ *---------- Getting socket and its address ---------------------
+*/
+/*---------------- HOST and PORT ------------------------------*/
+   if((path = getenv("DDPATH")) == NULL)
+   {
+      (void *)strcpy(rname,"DD.res");
+   }
+   else
+   {
+      (void *)strcpy(rname,path);
+      (void *)strcpy(rname + strlen(rname), "/DD.res");
+   }
+
+   if((resfile = fopen(rname,"r")) == NULL)
+   {
+      fprintf(stderr,"No resource file, sorry\n");
+      exit(1);
+   }
+
+   fgets(RemSerName, PATHLENGTH, resfile);
+   RemSerName[strlen(RemSerName)-1] = '\0';
+   fgets(line, PATHLENGTH, resfile);
+   sscanf(line,"%hu",&(IntAFAddr.sin_port));
+   IntAFAddr.sin_port = htons(IntAFAddr.sin_port); /* Conversion of the port number to
+                                                      universal network form */
+   fclose(resfile);
+/*---------------- END of FILE READING --------------------------*/
+
+/*
+ *------- Trying to open socket with this address and name ---------
+ */
+   if((Host = gethostbyname(RemSerName)) == NULL)  /* Get address and other information by
+                                                     host name, see netdb.h  */
+   {
+      fprintf(stderr,"Server %s not found\n",RemSerName);
+      return(-1);
+   }
+
+   if((SocketID = socket(PF_INET,SOCK_STREAM,PROTOCOL)) < 0)
+   {
+      perror("Socket:"); return(-1);
+   }
+/*
+ * Filling full internet address for socket "name"
+ * this address will be used to bind  point
+ */
+   IntAFAddr.sin_family = AF_INET;
+   memcpy(&IntAFAddr.sin_addr.s_addr,Host->h_addr_list[0],Host->h_length);
+/*
+   IntAFAddr.sin_family = Host->h_addrtype;
+   IntAFAddr.sin_addr.s_addr = INADDR_ANY;
+*/
+/* Naming of socket */
+   if(bind(SocketID,(struct sockaddr *)&IntAFAddr,sizeof(IntAFAddr))<0)
+   {
+      perror("Bind:"); return(-1);
+   }
+
+   /* Registration of socket as passive for external requests */
+   if(listen(SocketID,SOMAXCONN) < 0)
+   {
+      perror("Listen:"); return(-1);
+   }
+   fprintf(stderr, "DD_SERVER was connected...!\n");
+
+   /* Watch sochet before each send. */
+   FD_ZERO(&rfds);
+   FD_SET(SocketID, &rfds);
+
+
+
+   return(SocketID);
+}
+/*---------------- End of SET_LISTENER ---------------------*/
+
+/*----------------- SendToNet ------------------------------*/
+/*
+ *  Enhanced send function.
+ *  It buffers the packed end trying to send it by several attampts
+ */
+int SendToNet(int SocketID, char *buff, int length)
+{
+   int cc, pointer;
+   int retval;
+
+   pointer = 0;
+   while(pointer < length)
+   {
+      /* Wait up to 30 seconds. */
+//      tv.tv_sec = 30;
+//      tv.tv_usec = 0;
+
+//      retval = select(SocketID+1,NULL, &rfds, NULL, &tv);
+//      if(retval < 0) return -1;
+      if((cc = send(SocketID,buff+pointer,length - pointer,0)) < 0)
+      {
+        if(Verbose) perror("Send Data:");
+        return -1;
+      }
+/*
+      fprintf(stderr,"send: p = %d, l = %d, cc = %d\n",pointer, length,cc);
+      fprintf(stderr,"buff: %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n",
+                            buff[0],buff[1],buff[2],buff[3],buff[4],buff[5],buff[6],
+                            buff[7],buff[8],buff[9],buff[10],buff[11]);
+*/
+      pointer += cc;
+   }
+   return 0;
+}
+
+/*------------------ PUTHEADER -----------------------------*
+/*
+ * Encode end send Reply Header
+ */
+int PutHeader(int a1, int a2, int a3,int SocketID)
+{
+   int cc;
+   XDR xdrs;
+   char buf[REPLYLENGTH];
+
+   xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_ENCODE);
+   xdr_int(&xdrs,&a1);
+   xdr_int(&xdrs,&a2);
+   xdr_int(&xdrs,&a3);
+
+   xdr_destroy(&xdrs);
+
+/*  if((cc = send(SocketID,buf,REPLYLENGTH,0)) < 0) */
+  if((cc =  SendToNet(SocketID,buf, REPLYLENGTH)) < 0)
+  {
+       if(Verbose) perror("PutHeader:");
+       return(REPLYRECERR);
+  }
+   return(0);
+}
+/*------------------------end of PutHeader ------------------------*/
+
+/*===================== Send Constant Packet ====================)*/
+int SendConstantPacket(DD_Var_t *Data,int SocketID)
+{
+   caddr_t buff;
+   XDR xdrs;
+   int PacketSize,i,cc;
+   u_int MaxNumber,Number;
+   int error = OK;
+
+   MaxNumber = 1;
+   for(i = 0;i < Data->AttrData.DimNumber; i++)
+      MaxNumber = MaxNumber * Data->AttrData.Dimensions[i];
+   PacketSize = xdrlen[DD_INT] +                            /* Number of elements in Dimensions array */
+                xdrlen[DD_INT] * Data->AttrData.DimNumber + /* Dimensions array */
+                xdrlen[DD_INT] +                            /* Number of elements in data array */
+                MaxNumber * xdrlen[Data->AttrData.type];    /* Data Array */
+
+/* Sending Header */
+   if((error = PutHeader(Data->AttrData.type,
+                         Data->AttrData.DimNumber,
+                         PacketSize,SocketID)) < 0) return error;
+
+   buff =(caddr_t)malloc(PacketSize);
+   xdrmem_create(&xdrs, buff, (u_int)PacketSize, XDR_ENCODE);
+
+/* Packing Dimensions */
+   if(Data->AttrData.DimNumber > 0)
+   {
+      Number = (u_int)Data->AttrData.DimNumber;
+      xdr_array(&xdrs, (caddr_t *)&(Data->AttrData.Dimensions),
+      &Number,
+      (u_int)Data->AttrData.DimNumber,
+      unixlen[DD_INT],
+      (xdrproc_t)xdr_int);
+   }
+
+/* Packing Variables */
+   xdr_array(&xdrs,(caddr_t *)&(Data->AttrData.Variables[0]),
+                      &MaxNumber,
+                      MaxNumber,
+                      unixlen[Data->AttrData.type],
+                      (xdrproc_t)ConvFunc[Data->AttrData.type]);
+
+/* Sending Packet */
+/*   if((cc = send(SocketID,buff,PacketSize,0)) < 0)*/
+   if((cc =  SendToNet(SocketID,buff, PacketSize)) < 0)
+   {
+      if(Verbose) perror("Send Constant Packet: ");
+      error = REPLYRECERR;
+   }
+   xdr_destroy(&xdrs);
+   free(buff);
+   return error;
+}
+/*------------------- End Send Constant Packet -------------------------------*/
+
+/*===================== Send Data Packet ====================)*/
+int SendDataPacket(DD_Var_t *Data, int SocketID, int LastFlag)
+{
+   caddr_t buff;
+   XDR xdrs;
+   int PacketSize,i,cc,il;
+   u_int MaxNumber,Number;
+   int error = OK;
+
+   for(il = 0; il < Data->ParamSize; il++)
+   {
+      MaxNumber = 1;
+      for(i = 0;i < Data->VarData[il].DimNumber; i++)
+	 MaxNumber = MaxNumber * Data->VarData[il].Dimensions[i];
+
+      PacketSize = xdrlen[DD_INT] +                                                   /* Flag */
+		  xdrlen[DD_INT] +                                                    /* arrays  number */
+		  xdrlen[DD_INT] +                                                    /* Sise of dimensions array */
+		  xdrlen[DD_INT] *(Data->VarData[il].DimNumber+1) +                   /* dimensions array */
+		  MaxNumber*xdrlen[Data->VarData[il].type]*Data->VarData[il].VarNumber + /* set if data arrays */
+		  xdrlen[DD_INT] * Data->VarData[il].VarNumber;                      /* data arrays sizes */
+
+      /* Sending header */
+      if((error = PutHeader(Data->VarData[il].type,
+			   Data->VarData[il].DimNumber+1,
+			   PacketSize,SocketID)) < 0) return error;
+
+      buff =(caddr_t)malloc(PacketSize);
+      xdrmem_create(&xdrs, buff, (u_int)PacketSize, XDR_ENCODE);
+
+      /* Packing flag and Variables number */
+      xdr_int(&xdrs, &LastFlag);
+      xdr_int(&xdrs, &Data->VarData[il].VarNumber);
+
+      /* Packing dimensions */
+      if(Data->VarData[il].DimNumber > 0)
+      {
+	 Number = (u_int)Data->VarData[il].DimNumber;
+	 xdr_array(&xdrs,
+	 (caddr_t*)(&Data->VarData[il].Dimensions),
+	 &Number,
+	 (u_int )Data->VarData[il].DimNumber,
+	 unixlen[DD_INT],
+	 (xdrproc_t)xdr_int);
+      }
+
+      /*Packing Variables */
+      for(i = 0; i < Data->VarData[il].VarNumber; i++)
+      {
+	 Number = MaxNumber;
+	 xdr_array(&xdrs,
+		  (caddr_t *)(&Data->VarData[il].Variables[i]),
+		  &Number,
+		  MaxNumber,
+		  unixlen[Data->VarData[il].type],
+		  (xdrproc_t)ConvFunc[Data->VarData[il].type]);
+      }
+
+      /* Sending Data Packet */
+      if((cc =  SendToNet(SocketID,buff, PacketSize)) < 0)
+      {
+	 if(Verbose) perror("SendDataPacket(): ");
+	 error = REPLYRECERR;
+      }
+      xdr_destroy(&xdrs);
+      free(buff);
+      if(Verbose) fprintf(stderr,"SendDataPacket()[%d] succesful\n",il);
+   } // FOR il
+   return error;
+}
+/*----------------------- End Send Data Packet -------------*/
+
+/*--------------------- SERV -------------------------------*/
+/*
+ * Read requests from socket, call appropriate function and
+ * return packets with information
+ * Start of this subroutine is the start of new communication session
+ */
+
+void Serv(int SocketID)
+{
+   int cc;
+   int i,nlen;
+   char *bbt,  GetTime[20];int bbtt[100],j, NoAccessToWork = 0,DD_id;
+   char Acc_Int[20]; double TimeInt,TimeStart,TimeStop;
+   int ReqType;
+   static char *ReqName = NULL;
+   static char *ReqTime = NULL;
+   static char *ReqHost = NULL;
+   static char *ReqTicket = NULL;
+   static char *ReqLogin = NULL;
+   static char *STReqLogin = NULL;
+
+   /*------- Variables to create new VI ---------------*/
+   static char *NewVIName = NULL;    /* Full name of VI (data set to generate )*/
+   static char *RemSetID =  NULL;    /* ID of remote Data Set */
+   static char *RemBaseName = NULL;  /* Base Name of remote WEB service */
+   static char Command[MAXCOMMANDL];  /*Memory for command in system()
+   /*--------------------------------------------------*/
+
+   /*---------------------------------------------------
+    * Variables need for the multy variavles
+    * Data Get
+    *---------------------------------------------------*/
+   int PacketSize;                 // The size of the packet to get after the header packet
+   static int VarSize=0;           // The number of variables to get
+   static char **VarNames = NULL;  // Pointer to the C strings with the variable names
+   char *VarBuffer = NULL;
+   int BackFlag;                   // Variable for multi variable call
+   int il;
+   /*---------------------------------------------------*/
+
+   char *STReqHost = NULL;
+   int STid;
+   char *ReqBuf= NULL;
+   XDR xdrs;
+   int id=-1,lenall;
+   int op;
+   int errTick,serr;
+   DD_Var_t *Data;
+   int RemainID =0;    /* Number of remained ID in use */
+   static int TicketID = NOPERMISSION;
+   static int uid, FileAccID;
+   int GoOut = 0; /* The flag of finishing of session */
+   int LastFlag;  /* The flag of the end of data transmission */
+
+/* WORKING */
+   if(ReqName == NULL) ReqName = malloc(MAXSETLENGTH);
+   if(ReqTime == NULL) ReqTime = malloc(TIMELENGTH);
+   if(ReqBuf == NULL) ReqBuf = malloc(REQUESTLENGTH);
+   if(ReqHost == NULL) ReqHost = malloc(MAXHOSTLENGTH);
+   if(ReqTicket == NULL) ReqTicket = malloc(TICKETLENGTH);
+   if(ReqLogin == NULL) ReqLogin = malloc(USRLENGTH);
+   if(STReqLogin == NULL) STReqLogin = malloc(USRLENGTH);
+   if(STReqHost == NULL) STReqHost = malloc(MAXHOSTLENGTH);
+ /*==============================================*/
+
+/*------------------------- General Data Array Preparation ---------------------------*/
+
+  DD_Var  =  (DD_Var_t **)malloc(MaxIDNumber * sizeof(DD_Var_t *));
+  for(i=0;i<MaxIDNumber;i++) DD_Var[i] = NULL;
+
+/*-----------------------Open Access Virtual instrument ----------------------------------*/
+/**
+     sleep(60);
+**/
+     FileAccID = OpenInstr(ACCINSTR);
+     if(FileAccID < 0)
+     {
+       err = FileAccID;
+       fprintf(stderr,"Error while open %s VI\n",ACCINSTR);
+       goto endend;
+     }
+
+/*------------------------- Read Requests ---------------------------------------*/
+ do
+   {
+      /* Get request from client */
+      while((cc = recv(SocketID,ReqBuf,REQUESTLENGTH,0)) < 0);
+
+      err = 0;
+
+/* Decode Request */
+      xdrmem_create(&xdrs, ReqBuf, REQUESTLENGTH, XDR_DECODE);
+      xdr_int(&xdrs,&ReqType);
+
+      switch (ReqType)
+      {
+          case OPENINSREQ:
+               xdr_string(&xdrs,&ReqName,MAXSETLENGTH);
+
+               xdrmem_create(&xdrs, ReqBuf,REQUESTLENGTH , XDR_FREE);
+               while((cc = recv(SocketID,ReqBuf,REQUESTLENGTH,0)) < 0); /* Receive identification packet */
+               xdrmem_create(&xdrs, ReqBuf,REQUESTLENGTH, XDR_DECODE);
+               xdr_int(&xdrs,&uid);
+               xdr_string(&xdrs,&ReqHost,MAXHOSTLENGTH);
+               xdr_string(&xdrs,&ReqLogin,USRLENGTH);
+               if(Verbose)printf("Serv():OPENINSREQ: Client Pasport: ID = %d, Host <%s>\n",uid,ReqHost);
+
+               break;
+
+          case CLOSEINSREQ :
+               xdr_int(&xdrs,&id);
+               break;
+
+          case TIMESETREQ:
+               xdr_int(&xdrs,&id);
+               xdr_string(&xdrs,&ReqTime,TIMELENGTH);
+               break;
+
+          case DATAINFOREQ:
+               xdr_int(&xdrs,&id);
+               xdr_string(&xdrs,&ReqName,MAXVARLENGTH);
+               break;
+
+          /*--------------------------------------------
+	   * This request needs to receive the
+	   * additinal information from the client
+	   *------------------------------------------*/
+          case DATAGETREQ:
+	       /** sleep(60); **/
+	       /*----------------------------------------
+	        * Clear the list of variables
+		*---------------------------------------*/
+	       if(VarNames != NULL)
+	       {
+		  for(il=0;il < VarSize; il++) free(VarNames[il]);
+		  free(VarNames);
+		  VarNames = NULL;
+		  VarSize = 0;
+	       }
+	       /*-----------------------------------------
+	        * Decode the heading packet
+		*---------------------------------------*/
+               xdr_int(&xdrs,&id);
+               xdr_string(&xdrs,&ReqTime,TIMELENGTH);
+	       xdr_int(&xdrs,&PacketSize);
+	       xdr_destroy(&xdrs);
+	       /*-----------------------------------------
+	        * Receive and Decode the variable packet
+		*---------------------------------------*/
+	       if(VarBuffer != NULL) free(VarBuffer);
+	       VarBuffer = (char *)malloc(sizeof(char)*PacketSize);
+	       while((cc = recv(SocketID,VarBuffer,PacketSize,0)) < 0);
+	       xdrmem_create(&xdrs, VarBuffer,PacketSize, XDR_DECODE);
+	       xdr_int(&xdrs,&VarSize);
+	       VarNames = (char **)malloc(sizeof(char *) * VarSize);
+	       for(il=0;il < VarSize; il++)
+	       {
+	          VarNames[il] = (char *)malloc(sizeof(char) * MAXVARLENGTH);
+		  xdr_string(&xdrs,&(VarNames[il]),MAXVARLENGTH);
+		  if(Verbose) fprintf(stderr,"Serv():DATAGETREQ: Variable[%d] %s\n",il,VarNames[il]);
+	       }
+	       xdr_int(&xdrs,&BackFlag);
+               break;
+
+         case ADDVIREQ:
+              xdr_string(&xdrs,&NewVIName,MAXSETLENGTH);
+              xdr_string(&xdrs,&RemSetID,MAXVARLENGTH);
+              xdr_string(&xdrs,&RemBaseName,MAXVARLENGTH);
+              break;
+
+          case GETTICKETREQ:
+               xdrmem_create(&xdrs, ReqBuf,REQUESTLENGTH , XDR_FREE);
+               while((cc = recv(SocketID,ReqBuf,REQUESTLENGTH,0)) < 0);
+               xdrmem_create(&xdrs, ReqBuf, REQUESTLENGTH, XDR_DECODE);
+
+               xdr_int(&xdrs,&uid);
+               xdr_string(&xdrs,&ReqLogin,USRLENGTH);
+               xdr_string(&xdrs,&ReqTicket,TICKETLENGTH);
+               xdr_string(&xdrs,&ReqHost,MAXHOSTLENGTH);
+
+               break;
+
+
+          case SHOWTICKETREQ:
+               xdr_int(&xdrs,&STid);
+               xdr_string(&xdrs,&STReqHost,MAXHOSTLENGTH);
+               xdr_string(&xdrs,&STReqLogin,USRLENGTH);
+               break;
+          default: err = REQSENDERR;
+       }                               /* switch REQTYPE */
+       xdr_destroy(&xdrs);
+
+      /*------------------------------------------------
+       * Call data functions and response generation
+       *----------------------------------------------*/
+
+         switch(ReqType)
+         {
+            case OPENINSREQ:
+                 if(Verbose) fprintf(stderr,"Serv():OPENINSREQ:ShowTicket; Host %s\n",ReqHost);
+                 err = ShowTicket(uid,ReqHost,ReqLogin);
+                 if(err >= 0)
+                 {
+                   id = OpenInstr(ReqName);
+                   err = id;
+                   if(id >= 0) strcpy(DD_Var[id]->InstrName,ReqName);
+                   err = PutHeader(id,0,0,SocketID); /* return error if something is wrong */
+                 }
+                 else  PutHeader(err,0,0,SocketID);
+                 break;
+            case CLOSEINSREQ:
+                 if(id < 0){err = NOID;PutHeader(err,0,0,SocketID);}
+                 if(Verbose) fprintf(stderr,"Serv():CLOSEINSREQ: ID = %d\n",id);
+                 RemainID = CloseID(id);
+                 if(RemainID < 1)
+                 {
+                    err = NOID;
+                    PutHeader(err,0,0,SocketID);
+                 }
+                 else
+                 {
+                    err = PutHeader(RemainID-1,0,0,SocketID);
+                    if(RemainID == 1) GoOut = 1;
+                 }
+                 break;
+            case TIMESETREQ:
+                 if(id < 0) err = NOID;
+                 if(err >= 0) err = SetTime(DD_Var[id],DD_Time2Double(ReqTime));
+                  if(err == CTIMEISSHIFTED) err = SetTime(DD_Var[id],-1.0);
+                 if(err >= 0) PutHeader(0,0,0,SocketID);
+                 else PutHeader(err,0,0,SocketID);
+                 break;
+
+            case DATAINFOREQ:
+                 if(id < 0) err = NOID;
+                 else err = GetAttribute(id,ReqName);
+                 if(err >= 0) err = SendConstantPacket(DD_Var[id],SocketID);
+                 else PutHeader(err,0,0,SocketID);
+                 break;
+
+            case DATAGETREQ:
+                 if(id < 0) err = NOID;
+                 /*------ Call data until LastPacket Flag (OK) returns --------*/
+                 else do
+                 {
+                      err = GetMultiData(id,VarSize,VarNames,ReqTime,BackFlag);
+                      if(err >= 0)
+                      {
+			serr = SendDataPacket(DD_Var[id],SocketID,DD_Var[id]->LastPacketFlag); /* OK, MOREDATA, MOREDELAY */
+			if(Verbose) fprintf(stderr, "Server:DATAGETRQ (ID=%d):GetMultiData->SentPackets\n", id);
+                      }
+                 }
+                 while((err >= 0) && (DD_Var[id]->LastPacketFlag == MOREDATA));
+                 if(err < 0) PutHeader(err,0,0,SocketID);
+                 break;
+
+             case ADDVIREQ:
+                 sprintf(Command,ADDDATASETCALL,getenv("DDBASEBIN"),RemBaseName,RemSetID,NewVIName);
+                 if(Verbose) fprintf(stderr, "Serv:ADDVIREQ: Command = %s\n", Command);
+                 err = system(Command);
+                 switch(err)
+                 {
+                   case 0: PutHeader(OK,0,0,SocketID); break;
+                   case NOPHP:    PutHeader(NOEXEC,0,0,SocketID); break;
+                   case NOSCRIPT: PutHeader(NOEXEC,0,0,SocketID); break;
+                   default:       PutHeader(NOEXEC,0,0,SocketID);
+                 }
+                 GoOut = 1;
+                 break;
+
+             case GETTICKETREQ:
+                 errTick = CheckTicket(ReqLogin, ReqTicket);
+                 Put2Log(uid,ReqHost,ReqLogin,errTick); /* Log file */
+                 if(errTick >= 0) TicketID = GetTicket(uid,ReqHost,errTick);
+                 if(Verbose) printf("GETTICKETREQ: uid= %d ReqHost = %s ErrTick = %d\n",uid,ReqHost ,errTick);
+                 PutHeader(TicketID,0,0,SocketID);
+                 GoOut = 1;
+                 break;
+
+             case SHOWTICKETREQ:
+                 if(Verbose) printf("SHOWTICKETREQ; ShowTicket; Host %s\n",STReqHost);
+                 err = ShowTicket(STid,STReqHost,STReqLogin);
+                 PutHeader(err,0,0,SocketID);
+                 GoOut = 1;
+                 break;
+        }  /* swithch Reqtype */
+
+   } while(GoOut == 0);/* end while(GoOut) */
+   if(Verbose) fprintf(stderr,"DD_SERVER:Exit child process, communication closed\n");
+
+
+endend:
+   if(Verbose)
+      fprintf(stderr, "Serv():EndEnd:Close session %d at %s by error %d\n",SocketID,Double2DD_Time((double)time(NULL)),err);
+   RemainID = CloseID(FileAccID);
+   if(Verbose) fprintf(stderr, "Serv():EndEnd:Last Open VI (Access) is closed\n");
+
+   if(RemainID < 0) err = NOID;
+
+   free(ReqName);
+   free(ReqTime);
+   free(ReqBuf);
+   free(ReqHost);
+   free(ReqTicket);
+   free(ReqLogin);
+   free(STReqLogin);
+   free(STReqHost);
+   free(DD_Var);
+
+   shutdown(SocketID,2);
+   close(SocketID);
+   exit(0);
+}
+/*---------------------end of SERV ------------------------*/
+
+/*-----------------------MAIN ------------------------------*/
+int main(int argc, char **argv)
+{
+   int ListenerID;
+   int NewSocketID;
+   struct sockaddr NewSocketAddr;
+   socklen_t NewSocketLen;
+   int stat_loc;
+
+   if(argc < 2) Verbose = 0;
+   else if(((argv[1])[1] == 'v') || ((argv[1])[1] == 'V')) Verbose = 1;
+   else Verbose = 0;
+
+   if((ListenerID = SetListener()) < 0)
+   {
+     fprintf(stderr,"DD_server: I cant set Listener Socket\n");
+     exit(1);
+   }
+
+/*------- Define the maximum number of open Virtual Instruments ----------------*/
+   MaxIDNumber =  (size_t)(sysconf(_SC_OPEN_MAX) / 3L - 5L);
+
+/*-------- Endless listen ----------------------------------------------*/
+   while(1)
+   {
+      NewSocketLen = sizeof(NewSocketAddr);
+      if((NewSocketID = accept(ListenerID,&NewSocketAddr,&NewSocketLen)) < 0)
+      {
+         //   printf(" %d %d %d \n", ListenerID, (int)NewSocketLen, NewSocketID);
+            if(Verbose) perror("DD_Server: Accept: ");
+      }
+      else
+      {
+          if(Verbose) fprintf(stderr, "There is connection from ...\n");
+          if(fork() == 0)  /* I am child */
+          {
+             if(fork() == 0)
+             {
+                  Serv(NewSocketID); /*Real working */
+             }
+             else exit(0);
+          }
+          else wait(&stat_loc);  /* wait of finishing of child */
+          close(NewSocketID);
+     }
+   }
+   /* Unreachable point */
+
+   close(ListenerID);
+   return 0;
+}
diff --git a/src/SERVER/ExtDataRequest.c b/src/SERVER/ExtDataRequest.c
new file mode 100644
index 0000000..3f6ab4c
--- /dev/null
+++ b/src/SERVER/ExtDataRequest.c
@@ -0,0 +1,303 @@
+/**
+ *  @file ExtDataRequest.c
+ *  @version $Id: ExtDataRequest.c,v 1.6 2009/07/07 12:24:23 budnik Exp $
+ *=====================================================================
+ *                    ExtDataRequest.c
+ *                       V.2.6
+ *  Functions set to call external script to get more data for 
+ *  current database.
+ *
+ *  Versions:
+ * Aug 3, 2007, V.1.0,  Fedorov
+ * Sep 20, 2007, V.2.0, Fedorov, New solution for IsTimesLocked()
+ * Sep 20, 2007, V.2.1, Fedorov, New solution for IsTimesLocked()
+ * Sep 25, 2007, V.2.2, Fedorov, Variable GAP
+ * May 21, 2008, V.2.3, Fedorov, skip no data file
+ * May 22, 2008, V.2.4, Fedorov, Measuring of elapsed time of Lock
+ * Apr 11, 2009, V.2.5, Fedorov, Do not call new file if the data out of general limits
+ * Jul 07, 2009, V.2.6, Budnik, Special external call if there is empty times.nc; 
+ *                            if(DStop <= DD_Var->GlobalStart) 
+ *                            if(DStart >= DD_Var->GlobalStop)       
+ *=====================================================================*/
+
+#include <unistd.h>
+#include <string.h>
+#include "DD.h"
+#include "DD_comm.h"
+
+extern int Verbose;
+
+/*=====================================================================
+ *               Double2ISOTime()
+ * Covert double time to ISO time
+ * return pointer to statis string inside function
+ *=====================================================================*/
+char *Double2ISOTime(double CTime)
+{
+  static char ISO[25];
+  unsigned *UT;
+  
+  UT = Double2UT(CTime);
+  sprintf(ISO,ISOTIMEP,UT[0],UT[1],UT[2],UT[3],UT[4],UT[5],UT[6]);
+  return (char *)ISO;
+}
+
+/*=====================================================================
+ *               DoRequest
+ * Read request.
+ * return OK, or NOEXEC
+ *=====================================================================*/
+ int DoRequest(DD_Var_t *DD_Var, double Start, double Stop)
+ {
+    static char Command[MAXCOMMANDL];  /*Memory for command in system() */
+    static char StartISO[25],StopISO[25];
+    int err;
+    struct timeval tv;
+    struct timezone tz;
+    
+    /*======================================================
+     * Lock the VI 
+     * Set 1 means that VI is locked by THIS DD_Var and external program did not set LockFile yet
+     *=====================================================*/
+    DD_Var->VILocked = 1;
+    gettimeofday(&tv,&tz);
+    memcpy(&(DD_Var->LockStartTime),&(tv.tv_sec),sizeof(time_t));
+    
+    strcpy(StartISO,Double2ISOTime(Start));
+    strcpy(StopISO,Double2ISOTime(Stop));
+    sprintf(Command,GETNEWDATACALL,getenv("DDBASEBIN"),DD_Var->BaseName,DD_Var->RemSetID,DD_Var->path,StartISO,StopISO);
+    if(Verbose) fprintf(stderr, "DoRequest(): Command = %s\n", Command);
+    err = system(Command);
+    
+    switch(err)
+    {
+       case 0: return OK; 
+       case NOPHP:    return NOEXEC;
+       case NOSCRIPT: return NOEXEC;
+       default:       return NOEXEC;
+    }
+
+    return NOEXEC;
+ }
+
+/*======================================================================
+ *                ExtDataRequest
+ *  Return folowing values:
+ *  OK - request is accepted SERVER has to wait when LOCK file is gone
+ *  NOEXEC - error in external executable
+ *  NODATAATTIME - time corresponds to the NODATA interval
+ *  GAPISSMALL - Time is inside too small gap
+ *======================================================================*/
+ int ExtDataRequest(DD_Var_t *DD_Var, double CTime)
+ {
+    size_t Rmin,Rmax;
+    static size_t start[2] = {0,0};
+    static size_t TimeCount[2] = {1,TIMELENGTH};
+    char StartTime[TIMELENGTH];
+    char StopTime[TIMELENGTH];
+    double DStart, DStop;
+    int SearchResult, More, status;
+    
+    if(Verbose) fprintf(stderr,"ExtDataRequest: Rmin,Rmax = %d %d, CTime = %f\n",DD_Var->CurrRmin,DD_Var->CurrRmax, CTime);
+    
+    /*
+     * Search if there is an emtpy space ...
+     */
+    if(DD_Var->CurrRmin >= 0) Rmin = (size_t)DD_Var->CurrRmin; else Rmin = 0;
+    if(DD_Var->CurrRmax >= 0) Rmax = (size_t)DD_Var->CurrRmax; else Rmax = DD_Var->MaxTimeRecNum - 1;     
+   
+   if(Verbose) fprintf(stderr,"ExtDataRequest:  CTime = %s\n",Double2DD_Time(CTime));
+    /*
+     * No yet Records in times.nc
+    */
+    if (Rmax == -1) {
+
+      DStart = CTime - REQTIMEINT;
+      DStop = CTime + REQTIMEINT;
+      if(DStart > DD_Var->GlobalStop) 
+      {
+         if(Verbose) fprintf(stderr, "ExtDataRequest: Request exceeds the global stop\n");
+         return OUTOFTIME;
+      }
+      if(DStop < DD_Var->GlobalStart) 
+      {
+         if(Verbose) fprintf(stderr, "ExtDataRequest: Request is less than global start\n");
+         return OUTOFTIME;
+      }
+        return DoRequest(DD_Var, DStart, DStop);
+
+    }
+   
+    More = 1;
+    while(More)
+    {
+      start[0] = (Rmin + Rmax)/2;
+
+      status = nc_get_vara_text(DD_Var->tmID, DD_Var->StartID,start,TimeCount,StartTime);
+      DStart = DD_Time2Double(StartTime);
+
+      if(CTime > DStart)
+      {
+        status = nc_get_vara_text(DD_Var->tmID, DD_Var->StopID,start,TimeCount,StopTime);
+        DStop = DD_Time2Double(StopTime);
+        if(DStop >= CTime) /* This is really INSIDE NODATA */
+        {
+           DD_Var->TimeRecNumber = start[0];
+           More = 0;
+           return NODATAATTIME;
+        }
+        else               /* Try interval at the right */
+        {
+           if(start[0] >= DD_Var->MaxTimeRecNum - 1) /* It was the last record */
+           {
+             More = 0;
+             DD_Var->TimeRecNumber = DD_Var->MaxTimeRecNum - 1;
+             SearchResult =  DATAATLEFT;   /* We are on the right of all records */
+ 
+           }
+           else
+           {
+              if(Verbose) fprintf(stderr,"ExtDataRequest: We have to move to %d record, CTime = %s\n", start[0]+1,Double2DD_Time(CTime));
+             start[0]++;
+             status = nc_get_vara_text(DD_Var->tmID, DD_Var->StartID,start,TimeCount,StartTime);
+             DStart = DD_Time2Double(StartTime);
+             if(DStart >= CTime) /* No data interval is at the RIGHT */
+             {
+               DD_Var->TimeRecNumber = start[0];
+               More = 0;
+               SearchResult = DATAATRIGHT;
+             }
+             else
+             {
+               Rmin = start[0];
+                if(Rmax <= Rmin) Rmax = Rmin;
+               More = 1;
+             }
+           } /* else start[0] >= maximal */
+         }  /* else of TestTime >= CTime */
+
+     }     /*(CTime > DStart) */
+     else   /* StartTime(R) > CTime */
+     {
+         if(start[0] <= 0) /* CTime is on the left from the first interval */
+         {
+            More = 0;
+            DD_Var->TimeRecNumber = 0;
+            SearchResult = DATAATRIGHT;
+         }
+         else
+         {
+            start[0]--; /* Try interval at the left */
+            status = nc_get_vara_text(DD_Var->tmID, DD_Var->StopID,start,TimeCount,StopTime);
+            DStop = DD_Time2Double(StopTime);
+            if(CTime > DStop) /* Correct interval is on the right */
+            {
+               DD_Var->TimeRecNumber = start[0] + 1;
+               More = 0;
+               SearchResult = DATAATRIGHT;
+            }
+            else
+            {
+               Rmax = start[0];
+               More =1;
+            }
+         }
+     }
+  } /* while(More) */
+  
+  /*
+   * Probably we at the left or at the right of interval
+   */
+  if(SearchResult ==  DATAATLEFT) // Data are on the left of requested data
+  {
+      start[0] = DD_Var->TimeRecNumber;
+      status = nc_get_vara_text(DD_Var->tmID, DD_Var->StopID,start,TimeCount,StopTime);
+      DStart = DD_Time2Double(StopTime); //  Left boundary
+      if((CTime - DStart) > REQTIMEINT) DStart = CTime - REQTIMEINT;
+      DStop = CTime + REQTIMEINT;
+      if(DStart >= DD_Var->GlobalStop) 
+      {
+         if(Verbose) fprintf(stderr, "ExtDataRequest: Request exceeds the global stop\n");
+         return OUTOFTIME;
+      }
+      return DoRequest(DD_Var, DStart, DStop);
+  }
+  
+  if(DD_Var->TimeRecNumber == 0) // All data is on the right 
+  { 
+      start[0] = DD_Var->TimeRecNumber;
+      status = nc_get_vara_text(DD_Var->tmID, DD_Var->StartID,start,TimeCount,StartTime);
+      DStop = DD_Time2Double(StartTime); /* Right boundary */
+      if((DStop - CTime) > REQTIMEINT) DStop = CTime + REQTIMEINT;
+      DStart = CTime - REQTIMEINT;
+      if(DStop <= DD_Var->GlobalStart) 
+      {
+         if(Verbose) fprintf(stderr, "ExtDataRequest: Request is less than global start\n");
+         return OUTOFTIME;
+      }
+      return DoRequest(DD_Var, DStart, DStop);
+  }
+      
+  /*
+   * Now we are between two records
+   * We have to check if the gap is big enough
+   */
+   start[0] = DD_Var->TimeRecNumber;
+   status = nc_get_vara_text(DD_Var->tmID, DD_Var->StartID,start,TimeCount,StartTime);
+   DStop = DD_Time2Double(StartTime); /* GAP! */
+   
+   start[0]--;
+   status = nc_get_vara_text(DD_Var->tmID, DD_Var->StopID,start,TimeCount,StopTime);
+   DStart = DD_Time2Double(StopTime); /* GAP! */
+   
+ 
+   if((DStop - DStart) < DD_Var->MinGap) return GAPISSMALL;
+
+     
+   if((CTime - DStart) > REQTIMEINT) DStart = CTime - REQTIMEINT;
+   if((DStop - CTime) > REQTIMEINT) DStop = CTime + REQTIMEINT; 
+   /*
+   if(Verbose) 
+   {
+      fprintf(stderr,"DStart-GlobalStart = %f\n",DStart - DD_Var->GlobalStart);
+      fprintf(stderr,"DStop-GlobalStop = %f\n",DStop - DD_Var->GlobalStop);
+   }
+    if((DStop > DD_Var->GlobalStop) || (DStart < DD_Var->GlobalStart)) return OUTOFTIME;
+    */
+   return DoRequest(DD_Var, DStart, DStop);
+ }
+ 
+/*======================================================================
+ *                IsTimesLocked
+ * Return 1 if there is LOCK in the VI directory or if the corresponding flag in DD_Var is UP
+ *======================================================================*/
+ int IsTimesLocked(DD_Var_t *DD_VarL)
+ {
+    int status;
+    char FullPath[PATHLENGTH];
+    struct timeval tv;
+    struct timezone tz;
+
+     
+     strcpy(FullPath,DD_VarL->path);
+     strcat(FullPath,DIRLOCK);
+     status = access(FullPath, F_OK); /* negative if there is no file */
+     switch(DD_VarL->VILocked)
+     {
+       case 0: if(status < 0) return NOLOCK; /* NO LOCK */
+               else {DD_VarL->VILocked = 2; return LOCKED;} /* LOCK was made by another server */
+               break;
+       case 1: if(status < 0) /* LOCK was made by THIS server, PHP is not ready yet OR already removed(!)*/
+               {
+                  gettimeofday(&tv,&tz);
+                  if(difftime(tv.tv_sec,DD_VarL->LockStartTime) > 1.5) 
+                    {DD_VarL->VILocked = 0; return LOCKREMOVED;} /* PHP alreadyremoved LOCK */
+                  else  return LOCKED;
+               }     
+               else {DD_VarL->VILocked = 2; return LOCKED;} /* Now even PHP setup LOCK */
+               break;
+       case 2: if(status < 0) {DD_VarL->VILocked = 0; return LOCKREMOVED;} /* PHP removed LOCK */
+               else return LOCKED;                                  /*Keep LOCK condition */
+     }
+ }
+/*=============================================================================================*/
diff --git a/src/SERVER/UpdateTimeInfo.c b/src/SERVER/UpdateTimeInfo.c
new file mode 100644
index 0000000..7855b31
--- /dev/null
+++ b/src/SERVER/UpdateTimeInfo.c
@@ -0,0 +1,185 @@
+/*=====================================================================
+ *                  DD SYSTEM base package
+ *                   DD_Server library
+ *                    UpdateTimeInfo.c
+ *                        V.1.1
+ *  Functions to updete time constant in the DD_Var structure and 
+ *  auxial functions to search in the "times" file.
+ *
+ *  Versions:
+ *  Sep 20, 2007, V.1.0, Fedorov
+ *  Sep 23, 2007, V.1.1, Fedorov, SHARE MODE
+ *=====================================================================*/
+
+#include <netcdf.h>
+#include "DD.h"
+#include "DD_comm.h"
+
+extern int Verbose;
+/*---------------------------------------------------------
+ *            SearchRight()
+ *---------------------------------------------------------*/
+int SearchRight(DD_Var_t *DD_VarL, size_t Rmin, size_t Rmax)
+{
+  static size_t start[2] = {0,0};
+  static size_t TimeCount[2] = {1,TIMELENGTH};
+  static size_t FileCount[2] = {1,MAXFILENAME};
+  char TimeIntName[MAXSETLENGTH]; /* File name associated with the given time interval */
+  int NoDataFlag;
+  int status;
+  
+  start[0] = DD_VarL->TimeRecNumber;
+  
+  NoDataFlag = 1;
+  while(NoDataFlag)
+  {
+     status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->NameID,start,FileCount,TimeIntName);
+     if(strcmp(TimeIntName,NODATASTR) == 0) /* No data for this time interval */
+     {
+        start[0]++; /* Go right */
+        if(start[0] > Rmax)  return REACHRIGHT; /* End of alowed interval is reached */
+     }
+     else 
+     {
+        DD_VarL->TimeRecNumber = start[0];
+        NoDataFlag = 0;
+     }
+  }
+  return OKRIGHT;
+}
+
+/*---------------------------------------------------------
+ *            SearchLeft()
+ *---------------------------------------------------------*/
+int SearchLeft(DD_Var_t *DD_VarL, size_t Rmin, size_t Rmax)
+{
+  static size_t start[2] = {0,0};
+  static size_t TimeCount[2] = {1,TIMELENGTH};
+  static size_t FileCount[2] = {1,MAXFILENAME};
+  char TimeIntName[MAXSETLENGTH]; /* File name associated with the given time interval */
+  int NoDataFlag;
+  int status;
+  
+  start[0] = DD_VarL->TimeRecNumber;
+  
+  NoDataFlag = 1;
+  while(NoDataFlag)
+  {
+     status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->NameID,start,FileCount,TimeIntName);
+     if(strcmp(TimeIntName,NODATASTR) == 0) /* No data for this time interval */
+     {
+        if(start[0] > 0) start[0]--; else return REACHLEFT; /* Go left */
+        if(start[0] < Rmin)  return REACHLEFT;              /* End of alowed interval is reached */
+     }
+     else 
+     {
+        DD_VarL->TimeRecNumber = start[0];
+        NoDataFlag = 0;
+     }
+  }
+  return OKLEFT;
+}
+/*-----------------------------------------------------------------*/
+
+/*---------------------------------------------------------
+ *            UpdateTimeInfo()
+ *---------------------------------------------------------*/
+int UpdateTimeInfo(DD_Var_t *DD_VarL)
+{
+  static char StartName[] =  "StartTime";
+  static char StopName[] =   "StopTime";
+  static char FileName[] =   "FileName"; /* Variable IDs */
+  static char RecDimName[] = "record";
+  static int  RecDimID;
+  static size_t start[2] = {0,0};
+  static size_t TimeCount[2] = {1,TIMELENGTH};
+  char TimeS[TIMELENGTH];
+  size_t Rmin,Rmax;
+  int SearchStatus;
+  int status;  
+  /*---- Close file if it is open ---------------------------*/
+  if(DD_VarL->tmID > -1) status = nc_close(DD_VarL->tmID);
+  
+  if(Verbose) fprintf(stderr,"UpdateTimeInfo(%s): Start\n",DD_VarL->TimesFileName);
+  
+  /*---- Reopen times file ----------------------------------*/
+  status = nc_open(DD_VarL->TimesFileName, NC_NOWRITE|NC_SHARE,&(DD_VarL->tmID)); 
+  if(status != NC_NOERR)
+   {
+      if(Verbose) fprintf(stderr,"UpdateTimeInfo(%s): open file: message: %s\n",DD_VarL->TimesFileName,nc_strerror(status));
+      return(NOTIMESFILE);
+   }
+   /*
+    * Init corresponding constants
+    */
+    status =  nc_inq_varid(DD_VarL->tmID,FileName, &(DD_VarL->NameID));
+    status =  nc_inq_varid(DD_VarL->tmID,StartName,&(DD_VarL->StartID));
+    status =  nc_inq_varid(DD_VarL->tmID,StopName, &(DD_VarL->StopID));
+    if (status != NC_NOERR)
+    {
+        if(Verbose) fprintf(stderr,"UpdateTimeInfo(%s): Get parameters times file %s\n",DD_VarL->TimesFileName,nc_strerror(status));
+        return(NOTIMESFILE);
+    }
+
+     /* Get MaxRecord Number */
+     status = nc_inq_dimid(DD_VarL->tmID,RecDimName, &RecDimID);
+     if (status != NC_NOERR)
+     {
+        if(Verbose) fprintf(stderr,"UpdateTimeInfo(%s): Get Max records in Times file %s\n",DD_VarL->TimesFileName,nc_strerror(status));
+        return(NOTIMESFILE);
+     }
+     status = nc_inq_dimlen(DD_VarL->tmID,RecDimID, &(DD_VarL->MaxTimeRecNum));
+
+/* -----------------------------------------------------------------
+ * Search the extreme left and right valid intervals
+ * -----------------------------------------------------------------*/
+   Rmin = 0; Rmax = DD_VarL->MaxTimeRecNum - 1;
+   DD_VarL->TimeRecNumber = 0;
+   switch(SearchRight(DD_VarL,Rmin,Rmax))
+   {
+      case REACHRIGHT: SearchStatus = NOONEDATA;  
+                       DD_VarL->RValidMin = -1; 
+                       DD_VarL->RValidMax = -1; 
+                       DD_VarL->MinValidTime = -1.0;
+                       break;
+      case OKRIGHT: DD_VarL->RValidMin = DD_VarL->TimeRecNumber;SearchStatus = IDLE;
+   }
+ 
+   if(SearchStatus != NOONEDATA) /* Ther is something in the right */
+   {
+     DD_VarL->TimeRecNumber = Rmax;
+     switch(SearchLeft(DD_VarL,Rmin,Rmax))
+     {
+        case REACHLEFT: DD_VarL->RValidMin = -1; 
+                        DD_VarL->RValidMax = -1;  
+                        DD_VarL->MaxValidTime = -1.0;
+                        break; /* Impossible */
+        case OKLEFT: DD_VarL->RValidMax = (int)DD_VarL->TimeRecNumber;
+     }
+   }
+   
+   /*------ Define min and max valid times ------------------------*/
+   if(DD_VarL->RValidMin >= 0)
+   {
+     start[0] = (size_t)DD_VarL->RValidMin;
+     status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->StartID,start,TimeCount,TimeS);
+     DD_VarL->MinValidTime = DD_Time2Double(TimeS);
+   }
+   else DD_VarL->MinValidTime = -1.0;
+   if(DD_VarL->RValidMax >= 0)
+   {
+     start[0] = (size_t)DD_VarL->RValidMax;
+     status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->StopID,start,TimeCount,TimeS);
+     DD_VarL->MaxValidTime = DD_Time2Double(TimeS);
+   }
+   else DD_VarL->MaxValidTime = -1.0;
+
+   
+   /*------- Init other values ------------------------------------*/
+   DD_VarL->CurrRmin = -1;
+   DD_VarL->CurrRmax = -1;
+  /*-----------------------------------------------------------------------*/
+   if(Verbose) fprintf(stderr,"UpdateTimeInfo(%s): OK\n",DD_VarL->TimesFileName);
+   return OK;
+}
+/*====================================================================================*/
diff --git a/src/SERVER/ncfileop.c b/src/SERVER/ncfileop.c
new file mode 100755
index 0000000..76a06cb
--- /dev/null
+++ b/src/SERVER/ncfileop.c
@@ -0,0 +1,498 @@
+/*=====================================================================
+ *                DD SYSTEM base package
+ *                  DD_Server library
+ *                    ncfileop.c
+ *                      V.6.7
+ * Last revision:
+ *      Oct 24, 2002  New calculation of the maximum record size V 4.1
+ *      work with NC files is now in file ncfileop.c
+ *      Nov 19, 2004 Bug in the cach operation.
+ *      Aug 16, 2005 Cach improved
+ *      Mar 15, 2007 V.4.7 Some errors with cash
+ *      Jul 10, 2007 V.5.0 According to Server protocol 4.5.1 Call external database if need.
+ *                         If "times" has "NODATA" string as name of the file, return "NOTIME"
+ *      Sep 22, 2007 V.6.0 New approach. It tries to get new data between two files
+ *      Sep 25, 2007 V.6.1 Variable Minimal Gap
+ *      May 06, 2008 V.6.2 Fedorov, Max Records number processing
+ *      May 12, 2008 V.6.3 Fedorov, In Max Records error in malloc sizeof(int *)!!! important for 64
+ *      May 15, 2008 V.6.4 Fedorov, NoData interval processing. Just go to the next correct data interval.
+ *      Apr 08, 2009 V.6.5 Fedorov, Unziped files can be touched by groupe
+ *      Apr 14, 2009 V.6.6 Fedorov, nc_sync
+ *      Feb 02, 2010 V.6.7 Lena, wait to remove an old file in the cache
+ *======================================================================*/
+#include <netcdf.h>
+#include "DD.h"
+#include "DD_comm.h"
+
+/*------------------ GLOBAL VARIABLES --------------------------*/
+extern int Verbose;
+
+/*=============================================================
+ *                       CloseOldFile
+ *===========================================================*/
+int CloseOldFile(DD_Var_t *D)
+{
+    size_t CashStart[2] = {0L,0L};
+    size_t CashCount[2] = {1L,MAXFILENAME};
+    int status;
+
+    if(D->Maxnc_rec > 0)
+    {
+       status = nc_close(D->ncID);
+       if(status < 0) 
+       {
+          D->LastFileStatus = DATAFILEERR;
+          if(Verbose) fprintf(stderr,"CloseOldFile: file %s, error while closed\n",&(D->Cash.names[D->CurrCushN][0]),D->CurrCushN);
+          return DATAFILEERR;
+       }
+       if(Verbose) fprintf(stderr,"CloseOldFile: file %s, %d closed\n",&(D->Cash.names[D->CurrCushN][0]),D->CurrCushN);
+       D->CurrCushN = -1;
+       D->Maxnc_rec = 0;
+    }
+    else if(Verbose) fprintf(stderr,"CloseOldFile: Nothing To close\n");
+
+    return 1;
+}
+
+/*##############################################################*/
+/*-----------------------SETNEWFILE-----------------------------*/
+/*##############################################################*/
+
+int SetNewFile(DD_Var_t *D, int N)
+/*
+ * Function tries to get new data for the gap beetween files, or just 
+ * open a new data file according to offset N referring to current position in the times file.
+ * The current position changed if file is succesefully open.
+ * Return values: 
+ * OK 
+ * OUTOFTIME - next interval exceeeds GlobalStart/Stop
+ * TIMEINEMPTY - next interval marked as "NODATA"
+ * TRYAGAIN - the VI is blocked while new data is arriving
+ * WAITEXTCALL - new data is requested
+ * CACHTOOREC - now free space in the CACH
+ * CHACHERR - unrecovable error in CACH
+ * DATAFILEERR - unrecovable error in data file
+ *----------------------------------------------------------------
+ * At the entry we are assuming that VI is not locked!
+ */
+{
+  static char TimeDimName[] = "Time";
+  static size_t CashStart[2] = {0L,0L};
+  static size_t CashCount[2] = {1L,MAXFILENAME};
+  static size_t TimeCount[2] = {1,TIMELENGTH};
+
+  char Name[MAXFILENAME];               /* Name of data nc file */
+  char FullName[PATHLENGTH];            /* Full name of nc file */
+  char StartTime[TIMELENGTH];
+  char StopTime[TIMELENGTH];
+  static int NameID,TimeDimID;               /* NC variables ID for Times file */
+  static size_t start[2] = {0,0};                   /* NV start array */
+  static size_t FileCount[2] = {1,MAXFILENAME}; /* NC count array for Times file */
+  static size_t DimArray[NC_MAX_DIMS];  /* NC_MAX_DIMS is in netcdf.h */
+  static int DimIDArray[NC_MAX_DIMS];
+  size_t TestNumber;                                /* To test the new file number  */
+  int FileNumber, Find, OldestNumber, NewAttempt;
+  char command[300];
+  int dltt;
+  int status;
+  time_t CurrentTime;
+  double FirstTime, LastTime;
+  int More;
+
+/*--------------- Calculate the next file to open ---------------*/
+  TestNumber = D->TimeRecNumber + N;
+  if(Verbose) fprintf(stderr,"SetNewFile(): Record %d\n",TestNumber);
+
+  D->TimeRecNumber = TestNumber;
+  start[0] = TestNumber;
+  
+/*----------------------------------------------------------------*
+ *  Some test and call external archive we have to make only if  N > 0 
+ *  Otherwise we just reopen existing file
+ *----------------------------------------------------------------*/
+  if(N > 0)
+  {
+     if(TestNumber > D->RValidMax) /* Out of existing data files */
+     {
+        if(Verbose) fprintf(stderr,"SetNewFile(): TestNumber %d exides D->RValidMax %d\n",TestNumber,D->RValidMax);
+
+        if(D->ExtCallAllowed) 
+        {
+           More = 1;
+           while(More)
+           {
+            switch(status = ExtDataRequest(D, D->CDTime+D->MinGap))
+            {
+                case OK: return WAITEXTCALL;
+                case NODATAATTIME: /* The last files in the data base are only NODATA, let us try again with StopTime of  TestNumber */
+                  start[0] = TestNumber;
+                  status = nc_get_vara_text(D->tmID, D->StopID,start,TimeCount,StopTime);
+                  D->CDTime = DD_Time2Double(StopTime) + 0.001;
+                  if(Verbose) fprintf(stderr,"SetNewFile(): We found no data, Let us try another CDTime = %s\n",Double2DD_Time(D->CDTime));
+                  More = 1;
+                  break;
+                case GAPISSMALL: return TIMEINEMPTY; break;
+                case OUTOFTIME: return OUTOFTIME; break;
+                default: return DATAFILEERR;
+            }
+           }
+        } else return OUTOFTIME;
+     }
+  }
+  
+  /*--------------- Get File Name and start Time  ---------------------*/
+  status = nc_get_vara_text(D->tmID,D->NameID,start,FileCount,Name);
+  status = nc_get_vara_text(D->tmID, D->StartID,start,TimeCount,StartTime);
+  if(status != NC_NOERR)
+  {          
+     if(Verbose) fprintf(stderr,"SetNewFile(): Get File Name and StartTime  %s\n",nc_strerror(status));
+     D->LastFileStatus = DATAFILEERR;
+     return DATAFILEERR; 
+  }
+  FirstTime = DD_Time2Double(StartTime);
+  
+  if(N > 0)
+  {
+     if(strncmp(Name,"NODATA",6) == 0) /* Next record marked as NODATA */
+     {
+        if(D->ExtCallAllowed && (FirstTime - D->CDTime > D->MinGap)) /* Try to fill the gap between the data 
+                                                                      * and NODATA segment if there is enough gap
+                                                                      */
+        {
+           if(Verbose) fprintf(stderr,"SetNewFile(): There is a gap  %d\n",FirstTime - D->CDTime);
+           switch(status = ExtDataRequest(D, D->CDTime+D->MinGap))
+           {
+              case OK: return WAITEXTCALL;
+              case NODATAATTIME:
+              case GAPISSMALL: return TIMEINEMPTY; break;
+              case OUTOFTIME: return OUTOFTIME; break;
+              default: return DATAFILEERR;
+           }
+        } 
+        else /* Gap to NODATA interval is too small and we wiil try next time interval */
+        {
+           if(Verbose) fprintf(stderr,"SetNewFile(): Next File is NODATA, try file %d\n",++TestNumber);
+           status = nc_get_vara_text(D->tmID, D->StopID,start,TimeCount,StopTime);
+           D->CDTime = DD_Time2Double(StopTime);
+
+           switch( status = SetNewFile(D,1) )
+           {
+               case OK: return OK;
+               case WAITEXTCALL: return WAITEXTCALL;
+               case TIMEINEMPTY: return TIMEINEMPTY;
+               case OUTOFTIME: return OUTOFTIME;
+               case CACHERR: return CACHERR;
+               default: return DATAFILEERR;
+           }
+        }
+           
+     }
+     else   /* Next record is valid */
+     {
+//        sleep(40);
+        if(D->ExtCallAllowed && ((FirstTime - D->CDTime) > D->MinGap))
+        {
+            if(Verbose) fprintf(stderr,"SetNewFile(): File OK, but there is a gap  %d %d\n",FirstTime - D->CDTime, D->MinGap);
+           switch(status = ExtDataRequest(D, D->CDTime+D->MinGap))
+           {
+              case OK: return WAITEXTCALL;
+              case NODATAATTIME:
+              case GAPISSMALL: return TIMEINEMPTY; break;
+              case OUTOFTIME: return OUTOFTIME; break;
+              default: return DATAFILEERR;
+           }
+        }  /* else just continue */
+     }
+  }
+  
+/*-------------- refresh the Cache table ---------------------------*/
+  status = nc_sync(D->Cash.ID);
+  if(status != NC_NOERR) 
+  {          
+     if(Verbose) fprintf(stderr,"SetNewFile(): Cache Synchro: %s\n",nc_strerror(status));
+     return CACHERR;
+  }
+  for(CashStart[0] = 0; CashStart[0] < CASHLEN; CashStart[0]++)
+  {
+    status = nc_get_vara_text(D->Cash.ID, D->Cash.nameID,CashStart,CashCount,D->Cash.names[CashStart[0]]);
+    if(status != NC_NOERR) 
+    {          
+       if(Verbose) fprintf(stderr,"SetNewFile(): Cache Names: %s\n",nc_strerror(status));
+       D->LastFileStatus = CACHERR;
+       return CACHERR;
+    }
+    status = nc_get_vara_long(D->Cash.ID, D->Cash.timeID,CashStart,CashCount,&(D->Cash.times[CashStart[0]]));
+    if(status != NC_NOERR)
+    {          
+       if(Verbose) fprintf(stderr,"SetNewFile(): Cache Times %s\n",nc_strerror(status));
+       D->LastFileStatus = CACHERR;
+       return CACHERR;
+    }
+  }
+
+/*----------- Close the old file ----------------------*/
+  if((status = CloseOldFile(D)) < 0) return DATAFILEERR;
+
+  strcpy(FullName,D->path);
+  strcpy(FullName+strlen(D->path), Name);
+//  if(Verbose) fprintf(stderr,"SetNewFile(): New file to open: %s\n",FullName);
+
+  NewAttempt = 0;  
+
+  while (NewAttempt < 3) 
+  {
+      /*----- Search the new requested file in the cache and the oldest file ----------*/
+      FileNumber = 0; 
+      CurrentTime = time(NULL); Find = 0; OldestNumber = -1; 
+ 
+      while((FileNumber < CASHLEN) &&                                   // Cache is finished
+	((Find = strcmp(&(D->Cash.names[FileNumber][0]),Name)) != 0) && // File is already in the Cache
+	(D->Cash.names[FileNumber][0] != ' '))                          // There is empty space
+      {
+	if((D->Cash.times[FileNumber] < (CurrentTime - FILEACCMARG) ) && (OldestNumber == -1)) OldestNumber = FileNumber;
+	dltt = (int)(D->Cash.times[OldestNumber] - D->Cash.times[FileNumber]);
+	if(dltt > 0) OldestNumber = FileNumber;
+	FileNumber++;
+      }
+
+      /* ====================================================
+       * Sometimes it is possible, that:
+       * 1) No corresponding file in the cache (Find != 0)
+       * 2) The oldest file is not found (OldestNumber == -1)
+       * 3) cach is full (FileNumber == CASHLEN)
+       * Then we need to repeat the search after one sec delay
+       *==================================================== */
+      if((Find != 0) && (FileNumber == CASHLEN) && (OldestNumber == -1))
+      {
+	NewAttempt++;
+	sleep((unsigned )(FILEACCMARG));
+
+        if (Verbose)
+            fprintf(stderr,"Waiting %d secs to get the Oldest File\n", FILEACCMARG);
+
+      } else NewAttempt = 3;
+   }
+  
+//---------- Parsing resultat of search -------------
+//  if(Verbose)
+//  {
+//    if(OldestNumber > -1) fprintf(stderr,"SetNewFile(): Search: Is Oldest File %d %d %d\n", OldestNumber,D->Cash.times[OldestNumber],CurrentTime);
+//    else  fprintf(stderr,"SetNewFile(): Search: No Oldest File %d %d\n", OldestNumber,CurrentTime);
+//  }
+  
+  if(Find != 0) 
+/*---------------- No request file in the CACHE ----------------------*/
+  {
+     if(FileNumber < CASHLEN)
+     {
+        if(D->Cash.names[FileNumber][0] == ' ') /* There is empty space in the table */
+        {
+           strcpy(command, "gunzip -c ");
+           strcat(command, FullName);
+           strcat(command, ".gz > ");
+           strcat(command, FullName);
+           system(command);           /* File is unzipped */
+           sprintf(command, "chmod g+w %s\0",FullName);
+           system(command);           /* File is unzipped */
+
+           strcpy(&(D->Cash.names[FileNumber][0]),Name);
+           D->Cash.times[FileNumber] = CurrentTime;
+           CashStart[0] = FileNumber;
+           D->CurrCushN = FileNumber;
+        }  
+        else 
+        {          
+           D->LastFileStatus = CACHERR;
+           return CACHERR;             /* Unrecoverable error */
+        }
+     }
+     else  /* No empty space. It is necessury to remove one file */
+     {
+         if (OldestNumber > -1) //------ Oldest file is found -------
+         {
+            strcpy(command, "gunzip -c ");
+            strcat(command, FullName);
+            strcat(command, ".gz > ");
+            strcat(command, FullName);
+            system(command);           /* File is unzipped */
+            sprintf(command, "chmod g+w %s\0",FullName);
+            system(command);           /* File is unzipped */
+
+            strcpy(command, "rm ");
+            strcat(command,D->path);
+            strcat(command,&(D->Cash.names[OldestNumber][0]));
+            strcat(command, " &");
+            system(command);           /* Old file removed */
+            strcpy(&(D->Cash.names[OldestNumber][0]),Name);
+            D->Cash.times[OldestNumber] = CurrentTime;
+            CashStart[0] = OldestNumber;
+            D->CurrCushN = OldestNumber;
+         }
+         else {    
+           if(Verbose) fprintf(stderr,"SetNewFile(): return CACHTOOREC\n");      
+           D->LastFileStatus = CACHTOOREC;
+           D->TimeRecNumber -= N;
+           return CACHTOOREC; //----- Say client that all files are too new
+         }
+      }
+        /*------------ The place for new cache is found --------------*/
+        status = nc_put_vara_text(D->Cash.ID, D->Cash.nameID,CashStart,CashCount,&(D->Cash.names[CashStart[0]][0]));
+        status = nc_put_vara_long(D->Cash.ID, D->Cash.timeID,CashStart,CashCount,&(D->Cash.times[CashStart[0]]));
+        if(status != NC_NOERR) 
+        {
+           if(Verbose) fprintf(stderr,"SetNewFile(): Write Name and Time to cash: %s\n",nc_strerror(status));
+           D->LastFileStatus = CACHERR;
+           return CACHERR;
+        }
+        status = nc_sync(D->Cash.ID);
+  }
+//------------------ There is FILE already in the CACHE --------------  
+  else /*------- The requested file is already in the cache just refresh the time */
+  {
+        CashStart[0] = FileNumber;
+        D->Cash.times[FileNumber] = CurrentTime;  /* refresh the time */
+        D->CurrCushN = FileNumber;
+        status = nc_put_vara_long(D->Cash.ID, D->Cash.timeID,CashStart,CashCount,&(D->Cash.times[CashStart[0]]));
+        if(status != NC_NOERR) 
+        {          
+           if(Verbose) fprintf(stderr,"SetNewFile(): File In Cache: %s\n",nc_strerror(status));
+           D->LastFileStatus = CACHERR;
+           return CACHERR;
+        }
+        status = nc_sync(D->Cash.ID);
+  }
+
+//  if(Verbose) fprintf(stderr,"SetNewFile(): file %s, %d to be open\n",FullName,D->CurrCushN);
+
+
+/*--------------- CACHE refreshed and requested file is unzipped ------------------------*/
+/*----------------- Open requested file -----------------------------------------------*/
+
+  status = nc_open(FullName,NC_NOWRITE,&(D->ncID));
+  if(status != NC_NOERR)
+  {
+    if(Verbose) fprintf(stderr,"SetNewFile(): Error while File Open: %s\n",nc_strerror(status));
+    D->LastFileStatus =DATAFILEERR ;
+    return DATAFILEERR;
+  }
+  if(Verbose) fprintf(stderr,"SetNewFile(): %s is open\n",FullName);
+
+/* Recover time  dimension */
+  status = nc_inq_dimid(D->ncID,TimeDimName,&TimeDimID);
+  if(status != NC_NOERR) 
+  {
+    if(Verbose) fprintf(stderr,"SetNewFile(): Get Time Dim: %s\n",nc_strerror(status));
+    D->LastFileStatus = DATAFILEERR;
+    return DATAFILEERR;
+  }
+  status = nc_inq_dimlen(D->ncID,TimeDimID,&(D->Maxnc_rec));
+  if(status != NC_NOERR) 
+  {          
+    if(Verbose) fprintf(stderr,"SetNewFile: GetFile Length: %s\n",nc_strerror(status));
+    D->LastFileStatus = DATAFILEERR;
+    return DATAFILEERR;
+  }
+
+/* Setup current position in the new open file */
+  if(N > 0) D->nc_rec = 0;
+  if(N < 0) D->nc_rec = D->Maxnc_rec-1;
+  
+  D->LastFileStatus = OK;
+  return OK;
+}
+/*------------------------------------------------------------------------------------*/
+
+/*----------------- VarSize -----------------------------------*/
+int  VarSize(nc_type type)
+{
+   switch(type)
+   {
+     case NC_BYTE: return sizeof(char);
+     case NC_CHAR: return sizeof(char);
+     case NC_SHORT: return sizeof(short);
+     case NC_INT: return sizeof(int);
+     case NC_FLOAT: return sizeof(float);
+     case NC_DOUBLE: return sizeof(double);
+     default: return 1;
+   }
+}
+
+/*##############################################################*/
+/*----------------------- MaxRecord -----------------------------*/
+/*##############################################################*/
+
+size_t MaxRecord(int ncID)
+/* ncID - ID of already open NC file */
+{
+  int timedimid;   /* ID for dimension "Time" */
+
+  int nvars;
+  int ndims;
+  int *ndims_arr;      /* Array to keep number of dimensions of each variable */
+  size_t *dimleng_arr; /* Array to keep all length of dimensions */
+  nc_type *vartype_arr; /* Array to keep all types of variables */
+  int **dimid_arr; /* array of pointers to arrays of variable dimensions */
+
+  int status;     /* Error indicator */
+  int iv, id;
+  int cvarsize;    /* size of variable */
+  int maxsize;     /* maximal size */
+  int recordsize;   /* size by units */
+  size_t RecordNumber;
+
+  /*--- general information -------*/
+  status = nc_inq_ndims(ncID,&ndims);
+  status = nc_inq_nvars(ncID,&nvars);
+  status = nc_inq_unlimdim(ncID, &timedimid); /* What is unlimited dimension ID */
+
+  /*---- memory allocation --------*/
+  dimleng_arr = (size_t *)malloc(ndims * sizeof(size_t));
+  vartype_arr = (nc_type *)malloc(nvars * sizeof(nc_type));
+  dimid_arr = (int **)malloc(nvars * sizeof(int *));
+  ndims_arr = (int *)malloc(nvars * sizeof(int));
+
+  /* Length of each dimension */
+  for(id = 0; id < ndims; id++)
+  {
+     if(id == timedimid) dimleng_arr[id] = 1;
+     else status = nc_inq_dimlen(ncID, id, &(dimleng_arr[id]));
+  }
+
+  /* type and dimension of each variable */
+  for(iv = 0; iv < nvars; iv++)
+  {
+      status = nc_inq_vartype(ncID,iv,&(vartype_arr[iv]));
+      status = nc_inq_varndims(ncID,iv,&(ndims_arr[iv]));
+      dimid_arr[iv] = (int *)malloc(ndims_arr[iv]*sizeof(int)); /* memory for dim ID array */
+      status = nc_inq_vardimid(ncID,iv,dimid_arr[iv]);
+  }
+
+  /* calculation of size of variable and maximum size of variables */
+  maxsize = 0;
+  for(iv = 0; iv < nvars; iv++)
+  {
+     recordsize = 1;
+     for(id = 0; id < ndims_arr[iv]; id++)
+         recordsize *= dimleng_arr[(dimid_arr[iv])[id]];
+     cvarsize  = recordsize * VarSize(vartype_arr[iv]);
+     if(cvarsize > maxsize) maxsize = cvarsize;
+  }
+
+  /* calculation record number */
+  RecordNumber = (size_t)(MAXPACKSIZE / maxsize);
+  if(RecordNumber == 0)
+  {
+     if(Verbose) fprintf(stderr,"MaxRecord(%d): Error in calculation of records number,MAXPACKSIZE = %d, maxsize = %d\n",ncID,MAXPACKSIZE,maxsize);
+  }
+
+  /* Free all */
+  for(iv = 0; iv < nvars; iv++) free(dimid_arr[iv]);
+  free(ndims_arr);
+  free(dimid_arr);
+  free(vartype_arr);
+  free(dimleng_arr);
+
+  return RecordNumber;
+}
+/*----------------------------------------------------------------------*/
+
--
libgit2 0.21.2