syslib.c

Go to the documentation of this file.
00001 
00011 #ifndef NO_DOXYGEN
00012 #include "prolog.h"
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include <stdlib.h>
00016 #include <ctype.h>
00017 #include <stdarg.h>
00018 #ifdef UNIX
00019 # include <dirent.h>
00020 #endif
00021 #ifdef MSDOS
00022 # include <signal.h>
00023 # include <dos.h>
00024 # include "doscmd.h"
00025 # include "watchdog.h"
00026 #endif
00027 #ifdef WINNT
00028 # include "io.h"
00029 # include "ntcmd.h"
00030 #endif
00031 #ifdef NIOS
00032 # include "nioscmd.h"
00033 #endif
00034 #include "servdef.h"
00035 #include "database.h"
00036 #include "errors.h"
00037 #include "brdcast.h"
00038 #include "history.h"
00039 #include "srvip.h"
00040 #include "toolkit.h"
00041 
00042 int initRPC(void);
00043 int initSAPWatchDog(void);
00044 void FecSynchronize(void);
00045 void initWatchDog(void);
00046 void watchDog(void);
00047 void netWatchDog(void);
00048 int rdate(char *tsHost);
00049 char *whoami(char *user);
00050 extern FunHead FunList[];
00051 time_t *tnull = NULL;
00052 char tagNameFilter[64];
00053 char  dbgbuf[256];
00054 int StartupDebug = 1;
00055 extern int gDelayInitRPCServices;
00056 #ifndef NODAL
00057 EXPORT int NGdebug=0;
00058 #endif
00059 #if !defined(IPXNW) && !defined(IPXBSD)
00060 BYTE reg_socket[2] = { 0, 0 };
00061 IPXAddress IncomingIPXfec;
00062 #endif
00063 
00067 char gUserName[20] = "";
00068 FILE *dbgfp = NULL;
00069 WORD watchdogBaseAddress = 0x0000;
00070 int MaxNumGlobals = MAXGLOBALS;
00071 #ifndef GLOBAL_SYNCHRONIZATION
00072 # define GLOBAL_SYNCHRONIZATION TRUE
00073 #endif
00074 
00075 #ifndef STD_TIME_STR
00076 # define STD_TIME_STR "CET"
00077 #endif
00078 #ifndef DST_TIME_STR
00079 # define DST_TIME_STR "CDT"
00080 #endif
00081 #ifndef STD_TIMEZONE_STR
00082 # define STD_TIMEZONE_STR "TZ=GMT-1GDT"
00083 #endif
00084 #ifndef DLT_TIMEZONE_STR
00085 # define DLT_TIMEZONE_STR "TZ=GMT-1GDT"
00086 #endif
00087 #ifndef STD_TIME_UTC_OFFSET
00088 # define STD_TIME_UTC_OFFSET 0
00089 #endif
00090 #ifndef NLINES
00091 # define NLINES 1000
00092 #endif
00093 
00094 char *ltzname[2] = { STD_TIME_STR, DST_TIME_STR };
00095 char FecDBpath[80];
00096 char *vFeclogBuffer = NULL;
00097 int vFeclogBufferPos = 0;
00098 int leftFeclogTime = FALSE;
00099 char *getTimeServerHost(void);
00100 int METFindDaylight(time_t t);
00101 int NoDstFindDaylight(time_t t);
00102 int (*findDaylightHook)(time_t) = METFindDaylight;
00103 
00104 EXPORT void (*cdiSystemInitHook)(void) = NULL;
00105 EXPORT int (*cdiCloseLinkHook)(int) = NULL;
00106 EXPORT char *(*getCdiLinkNameHook)(char *,char *) = NULL;
00107 EXPORT int (*cdiExecLinkHook)(char *,char *,DTYPE *,DTYPE *,short,UINT16) = NULL;
00108 EXPORT int (*cdiAttachLinkHook)(char *,char *,DTYPE *,DTYPE *,short,int,void (*)(int,int),int,UINT32) = NULL;
00109 EXPORT void (*cdiSystemFreeHook)(void) = NULL;
00110 
00111 void fixLocalTimeSettings(void)
00112 {
00113   char *ptr=NULL;
00114   if ((ptr=getenv("STD_TIME_STR")) != NULL)
00115   {
00116     ltzname[0] = ptr;
00117   }
00118   if ((ptr=getenv("DST_TIME_STR")) != NULL)
00119   {
00120     ltzname[1] = ptr;
00121   }
00122   if (!strcmp(ltzname[0],ltzname[1])) /* no dst ! */
00123   {
00124     findDaylightHook = NoDstFindDaylight;
00125   }
00126 }
00127 EXPORT UINT32 ElfHash(const unsigned char *key)
00128 {
00129   UINT32 g, h = 0;
00130   while (*key)
00131   {
00132     h = (h << 4) + *key++;
00133     g = h & 0xF0000000L;
00134     if (g) h ^= g >> 24;
00135     h &= ~g;
00136   }
00137   return h;
00138 }
00139 EXPORT int getFormatSize(int fmt)
00140 {
00141   switch (fmt)
00142   {
00143     case CF_DOUBLE  : return 8;
00144     case CF_SHORT   : return 2;
00145     case CF_BYTE    : return 1;
00146     case CF_LONG    : return 4;
00147     case CF_FLOAT   : return 4;
00148     case CF_STRUCT  : return 1;
00149     case CF_POCALBLK: return 1;
00150     case CF_CHAR8   : return 8;
00151     case CF_CHAR16  : return 16;
00152     case CF_CHAR32  : return 32;
00153     case CF_CHAR48  : return 48;
00154     case CF_CHAR64  : return 64;
00155     case CF_CHAR16FI: return 24;
00156     case CF_SI      : return 6;
00157     case CF_FI      : return 8;
00158     case CF_II      : return 8;
00159     case CF_DI      : return 12;
00160     case CF_TDS     : return 12;
00161     case CF_HITTS   : return 6;
00162     case CF_CHAR8I  : return 12;
00163     case CF_CHAR16I : return 20;
00164     case CF_CHAR32I : return 36;
00165     case CF_CHAR48I : return 52;
00166     case CF_CHAR64I : return 68;
00167     case CF_USTRING : return 96;
00168     case CF_FFI     : return 12;
00169     case CF_FII     : return 12;
00170     case CF_IFFF    : return 16;
00171     case CF_IIII    : return 16;
00172     case CF_TTII    : return 16;
00173     case CF_IIFF    : return 16;
00174     case CF_FIFI    : return 16;
00175     case CF_XY      : return  8;
00176     case CF_TDSI    : return 12;
00177     case CF_SPECTRUM: return  4;
00178     case CF_TEXT    : return  1;
00179     case CF_XML     : return  1;
00180     case CF_BOOLEAN : return  4;
00181     case CF_BIT     : return  4;
00182     case CF_LNGDBL  : return  12;
00183     case CF_FLTDBL  : return  12;
00184     case CF_DBLDBL  : return  16;
00185     case CF_NAMEDBLDBL : return  32;
00186     case CF_NAME16II : return  24;
00187     case CF_III     : return  12;
00188     case CF_NAME32DBLDBL : return  48;
00189     case CF_NAME64DBLDBL : return  80;
00190     case CF_IFFFNAME : return  32;
00191     case CF_DEFAULT : return  1;
00192     default : break;
00193   }
00194   return 0;
00195 }
00196 short ftoi(char *fmt)
00197 {
00198   char *c,fmtstr[64];
00199   short ifmt;
00200   strncpy(fmtstr,fmt,64);
00201   if ((c=strchr(fmtstr,'.')) != NULL) *c = 0;
00202   strupr(fmtstr);
00203   if ((ifmt=getSimpleFormatType(fmtstr)) != CF_NULL) return ifmt;
00204   return getCompoundFormatType(fmtstr);
00205 }
00206 char *itof(int fmt)
00207 {
00208   static char s[64];
00209   switch(LFMT(fmt))  
00210   {                 
00211     case CF_BYTE: return "BYTE";
00212     case CF_SHORT: return "short";
00213     case CF_LONG: return "UINT32";
00214     case CF_FLOAT: return "float";
00215     case CF_DOUBLE: return "double";
00216     case CF_TEXT: return "char";
00217     case CF_NAME8: return "NAME8";
00218     case CF_NAME16: return "NAME16";
00219     case CF_NAME32: return "NAME32";
00220     case CF_NAME48: return "NAME48";
00221     case CF_NAME64: return "NAME64";
00222     case CF_LNGINT: return "LNGINT";
00223     case CF_FLTINT: return "FLTINT";
00224     case CF_DBLDBL: return "DBLDBL";
00225     case CF_NAME8I: return "NAME8I";
00226     case CF_NAME16I: return "NAME16I";
00227     case CF_NAME32I: return "NAME32I";
00228     case CF_NAME48I: return "NAME48I";
00229     case CF_NAME64I: return "NAME64I";
00230     case CF_NAME16FI: return "NAME16FLTINT";
00231     case CF_NAME16II: return "NAME16INTINT";
00232     case CF_INTFLTINT: return "INTFLTINT";
00233     case CF_FLTINTINT: return "FLTINTINT";
00234     case CF_FLTFLTINT: return "FLTFLTINT";
00235     case CF_FILTER: return "FILTER";
00236     case CF_ADDRESS: return "ADDRESS";
00237     case CF_USTRING: return "USTRING";
00238     case CF_SPECTRUM: return "SPECTRUM";
00239     case CF_POINT: return "POINT";
00240     case CF_WINDOW: return "WINDOW";
00241     case CF_BOOLEAN: return "BOOLEAN";
00242     case CF_IIFF: return "IIFF";
00243     case CF_FIFI: return "FIFI";
00244     default: break;
00245   }
00246   sprintf(s,"%d",LFMT(fmt));
00247   return s;
00248 }
00249 short getArrayType(char *fmt)
00250 {
00251   char *c,typstr[64];
00252   short itype = AT_UNKNOWN;
00253   if ((c=strchr(fmt,'.')) == NULL) return itype;
00254   c++; strncpy(typstr,c,64); strupr(typstr);
00255   if (strstr(typstr,"BOOLEAN") != NULL) itype = AT_BOOLEAN;
00256   if (strstr(typstr,"DOUBLE") != NULL) itype = AT_DOUBLE;
00257   if (strstr(typstr,"CHANNEL") != NULL) itype |= AT_CHANNEL;
00258   else if (strstr(typstr,"SPECTRUM") != NULL) itype |= AT_SPECTRUM;
00259   else if (strstr(typstr,"TRACE") != NULL) itype |= AT_SPECTRUM;
00260   else if (strstr(typstr,"WAVEFORM") != NULL) itype |= AT_SPECTRUM;
00261   else if (strstr(typstr,"UNSTRUCTURED") != NULL) itype |= AT_UNSTRUCTURED;
00262   else if (strstr(typstr,"BLOB") != NULL) itype |= AT_UNSTRUCTURED;
00263   else if (strstr(typstr,"IMAGE") != NULL) itype |= AT_UNSTRUCTURED;
00264   else if (strstr(typstr,"STRUCTURED") != NULL) itype |= AT_STRUCTURED;
00265   return itype;
00266 }
00267 short getArrayRowLength(char *fmt)
00268 {
00269   char *c,typstr[64];
00270   if ((c=strstr(fmt,"DOUBLE.")) == NULL) return 0;
00271   c++; strncpy(typstr,c,64); strupr(typstr);
00272   if ((c=strchr(typstr,'X')) != NULL) c++; else c = typstr;
00273   return atoi(c);
00274 }
00275 short mtoi(char *mod)
00276 {
00277   short accessMode = CA_NULL;
00278 
00279   if (strstr(strupr(mod),"READ")) accessMode |= CA_READ;
00280   if (strstr(mod,"WRITE"))        accessMode |= CA_WRITE;
00281   if (strstr(mod,"ASYNC"))        accessMode |= CA_ASYNC;
00282 
00283   return accessMode;
00284 }
00285 
00286 char *itom(short accessMode)
00287 {
00288   static char accessModeStr[32];
00289 
00290   accessModeStr[0] = 0;
00291   if (accessMode & 0x01) strcat(accessModeStr,strlen(accessModeStr)?"|READ":"READ");
00292   if (accessMode & 0x02) strcat(accessModeStr,strlen(accessModeStr)?"|WRITE":"WRITE");
00293   if (accessMode & 0x04) strcat(accessModeStr,strlen(accessModeStr)?"|ASYNC":"ASYNC");
00294   if (strlen(accessModeStr) == 0) strcat(accessModeStr,"NO");
00295 
00296   strcat(accessModeStr," ACCESS");
00297   return accessModeStr;
00298 }
00299 time_t startuptime;
00300 double gDataTimeStamp;                                      /* System Timestamp  */
00301 double gServerDataTimeStamp;                                /* System Timestamp for server thread */
00302 double gDataTimeStampOffset = 0.0;                          /* for external synchronization */
00303 void hardDelay(int msec)
00304 {
00305   struct timeval tv0,tv;
00306   gettimeofday(&tv0,(struct timezone *)NULL);
00307   tv = tv0;
00308   while (MSECS(tv,tv0) < msec) gettimeofday(&tv,(struct timezone *)NULL);
00309 }
00310 short SychronizeFecClock = 1;
00311 #ifdef MSDOS
00312 void GetCommand(void);
00313 #else
00314 int readvFecLog(char *textbuf,int sizeInBytes);
00315 int vfeclog(char *text);
00316 #endif
00317 #ifdef MSDOS
00318 #pragma warn -wccc
00319 #pragma warn -rch
00320 #endif
00321 void DataDump(char *txt,char *data,int siz,short fmt,short dir)
00322 {
00323   int i,j,l,fsiz,msiz;
00324   float  fdat;
00325   UINT32 ldat,tdat;
00326   short  sdat;
00327   double ddat,ddat2;
00328   time_t timdat;
00329 
00330   dbglog("%s %d entries %s\n",txt,siz,dir == RTOL ? "received" : "returned");
00331   dbgbuf[0] = 0;
00332   switch (fmt)
00333   {
00334    case CF_SHORT:
00335        for (i=0;i<siz;i++)
00336        {
00337           memcpy(&sdat,(short *)&data[i*2],2);
00338           sprintf(&dbgbuf[strlen(dbgbuf)],"%d ",sdat);
00339           if ((i+1)%8 == 0) { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = 0; }
00340        }
00341        break;
00342    case CF_LONG:
00343        for (i=0;i<siz;i++)
00344        {
00345           memcpy(&ldat,(UINT32 *)&data[i*4],4);
00346 #         ifdef MSDOS
00347           sprintf(&dbgbuf[strlen(dbgbuf)],"%ld ",ldat);
00348 #         else
00349           sprintf(&dbgbuf[strlen(dbgbuf)],"%d ",ldat);
00350 #         endif
00351           if ((i+1)%8 == 0) { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = 0; }
00352        }
00353        break;
00354    case CF_FLOAT:
00355        for (i=0;i<siz;i++)
00356        {
00357           memcpy(&fdat,(float *)&data[i*4],4);
00358           sprintf(&dbgbuf[strlen(dbgbuf)],"%g ",fdat);
00359           if ((i+1)%8 == 0) { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = 0; }
00360        }
00361        break;
00362    case CF_BYTE:
00363        for (i=0;i<siz;i++)
00364        {
00365           sprintf(&dbgbuf[strlen(dbgbuf)],"%d ",((unsigned char *)data)[i]);
00366           if ((i+1)%8 == 0) { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = 0; }
00367        }
00368        break;
00369     case CF_DOUBLE:
00370        for (i=0;i<siz;i++)
00371        {
00372           memcpy(&ddat,(double *)&data[i*8],8);
00373           sprintf(&dbgbuf[strlen(dbgbuf)],"%g ",ddat);
00374           if ((i+1)%8 == 0) { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = 0; }
00375        }
00376        break;
00377    case CF_TEXT:
00378        for (i=0,j=0; i<siz; i++)
00379        {
00380           dbgbuf[j++] = data[i];
00381           if (j > 254) { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = j = 0; }
00382        }
00383        break;
00384    case CF_NAME8:
00385    case CF_NAME16:
00386    case CF_NAME32:
00387    case CF_NAME48:
00388    case CF_NAME64:
00389        fsiz = fmtsizeof(fmt); msiz = 64/fsiz;
00390        for (i=0,j=0;i<siz;i++)
00391        {
00392           for (l=0; l<fsiz; l++) dbgbuf[j++] = data[i*fsiz+l];
00393           if ((i+1)%msiz == 0)  { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = j = 0; }
00394           else dbgbuf[j++] = ' ';
00395        }
00396        break;
00397 #  ifndef SMALL_TINE_LIB /* for MSDOS, etc. ... */
00398    case CF_II:
00399        for (i=0;i<siz;i++)
00400        {
00401           memcpy(&ldat,(UINT32 *)&data[i*8],4);
00402           memcpy(&tdat,(UINT32 *)&data[i*8+4],4);
00403           sprintf(&dbgbuf[strlen(dbgbuf)],"%d %d  ",ldat,tdat);
00404           if ((i+1)%8 == 0) { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = 0; }
00405        }
00406        break;
00407    case CF_FI:
00408        for (i=0;i<siz;i++)
00409        {
00410           memcpy(&fdat,(float *)&data[i*8],4);
00411           memcpy(&tdat,(UINT32 *)&data[i*8+4],4);
00412           sprintf(&dbgbuf[strlen(dbgbuf)],"%g %d  ",fdat,tdat);
00413           if ((i+1)%8 == 0) { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = 0; }
00414        }
00415        break;
00416    case CF_DI:
00417        for (i=0;i<siz;i++)
00418        {
00419           memcpy(&ddat,(double *)&data[i*12],8);
00420           memcpy(&tdat,(UINT32 *)&data[i*12+8],4);
00421           sprintf(&dbgbuf[strlen(dbgbuf)],"%g %d  ",ddat,tdat);
00422           if ((i+1)%8 == 0) { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = 0; }
00423        }
00424        break;
00425    case CF_DBLDBL:
00426        for (i=0;i<siz;i++)
00427        {
00428           memcpy(&ddat2,(double *)&data[i*16],8);
00429           memcpy(&ddat,(double *)&data[i*16+8],8);
00430           sprintf(dbgbuf,"%g %g (%10.4f)\n",ddat2,ddat,ddat);
00431           dbglog(dbgbuf);
00432        }
00433        break;
00434    case CF_NAMEDBLDBL:
00435        for (i=0,j=0;i<siz;i++)
00436        {
00437           for (l=0; l<16; l++) dbgbuf[j++] = data[i*32+l];
00438           memcpy(&ddat2,&data[i*32+16],8);
00439           memcpy(&ddat,&data[i*32+24],8);
00440           sprintf(&dbgbuf[strlen(dbgbuf)]," %g %g\n",ddat2,ddat);
00441           dbglog(dbgbuf); dbgbuf[0] = j = 0;
00442        }
00443        break;
00444    case CF_TDS:
00445        for (i=0;i<siz;i++)
00446        {
00447           memcpy(&tdat,(UINT32 *)&data[i*12],4);
00448           memcpy(&fdat,(float *)&data[i*12+4],4);
00449           memcpy(&ldat,(UINT32 *)&data[i*12+8],4);
00450           sprintf(&dbgbuf[strlen(dbgbuf)],"%d %g %d  ",tdat,fdat,ldat);
00451           if ((i+1)%8 == 0) { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = 0; }
00452        }
00453        break;
00454    case CF_NAME16I:
00455        for (i=0,j=0;i<siz;i++)
00456        {
00457           for (l=0; l<16; l++) dbgbuf[j++] = data[i*20+l];
00458           memcpy(&ldat,&data[i*20+16],4);
00459           sprintf(&dbgbuf[strlen(dbgbuf)]," %d\n",ldat);
00460           dbglog(dbgbuf); dbgbuf[0] = j = 0;
00461        }
00462        break;
00463    case CF_NAME8I:
00464        for (i=0,j=0;i<siz;i++)
00465        {
00466           for (l=0; l<8; l++) dbgbuf[j++] = data[i*12+l];
00467           memcpy(&ldat,&data[i*12+8],4);
00468           sprintf(&dbgbuf[strlen(dbgbuf)]," %d\n",ldat);
00469           dbglog(dbgbuf); dbgbuf[0] = j = 0;
00470        }
00471        break;
00472    case CF_NAME32I:
00473        for (i=0,j=0;i<siz;i++)
00474        {
00475           for (l=0; l<32; l++) dbgbuf[j++] = data[i*36+l];
00476           memcpy(&ldat,&data[i*36+32],4);
00477           sprintf(&dbgbuf[strlen(dbgbuf)]," %d\n",ldat);
00478           dbglog(dbgbuf); dbgbuf[0] = j = 0;
00479        }
00480        break;
00481    case CF_NAME48I:
00482        for (i=0,j=0;i<siz;i++)
00483        {
00484           for (l=0; l<52; l++) dbgbuf[j++] = data[i*52+l];
00485           memcpy(&ldat,&data[i*52+48],4);
00486           sprintf(&dbgbuf[strlen(dbgbuf)]," %d\n",ldat);
00487           dbglog(dbgbuf); dbgbuf[0] = j = 0;
00488        }
00489        break;
00490    case CF_NAME16FI:
00491        for (i=0,j=0;i<siz;i++)
00492        {
00493           for (l=0; l<16; l++) dbgbuf[j++] = data[i*24+l];
00494           memcpy(&fdat,&data[i*24+16],4);
00495           memcpy(&ldat,&data[i*24+20],4);
00496 #         ifdef MSDOS
00497           sprintf(&dbgbuf[strlen(dbgbuf)]," %f %ld\n",fdat,ldat);
00498 #         else
00499           sprintf(&dbgbuf[strlen(dbgbuf)]," %f %d\n",fdat,ldat);
00500 #         endif
00501           dbglog(dbgbuf); dbgbuf[0] = j = 0;
00502        }
00503        break;
00504    case CF_FFI:
00505        for (i=0;i<siz;i++)
00506        {
00507           memcpy(&fdat,(float *)&data[i*12],4);
00508           sprintf(&dbgbuf[strlen(dbgbuf)],"%g",fdat);
00509           memcpy(&fdat,(float *)&data[i*12+4],4);
00510           memcpy(&tdat,(UINT32 *)&data[i*12+8],4);
00511           sprintf(&dbgbuf[strlen(dbgbuf)]," %g %d  ",fdat,tdat);
00512           if ((i+1)%3 == 0) { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = 0; }
00513        }
00514        break;
00515    case CF_IFFF:
00516        for (i=0;i<siz;i++)
00517        {
00518           memcpy(&tdat,(UINT32 *)&data[i*16],4);
00519           memcpy(&fdat,(float *)&data[i*16+4],4);
00520 #         ifdef MSDOS
00521           sprintf(&dbgbuf[strlen(dbgbuf)],"%ld %g",tdat,fdat);
00522 #         else
00523           sprintf(&dbgbuf[strlen(dbgbuf)],"%d %g",tdat,fdat);
00524 #         endif
00525           memcpy(&fdat,(float *)&data[i*16+8],4);
00526           sprintf(&dbgbuf[strlen(dbgbuf)]," %g",fdat);
00527           memcpy(&fdat,(float *)&data[i*16+12],4);
00528           sprintf(&dbgbuf[strlen(dbgbuf)]," %g  ",fdat);
00529           if ((i+1)%2 == 0) { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = 0; }
00530        }
00531        break;
00532    case CF_USTRING:
00533        for (i=0;i<siz;i++)
00534        {
00535           memcpy(&tdat,(UINT32 *)&data[i*96],4);
00536           memcpy(&fdat,(float *)&data[i*96+4],4);
00537 #         ifdef MSDOS
00538           sprintf(&dbgbuf[strlen(dbgbuf)],"%ld %g",tdat,fdat);
00539 #         else
00540           sprintf(&dbgbuf[strlen(dbgbuf)],"%d %g",tdat,fdat);
00541 #         endif
00542           memcpy(&fdat,(float *)&data[i*96+8],4);
00543           memcpy(&tdat,(UINT32 *)&data[i*96+12],4);
00544 #         ifdef MSDOS
00545           sprintf(&dbgbuf[strlen(dbgbuf)]," %g %ld %s\n",fdat,tdat,&data[i*96+16]);
00546 #         else
00547           sprintf(&dbgbuf[strlen(dbgbuf)]," %g %d %s\n",fdat,tdat,&data[i*96+16]);
00548 #         endif
00549           dbglog(dbgbuf); dbgbuf[0] = 0;
00550        }
00551        break;
00552    case CF_SPECTRUM:
00553        timdat = (time_t)(*((UINT32 *)&data[80]));
00554 #      ifdef MSDOS
00555        sprintf(&dbgbuf[strlen(dbgbuf)],"%s\n>%s>start: %g\n>inc: %g\n>status: %lu\n",
00556 #      else
00557        sprintf(&dbgbuf[strlen(dbgbuf)],"%s\n>%s>start: %g\n>inc: %g\n>status: %u\n",
00558 #      endif
00559                (char *)&data[0],ctime(&timdat),*((float *)&data[84]),
00560                *((float *)&data[88]),*((UINT32 *)&data[92]));
00561        dbglog(dbgbuf); dbgbuf[0] = 0;
00562        for (i=0;i<siz;i++)
00563        {
00564           memcpy(&fdat,&data[96+i*4],4);
00565           sprintf(&dbgbuf[strlen(dbgbuf)],"%g ",fdat);
00566           if ((i+1)%8 == 0) { strcat(dbgbuf,"\n"); dbglog(dbgbuf); dbgbuf[0] = 0; }
00567        }
00568        break;
00569 #  endif /* SMALL_TINE_LIB */
00570    default:
00571        dbgbuf[0] = 0;
00572        break;
00573   }
00574   strcat(dbgbuf,"\n"); 
00575   dbglog(dbgbuf);
00576 }
00577 
00578 int datacmp(BYTE *d1,BYTE *d2,int siz,int fmt,double t)
00579 /* compares array d1[siz] against d2[siz] with given format
00580    and tolerance */
00581 {
00582   int fmtsize,i;
00583 
00584   fmtsize = fmtsizeof(fmt);
00585   if (!memcmp(d1,d2,siz*fmtsize)) return 0;
00586   if ((short)t == 0) return 1;
00587 
00588   /* data have changed, but by how much? */
00589   switch (fmt)
00590   {
00591    case CF_DOUBLE:
00592        for (i=0; i<siz; i++)
00593         if ( ((double *)d1)[i] < ((double *)d2)[i] - t ||
00594              ((double *)d1)[i] > ((double *)d2)[i] + t ) return 1;
00595        return 0;
00596    case CF_SHORT:
00597        for (i=0; i<siz; i++)
00598         if ( ((short *)d1)[i] < ((short *)d2)[i] - (short)t ||
00599              ((short *)d1)[i] > ((short *)d2)[i] + (short)t ) return 1;
00600        return 0;
00601    case CF_LONG:
00602        for (i=0; i<siz; i++)
00603         if ( ((UINT32 *)d1)[i] < ((UINT32 *)d2)[i] - (UINT32)t ||
00604              ((UINT32 *)d1)[i] > ((UINT32 *)d2)[i] + (UINT32)t ) return 1;
00605        return 0;
00606    case CF_FLOAT:
00607        for (i=0; i<siz; i++)
00608         if ( ((float *)d1)[i] < ((float *)d2)[i] - (float)t ||
00609              ((float *)d1)[i] > ((float *)d2)[i] + (float)t ) return 1;
00610        return 0;
00611    case CF_BYTE:
00612        for (i=0; i<siz; i++)
00613         if ( ((BYTE *)d1)[i] < ((BYTE *)d2)[i] - (BYTE)t ||
00614              ((BYTE *)d1)[i] > ((BYTE *)d2)[i] + (BYTE)t ) return 1;
00615        return 0;
00616   }
00617   return -1;
00618 }
00619 EXPORT int reformat(BYTE *dstData,int dstFmt,BYTE *srcData,int srcFmt,int num)
00620 {
00621   DTYPE d;
00622   UINT32 n = (UINT32)num;
00623 
00624   if (dstFmt == srcFmt) return  0;
00625 
00626   d.dArrayLength = num;
00627   d.dFormat = srcFmt;
00628   d.data.bptr = srcData;
00629 
00630   switch (dstFmt)
00631   {
00632     case CF_SHORT: return getValuesAsShort(&d,(short *)dstData,(short)num);
00633     case CF_LONG: return getValuesAsLong(&d,(UINT32 *)dstData,(short)num);
00634     case CF_FLOAT: return getValuesAsFloat(&d,(float *)dstData,(short)num);
00635     case CF_DOUBLE: return getValuesAsDouble(&d,(double *)dstData,(short)num);
00636     case CF_TEXT: return getValuesAsString(&d,(char *)dstData,&n);
00637     case CF_NAME8: return getValuesAsString(&d,((NAME8 *)dstData)->name,&n);
00638     case CF_NAME16: return getValuesAsString(&d,((NAME16 *)dstData)->name,&n);
00639     case CF_NAME32: return getValuesAsString(&d,((NAME32 *)dstData)->name,&n);
00640     case CF_NAME48: return getValuesAsString(&d,((NAME48 *)dstData)->name,&n);
00641     case CF_NAME64: return getValuesAsString(&d,((NAME64 *)dstData)->name,&n);
00642   }
00643   return illegal_format;
00644 }
00645 
00646 #if defined(MSDOS)|defined(VAX_VMS)|defined(WINNT)
00647 EXPORT struct timeval *gettimeofday(struct timeval *t,struct timezone *tz)
00648 {
00649   struct timeb tb;
00650   ftime(&tb);
00651   t->tv_sec  = (long)tb.time;
00652   t->tv_usec = ((UINT32)tb.millitm)*1000L;
00653   return t;
00654 }
00655 #elif defined(VXWORKS)
00656 struct timeval *gettimeofday(struct timeval *t,struct timezone *tz)
00657 {
00658   struct timespec ts;
00659   clock_gettime(CLOCK_REALTIME,&ts);
00660   t->tv_sec  = ts.tv_sec;
00661   t->tv_usec = ts.tv_nsec/1000;
00662   return t;
00663 }
00664 int millisleep(int msecs)
00665 {
00666 # ifdef USE_TASKDELAY
00667   static int tps = 0;
00668   if (tps == 0) tps = sysClkRateGet();
00669   return taskDelay((tps * msecs)/1000);
00670 # else
00671   struct timespec ts;
00672   ts.tv_sec = msecs/1000;
00673   ts.tv_nsec = (msecs%1000) * 1000000;
00674   return nanosleep(&ts,NULL);
00675 # endif
00676 }
00677 #endif
00678 
00693 int findDaylight(time_t t)
00694 {
00695   return (findDaylightHook != NULL) ? findDaylightHook(t) : 0;
00696 }
00697 int NoDstFindDaylight(time_t t) 
00698 {
00699   t = t;
00700   return 0;
00701 }
00702 int METFindDaylight(time_t t)
00703 {
00704   int dl;
00705   struct tm *tm = localtime(&t);
00706 # if defined(UNIX) || defined(WINNT)
00707   if (tm->tm_isdst > 0) return 1;
00708   if (tm->tm_isdst == 0) return 0;
00709 # endif
00710   if      (tm->tm_mon<2 || tm->tm_mon>9)       dl = 0;  /* winter */
00711   else if (tm->tm_mon>2 && tm->tm_mon<9)       dl = 1;  /* summer */
00712   else if (tm->tm_mon==2)                               /* March */
00713   { if      (tm->tm_mday < 25)                  dl = 0;
00714     else if (tm->tm_wday > tm->tm_mday-25)      dl = 0;
00715     else if (tm->tm_wday == 0 && tm->tm_hour<2) dl = 0; /* Sunday */
00716     else dl = 1;
00717   }
00718   else                                                  /* October */
00719   { if      (tm->tm_mday < 25)                  dl = 1;
00720     else if (tm->tm_wday > tm->tm_mday-25)      dl = 1;
00721     else if (tm->tm_wday == 0 && tm->tm_hour<2) dl = 1; /* Sunday */
00722     else dl = 0;
00723   }
00724   return dl;
00725 }
00726 int search_function(char name[6], FunHead **header, int *type)
00727 {
00728   int i;
00729   FunHead *p;
00730 
00731   for (i=0; i<NumNodalFunctions; i++)
00732   {
00733     if (!strncmp(name,(p = &FunList[i])->F_name,6))
00734     {
00735       *type = p->F_type;
00736       *header = p;
00737       return 0;
00738     }
00739   }
00740   return non_existent;
00741 }
00761 char *whoami(char *user)
00762 {
00763   char *up;
00764   static char usrnam[16];
00765 # ifdef UNIX
00766   FILE *upipe = NULL;
00767 # endif
00768 
00769   if (strlen(gUserName)) { strncpy(usrnam,gUserName,16); goto out; }
00770   strcpy(usrnam,"UNKNOWN");
00771   if ((up=getenv("LOGINAME"))  == NULL &&  /* Novell env. */
00772       (up=getenv("LOGINNAME")) == NULL &&  /*      "      */
00773       (up=getenv("USERNAME"))  == NULL &&  /*      NT     */
00774       (up=getenv("USER"))  == NULL)        /*     UNIX    */
00775        up = getenv("LOGNAME");             /*     UNIX    */
00776   if (up) strncpy(usrnam,up,15);
00777 # if defined(VAX_VMS)
00778   else strncpy(usrnam,"VAX_USER",15);
00779 # elif defined(VXWORKS)
00780   else strncpy(usrnam,"VXW_USER",15);
00781 # elif defined(NIOS)
00782   else strncpy(usrnam,"NIOS_USER",15);
00783 # elif defined(UNIX)
00784   else
00785   {
00786     if ((upipe=popen("whoami","r")) && fgets(usrnam,sizeof(usrnam),upipe))
00787       usrnam[strcspn(usrnam,"\n")] = 0; /* strip CR from whoami return */
00788     if (upipe != NULL) pclose(upipe);
00789   }
00790 # endif
00791   strupr(usrnam);
00792 out:
00793   if (NGdebug) dbglog("Recognizing user: %s",usrnam);
00794   if (user != NULL) strcpy(user,usrnam);
00795   return usrnam;
00796 }
00797 int isAbsolutePath(char *fname)
00798 {
00799   if (fname == NULL || strlen(fname) < 2) return FALSE;
00800   if (fname[1] == ':') return TRUE;
00801   if (fname[0] == '\\') return TRUE;
00802   if (fname[0] == '/') return TRUE;
00803   return FALSE;
00804 }
00805 #define NotALogFile(f) (\
00806   strstr(f,".log") == NULL &&\
00807   strstr(f,".txt") == NULL &&\
00808   strstr(f,".ini") == NULL &&\
00809   strstr(f,".dat") == NULL &&\
00810   strstr(f,".cfg") == NULL &&\
00811   strstr(f,".csv") == NULL)
00812 char gFeclogPath[80];
00813 void applyFecLogPath(char *path,int pathlen)
00814 {
00815   char root[256];
00816   int len = (int)strlen(gFeclogPath);
00817   if (path == NULL) return;
00818   if (isAbsolutePath(path)) return; /* nothing to apply */
00819   if (len + (int)strlen(path) > pathlen) 
00820   {
00821     dbglog("%s + %s too long!",gFeclogPath,path);
00822     return;
00823   }
00824   strncpy(root,gFeclogPath,80);
00825 # if defined(UNIX) || defined(VXWORKS)
00826   if (len == 0) strcpy(root,"./");
00827 # else
00828   if (len == 0) return; /* nothing to apply */
00829 # endif
00830   strncat(root,path,128);
00831   strncpy(path,root,256); /* copy it back */
00832   return;
00833 }
00834 #define MAX_FILE_SCAN_LIMIT 100
00835 int scanFecLogFiles(char *path,char *subpath,NAME64 *namebuf,int *numfiles,int numoffset)
00836 {
00837   int n = numoffset;
00838   static int scancounter = 0;
00839 # ifdef UNIX
00840   char fn[128],tfn[32];
00841 # ifdef FECLOG_SCANDIR
00842   char spath[64];
00843 # endif
00844   DIR *dp;
00845   struct dirent *dirp;
00846 # ifdef FECLOG_SCANDIR
00847   int nread = 0;
00848 # endif
00849 # endif
00850 # ifdef WINNT
00851   char fn[128],fnp[128],tfn[32],spath[64];
00852   struct _finddata_t fp;
00853   SINT32 hfp;
00854   int nread = 0;
00855 # endif
00856 # ifdef MSDOS
00857   char fn[128],fnp[128],tfn[32],spath[64];
00858   struct find_t fb;
00859   int nread = 0;
00860 # endif
00861 
00862   if (namebuf == NULL || numfiles == NULL || *numfiles == 0) return argument_list_error;
00863   if (subpath != NULL) scancounter = 0;
00864 # if defined(UNIX)
00865   if (path != NULL && strlen(path) > 0) strncpy(fn,path,128);
00866   if ((dp=opendir(fn)) == NULL) return no_such_file;
00867   while ((dirp=readdir(dp)) != NULL)
00868   {
00869     if (scancounter++ > MAX_FILE_SCAN_LIMIT) break;
00870     if (!strcmp(dirp->d_name,".") || !strcmp(dirp->d_name,"..")) continue;
00871 #   ifdef FECLOG_SCANDIR
00872     if (dirp->d_type == DT_DIR)
00873     {
00874       if (strlen(path) + strlen(dirp->d_name) > 128) continue;
00875       if (subpath != NULL) strncpy(spath,subpath,60); else spath[0] = 0;
00876       strcat(path,dirp->d_name);
00877       strncpy(fn,path,128);
00878       strcat(spath,dirp->d_name); strcat(spath,"/");
00879       nread = *numfiles;
00880       scanFecLogFiles(fn,spath,namebuf,&nread,n);
00881       n = nread;
00882     }
00883 #   endif
00884     strncpy(tfn,dirp->d_name,32); strlwr(tfn);
00885     if (NotALogFile(tfn)) continue;
00886     if (n >= *numfiles) break;
00887     if (subpath != NULL && strlen(subpath) + strlen(dirp->d_name) < 64)
00888     {
00889       sprintf(namebuf[n++].name,"%s%s",subpath,dirp->d_name);
00890     }
00891     else
00892     {
00893       strncpy(namebuf[n++].name,dirp->d_name,32);
00894     }
00895   }
00896   closedir(dp);
00897 # elif defined(WINNT)
00898   if (strlen(path) > 0 && path[strlen(path)-1] != '\\') strcat(path,"\\");
00899   if (subpath != NULL) strncpy(spath,subpath,48);
00900   sprintf(fn,"%s*.*",path);
00901   if ((hfp=(SINT32)_findfirst(fn, &fp)) == -1) return no_such_file;
00902   do
00903   {
00904     if (scancounter++ > MAX_FILE_SCAN_LIMIT) break;
00905     if (!strcmp(fp.name,".") || !strcmp(fp.name,"..")) continue;
00906     if (fp.attrib & _A_SUBDIR)
00907     {
00908       if (subpath != NULL) strncpy(spath,subpath,60); else spath[0] = 0;
00909       strncpy(fnp,path,128);
00910       if (strlen(fnp) + strlen(fp.name) > 128) continue;
00911       if (strlen(spath) + strlen(fp.name) > 60) continue;
00912       strcat(fnp,fp.name); strcat(fnp,"\\");
00913       strcat(spath,fp.name); strcat(spath,"\\");
00914       nread = *numfiles;
00915       scanFecLogFiles(fnp,spath,namebuf,&nread,n);
00916       n = nread;
00917     }
00918     strncpy(tfn,fp.name,32); strlwr(tfn);
00919     if (NotALogFile(tfn)) continue;
00920     if (n >= *numfiles) break;
00921     if (subpath != NULL && strlen(subpath) + strlen(fp.name) < 64)
00922     {
00923       sprintf(namebuf[n++].name,"%s%s",subpath,fp.name);
00924     }
00925     else
00926     {
00927       strncpy(namebuf[n++].name,fp.name,32);
00928     }
00929   } while (_findnext(hfp,&fp) != -1);
00930 # elif defined(MSDOS)
00931   if (strlen(path) > 0 && path[strlen(path)-1] != '\\') strcat(path,"\\");
00932   sprintf(fn,"%s*.*",path);
00933   if (_dos_findfirst(fn,_A_NORMAL,&fb) != 0) return no_such_file;
00934   do
00935   {
00936     if (scancounter++ > MAX_FILE_SCAN_LIMIT) break;
00937     if (!strcmp(fb.name,".") || !strcmp(fb.name,"..")) continue;
00938     if (fb.attrib & FA_DIREC)
00939     {
00940       if (subpath != NULL) strncpy(spath,subpath,60); else spath[0] = 0;
00941       strncpy(fnp,path,128);
00942       if (strlen(fnp) + strlen(fb.name) > 128) continue;
00943       if (strlen(spath) + strlen(fb.name) > 60) continue;
00944       strcat(fnp,fb.name); strcat(fnp,"\\");
00945       strcat(spath,fb.name); strcat(spath,"\\");
00946       nread = *numfiles;
00947       scanFecLogFiles(fnp,spath,namebuf,&nread,n);
00948       n = nread;
00949     }
00950     strncpy(tfn,fb.name,32); strlwr(tfn);
00951     if (NotALogFile(tfn)) continue;
00952     if (n >= *numfiles) break;
00953     if (subpath != NULL && strlen(subpath) + strlen(fb.name) < 64)
00954     {
00955       sprintf(namebuf[n++].name,"%s%s",subpath,fb.name);
00956     }
00957     else
00958     {
00959       strncpy(namebuf[n++].name,fb.name,13);
00960     }
00961   } while (_dos_findnext(&fb) == 0);
00962 # endif
00963   *numfiles = n;
00964   return 0;
00965 }
00966 int readFecLog(char *textbuf,int sizeInBytes)
00967 {
00968 # ifndef MSDOS
00969   if (vFeclogBuffer != NULL) return readvFecLog(textbuf,sizeInBytes);
00970 # endif
00971   return readFecLogFile("fec.log",textbuf,sizeInBytes);
00972 }
00973 int readFecLogFile(char *fname,char *textbuf,int sizeInBytes)
00974 {
00975   int cc=0,useAbsolutePath=0;
00976   FILE *fp = NULL, *fpb = NULL;
00977   char fn[128],bakname[96], *c;
00978   int sz=0,szb=0,szt=0,pos=0;
00979 # ifdef MSDOS
00980   static char *fmod = "r+t";
00981 # else
00982   static char *fmod = "r";
00983 # endif
00984 
00985   if (nofeclog) return 0;
00986   if (fname == NULL) return no_such_file;
00987   useAbsolutePath = isAbsolutePath(fname);
00988   if (useAbsolutePath) strncpy(fn,fname,128); else sprintf(fn,"%s%s",gFeclogPath,fname);
00989   if ((fp=fopen(fn,fmod)) == NULL) goto checkbak;
00990   fseek(fp,0,SEEK_END); sz = ftell(fp);
00991 checkbak:
00992   if (sz < sizeInBytes)  /* look for back file */
00993   {
00994     szt = 0;
00995     strncpy(bakname,fname,95); bakname[95] = 0;
00996     if ((c=strstr(bakname,".log")) != NULL) *c = 0;
00997     strcat(bakname,".bak");
00998     if (useAbsolutePath) strncpy(fn,bakname,128); else sprintf(fn,"%s%s",gFeclogPath,bakname);
00999     if ((fpb=fopen(fn,fmod)) == NULL) goto filesread;
01000     szt = sizeInBytes - sz;
01001     fseek(fpb,0,SEEK_END); szb = ftell(fpb);
01002     if (szb > szt) pos = szb - szt;
01003     fseek(fpb,pos,SEEK_SET);
01004     szt = (int)fread(textbuf,1,szt,fpb);
01005     pos = 0;
01006     fclose(fpb);
01007   }
01008 filesread:
01009   if (fp)
01010   {
01011     if (sz > sizeInBytes) pos = sz - sizeInBytes;
01012     fseek(fp,pos,SEEK_SET);
01013     szb = (int)fread(&textbuf[szt],1,sizeInBytes-szt,fp);
01014     fclose(fp);
01015     textbuf[szt+szb] = 0;
01016   }
01017   if (sz == 0 && szb == 0) cc = no_such_file;
01018   if (cc) dbglog("%s : %s",fn,erlst[cc]);
01019   return cc;
01020 }
01021 int writeFecLogFile(char *fname,char *textbuf,int sizeInBytes)
01022 {
01023   int cc=0,useAbsolutePath=0;
01024 # ifndef FS_RDONLY
01025   FILE *fp = NULL;
01026   char fn[128],fb[128], *c;
01027 # ifdef MSDOS
01028   static char *fmod = "w+t";
01029 # else
01030   static char *fmod = "w";
01031 # endif
01032 
01033   if (fname == NULL) return no_such_file;
01034   if (sizeInBytes <= 0) return dimension_error;
01035   useAbsolutePath = isAbsolutePath(fname);
01036   if (useAbsolutePath) strncpy(fn,fname,128); else sprintf(fn,"%s%s",gFeclogPath,fname);
01037   strncpy(fb,fn,123); fb[123] = 0;
01038   if ((c=strchr(fb,'.')) != NULL) *c = 0;
01039   strcat(fb,".bak");
01040   remove(fb);
01041   rename(fn,fb);
01042   if ((fp=fopen(fn,fmod)) == NULL) ccerr(file_error);
01043   fwrite(textbuf,1,sizeInBytes,fp);
01044   fclose(fp);
01045 # else 
01046   useAbsolutePath = 0;
01047   ccerr(not_implemented); /* no way to write a log file */
01048 # endif
01049 err:
01050   if (cc) dbglog("%s : %s",fn,erlst[cc]);
01051   return cc;
01052 }
01053 extern char TimeServerHost[64];
01054 char *TimeServerHostPtr=NULL;
01055 char *getTimeServerHost(void)
01056 {
01057   char *ptr=NULL;
01058   if ((ptr=getenv("RDATE")) != NULL)
01059   {
01060     if (!strcmp(ptr,"NONE")) return NULL;
01061     strncpy(TimeServerHost,ptr,64);
01062   }
01063   else
01064   {
01065     if (TIME_SERVER_HOST != NULL) strncpy(TimeServerHost,TIME_SERVER_HOST,64);
01066     else return NULL;
01067   }
01068   return TimeServerHost;
01069 }
01070 int readSelfTest(char *eqm,char *textbuf,int sizeInBytes)
01071 {
01072   int cnt=0,cc=0,sz=0;
01073   FILE *fp = NULL;
01074   char fn[96],lcl[16];
01075 # ifdef MSDOS
01076   char *stext = "-t";
01077   static char *fmod = "r+t";
01078 # else
01079   char *stext = "-selftest";
01080   static char *fmod = "r";
01081 # endif
01082   strncpy(lcl,eqm,EQP_NAME_SIZE);
01083 openSelfTestFile:
01084   textbuf[0] = 0;
01085   sprintf(fn,"%s%s%s.csv",FecDBpath,lcl,stext);
01086   if ((fp=fopen(fn,fmod)) == NULL) 
01087   {
01088     if (cnt++ == 0)
01089     {
01090       strlwr(lcl);                    /* try lower case local eqm name */
01091       goto openSelfTestFile;
01092     }
01093     ccerr(no_such_file);
01094   }
01095   sz = (int)fread(textbuf,1,sizeInBytes,fp);
01096   fclose(fp);
01097 err:
01098   return sz;
01099 }
01100 
01101 #ifdef NIOS
01102 int nr_setclock(SINT32 tgtTime);
01103 extern time_t getUnixTime(char *tsHost);
01104 int rdate(char *tsHost)
01105 {
01106   int isdst;                         /* daylight saving time flag   */
01107   time_t utime=time(NULL);
01108   SINT32dt;
01109 
01110   isdst = findDaylight(utime);
01111   putenv(isdst ? DLT_TIMEZONE_STR : STD_TIMEZONE_STR);
01112   tzset();
01113 
01114   if ((utime=getUnixTime(tsHost)) == 0) return -1;
01115   if ((dt=nr_setclock(utime)) != 0) 
01116   {
01117     feclog("adjust system clock by %d seconds",dt);
01118   }
01119   return 0;
01120 }
01121 void FecShowtime(void)
01122 {
01123   char tstr[32], s[80];
01124   time_t t = time(NULL);
01125 
01126   memset(tstr,0,32);
01127   strncpy(tstr,ctime(&t),19);
01128   sprintf(s,"current FEC time: %s (UNIX: %d)\n>",&tstr[4],t);
01129   ttyoutput(s);
01130 }
01131 int FecSettime(void)
01132 {
01133   static time_t lastlogged = 0;
01134   time_t t;
01135   int delt,log = 0;
01136 
01137   t = time(NULL);
01138   rdate(TimeServerHostPtr);
01139   delt = (int)(time(NULL) - t);
01140   if (abs(delt) > 2) log = 1;
01141   if (t > lastlogged + (3600*24)) log = 1;
01142   if (NGdebug)
01143   {
01144     ttyoutput("time synchronized to server\n>");
01145     FecShowtime();
01146   }
01147   if (log)
01148   {
01149     feclog("synchronized (%d sec)",delt);
01150     lastlogged = t;
01151   }
01152   return 0;
01153 }
01154 void FecSynchronize(void)
01155 {
01156   time_t t = time(NULL);
01157 
01158   if ((t % 3600) == 0)     /* sychronize once per hour */
01159   {
01160     FecSettime();
01161   }
01162 }
01163 #endif /* NIOS */
01164 
01165 #ifdef MSDOS
01166 
01167 int hConn,hControl;
01168 WORD userConnNr;                     /* IPX connection number of PC */
01169 extern time_t getUnixTime(char *tsHost);
01170 int rdate(char *tsHost)
01171 {
01172   struct dostime_t t, t0;
01173   struct dosdate_t d, d0;
01174   struct tm *lt;
01175   time_t utime = getUnixTime(tsHost);
01176   int isdst;                         /* daylight saving time flag   */
01177 
01178   isdst = findDaylight(utime);
01179   putenv(isdst ? DLT_TIMEZONE_STR : STD_TIMEZONE_STR);
01180   tzset();
01181 
01182   if (utime == 0) return -1;
01183 
01184   lt = localtime(&utime);
01185 
01186   _dos_gettime(&t); _dos_getdate(&d);
01187   memcpy(&d0,&d,sizeof(struct dosdate_t));
01188   memcpy(&t0,&t,sizeof(struct dostime_t));
01189 
01190   d.year  = 1900 + lt->tm_year;
01191   d.month = 1 + lt->tm_mon;
01192   d.day   = lt->tm_mday;
01193   t.hour  = lt->tm_hour;
01194   t.minute= lt->tm_min;
01195   t.second= lt->tm_sec;
01196 
01197   if (memcmp(&d,&d0,sizeof(struct dosdate_t)) ) _dos_setdate(&d);
01198   if (memcmp(&t,&t0,sizeof(struct dostime_t)) ) _dos_settime(&t);
01199 
01200   return 0;
01201 }
01202 int DiskErrorCount = 0;
01203 #pragma argsused
01204 int NetHandler(int errval,int ax,int bp,int si)
01205 {
01206   if (ax > 0x04)hardretn(2);
01207   DiskErrorCount++;
01208   return 2;
01209 }
01210 UINT32 far *ColdBoot = (UINT32 far *)0x00400072L;
01211 NodalError F_boot(void)
01212 {
01213   feclog("Booting ...");
01214   *ColdBoot = 0x1234;
01215   asm DB 0EAh,0,0,0FFh,0FFh
01216   return 0;
01217 }
01218 
01219 #define WD_PFORTE 0
01220 #define WD_BECKER 1
01221 #ifndef WD_CARD
01222 # define WD_CARD WD_PFORTE
01223 #endif
01224 
01225 #define WATCH_INTERVAL  5
01226 #define WD_RESET(i)  ((i)+0x0003)
01227 #define WD_POLL(i)   ((i)+0x0002)
01228 #define WD_STATUS(i) ((i)+0x0001)
01229 
01230 int watchdogEnabled = 0;
01231 int watchdogType = WD_CARD;
01232 void GetWatchDogBaseAddress(void)
01233 {
01234   char *c,str[80];
01235   if ((c=getenv("WD_TYPE")) != NULL)
01236   {
01237     if (strstr(c,"BECKER") != NULL) watchdogType = WD_BECKER;
01238   }
01239   sprintf(str,"WD_TYPE : [%s]",c != NULL ? c : "");
01240   feclog(str);
01241   if ((c=getenv("WD_BASEADDR")) != NULL || (c=getenv("WATCHDOG")) != NULL)
01242   {
01243     watchdogBaseAddress = (WORD)strtol(c,NULL,0);
01244   }
01245   sprintf(str,"WD_BASEADDR : [%s]",c != NULL ? c : "");
01246   feclog(str);
01247 }
01248 void initWatchDog(void)
01249 {
01250   char str[256];
01251   WORD baddr = watchdogBaseAddress;
01252 
01253   if (watchdogBaseAddress == 0) return;
01254   if (baddr < 0x240 || baddr > 0x400)
01255   {
01256     sprintf(str,"Illegal watchdog port : %x",baddr);
01257     watchdogBaseAddress = 0;
01258   }
01259   else
01260   {
01261     sprintf(str,"Initializing WATCHDOG at base address %x",baddr);
01262     if (watchdogType == WD_PFORTE)
01263     {
01264       outport(baddr,0x1111);           /* set pattern */
01265       outport(baddr+4,0x01);           /* enable watchdog */
01266       watchdogEnabled = 1;
01267     }
01268     else if (watchdogType == WD_BECKER)
01269     {
01270       outportb(WD_STATUS(baddr),0x01);    /* contact watchdog */
01271       outportb(watchdogBaseAddress,0x00); /* enable watchdog */
01272       watchdogEnabled = 1;
01273     }
01274   }
01275   feclog(str);
01276   return;
01277 }
01278 extern struct timeval thisCycleTime;
01279 void watchDog(void)
01280 {
01281   static unsigned int status, temp;
01282   static time_t t0 = 0;
01283 
01284   if (t0 == 0) initWatchDog();
01285   if (watchdogBaseAddress == 0) return;
01286   if (time(NULL) < t0 + WATCH_INTERVAL ||
01287       !watchdogBaseAddress ||
01288       !watchdogEnabled) return;
01289   t0 = time(NULL);
01290 
01291   if (watchdogType == WD_PFORTE)
01292   {
01293     outport(watchdogBaseAddress+2,0x1111);          /* feed watchdog */
01294     status = 1;
01295   }
01296   else if (watchdogType == WD_BECKER)
01297   {
01298     outportb(WD_POLL(watchdogBaseAddress),0x01);    /* feed watchdog */
01299     status = inportb(watchdogBaseAddress);
01300     temp = inportb(watchdogBaseAddress+1);
01301   }
01302   if (NGdebug>1)
01303   {
01304     dbglog("Watchdog %s (%x)",status == 1 ? "active" : "inactive",status);
01305     dbglog("Temperature %d (%x)",temp,temp);
01306   }
01307   return;
01308 }
01309 void enableWatchDog(void)
01310 {
01311   if (!watchdogBaseAddress || watchdogEnabled) return;
01312   if (watchdogType == WD_PFORTE)
01313   {
01314     outport(watchdogBaseAddress,0x1111);           /* set pattern */
01315     outport(watchdogBaseAddress+4,0x01);           /* enable watchdog */
01316   }
01317   else if (watchdogType == WD_BECKER)
01318   {
01319     outportb(watchdogBaseAddress,0x00);           /* enable watchdog */
01320   }
01321   watchdogEnabled = 1;
01322   return;
01323 }
01324 void disableWatchDog(void)
01325 {
01326   if (!watchdogBaseAddress || !watchdogEnabled) return;
01327   if (watchdogType == WD_PFORTE)
01328   {
01329     outport(watchdogBaseAddress+4,0x00);   /* disable watchdog */
01330   }
01331   else if (watchdogType == WD_BECKER)
01332   {
01333     outportb(watchdogBaseAddress,0x01);    /* disable watchdog */
01334   }
01335   watchdogEnabled = 0;
01336   return;
01337 }
01338 void FecShowtime(void)
01339 {
01340   char tstr[32],strbuf[CMDSIZE];
01341   time_t t = time(NULL);
01342 
01343   memset(tstr,0,32);
01344   strncpy(tstr,ctime(&t),19);
01345   sprintf(strbuf,"current FEC time: %s (UNIX: %ld)\n>",&tstr[4],t);
01346   ttyoutput(strbuf);
01347 }
01348 int FecSettime(void)
01349 {
01350   static time_t lastlogged = 0;
01351   time_t t;
01352   int delt,log = 0;
01353   char str[80];
01354 
01355   t = time(NULL);
01356   rdate(TimeServerHostPtr);
01357   delt = (int)(time(NULL) - t);
01358   if (abs(delt) > 2) log = 1;
01359   if (t > lastlogged + (3600*24)) log = 1;
01360   if (NGdebug)
01361   {
01362     ttyoutput("time synchronized to server\n>");
01363     FecShowtime();
01364   }
01365   if (log)
01366   {
01367     sprintf(str,"synchronized (%+d sec)",delt);
01368     feclog(str);
01369     lastlogged = t;
01370   }
01371   return 0;
01372 }
01373 void FecSynchronize(void)
01374 {
01375   struct time t;
01376   static int next_hour = -1;
01377 
01378   gettime(&t);
01379   if (next_hour < 0) next_hour = t.ti_hour;
01380   if (t.ti_hour == next_hour)     /* sychronize once per hour */
01381   {
01382     FecSettime();
01383     gettime(&t);
01384     next_hour = (next_hour + 1) % 24;
01385   }
01386 }
01387 
01388 #else  /* MSDOS not defined */
01389 
01390 int vfeclog(char *text)
01391 {
01392   int i, len, maxlen = FeclogDepth*80;
01393   char str[255];
01394   if (vFeclogBuffer == NULL || text == NULL) return 0;
01395   strncpy(str,text,255);
01396   len = (int)strlen(str);
01397   for (i=0; i<len; i++) vFeclogBuffer[(vFeclogBufferPos+i)%maxlen] = str[i];
01398   vFeclogBufferPos = (vFeclogBufferPos + len) % maxlen;
01399   return 0;
01400 }
01401 int readvFecLog(char *textbuf,int sizeInBytes)
01402 {
01403   int endptr = vFeclogBufferPos, startptr = 0;
01404   int i, maxlen = FeclogDepth*80;
01405   if (vFeclogBuffer[vFeclogBufferPos] != 0)
01406   {
01407     endptr = (vFeclogBufferPos + maxlen - 1)%maxlen;
01408     startptr = vFeclogBufferPos;
01409   }
01410   if (sizeInBytes < (endptr-startptr+maxlen)%maxlen)
01411     startptr = (endptr - sizeInBytes + maxlen) % maxlen;
01412   for (i=0; i<sizeInBytes; i++)
01413   {
01414     if (i >= maxlen) break;
01415     if ((textbuf[i]=vFeclogBuffer[(startptr+i)%maxlen]) == 0) break;
01416   }
01417   return 0;
01418 }
01419 #ifndef WINNT /* or MSDOS */
01420 char *_strdate(char *buf)
01421 {
01422   time_t t;
01423   struct tm *tm;
01424   time(&t);  
01425   t += (SINT32)gDataTimeStampOffset;
01426   tm=localtime(&t);
01427   sprintf(buf,"%02d/%02d/%02d",(tm->tm_mon)+1,tm->tm_mday,tm->tm_year%100);
01428   return buf;
01429 }
01430 char *_strtime(char *buf)
01431 {
01432   time_t t;
01433   struct tm *tm;
01434   time(&t);  
01435   t += (SINT32)gDataTimeStampOffset;
01436   tm=localtime(&t);
01437   sprintf(buf,"%02d:%02d:%02d",tm->tm_hour,tm->tm_min,tm->tm_sec);
01438   return buf;
01439 }
01440 char *strupr(char *s)
01441 {
01442   char *c;
01443   for (c=s; c && *c; c++) if (*c >= 'a' && *c <= 'z') *c -= 32;
01444   return s;
01445 }
01446 char *strlwr(char *s)
01447 {
01448   char *c;
01449   for (c=s; c && *c; c++) if (*c >= 'A' && *c <= 'Z') *c += 32;
01450   return s;
01451 }
01452 char *strrev(char *s)
01453 {
01454   char c;
01455   register int i,len = (int)strlen(s);
01456   for (i=0; i<len/2; i++) { c = s[i]; s[i] = s[len-1-i]; s[len-1-i] = c; }
01457   return s;
01458 }
01459 #ifndef NIOS /* or WINNT or MSDOS */
01460 int stricmp(char *s1,char *s2)
01461 {
01462   char *c1,*c2;
01463   for (c1=s1,c2=s2; *c1 != 0 && *c2 != 0; c1++,c2++)
01464     if (toupper(*c1) != toupper(*c2)) break;
01465   return toupper(*c2) - toupper(*c1);
01466 }
01467 int strnicmp(char *s1,char *s2,int n)
01468 {
01469   char *c1,*c2;
01470   int i;
01471   for (c1=s1,c2=s2,i=0; *c1 != 0 && *c2 != 0; c1++,c2++,i++)
01472   {
01473     if (toupper(*c1) != toupper(*c2)) break;
01474     if (i >= n-1) break;
01475   }
01476   return toupper(*c2) - toupper(*c1);
01477 }
01478 #endif /* not defined NIOS, DOS, WINNT */
01479 #endif /* not defined WINNT, DOS */
01480 
01481 int D_dummy(double *v,short r,short n,short f,char *p) { return 0; }
01482 FunHead FunList[] =
01483 {
01484    { 0,"DUMMY","",D_dummy},
01485    { 0,"DUMMY","",D_dummy},
01486    { 0,"DUMMY","",D_dummy},
01487    { 0,"DUMMY","",D_dummy},
01488    { 0,"DUMMY","",D_dummy},
01489    { 0,"DUMMY","",D_dummy},
01490    { 0,"DUMMY","",D_dummy},
01491    { 0,"DUMMY","",D_dummy},
01492    { 0,"DUMMY","",D_dummy},
01493    { 0, "","", NULL },
01494 };
01495 int NumNodalFunctions = sizeof(FunList)/sizeof(FunHead) - 1;
01496 
01497 #endif /* else MSDOS not defined */
01498 
01499 #ifdef VXWORKS
01500 void RPCConsumer(void)
01501 {
01502   for(;;) doConsumer();
01503 }
01504 void VXWbkgtsk(void (*tsk)(void),int rate,int ref)
01505 {
01506   int ticks = (sysClkRateGet() * rate) / 1000;
01507   void (*bkgtsk)(void) = tsk;
01508   int ready = FALSE;
01509   ExportListStruct *el = getExportListItemFromId(ref);
01510 
01511   if (ticks < 1) ticks = 1;
01512   if (StartupDebug)
01513   {
01514     dbglog("background task polling rate : %d msec (%d ticks)",rate,ticks);
01515   }
01516   if (el == NULL) ready = TRUE;
01517   while (!ServerExitCondition)
01518   {
01519     if (!ready) ready = el->inidone;
01520     if (ServerInitialized && ready) bkgtsk();
01521     taskDelay(ticks);
01522   }
01523 }
01524 #endif /* VXWORKS */
01525 
01526 #ifdef MULTITHREADED
01527 #include "threader.h"
01528 int useMultiThreadedBackgroundTasks = TRUE;
01529 int useMultiThreadedEquipmentFunctions = FALSE;
01530 int hEqpFcnThread = 0;
01531 #if defined(UNIX)
01532 pthread_attr_t gBkgThreadAttr, *gPtrBkgThreadAttr = &gBkgThreadAttr;
01533 pthread_attr_t gEqpThreadAttr, *gPtrEqpThreadAttr = &gEqpThreadAttr;
01534 pthread_mutex_t EqpThreadMutex = PTHREAD_MUTEX_INITIALIZER;
01535 pthread_mutex_t *hEqpThreadMutex = &EqpThreadMutex;
01536 int bkgCreateThread(BkgThreadFcn *tsk)
01537 {
01538   int cc;
01539   pthread_t tid;
01540   pthread_attr_init(gPtrBkgThreadAttr);
01541   cc = pthread_create(&tid,gPtrBkgThreadAttr,bkgTaskThread,(void *)tsk);
01542   return cc ? 0 : (int)tid;
01543 }
01544 int eqpCreateThread(void)
01545 {
01546   int cc;
01547   pthread_t tid;
01548 
01549   if ((cc=pthread_mutex_init(hEqpThreadMutex,NULL)) != 0)
01550   {
01551     feclog("Cannot create Equipment Function Mutex: error %d",cc);
01552     return 0;
01553   }
01554   if ((cc=pthread_mutex_lock(hEqpThreadMutex)) != 0)
01555   {
01556     feclog("Cannot lock Equipment Function Mutex: error %d",cc);
01557     return 0;
01558   }
01559   pthread_attr_init(gPtrEqpThreadAttr);
01560 # ifdef FORCE_PTHREAD_SCOPE_SYSTEM
01561   if ((cc=pthread_attr_setscope(gPtrEqpThreadAttr,PTHREAD_SCOPE_SYSTEM)) != 0) 
01562   {
01563     feclog("Cannot set thread scope !\n");
01564   }
01565 # endif
01566   cc = pthread_create(&tid,gPtrEqpThreadAttr,eqpTaskThread,NULL);
01567   return cc ? 0 : (int)tid;
01568 }
01569 int WaitForMutex(pthread_mutex_t *mx,int to)
01570 {
01571   struct timespec ts;
01572 # ifdef NO_MUTEX_TIMEDLOCK
01573   int cc = -1;
01574   struct timeval tv0, tv1;
01575 # endif
01576   ts.tv_sec = 0; ts.tv_nsec = 1000;
01577   nanosleep(&ts,NULL);
01578   if (to < 0) return pthread_mutex_lock(mx);
01579 # ifndef NO_MUTEX_TIMEDLOCK
01580   ts.tv_sec = to/1000;
01581   ts.tv_nsec = (to%1000) * 1000000;
01582   return pthread_mutex_timedlock(mx,&ts);
01583 # else
01584   gettimeofday(&tv0,(struct timezone *)NULL); tv1 = tv0;
01585   while ((UINT32)MSECS(tv1,tv0) < to)
01586   {
01587     if ((cc=pthread_mutex_trylock(mx)) == 0) return 0;
01588     gettimeofday(&tv1,(struct timezone *)NULL);
01589   }
01590   return cc;
01591 # endif
01592 }
01593 
01594 #elif defined(WINNT)
01595 DWORD dwBkgThreadId,dwEqpThreadId;
01596 HANDLE hEqpThreadMutex;
01597 int bkgCreateThread(BkgThreadFcn *tsk)
01598 {
01599   return (int)CreateThread(NULL,0,bkgTaskThread,(LPVOID)tsk,0,&dwBkgThreadId);
01600 }
01601 int eqpCreateThread(void)
01602 {
01603   if ((hEqpThreadMutex=CreateMutex(NULL,TRUE,EqpThreadMutexName)) == NULL)
01604   {
01605     feclog("Cannot create Equipment Function Mutex!");
01606     return 0;
01607   }
01608   return (int)CreateThread(NULL,0,eqpTaskThread,NULL,0,&dwEqpThreadId);
01609 }
01610 #endif /* UNIX or WINNT */
01611 
01612 THREAD_TYPE eqpTaskThread(THREAD_PARAM lpvThreadParam)
01613 {
01614   ExportListStruct *el;
01615   ContractListStruct *cl;
01616   struct timeval tv0, tv1;
01617   UINT32 delay = gSystemTick;
01618   int wasCalled = FALSE;
01619   while (!ServerExitCondition)
01620   {
01621     WaitForMutex(hEqpThreadMutex,-1);
01622     wasCalled = FALSE;
01623     if (NGdebug > 2) dbglog("[T2]: got mutex");
01624     if ((cl=ContractListItem) != NULL)
01625     {
01626       if (cl->compStatus == not_signalled) cl->compStatus = not_posted;
01627       if (cl->compStatus == not_posted && (el=cl->exp)->EqpFcn != NULL)
01628       {
01629         gettimeofday(&tv0,(struct timezone *)NULL);
01630         cl->compStatus = (*el->EqpFcn)(cl->lngDeviceName,cl->lngPropertyName,
01631                                        cl->dout,cl->din,cl->contract.EqpAccess);
01632         gettimeofday(&tv1,(struct timezone *)NULL);
01633         delay = ((UINT32)MSECS(tv1,tv0) < gSystemTick) ? 0 : gSystemTick;
01634         wasCalled = TRUE;
01635       }
01636       if (NGdebug > 2) 
01637         dbglog("[T2]: %s %s %s <%d> %s -> delay %d ms",
01638           cl->contract.EqpName,cl->contract.EqpDeviceName,
01639           cl->contract.EqpProperty,cl->compStatus,wasCalled ? "done" : "not called",delay);
01640     }
01641     else 
01642     {
01643       if (NGdebug > 2) dbglog("[T2]: Contract empty -> delay %d ms",delay);
01644     }
01645     ContractListItem = NULL;
01646     ReleaseMutex(hEqpThreadMutex); /* let the primary thread catch this */
01647     if (NGdebug > 2) dbglog("[T2]: Release mutex");
01648     millisleep(delay);           /* avoid spinning here if we can help it ! */
01649     delay += gSystemTick;
01650   }
01651   return 0;
01652 }
01653 THREAD_TYPE bkgTaskThread(THREAD_PARAM lpvThreadParam)
01654 {
01655   int dly;
01656   struct timeval tv1,tv2;
01657   int ready = FALSE;
01658 
01659   BkgThreadFcn btf;
01660 
01661   btf = *(BkgThreadFcn *)lpvThreadParam;
01662   if (btf.ref == NULL) ready = TRUE;
01663   while (!ServerExitCondition)
01664   {
01665     if (!ready) ready = ((ExportListStruct *)btf.ref)->inidone;
01666     gettimeofday(&tv1,(struct timezone *)NULL);
01667     if (ServerInitialized && ready) btf.tsk();    /* do the registered background task */
01668     gettimeofday(&tv2,(struct timezone *)NULL);
01669     dly = btf.rate - MSECS(tv2,tv1);
01670     if (dly < 0) dly = 0;
01671     millisleep(dly);
01672   }
01673   return 0;
01674 }
01675 #endif /* MULTITHREADED */
01676 void _SystemEngine(void)
01677 {
01678   if (NrOfEqpTypes) dorpc();   /* check remote tasks  */
01679   if (nConnectionTableEntries) doConsumer();     /* Check our client list if any */
01680 }
01681 EXPORT int ServerInitialized = FALSE;
01682 #if !defined(UNIX) && !defined(WINNT)
01683 EXPORT int dbglog(char *text,...)
01684 {
01685   int cc=0;
01686   char str[256];
01687   va_list args;
01688 
01689   if (strlen(text) > 80) ccerr(string_too_long);
01690   va_start(args,text);
01691   vsprintf(str,text,args);
01692   if (str[strlen(str)-1] == '\n') strcat(str,">");
01693   else sprintf(&str[strlen(str)]," @%s\n>",getDataTimeString((double)time(NULL),FALSE));
01694   va_end(args);
01695   if (strlen(tagNameFilter) && !strstr(str,tagNameFilter)) return 0;
01696   printf(str);
01697 err:
01698   return cc;
01699 }
01700 int dbgoutput(char *str,time_t *ts)
01701 {
01702   char strbuf[CMDSIZE];
01703   if (strlen(tagNameFilter) && !strstr(str,tagNameFilter)) return 0;
01704   if (ts != NULL)
01705   {
01706     if (strlen(str) > CMDSIZE-29) str[CMDSIZE-29] = 0; /* just in case */
01707     sprintf(strbuf,"%s @%ld\n>",str,*ts);
01708   }
01709   else sprintf(strbuf,"%s\n>",str);
01710 
01711   printf(strbuf);
01712   if (dbgfp != NULL) fprintf(dbgfp,strbuf);
01713   return 0;
01714 }
01715 #endif
01716 #ifdef UNIX
01717 int millisleep(int msec)
01718 {
01719 # ifdef USE_USLEEP
01720   return usleep(msec*1000);
01721 # else
01722   struct timespec ts;
01723   if (msec <= 0) return 0;
01724   ts.tv_sec = msec/1000;
01725   ts.tv_nsec = (msec%1000) * 1000000;
01726   return nanosleep(&ts,NULL);
01727 # endif
01728 }
01729 #endif
01730 int dumpSemaphores(void)
01731 {
01732   char s[256];
01733   sprintf(s,"Attach Link   : %d\n",AttachLinkSemaphore); ttyoutput(s);
01734   sprintf(s,"Exec Link     : %d\n",ExecLinkSemaphore); ttyoutput(s);
01735   sprintf(s,"Recv Global   : %d\n",recvNetGlobalSemaphore); ttyoutput(s);
01736   sprintf(s,"Consumer Loop : %d\n",doConsumerSemaphore); ttyoutput(s);
01737   sprintf(s,"EqpFcn busy   : %d\n",gEqpFcnBusySemaphore); ttyoutput(s);
01738   sprintf(s,"Exit Condition: %d\n",ServerExitCondition); ttyoutput(s);
01739   return 0;
01740 }
01741 void fixFecRepository(void)
01742 {
01743   char *ptr;
01744   int len;
01745   memset(FecDBpath,0,80);
01746   if ((ptr=getenv("FEC_HOME")) != NULL || (ptr=getenv("FECDB")) != NULL)
01747   {
01748     strncpy(FecDBpath,ptr,80);
01749 #   ifdef FS_DELIMITER
01750     len = (int)strlen(FecDBpath);
01751     if (FecDBpath[len-1] != FS_DELIMITER) FecDBpath[len] = FS_DELIMITER;
01752 #   endif
01753   }
01754   memset(gFeclogPath,0,80);
01755   if ((ptr=getenv("FEC_LOG")) != NULL || (ptr=getenv("FECLOG")) != NULL) 
01756   {
01757     strncpy(gFeclogPath,ptr,64);
01758 #   ifdef FS_DELIMITER
01759     len = (int)strlen(gFeclogPath);
01760     if (gFeclogPath[len-1] != FS_DELIMITER) gFeclogPath[len] = FS_DELIMITER;
01761 #   endif
01762   }
01763   else
01764   {
01765     strncpy(gFeclogPath,FecDBpath,64);
01766   }
01767   if ((ptr=getenv("FECLOGDEPTH")) != NULL || (ptr=getenv("LOGDEPTH")) != NULL) 
01768     FeclogDepth = atoi(ptr);
01769   if ((ptr=getenv("FECPOLLRATE")) != NULL) 
01770   {
01771     MinPollingRate = atoi(ptr);
01772     if (MinPollingRate < 10) MinPollingRate = 10;
01773     if (MinPollingRate > 1000) MinPollingRate = 1000;
01774   }
01775   if ((ptr=getenv("FECWORKAREASIZE")) != NULL)
01776   {
01777     MaxRPCTransportSize = atoi(ptr);
01778     if (MaxRPCTransportSize < 4096) MaxRPCTransportSize = 4096;
01779   }
01780 }
01781 #endif /* NO_DOXYGEN */
01782 #if defined(VXWORKS) || defined(NIOS)
01783 EXPORT int nofeclog = TRUE;
01784 #else
01785 EXPORT int nofeclog = FALSE;
01786 #endif
01787 EXPORT int putCommandsInFeclog = TRUE;
01788 EXPORT int FeclogDepth = NLINES;
01789 EXPORT int useGlobalSynchronization = GLOBAL_SYNCHRONIZATION;
01790 EXPORT int feclog(char *text,...)
01791 {
01792   int len,cc=0;
01793   double ts = makeDataTimeStamp();
01794   static SINT32 flen = -1;
01795   char str[256],fn[96],fb[96];
01796   FILE *fp = NULL;
01797   va_list args;
01798 # ifdef MSDOS
01799   static char *fmod = "a+t";
01800 # else
01801   static char *fmod = "a+";
01802 # endif
01803   fn[0] = 0;
01804   if (strlen(text) > 80) ccerr(string_too_long);
01805   va_start(args,text);
01806   sprintf(str,"%s[%s] ",getDataTimeString(ts,0),gFecName);
01807   vsprintf(&str[strlen(str)],text,args);
01808   if (str[strlen(str)-1] != '\n') strcat(str,"\n");
01809   va_end(args);
01810   if (NGdebug) dbglog(str);
01811 # ifndef MSDOS
01812   if (vFeclogBuffer != NULL) return vfeclog(str);
01813 # endif
01814   if (nofeclog) ccerr(0);
01815 # ifndef FS_RDONLY
01816   sprintf(fn,"%s%s",gFeclogPath,"fec.log");
01817   if ((fp=fopen(fn,fmod)) == NULL) ccerr(file_error);
01818   fwrite(str,len=(int)strlen(str),1,fp);
01819   if (flen == -1) flen = ftell(fp);
01820   if ((flen += len) < FeclogDepth*2*80) ccerr(0);     /* finished */
01821   fclose(fp); fp = NULL; flen = 0;
01822   sprintf(fb,"%s%s",gFeclogPath,"fec.bak");
01823   remove(fb);
01824   rename(fn,fb);
01825 # else 
01826   fb[0] = 0; len = 0; flen = flen; /* avoid warnings in this case */
01827   ccerr(not_implemented); /* no way to write a log file */
01828 # endif
01829 err:
01830   if (fp) fclose(fp);
01831   if (cc)
01832   {
01833     dbglog("%s : %s",fn,erlst[cc]);
01834   }
01835   return cc;
01836 }
01837 EXPORT char *getDataTimeString(double ts,int useLongStringFormat)
01838 {
01839   static char tsstr[64];
01840   time_t t = (time_t)ts;
01841   UINT32 ms = (UINT32)((ts-(double)t) * 1000.0);
01842   int isdst = findDaylight(t);
01843   struct tm *tms;
01844 
01845   t += (isdst+1) * STD_TIME_UTC_OFFSET;
01846 
01847   if (useLongStringFormat)
01848   {
01849     strncpy(tsstr,ctime(&t),24);
01850     strncpy(&tsstr[28],&tsstr[20],4); tsstr[32] = 0;
01851 #   ifdef MSDOS
01852     sprintf(&tsstr[19],".%03ld",ms);
01853 #   else
01854     sprintf(&tsstr[19],".%03d",ms);
01855 #   endif
01856     sprintf(&tsstr[23]," %s",ltzname[isdst]);
01857     tsstr[27] = ' ';
01858   }
01859   else
01860   {
01861     tms = localtime(&t);
01862     sprintf(tsstr,"%02d.%02d.%02d %02d:%02d:%02d.%03d %s",
01863       tms->tm_mday,tms->tm_mon+1,tms->tm_year%100,
01864       tms->tm_hour,tms->tm_min,tms->tm_sec,
01865       (int)ms,ltzname[isdst]);
01866   }
01867   return tsstr;
01868 }
01869 EXPORT struct timeval *getDataTimeStampAsTimeval(void)
01870 {
01871   static struct timeval tv;
01872   tv.tv_sec = RPCtimestamp;
01873   tv.tv_usec = (RPCtimestampMSEC) * 1000;
01874   return &tv;
01875 }
01876 EXPORT double getDataTimeStamp(void)
01877 {
01878   return gDataTimeStamp;
01879 }
01880 EXPORT double makeDataTimeStamp(void)
01881 {
01882   struct timeval tv;
01883   double ts;
01884   gettimeofday(&tv,(struct timezone *)NULL);
01885   ts = (double)tv.tv_sec;
01886   ts += (double)(tv.tv_usec)/1000000.0;
01887   ts += gDataTimeStampOffset;
01888   return ts;
01889 }
01890 EXPORT double putDataTimeStamp(double toffset, time_t tsec, int tmsec)
01891 {
01892   double ts;
01893   ts = (double)tsec;
01894   ts += (double)tmsec/1000.0;
01895   ts += toffset;
01896   return ts;
01897 }
01898 EXPORT void setDataTimeStamp(double ts)
01899 {
01900   gServerDataTimeStamp = ts;                                /* this should be thread-safe */
01901   gDataTimeStamp = ts;                                      /* this isn't */
01902 }
01903 EXPORT int _SystemCycle(int chkcmd)
01904 {
01905   if (NrOfEqpTypes || 
01906       FecNameRegistered || 
01907       gDelayInitRPCServices) 
01908     dorpc();                                             /* check remote tasks  */
01909   checkTasklist();                                 /* run through the task list */
01910   if (nConnectionTableEntries) doConsumer();    /* Check our client list if any */
01911   if (nHistoryRecords) historyCycle();
01912 # ifdef RDATE
01913   if (SychronizeFecClock) FecSynchronize();                  /* Synchronize FEC */
01914 # endif
01915 # ifdef MSDOS
01916   if (watchdogBaseAddress) watchDog();                     /* hardware watchdog */
01917   netWatchDog();                                            /* network watchdog */
01918 # endif
01919 # if defined(MSDOS) || defined(WINNT) || defined(NIOS)
01920   if (chkcmd) GetCommand();    /* simple command line interpreter */
01921 # endif
01922 # ifdef UNIX
01923   foregroundTTY = foreground = chkcmd ? IsInForeground() : 0;
01924 # endif
01925   return (ReturnToServerCycle | ReturnToClientCycle); /* need to return */
01926 }
01927 EXPORT void _SystemDelay(int msec)
01928 {
01929   int forever;
01930   struct timeval tv0,tv;
01931   gettimeofday(&tv0,(struct timezone *)NULL);
01932   tv = tv0;
01933   forever = msec < 0 ? 1 : 0;
01934   while (forever || (MSECS(tv,tv0) < msec))
01935   {
01936     SystemCycle(TRUE);
01937     gettimeofday(&tv,(struct timezone *)NULL);
01938   }
01939 }
01940 EXPORT int _SystemInit(int netchk)
01941 {
01942   int cc;
01943 
01944   fixLocalTimeSettings();
01945   fixFecRepository();
01946 # ifndef MSDOS
01947   if (nofeclog && FeclogDepth > 0)
01948   {
01949     vFeclogBuffer = (char *)SystemCalloc(FeclogDepth,80);
01950   }
01951 # else
01952   signal(SIGFPE,SIG_IGN);            /* catch Floating domain errors */
01953   harderr(NetHandler);               /* start error handler          */
01954   whoami(gUserName);                  /* find out who we are */
01955   GetWatchDogBaseAddress();          /* check environment for watchdog */
01956 # endif
01957 # if defined(RDATE)
01958   TimeServerHostPtr = getTimeServerHost();
01959   rdate(TimeServerHostPtr);          /* synchronize */
01960 # elif !defined(VXWORKS)
01961   tzset();
01962 # endif
01963 
01964   if ((cc=initRPC()) != 0) return cc;
01965 
01966 # ifdef MULTITHREADED
01967   if (useMultiThreadedEquipmentFunctions) 
01968   {
01969     hEqpFcnThread = eqpCreateThread();
01970     feclog("FEC: Equipment Functions managed in separate thread");
01971   }
01972 # endif
01973 
01974 # ifdef MSDOS
01975   if (netchk)     /* network watchdog */
01976     feclog(initSAPWatchDog() ? "SAP Watchdog not active" : "SAP Watchdog active");
01977   feclog("started");
01978 # endif
01979 
01980   ServerInitialized = TRUE;
01981 
01982   return cc;
01983 }
01984 EXPORT int _SystemReset(int level)
01985 {
01986   level = level;                    /* keep level in mind for later use */
01987   ReturnToClientCycle = 0;          /* no immediate need */
01988   ReturnToServerCycle = 0;
01989   nConnectionTableEntries = NameServerLoaded ? 1 : 0; /* clear the connection table */
01990   doConsumerSemaphore = 0;          /* clear all semaphores */
01991   ExecLinkSemaphore = 0;
01992   AttachLinkSemaphore = 0;
01993   recvNetGlobalSemaphore = 0;
01994   isNameServerRequest = FALSE;
01995   return 0;
01996 }
01997 EXPORT BYTE *SystemVersion(void)
01998 {
01999   static BYTE ver[4];
02000   ver[0] = MAJOR_VERSION; ver[1] = MINOR_VERSION;
02001   ver[2] = VERSION_REVISION/256; ver[3] = VERSION_REVISION%256;
02002   return ver;
02003 }
02004 EXPORT int _SystemScheduleProperty(char *eqm, char *prp)
02005 {
02006   int i;
02007   ContractListStruct *cl;       /* improve readability by assignment */
02008   char *p=NULL,prpstr[512];
02009 
02010   if (eqm == NULL || prp == NULL) return argument_list_error;
02011   strncpy(prpstr,prp,512);
02012   for (p=strtok(prpstr,",|"); p != NULL; p=strtok(NULL,",|"))
02013   {
02014     if (GetPropertyId(eqm,p) < 0) continue;
02015     for (i=0; i<ncontract; i++)
02016     {
02017       if ((cl=ContractList[i])->expired) continue; 
02018       if (cl->nconsumer > 0 && !strncmp(cl->contract.EqpProperty,p,EQP_PROP_SIZE))
02019       {
02020         /* guarantee immediate execution of any contract using this property */
02021         cl->lasttime.tv_sec = cl->lasttime.tv_usec = PRP_SCHEDULE_SIGNAL;
02022       }
02023     }
02024   }
02025   ProduceData(&thisCycleTime);                  /* call the contract */
02026   while (StaleData) DeliverData(&thisCycleTime);/* send it out */
02027 
02028   return 0;
02029 }
02030 EXPORT UINT32 setWorkAreaSize(UINT32 size)
02031 {
02032   if (!ServerInitialized &&  /* server already initialized => too late!*/
02033        size > MIN_WORK_SIZE) /* small setting not allowed */
02034     MaxRPCTransportSize = (UINT32)size;
02035   return (UINT32)MaxRPCTransportSize; /* return the working variable */
02036 }
02037 EXPORT int SetBurstLimit(int npackets)
02038 {
02039   if (npackets < 1) npackets = 1;
02040   gBurstLimit = npackets;
02041   return gBurstLimit;
02042 }
02043 EXPORT int SetCycleDelay(int msecs)
02044 {
02045   if (msecs < 0) msecs = 0;
02046   gCycleDelay = msecs;
02047   return gCycleDelay;
02048 }
02049 EXPORT char *GetFeclogPath(void)
02050 {
02051   return gFeclogPath;
02052 }
02053 EXPORT char *GetFecHome(void)
02054 {
02055   return FecDBpath;
02056 }

Generated on Sat May 26 11:35:28 2007 for clientlib by  doxygen 1.4.7