00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 #include <time.h>
00026 #include <ctype.h>
00027 #include <math.h>
00028 #include <assert.h>
00029 #include <errno.h>
00030 #include <unistd.h>
00031 #include <string.h>
00032 #include <sys/types.h>
00033 #include <sys/stat.h>
00034 #include <fcntl.h>
00035 #include <stdarg.h>
00036 #include <dirent.h>
00037
00038 #include "common.h"
00039
00040
00041
00042
00043
00044
00045
00046 struct dirent **cacheFileList=NULL;
00047
00048 FILE * cacheFile=NULL;
00049 char cacheFileName[128];
00050 char cacheDir[128];
00051
00052 time_t lastCacheTime=0;
00053
00054 int64_t lastCacheOffset=0;
00055
00056 int cacheOutput=-1;
00057
00058 int startCacheTime=0;
00059
00060 char testForSN[128];
00061 time_t testForTime;
00062
00063 int nTimesInCache=0;
00064
00066 void ResetCacheCounters(void)
00067 {
00068 cacheOutput=-1;
00069 lastCacheTime=0;
00070 lastCacheOffset=0;
00071 }
00072
00074 int CacheFileSelect(const struct dirent* t)
00075 {
00076 int t1,t2,ok;
00077 char s[128];
00078 struct stat st;
00079
00080 if (sscanf(t->d_name,"%s %d %d",s,&t1,&t2)==3)
00081 {
00082 if ((t1<0)||(t2<0))
00083 {
00084 return(0);
00085 }
00086 ok=1;
00087
00088 if ((strlen(testForSN)>0)&&(testForTime!=-2))
00089 {
00090
00091 if (strcmp(s,testForSN)!=0)
00092 {
00093 ok=0;
00094 }
00095
00096 if ( (testForTime<t1) || ((testForTime>t2)&&(t2!=0)) )
00097 {
00098 ok=0;
00099 }
00100 }
00101 if (ok==0)
00102 {
00103
00104 sprintf(s,"%s/%s",cacheDir,t->d_name);
00105 if (stat(s,&st)==0)
00106 {
00107 if (abs(time(NULL)-st.st_mtime)>7*86400)
00108 {
00109 unlink(s);
00110 }
00111 }
00112 }
00113 return(ok);
00114 }
00115 return(0);
00116 }
00117
00118
00121 void OpenCacheFileWrite(int wr)
00122 {
00123 char *t;
00124 PrintDebug("open cache file for write: %d\n",wr);
00125 strcpy(cacheFileName,"");
00126 strcpy(cacheDir,".");
00127 t=getenv("TITAN2CACHE");
00128 if (localCache)
00129 {
00130 strcpy(cacheDir,"./");
00131 strcpy(cacheFileName,"");
00132 }
00133 else
00134 {
00135 if (t)
00136 {
00137 strcpy(cacheDir,t);
00138 strcpy(cacheFileName,t);
00139 strcat(cacheFileName,"/");
00140 }
00141 else
00142 {
00143 t=getenv("HOME");
00144 if (t)
00145 {
00146 strcpy(cacheFileName,t);
00147 strcat(cacheFileName,"/");
00148 strcat(cacheFileName,".titancache");
00149 strcpy(cacheDir,cacheFileName);
00150 mkdir(cacheFileName,S_IRWXU);
00151 }
00152 strcat(cacheFileName,"/");
00153 }
00154 }
00155 if (wr)
00156 {
00157 int fd;
00158 if (localCache)
00159 {
00160 strcpy(cacheFileName,".LocalTitanCache");
00161 assert((cacheFile=fopen(cacheFileName,"at"))!=NULL);
00162 }
00163 else
00164 {
00165 strcat(cacheFileName,"titancacheXXXXXX");
00166 fd=OpenTempFile(cacheFileName);
00167 assert((cacheFile=fdopen(fd,"wt"))!=NULL);
00168 }
00169 fprintf(cacheFile,"#ROOT %s\n",baseDir);
00170 startCacheTime=(int)(currentTime.usecond>>32);
00171 PrintDebug("open (W): %s\n",cacheFileName);
00172 cacheOutput=1;
00173 }
00174 nTimesInCache=0;
00175 }
00176
00180 char *CacheRead(char *line)
00181 {
00182 if (cacheOutput!=0)
00183 {
00184 return(NULL);
00185 }
00186 return(fgets(line,127,cacheFile));
00187 }
00188
00190 void RewindCache(void)
00191 {
00192 if (cacheFile!=NULL)
00193 {
00194 if (cacheOutput==0)
00195 {
00196 rewind(cacheFile);
00197 }
00198 }
00199 }
00200
00205 int OpenCacheFileRead(char *SN, time_t t)
00206 {
00207 int nfiles,i;
00208
00209
00210 if (cacheFile!=NULL)
00211 {
00212
00213 return(cacheOutput);
00214 }
00215
00216
00217 if (localCache)
00218 {
00219 strcpy(cacheFileName,".LocalTitanCache");
00220 cacheFile=fopen(cacheFileName,"rt");
00221 if (cacheFile!=NULL)
00222 {
00223 PrintDebug("open (R): %s\n",cacheFileName);
00224 cacheOutput=0;
00225 }
00226 else
00227 {
00228 cacheOutput=-1;
00229 }
00230 return(cacheOutput);
00231 }
00232
00233
00234
00235 if ((SN!=NULL)&&(t!=-2))
00236 {
00237
00238 if (strlen(SN)==0)
00239 {
00240
00241 return(cacheOutput);
00242 }
00243 strcpy(testForSN,SN);
00244 }
00245 else
00246 {
00247 PrintLog("clearing cache\n");
00248
00249 OpenCacheFileWrite(0);
00250 testForSN[0]=0;
00251 }
00252 testForTime=t;
00253 nfiles=__scandir(cacheDir,&cacheFileList,CacheFileSelect,__alphasort);
00254 PrintDebug("there: '%s', T=%d, n=%d (%s)\n",SN?SN:"null",t,nfiles,cacheDir);
00255 if ((nfiles>1)&&((SN!=NULL)&&(t!=-2)))
00256 {
00257 PrintWarning("multiple cachefile for %s [%d]\n",
00258 testForSN,testForTime);
00259 }
00260
00261 if (nfiles>0)
00262 {
00263 for (i=0; i<nfiles; i++)
00264 {
00265
00266 sprintf(cacheFileName,"%s%s%s",
00267 cacheDir,
00268 "/",
00269 cacheFileList[i]->d_name);
00270
00271 if ((SN!=NULL)&&(t!=-2))
00272 {
00273
00274 if (cacheFile==NULL)
00275 {
00276 cacheFile=fopen(cacheFileName,"rt");
00277 if (cacheFile!=NULL)
00278 {
00279 PrintDebug("open (R): %s\n",cacheFileName);
00280 cacheOutput=0;
00281 break;
00282 }
00283 }
00284 }
00285
00286 else
00287 {
00288
00289 unlink(cacheFileName);
00290 PrintDebug("%s removed\n");
00291 }
00292 }
00293 }
00294 else
00295 {
00296 cacheOutput=-1;
00297 }
00298 return(cacheOutput);
00299 }
00300
00305 int CompareCacheLines(const void *p1, const void *p2)
00306 {
00307 char *s1=*(char **)p1;
00308 char *s2=*(char **)p2;
00309
00310 if ((memcmp("#TIME",s1,5)==0)&&(memcmp("#TIME",s2,5)==0))
00311 {
00312 int t1=0,t2=0;
00313
00314 sscanf(s1,"%*s %*s %*s %d",&t1);
00315 sscanf(s2,"%*s %*s %*s %d",&t2);
00316 return(t1-t2);
00317 }
00318 else
00319
00320 {
00321
00322 return(0);
00323
00324 }
00325 }
00326
00329 void SortCacheFile(char *fn)
00330 {
00331 FILE *f;
00332 char **table=NULL;
00333 int nlines=0,nbuff=0,i;
00334 int NL_STEP=1024,LL=80;
00335
00336 f=fopen(fn,"rt");
00337
00338 if (!f)
00339 {
00340 return;
00341 }
00342
00343 while (!feof(f))
00344 {
00345 if (nlines>=nbuff)
00346 {
00347 nbuff+=NL_STEP;
00348 table=(char **)realloc(table,nbuff*sizeof(char *));
00349 for (i=nlines; i<nbuff; i++)
00350 {
00351 table[i]=(char *)malloc(LL);
00352 memset(table[i],0,LL);
00353 }
00354 }
00355 fgets(table[nlines],79,f);
00356 nlines++;
00357 }
00358
00359 fclose(f);
00360
00361 if (nlines==0)
00362 {
00363 return;
00364 }
00365
00366 qsort(table,nlines,sizeof(char*),CompareCacheLines);
00367
00368 if (nlines<10)
00369 {
00370
00371
00372 PrintDebug("killing the small cache file\n");
00373 }
00374
00375 else
00376 {
00377
00378 f=fopen(fn,"wt");
00379
00380 fprintf(f,"%s",table[0]);
00381 for (i=1; i<nlines; i++)
00382 {
00383 if (strcmp(table[i-1],table[i])!=0)
00384 {
00385 fprintf(f,"%s",table[i]);
00386 }
00387 }
00388
00389 fclose(f);
00390
00391
00392 }
00393 for (i=0; i<nbuff; i++)
00394 {
00395 free(table[i]);
00396 }
00397 free(table);
00398 }
00399
00402 void CloseCacheFile(int cancel)
00403 {
00404 char line[128];
00405
00406 if (localCache!=0)
00407 {
00408 if (cacheFile!=NULL)
00409 {
00410 fclose(cacheFile);
00411 }
00412 cacheFile=NULL;
00413 SortCacheFile(cacheFileName);
00414 return;
00415 }
00416
00417
00418 if (cacheFile)
00419 {
00420 PrintDebug("close: %s\n",cacheFileName);
00421 fclose(cacheFile);
00422 cacheFile=NULL;
00423 PrintDebug("sort cache file...\n");
00424 SortCacheFile(cacheFileName);
00425 if (cacheOutput==1)
00426 {
00427 if (cancel==0)
00428 {
00429 int end=(int)(currentTime.usecond>>32);
00430 if (end<0)
00431 {
00432 end=0;
00433 }
00434 sprintf(line,"%s%s%s %d %d",
00435 cacheDir,
00436 "/",
00437 HWConfig.serialNumber,
00438 startCacheTime,end);
00439 if ((strlen(HWConfig.serialNumber)>0)&&(nTimesInCache>5))
00440 {
00441 PrintDebug("rename: %s -> %s\n",
00442 cacheFileName,line);
00443 Rename(cacheFileName,line);
00444 }
00445 }
00446 unlink(cacheFileName);
00447 }
00448 }
00449 ResetCacheCounters();
00450 }
00451
00454 void CachePrint(const char *format, ...)
00455 {
00456 va_list ap;
00457 if (noCache==1)
00458 {
00459 return;
00460 }
00461 if (cacheFile==NULL)
00462 {
00463 OpenCacheFileWrite(1);
00464 }
00465 if (cacheFile!=NULL)
00466 {
00467 if (startCacheTime<0)
00468 {
00469 startCacheTime=(int)(currentTime.usecond>>32);
00470 }
00471 va_start(ap,format);
00472 vfprintf(cacheFile,format,ap);
00473 va_end(ap);
00474 }
00475 }
00476
00478 void CachePrintCST(void)
00479 {
00480 if (cacheOutput==0)
00481 {
00482 return;
00483 }
00484
00485
00486 }
00487
00489 void CachePrintTIME(void)
00490 {
00491 if (cacheOutput==0)
00492 {
00493 return;
00494 }
00495 if (currentTime.usecond>>32!=-1)
00496 {
00497 if (titan2File!=NULL)
00498 {
00499 CachePrint("#TIME %s %ld %ld\n",currentFile,SafeFtell(titan2File),
00500 (int)((currentTime.usecond>>32)));
00501 fflush(cacheFile);
00502 }
00503 }
00504 nTimesInCache++;
00505 }
00506
00508 void CacheCallBack(void)
00509 {
00510 if (noCache==1)
00511 {
00512 return;
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522 if (cacheOutput==-1)
00523 {
00524 OpenCacheFileRead(HWConfig.serialNumber,currentTime.usecond>>32);
00525 }
00526 if (cacheOutput==0)
00527 {
00528 return;
00529 }
00530
00531
00532 if (beginWindow>0)
00533 {
00534 return;
00535 }
00536
00537
00538 if (abs(lastCacheTime-(currentTime.usecond>>32))>12*3600)
00539 {
00540 CachePrintTIME();
00541 lastCacheTime=currentTime.usecond>>32;
00542 return;
00543 }
00544
00545 if (abs(lastCacheOffset-totalFrameProcessed*12)>(10<<20))
00546 {
00547 CachePrintTIME();
00548 lastCacheOffset=totalFrameProcessed*12;
00549 return;
00550 }
00551 }
00552
00555 void InitCache(void)
00556 {
00557 if (noCache==1)
00558 {
00559 PrintDebug("no cache ?\n");
00560
00561 }
00562 OpenCacheFileWrite(0);
00563 PrintDebug("cache dir: %s\n",cacheDir);
00564 }