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]))
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;
00301 double gServerDataTimeStamp;
00302 double gDataTimeStampOffset = 0.0;
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
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
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
00580
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
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;
00711 else if (tm->tm_mon>2 && tm->tm_mon<9) dl = 1;
00712 else if (tm->tm_mon==2)
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;
00716 else dl = 1;
00717 }
00718 else
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;
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 &&
00772 (up=getenv("LOGINNAME")) == NULL &&
00773 (up=getenv("USERNAME")) == NULL &&
00774 (up=getenv("USER")) == NULL)
00775 up = getenv("LOGNAME");
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;
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;
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;
00829 # endif
00830 strncat(root,path,128);
00831 strncpy(path,root,256);
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)
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);
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);
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;
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)
01159 {
01160 FecSettime();
01161 }
01162 }
01163 #endif
01164
01165 #ifdef MSDOS
01166
01167 int hConn,hControl;
01168 WORD userConnNr;
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;
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);
01265 outport(baddr+4,0x01);
01266 watchdogEnabled = 1;
01267 }
01268 else if (watchdogType == WD_BECKER)
01269 {
01270 outportb(WD_STATUS(baddr),0x01);
01271 outportb(watchdogBaseAddress,0x00);
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);
01294 status = 1;
01295 }
01296 else if (watchdogType == WD_BECKER)
01297 {
01298 outportb(WD_POLL(watchdogBaseAddress),0x01);
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);
01315 outport(watchdogBaseAddress+4,0x01);
01316 }
01317 else if (watchdogType == WD_BECKER)
01318 {
01319 outportb(watchdogBaseAddress,0x00);
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);
01330 }
01331 else if (watchdogType == WD_BECKER)
01332 {
01333 outportb(watchdogBaseAddress,0x01);
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)
01381 {
01382 FecSettime();
01383 gettime(&t);
01384 next_hour = (next_hour + 1) % 24;
01385 }
01386 }
01387
01388 #else
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
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
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
01479 #endif
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
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
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
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);
01647 if (NGdebug > 2) dbglog("[T2]: Release mutex");
01648 millisleep(delay);
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();
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
01676 void _SystemEngine(void)
01677 {
01678 if (NrOfEqpTypes) dorpc();
01679 if (nConnectionTableEntries) doConsumer();
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;
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
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);
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;
01827 ccerr(not_implemented);
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;
01901 gDataTimeStamp = ts;
01902 }
01903 EXPORT int _SystemCycle(int chkcmd)
01904 {
01905 if (NrOfEqpTypes ||
01906 FecNameRegistered ||
01907 gDelayInitRPCServices)
01908 dorpc();
01909 checkTasklist();
01910 if (nConnectionTableEntries) doConsumer();
01911 if (nHistoryRecords) historyCycle();
01912 # ifdef RDATE
01913 if (SychronizeFecClock) FecSynchronize();
01914 # endif
01915 # ifdef MSDOS
01916 if (watchdogBaseAddress) watchDog();
01917 netWatchDog();
01918 # endif
01919 # if defined(MSDOS) || defined(WINNT) || defined(NIOS)
01920 if (chkcmd) GetCommand();
01921 # endif
01922 # ifdef UNIX
01923 foregroundTTY = foreground = chkcmd ? IsInForeground() : 0;
01924 # endif
01925 return (ReturnToServerCycle | ReturnToClientCycle);
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);
01953 harderr(NetHandler);
01954 whoami(gUserName);
01955 GetWatchDogBaseAddress();
01956 # endif
01957 # if defined(RDATE)
01958 TimeServerHostPtr = getTimeServerHost();
01959 rdate(TimeServerHostPtr);
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)
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;
01987 ReturnToClientCycle = 0;
01988 ReturnToServerCycle = 0;
01989 nConnectionTableEntries = NameServerLoaded ? 1 : 0;
01990 doConsumerSemaphore = 0;
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;
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
02021 cl->lasttime.tv_sec = cl->lasttime.tv_usec = PRP_SCHEDULE_SIGNAL;
02022 }
02023 }
02024 }
02025 ProduceData(&thisCycleTime);
02026 while (StaleData) DeliverData(&thisCycleTime);
02027
02028 return 0;
02029 }
02030 EXPORT UINT32 setWorkAreaSize(UINT32 size)
02031 {
02032 if (!ServerInitialized &&
02033 size > MIN_WORK_SIZE)
02034 MaxRPCTransportSize = (UINT32)size;
02035 return (UINT32)MaxRPCTransportSize;
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 }