/* $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 #include "DD.h" #include "DD_comm.h" #include "DD_Access.h" #include #include #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 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, 18 bytes*/ int ScAddrLen = sizeof(struct sockaddr); /* size of socket address, 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 -------------------------------*/