/* $Id: DD_client.c,v 1.3 2009/04/14 08:37:28 budnik Exp $ */ /*============================================================== * DD SYSTEM * DD_client.c * V.4.8 * 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 05, 2017 - Renard, V.7.0 *===============================================================*/ #include #include #include #include #include #include #include "DD.hh" #ifdef LOG4CXX log4cxx::LoggerPtr DD_Client::_logger = log4cxx::Logger::getLogger( "AMDA-Kernel.DD_Client"); #endif /*------------------ GLOBAL STATIC VARIABLES --------------------------*/ //extern int errno; /*================== FUNCTIONS =================================*/ /*----------------------- GET User Host-------------------------------*/ static size_t unixlen[] = {sizeof(char),sizeof(int),sizeof(float),sizeof(double),sizeof(short)}; static xdrproc_t ConvFunc[5] = {(xdrproc_t )xdr_char, (xdrproc_t )xdr_int, (xdrproc_t )xdr_float, (xdrproc_t )xdr_double, (xdrproc_t )xdr_short}; DD_Client:: DD_Client() : idd (DD_CHAR, 0, NULL,1, (void**) malloc(sizeof(void*))), CurrentData(NULL), _varNumber(0), SocketID( -1), UserID(0), m1(0X000000FF), m2( 0X0000FF00), m3(0X00FF0000), m4( 0XFF000000), //Host(NULL), buffSetVarialbe(NULL), bufDD_SetTime (NULL), op(TIMESETREQ), bufDD_GetData( NULL), LastPacketFlag(OK), bufDD_Close (NULL), opDD_Close(CLOSEINSREQ), bufDD_AddDataSet(NULL), opDD_AddDataSet(ADDVIREQ), Version(VERSION) { UserName[0] = '\0'; UserHost[0] = '\0'; RemSerName[0]='\0'; strcpy(TimeInt, "0000000000001000"); idd.Variables[0]=NULL; } int DD_Client::GetUserHost() { int userid; userid = getuid(); /* Get a client user ID */ #ifdef LOG4CXX //LOG4CXX_DEBUG(_logger, "DD_Client::GetUserHost - UserId : " << userid); #endif /* 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') { char HostName[HOSTNAMELENGTH]; gethostname(HostName, HOSTNAMELENGTH); /* Get a client host name */ struct sockaddr_in addr; if (getInfoFromHostName(HostName,addr) != 0) return NOHOST; unsigned int b1, b2, b3, b4; sscanf(inet_ntoa( addr.sin_addr), "%3u.%3u.%3u.%3u", &b1, &b2, &b3, &b4); snprintf(UserHost, MAXHOSTLENGTH, "%03u.%03u.%03u.%03u", b1, b2, b3, b4); #ifdef LOG4CXX // LOG4CXX_DEBUG(_logger, "DD_Client::GetUserHost - UserHost : " << UserHost); #endif } return userid; } void DD_Client::setUserHost(const char* host) { snprintf(UserHost, MAXHOSTLENGTH, "%s", host); #ifdef LOG4CXX // LOG4CXX_DEBUG(_logger, "DD_Client::setUserHost - UserHost : " << UserHost); #endif } void DD_Client::setUserName(const char* name) { snprintf(UserName, USRLENGTH, "%s", name); #ifdef LOG4CXX // LOG4CXX_DEBUG(_logger, "DD_Client::setUserName - UserName : " << UserName); #endif } int DD_Client::getInfoFromHostName(const char *hostName, struct sockaddr_in &addr) { struct addrinfo hints; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; hints.ai_protocol = 0; hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; struct addrinfo *result; int s; s = getaddrinfo(hostName, NULL, &hints, &result); if (s != 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::getIpFromHostName - Cannot get ip from host name " << hostName); #endif return NOHOST; } struct sockaddr_in *h; h = (struct sockaddr_in *) result->ai_addr; memcpy(&addr,h,sizeof(struct sockaddr_in)); freeaddrinfo(result); return 0; } /*-------------------------------------------------------------------*/ /*------------------ MAKE_CONNECTION ---------------------------*/ /* * The function returns opened socket, ready to read and write */ int DD_Client::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 */ /*---------- Variables for network ---------------------*/ 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) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::GetSocket - Cannot find resource file " << rname); #endif fprintf(stderr,"No resource file, sorry\n"); exit(1); } fgets(RemSerName, PATHLENGTH-1, resfile); fgets(line, PATHLENGTH-1, resfile); fclose(resfile); RemSerName[strlen(RemSerName)-1] = '\0'; sscanf(line,"%5d",&(normaddr)); /*---------------- END of FILE READING --------------------------*/ /* *------- Trying to open socket with this address and name --------- */ if((SocketID = socket(AF_INET,SOCK_STREAM,PROTOCOL)) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::GetSocket - Socket error "); #endif perror("Socket:"); return(-1); } /* Filling full internet address for socket "name" * this address will be used to get communication point */ struct sockaddr_in IntAFAddr; if (getInfoFromHostName(RemSerName,IntAFAddr) != 0) return NOHOST; IntAFAddr.sin_port = htons((uint16_t)normaddr); /* Conversion of the port number to universal net form */ #ifdef LOG4CXX //LOG4CXX_DEBUG(_logger, "DD_Client::GetSocket - HostName : " << RemSerName << " - IP : " << inet_ntoa(IntAFAddr.sin_addr) << " - Port : " << IntAFAddr.sin_port); #endif /* Connection to server socket on remote computer */ int errnum = connect(SocketID,(struct sockaddr *)&IntAFAddr,sizeof(struct sockaddr_in)); if(errnum < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::GetSocket - Connection to server socket error - " << strerror (errnum)); #endif perror("connect"); return(-1); } /* * Get Host name and Host ID for security application */ if((UserID = GetUserHost()) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::GetSocket - NOHOST error"); #endif return(NOHOST); } return SocketID; } /*------------------- end of GetSocket ---------------------*/ /*==================== Receive From Net ======================*/ /* * Smart buffered receiver */ int DD_Client::ReceiveFromNet(char *buf, int PacketSize) { int CurLength = 0; do { int i = 0; int cc = 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_Client::DD_SetVariable(char *InstrName) { int InstrID; /* Instrumnet ID to return */ int Request = OPENINSREQ; int hostlen,userlen; char *PUserHost = UserHost, *PUserName = UserName; char *pDDuser; /* 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) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_SetVariable - No connection"); #endif return(NOCONNECTION); } /* Encoding request by XDR to buf */ /* Buffer and stream allocation */ buffSetVarialbe = (caddr_t)calloc(REQUESTLENGTH, 1); xdrmem_create(&xdrs, buffSetVarialbe, REQUESTLENGTH, XDR_ENCODE); xdr_int(&xdrs,&Request); xdr_string(&xdrs, &InstrName, strlen(InstrName)); /* Send Open Virtual Instrument request */ if( send(SocketID,buffSetVarialbe,REQUESTLENGTH,0) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_SetVariable - Cannot open virtual instrument"); #endif perror("DD_SetVariable:"); free(buffSetVarialbe); xdr_destroy(&xdrs); return(REQSENDERR); } xdrmem_create(&xdrs, buffSetVarialbe, REQUESTLENGTH, XDR_FREE); /*-------- preparation an authorization request ----------------*/ if(UserName[0] == '\0') { pDDuser = getenv ("DDUSER"); if (pDDuser != NULL) strcpy(UserName, pDDuser); else { strcpy(UserName,NONAME); #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_SetVariable - UserName is undefined"); #endif } } hostlen = strlen(UserHost); userlen = strlen(UserName); xdrmem_create(&xdrs, buffSetVarialbe,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( send(SocketID,buffSetVarialbe,REQUESTLENGTH,0) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_SetVariable - Cannot send request"); #endif perror("DD_Set_Variable:"); free(buffSetVarialbe); xdr_destroy(&xdrs); return(REQSENDERR); } free(buffSetVarialbe); xdr_destroy(&xdrs); /* Get reply */ buffSetVarialbe = (caddr_t)malloc(REPLYLENGTH); /* i=0; while(((cc = recv(SocketID,buff,REPLYLENGTH,0)) < 0) && (i < TRY)) i++; */ if( ReceiveFromNet(buffSetVarialbe, REPLYLENGTH) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_SetVariable - Cannot receive from net"); #endif perror("DD_SET_Variable:"); free(buffSetVarialbe); return(REPLYRECERR); } xdrmem_create(&xdrs, buffSetVarialbe, REPLYLENGTH, XDR_DECODE); xdr_int(&xdrs,&InstrID); /* Free all */ free(buffSetVarialbe); xdr_destroy(&xdrs); return InstrID; } /*----------------------- DD_GetInform -----------------------------*/ /* * Returns "OK" if OK, fill DD_Data structure * Return negative value if error */ int DD_Client::DD_GetInform(int VarID,char *AttrName,DD_data_t **data) { XDR xdrs; caddr_t bufDD_GetInform = NULL; int length; int op = DATAINFOREQ; int type; /* type of information or error */ int DimNumbers; int PacketSize; 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 --------------------*/ bufDD_GetInform = (caddr_t)calloc(REQUESTLENGTH,1); xdrmem_create(&xdrs, bufDD_GetInform, REQUESTLENGTH, XDR_ENCODE); /*------------------- Encoding the request ----------------------*/ xdr_int(&xdrs,&op); xdr_int(&xdrs,&VarID); xdr_string(&xdrs, &AttrName, length); /*------------------------ Send request ---------------------------*/ if( send(SocketID,bufDD_GetInform,REQUESTLENGTH,0) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_GetInform - Cannot send request"); #endif perror("DD_GetInform:"); free(bufDD_GetInform); xdr_destroy(&xdrs); return(REQSENDERR); } free(bufDD_GetInform); xdr_destroy(&xdrs); /*------------------------ Get reply header ------------------------*/ bufDD_GetInform = (caddr_t)malloc(REPLYLENGTH); /* i=0; while(((cc = recv(SocketID,buf,REPLYLENGTH,0)) < 0) && (i < TRY)) i++; if(cc < 0) */ if(( ReceiveFromNet(bufDD_GetInform, REPLYLENGTH)) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_GetInform - Cannot receive from net"); #endif perror("DD_GetInform:"); free(bufDD_GetInform); return(REPLYRECERR); } xdrmem_create(&xdrs, bufDD_GetInform, REPLYLENGTH, XDR_DECODE); xdr_int(&xdrs,&type); if(type < 0) { free(bufDD_GetInform); xdr_destroy(&xdrs); return(type); } xdr_int(&xdrs,&DimNumbers); xdr_int(&xdrs,&PacketSize); free(bufDD_GetInform); xdr_destroy(&xdrs); idd.DimNumber = DimNumbers; idd.type = type; /*---------------------------- Get Data Packet ----------------------*/ if(PacketSize > 0) bufDD_GetInform = (caddr_t)malloc(PacketSize); else { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_GetInform - Cannot Cannot get data packet"); #endif return(REPLYRECERR); } if(( ReceiveFromNet(bufDD_GetInform, PacketSize)) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_GetInform - Cannot receive from net"); #endif perror("DD_GetInform:"); free(bufDD_GetInform); return(REPLYRECERR); } /*--------------------- Decoding data packet ------------------------*/ if(DimNumbers > 0) { /*----------- Memory allocation and xdr creating -----------------*/ xdrmem_create(&xdrs, bufDD_GetInform, (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(int i=0; i < DimNumbers;i++) count = count*idd.Dimensions[i]; MaxNumber = count; } else { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_GetInform - Cannot decoding data packet"); #endif free(bufDD_GetInform); 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], ConvFunc[type]); /*-------------------------- Free all ------------------------------*/ free(bufDD_GetInform); 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_Client:: DD_SetTime(int VarID,char *Time) { int type; int DoneFlag = 0; while(DoneFlag == 0) { /* Allocatein memory and stream */ bufDD_SetTime = (caddr_t)calloc(REQUESTLENGTH, 1); xdrmem_create(&xdrsDD_SetTime, bufDD_SetTime, REQUESTLENGTH, XDR_ENCODE); /* Encoding the request */ xdr_int(&xdrsDD_SetTime,&op); xdr_int(&xdrsDD_SetTime,&VarID); xdr_string(&xdrsDD_SetTime, &Time, TIMELENGTH); /* Send request */ if(( send(SocketID,bufDD_SetTime,REQUESTLENGTH,0)) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_SetTime - Cannot send request"); #endif perror("DD_SetTime:"); free(bufDD_SetTime); xdr_destroy(&xdrsDD_SetTime); return(REQSENDERR); } free(bufDD_SetTime); xdr_destroy(&xdrsDD_SetTime); /* Get reply header */ bufDD_SetTime = (caddr_t)malloc(REPLYLENGTH); if(( ReceiveFromNet(bufDD_SetTime, REPLYLENGTH)) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_SetTime - Cannot receive from net"); #endif perror("DD_SetTime:"); free(bufDD_SetTime); return(REPLYRECERR); } xdrmem_create(&xdrsDD_SetTime, bufDD_SetTime, REPLYLENGTH, XDR_DECODE); xdr_int(&xdrsDD_SetTime,&type); free(bufDD_SetTime); xdr_destroy(&xdrsDD_SetTime); 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_Client:: DD_SetTimeInfo(int VarID, char *Time, double *RealTime) { int err; DD_data_t *data; if ((err = DD_SetTime(VarID, Time)) < 0) { while ((err == WAITEXTCALL) || (err == TRYAGAIN)) { sleep(2); err = DD_SetTime(VarID, Time); } } if (err < 1) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_SetTimeInfo - Cannot set time " << Time); #endif return err; } if ((err = DD_GetData(VarID, (char *)"Time", TimeInt, &data)) < 0) { while ((err == WAITEXTCALL) || (err == TRYAGAIN)) { sleep(2); err = DD_GetData(VarID, (char *)"Time", TimeInt, &data); } } if (err < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_SetTimeInfo - Cannot get data " << Time); #endif return err; } if (data->VarNumber < 1) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_SetTimeInfo - OUTOFTIME error " << Time); #endif return OUTOFTIME; } *RealTime = DD_Time2Double((char *)data->Variables[0]); //BRE - When the corresponding time is the last one of a file, MOREDATA is returned by DDServer. // => force recall of DD_GetData to open the next file and finish correctly the request if (err == MOREDATA) { if ((err = DD_GetData(VarID, (char *)"Time", TimeInt, &data)) < 0) { while ((err == WAITEXTCALL) || (err == TRYAGAIN)) { sleep(2); err = DD_GetData(VarID, (char *)"Time", TimeInt, &data); } } } return 1 ; } /*------------------------- DD_GETDATA --------------------------------*/ /* * VarID - ID of open virtual instrument * VarName - Variable name associated with this virtual instrument * 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_Client::DD_GetData(int VarID,char *VarName,char *TimeInt,DD_data_t **data) { char *xxx=VarName; int 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 - array 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_Client::DD_GetMultiData(int VarID,size_t VarSize, char **VarNames,char *TimeInt,DD_data_t **data, int BackFlag) { size_t id; 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; u_int count, MaxSize=0; int i; /*-------------------------------------- * Create a new Current Data empty array *-------------------------------------*/ for( int i = 0; i < _varNumber; ++i) { CurrentData[i].clear(); } delete[] CurrentData; _varNumber = VarSize; CurrentData = new DD_data_t[_varNumber]; /*-------------------------------------------------------------- * 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 *------------------------------*/ bufDD_GetData = (caddr_t)calloc(REQUESTLENGTH, 1); xdrmem_create(&xdrsDD_GetData, bufDD_GetData, REQUESTLENGTH, XDR_ENCODE); /* Encoding the request */ xdr_int(&xdrsDD_GetData,&op); xdr_int(&xdrsDD_GetData,&VarID); xdr_string(&xdrsDD_GetData,&TimeInt,TIMELENGTH); xdr_int(&xdrsDD_GetData,&XDRReqlength); /* Send the first request */ if(( send(SocketID,bufDD_GetData,REQUESTLENGTH,0)) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Cannot send the first request"); #endif perror("DD_GetData: First Request"); free(bufDD_GetData); free(NameLength); xdr_destroy(&xdrsDD_GetData); return(REQSENDERR); } free(bufDD_GetData); xdr_destroy(&xdrsDD_GetData); /*-------------------------------- * The Second packet of XDRReqlength size * Allocation corresponding memory and stream *------------------------------*/ bufDD_GetData = (caddr_t)malloc(XDRReqlength); xdrmem_create(&xdrsDD_GetData, bufDD_GetData, XDRReqlength, XDR_ENCODE); xdr_int(&xdrsDD_GetData,(int *)(&VarSize)); for(id = 0; id < VarSize; id++) xdr_string(&xdrsDD_GetData, &VarNames[id], NameLength[id]); free(NameLength); NameLength = NULL; xdr_int(&xdrsDD_GetData,&BackFlag); /* Send the second request */ if(( send(SocketID,bufDD_GetData,XDRReqlength,0)) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Cannot send the second request"); #endif perror("DD_GetData:Second Packet"); free(bufDD_GetData); xdr_destroy(&xdrsDD_GetData); return(REQSENDERR); } free(bufDD_GetData); xdr_destroy(&xdrsDD_GetData); } /*----------------------------------------------------------- * Get the VarSize reply headers and VarSize data *----------------------------------------------------------*/ for(id = 0; id < VarSize; id++) { /*------------------- * The header *-----------------*/ bufDD_GetData = (caddr_t)malloc(REPLYLENGTH); if(( ReceiveFromNet(bufDD_GetData, REPLYLENGTH)) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Cannot receive header"); #endif perror("DD_GetData:Error while header receive"); free(bufDD_GetData); return(REPLYRECERR); } xdrmem_create(&xdrsDD_GetData, bufDD_GetData, REPLYLENGTH, XDR_DECODE); xdr_int(&xdrsDD_GetData,&type); xdr_int(&xdrsDD_GetData,&DimNumbers); xdr_int(&xdrsDD_GetData,&PacketSize); free(bufDD_GetData); xdr_destroy(&xdrsDD_GetData); if (type < 0) /* Server returns unrecoverable error */ { #ifdef LOG4CXX LOG4CXX_DEBUG(_logger, "DD_Client::DD_GetMultiData - Server returns " << type << ", no data\n"); #endif fprintf(stderr, "DD_GetData: Server returns %d, no data\n", type); return type; } /*----------- Header is received ----------------------*/ CurrentData[id].DimNumber = DimNumbers - 1; CurrentData[id].type = type; /*--------------- Receive Data Packet ------------------------------*/ if(PacketSize > 0) bufDD_GetData = (caddr_t)malloc(PacketSize); else { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Cannot receive data packet"); #endif return(REPLYRECERR); } if((ReceiveFromNet(bufDD_GetData, PacketSize)) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Cannot receive data packet from web"); #endif perror("DD_GetData: Error while data packet receive"); free(bufDD_GetData); return(REPLYRECERR); } /*----------------- Decoding data packet --------------------*/ if(DimNumbers > 1) { xdrmem_create(&xdrsDD_GetData, bufDD_GetData, (u_int)PacketSize, XDR_DECODE); count = DimNumbers-1; /* allocation memory for dimensions */ CurrentData[id].Dimensions = (int *)malloc((DimNumbers-1)*sizeof(int)); xdr_int(&xdrsDD_GetData,&LastPacketFlag); /* Last Paket Indicatort*/ xdr_int(&xdrsDD_GetData,&CurrentData[id].VarNumber); /* Variables number */ if(LastPacketFlag > 2) { LastPacketFlag = OK; CurrentData[id].VarNumber = 0; free(bufDD_GetData); #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Reply received error"); #endif return(REPLYRECERR); } /*----- Decoding dimensions array -------------------*/ xdr_array(&xdrsDD_GetData, (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) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Reply received error"); #endif free (bufDD_GetData); 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(&xdrsDD_GetData,(caddr_t *)(&(CurrentData[id].Variables[i])),&count,MaxSize,unixlen[type], (xdrproc_t)ConvFunc[type]); } /* Free all */ free(bufDD_GetData); xdr_destroy(&xdrsDD_GetData); } *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_Client:: DD_Close(int VarID) { int RemainedID; /* Server returns number of remained ID */ /* Allocatein memory and stream */ bufDD_Close = (caddr_t)calloc(REQUESTLENGTH, 1); xdrmem_create(&xdrsDD_Close, bufDD_Close, REQUESTLENGTH, XDR_ENCODE); /* Encoding the request */ xdr_int(&xdrsDD_Close,&opDD_Close); xdr_int(&xdrsDD_Close,&VarID); /* Send request */ if(( send(SocketID,bufDD_Close,REQUESTLENGTH,0)) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_Close - Cannot send request " << VarID); #endif perror("DD_Close:"); free(bufDD_Close); xdr_destroy(&xdrsDD_Close); return(REQSENDERR); } free(bufDD_Close); xdr_destroy(&xdrsDD_Close); /* Get reply header */ bufDD_Close = (caddr_t)malloc(REPLYLENGTH); /* i = 0; while(((cc = recv(SocketID,buf,REPLYLENGTH,0)) < 0) && (i < TRY)) i++; if(cc < 0) */ if(( ReceiveFromNet(bufDD_Close, REPLYLENGTH)) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_Close - Cannot receive from net " << VarID); #endif perror("DD_Close:"); free(bufDD_Close); return(REPLYRECERR); } xdrmem_create(&xdrsDD_Close, bufDD_Close, REPLYLENGTH, XDR_DECODE); xdr_int(&xdrsDD_Close,&RemainedID); if(RemainedID< 0) { free(bufDD_Close); xdr_destroy(&xdrsDD_Close); return(RemainedID); } free(bufDD_Close); xdr_destroy(&xdrsDD_Close); if(RemainedID == 0) { shutdown(SocketID,2); close(SocketID); SocketID = -1; /* UserHost[0] = '\0'; UserName[0] = '\0'; */ } return(1); } DD_Client::~DD_Client() { for( int i = 0; i < _varNumber; ++i) { CurrentData[i].clear(); } delete[] CurrentData; } /*------------------------------------------------------------------------------*/ /*=============== DATABASE UPDATE FUNCTIONS ====================================*/ /*------------------ DD_AddDataSet() -------------------------------------------*/ int DD_Client:: DD_AddDataSet(char *DataSetName, char *RemSetID, char *BaseName) { int Err; /* Server returns OK or NOEXEC */ int length; int CloseFlag = 0; /* If there is no connection, try to get it */ if(SocketID < 0) { if((SocketID = GetSocket()) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_AddDataSet - No connection"); #endif return(NOCONNECTION); } CloseFlag = 1; // To close Connection at the end } /* Allocatein memory and stream */ bufDD_AddDataSet = (caddr_t)malloc(REQUESTLENGTH); xdrmem_create(&xdrsDD_AddDataSet, bufDD_AddDataSet, REQUESTLENGTH, XDR_ENCODE); /* Encoding the request */ xdr_int(&xdrsDD_AddDataSet,&opDD_AddDataSet); /* Coding DataSetName */ if((length = strlen(DataSetName)) > MAXSETLENGTH) length = MAXSETLENGTH; xdr_string(&xdrsDD_AddDataSet, &DataSetName, length); /* Coding RemSetID */ if((length = strlen(RemSetID)) > MAXVARLENGTH) length = MAXVARLENGTH; xdr_string(&xdrsDD_AddDataSet, &RemSetID, length); /* Coding BaseName */ if((length = strlen(BaseName)) > MAXVARLENGTH) length = MAXVARLENGTH; xdr_string(&xdrsDD_AddDataSet, &BaseName, length); /* Send request */ if(( send(SocketID,bufDD_AddDataSet,REQUESTLENGTH,0)) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_AddDataSet - Cannot send request"); #endif perror("DD_AddDataSet:"); free(bufDD_AddDataSet); xdr_destroy(&xdrsDD_AddDataSet); return(REQSENDERR); } free(bufDD_AddDataSet); xdr_destroy(&xdrsDD_AddDataSet); /* Get reply header */ bufDD_AddDataSet = (caddr_t)malloc(REPLYLENGTH); if(( ReceiveFromNet(bufDD_AddDataSet, REPLYLENGTH)) < 0) { #ifdef LOG4CXX LOG4CXX_ERROR(_logger, "DD_Client::DD_AddDataSet - Cannot receive from net"); #endif perror("DD_AddDataSet:"); free(bufDD_AddDataSet); return(REPLYRECERR); } xdrmem_create(&xdrsDD_AddDataSet, bufDD_AddDataSet, REPLYLENGTH, XDR_DECODE); xdr_int(&xdrsDD_AddDataSet,&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 ---------------------------------------*/ const char *DD_Client:: DD_GetVersion() /* * return static pointer to internal string with the DDLIB-SERVER package version */ { return Version; } /*------------------------- End Library -------------------------------*/