00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef OMNI
00024
00025 #define OMNI_RELEASE_STR "OMNI 2.1 - "__DATE__" - "
00026
00027 #include <sys/time.h>
00028 #include <math.h>
00029 struct timeval tvStart, tvStop;
00030
00031 char *errorColor, *normalColor;
00032
00033 struct OmniStationType
00034 {
00035 char name[16];
00036 char group[32];
00037 int running;
00038 int error;
00039 struct ShortInfos shi;
00040 struct OsirisInformationField oif[OIF_FIELDS_NUMBER];
00041 char alertHtml[30*128];
00042 char alertTip[30*128];
00043 char osirisErrorMessage[OSIRIS_ERROR_MESSAGES][OSIRIS_ERROR_MESSAGE_LENGTH+1];
00044 struct OmniStationType *next;
00045 };
00046
00047 struct OmniStationType *omniStation=NULL;
00048
00049 #define OMNI_SUPERVISOR (1<<0)
00050 #define OMNI_CONFIGURATOR (1<<1)
00051 #define OMNI_SINGLESTATION (1<<2)
00052 #define OMNI_TAILER (1<<3)
00053 #define OMNI_HEADER (1<<4)
00054 #define OMNI_DATASELECT (1<<5)
00055 #define OMNI_DISPATCH (1<<6)
00056 #define OMNI_DATACENTER (1<<7)
00057 #define OMNI_SHOWEVENT (1<<8)
00058 #define OMNI_BUILDMAP (1<<9)
00059 #define OMNI_BUILDTOPO (1<<10)
00060 #define OMNI_MAIN (1<<11)
00061 #define OMNI_MATRIX (1<<12)
00062
00063
00064 #define CONTACT (1<<0)
00065 #define PPP (1<<1)
00066 #define VPN (1<<2)
00067 #define WIRELESS (1<<3)
00068 #define ETHERNET (1<<4)
00069 #define USB (1<<5)
00070
00071 #define AVAILABLE_COLOR "green"
00072 #define RUNNING_COLOR "blue"
00073 #define WAITING_COLOR "grey"
00074 #define MISSED_COLOR "red"
00075
00076 #define MAPX 800
00077 #define MAPY 600
00078
00079 #define _BUF_SIZE 65535
00080 #define __min(a,b) (a<b?(a):(b))
00081
00082 char *omniDir=NULL;
00083
00084 #define MAX_STATION 1000
00085 char currentNetwork[MAX_STATION][10];
00086 int networkDefined=0;
00087
00088 void FilterPostInput(void)
00089 {
00090 char line[_BUF_SIZE+1];
00091 char *g;
00092 int len=0;
00093 g=MyGetenv("CONTENT_LENGTH");
00094 if (g)
00095 {
00096 sscanf(g,"%d",&len);
00097 len++;
00098 }
00099 PrintError("len=%d\n",len);
00100 fgets(line,__min(_BUF_SIZE,len),stdin);
00101 printf("%s",line);
00102 PrintError("len=%d '%s'\n",len,line);
00103 printf("\n");
00104 }
00105
00109 void CleanDir(char *dir, int timeout)
00110 {
00111 int n;
00112 struct dirent **direntry;
00113
00114 int CleanDirSelect(const struct dirent* t)
00115 {
00116 char s[128];
00117 struct stat sb;
00118 sprintf(s,"%s/%s",dir,t->d_name);
00119 if (stat(s,&sb)==0)
00120 {
00121 if (abs(time(NULL)-sb.st_mtime)>timeout)
00122 {
00123 return(1);
00124 }
00125 }
00126 return(0);
00127 }
00128
00129 n=__scandir(dir,&direntry,CleanDirSelect,__alphasort);
00130
00131 if (n>0)
00132 {
00133 int i;
00134 char s[128];
00135 for (i=0; i<n; i++)
00136 {
00137 sprintf(s,"%s/%s",dir,direntry[i]->d_name);
00138 unlink(s);
00139 free(direntry[i]);
00140 }
00141 free(direntry);
00142 }
00143 }
00144
00145
00148 void CheckAlertFiles(void)
00149 {
00150 char *oldOaf=NULL;
00151 char *tok;
00152 char *newOaf=NULL;
00153 char *MailFrom,*MailTo,*SmtpServer,*OIF;
00154 FILE *fo,*fn;
00155 char oldLine[255];
00156 char newLine[255];
00157 char MailToTok[255];
00158 int mail=0;
00159 char a[64];
00160 int t;
00161 oldOaf=MyGetenv("OLDOAF");
00162 newOaf=MyGetenv("NEWOAF");
00163 MailFrom=MyGetenv("MailFrom");
00164 MailTo=MyGetenv("MailTo");
00165 OIF=MyGetenv("OIF");
00166 SmtpServer=MyGetenv("SmtpServer");
00167
00168 if ((oldOaf==NULL)||(newOaf==NULL)||(OIF==NULL)||
00169 (MailFrom==NULL)||(MailTo==NULL)||
00170 (SmtpServer==NULL))
00171 {
00172 PrintError("missing definition\n");
00173 exit(0);
00174 }
00175
00176 fo=fopen(oldOaf,"rt");
00177 fn=fopen(newOaf,"rt");
00178
00179 if ((fo==NULL)||(fn==NULL))
00180 {
00181 exit(0);
00182 }
00183 mail=0;
00184
00185 while (!feof(fn))
00186 {
00187
00188 oldLine[0]=newLine[0]=0;
00189 fgets(oldLine,254,fo);
00190 fgets(newLine,254,fn);
00191 if ((oldLine[0]==0)&&(newLine[0]==0))
00192 {
00193 break;
00194 }
00195
00196 if (memcmp(newLine,oldLine,14))
00197 {
00198
00199 mail=1;
00200 break;
00201 }
00202 }
00203
00204 while (!feof(fo))
00205 {
00206 oldLine[0]=newLine[0]=0;
00207 fgets(oldLine,254,fo);
00208 fgets(newLine,254,fn);
00209 if ((oldLine[0]==0)&&(newLine[0]==0))
00210 {
00211 break;
00212 }
00213 if (memcmp(newLine,oldLine,14))
00214 {
00215 mail=1;
00216 break;
00217 }
00218 }
00219
00220 if (mail==0)
00221 {
00222 exit(0);
00223 }
00224 puts("helo localhost.localdomain");
00225 printf("mail from: <%s>\n",MailFrom);
00226 strcpy(MailToTok,MailTo);
00227 tok=strtok(MailToTok,",");
00228 while (tok)
00229 {
00230 printf("rcpt to: <%s>\n",tok);
00231 tok=strtok(NULL,",");
00232 }
00233 puts("data");
00234 printf("To: %s\n",MailTo);
00235 printf("Subject: [OMNI] %s: alert state has changed\n",MyGetenv("STATION"));
00236 t=time(NULL);
00237 printf("\nDate: %.16s\n",time2str((double)t));
00238 rewind(fo);
00239 rewind(fn);
00240 printf("\n\nNew alert state:\n");
00241 while (!feof(fn))
00242 {
00243 oldLine[0]=newLine[0]=0;
00244 if (NULL==fgets(newLine,254,fn))
00245 {
00246 break;
00247 }
00248 sscanf(newLine,"%s %d",a,&t);
00249
00250 printf("%-16s %s",a,newLine+32);
00251 }
00252 printf("\n\nOld alert state:\n");
00253 while (!feof(fo))
00254 {
00255 oldLine[0]=newLine[0]=0;
00256 if (NULL==fgets(oldLine,254,fo))
00257 {
00258 break;
00259 }
00260 sscanf(oldLine,"%s %d",a,&t);
00261
00262 printf("%-16s %s",a,oldLine+32);
00263 }
00264 printf("\n\nOIF follows:\n");
00265 fclose(fn);
00266 fclose(fo);
00267 fn=fopen(OIF,"rt");
00268 while (fgets(oldLine,254,fn)!=NULL)
00269 {
00270 printf("%s",oldLine);
00271 }
00272 fclose(fn);
00273 puts("\n.");
00274 puts("quit");
00275 exit(0);
00276 }
00277
00279 void CheckLoadAvg(void)
00280 {
00281 float load;
00282 float maxLoad;
00283 FILE *f;
00284 char *s;
00285 int cont=12;
00286
00287 s=MyGetenv("MAXLOAD");
00288 if (!s)
00289 {
00290 exit(0);
00291 }
00292 sscanf(s,"%f",&maxLoad);
00293
00294 while (access("pid",R_OK)==0)
00295 {
00296 int st;
00297
00298 f=fopen("/proc/loadavg","rt");
00299 if (f)
00300 {
00301 fscanf(f,"%f",&load);
00302 fclose(f);
00303 }
00304
00305 if (load<maxLoad)
00306 {
00307 exit(0);
00308 }
00309
00310 st=5+rand() % 20;
00311 printf("sleeping %d (%f>%f)\n",st,load,maxLoad);
00312 sleep(st);
00313 cont--;
00314 if (cont==0)
00315 {
00316 exit(0);
00317 }
00318 }
00319
00320
00321
00322 kill(getppid(),SIGTERM);
00323 exit(0);
00324 }
00325
00328 int IncreaseEvtId(void)
00329 {
00330 char file[128];
00331 char renamed[128];
00332 int id=0,cnt;
00333 FILE *f;
00334 sprintf(file,"%s/evtid",omniDir);
00335 sprintf(renamed,"%s/evtid.renamed",omniDir);
00336
00337 cnt=10;
00338 while ( (access(file,R_OK)!=0) || (access(renamed,R_OK)==0) )
00339 {
00340
00341 sleep(1);
00342
00343 cnt--;
00344 if (cnt<0)
00345 {
00346 break;
00347 }
00348
00349 }
00350
00351 unlink(renamed);
00352 rename(file,renamed);
00353
00354 f=fopen(renamed,"rt");
00355
00356 fscanf(f,"%d",&id);
00357
00358 fclose(f);
00359
00360 id++;
00361
00362 f=fopen(renamed,"wt");
00363
00364 fprintf(f,"%d",id);
00365
00366 fclose(f);
00367
00368 unlink(file);
00369 rename(renamed,file);
00370 return(id);
00371 }
00372
00373
00375 void DispatchDataRequest(void)
00376 {
00377 struct tm tm;
00378 char sta[128],event[256],line[128];
00379 int length;
00380 int sl;
00381 time_t T;
00382 struct OmniStationType *cur;
00383 int id;
00384 FILE *f;
00385 char iline[_BUF_SIZE+1];
00386 char *g;
00387 int ilen=0;
00388 g=MyGetenv("CONTENT_LENGTH");
00389 if (g)
00390 {
00391 sscanf(g,"%d",&ilen);
00392 ilen++;
00393 }
00394 PrintError("ilen=%d\n",ilen);
00395 fgets(iline,__min(_BUF_SIZE,ilen),stdin);
00396
00397 id=IncreaseEvtId();
00398 memset(&tm,0,sizeof(struct tm));
00399
00400 sscanf(iline,"%*5c%d%*7c%d%*5c%d%*6c%d%*8c%d%*8c%d%n",
00401 &(tm.tm_year),&(tm.tm_mon),&(tm.tm_mday),
00402 &(tm.tm_hour),&(tm.tm_min),&length,&sl);
00403 tm.tm_year-=1900;
00404 tm.tm_mon--;
00405 T=mktime(&tm);
00406 sprintf(event,"EVT%04d|%ld|%ld|lat|lon|dep|T0|%s",
00407 id,T,T+length,asctime(&tm));
00408
00409 sprintf(line,"%s/Data/EVT%04d",omniDir,id);
00410 mkdir(line,0777);
00411
00412 sprintf(line,"%s/Data/EVT%04d/EVT%04d",
00413 omniDir,id,id);
00414 if (NULL!=(f=fopen(line,"wt")))
00415 {
00416 fprintf(f,"%s",event);
00417 fclose(f);
00418 }
00419 PrintError("iline='%s', sl=%d\n",iline,sl);
00420
00421 while (sl<strlen(iline))
00422 {
00423 char c;
00424 int len=0;
00425 memset(sta,0,128);
00426
00427 while (sl<strlen(iline))
00428 {
00429 c=iline[sl++];
00430 if (c=='=')
00431 {
00432 break;
00433 }
00434 }
00435
00436 while (sl<strlen(iline))
00437 {
00438 c=iline[sl++];
00439 if (c=='&')
00440 {
00441 break;
00442 }
00443 if (!isalnum(c))
00444 {
00445 break;
00446 }
00447 sta[len++]=c;
00448 if (len>32)
00449 {
00450 break;
00451 }
00452 }
00453
00454 if (len>0)
00455 {
00456 if (strcmp("submit",sta)==0)
00457 {
00458 break;
00459 }
00460 }
00461 if (len==0)
00462 {
00463 continue;
00464 }
00465
00466 PrintError("processing '%s'\n",sta);
00467
00468 if (0==strcmp(sta,"ALLSTATIONS"))
00469 {
00470 for (cur=omniStation; cur; cur=cur->next)
00471 {
00472
00473 if (cur->running==0)
00474 {
00475 continue;
00476 }
00477
00478 if ((cur->oif[ndx_sysd_OsirisPhysicalChannels].valid==0)||
00479 (cur->oif[ndx_sysd_OsirisPhysicalChannels].value.d==0))
00480 {
00481 continue;
00482 }
00483 PrintError(" ok for '%s'\n",cur->name);
00484
00485 sprintf(line,"%s/%s/requests",omniDir,cur->name);
00486 mkdir(line,0777);
00487
00488 sprintf(line,"%s/%s/requests/EVT%04d",
00489 omniDir,cur->name,id);
00490 if (NULL!=(f=fopen(line,"wt")))
00491 {
00492 fprintf(f,"%s",event);
00493 fclose(f);
00494 }
00495 }
00496 break;
00497 }
00498
00499 for (cur=omniStation; cur; cur=cur->next)
00500 {
00501 PrintLog("%s/%s\n",sta,cur->name);
00502 if (0==strcmp(sta,cur->name))
00503 {
00504 break;
00505 }
00506 }
00507
00508 if (cur==NULL)
00509 {
00510 PrintError("station '%s' not found\n",sta);
00511 continue;
00512 }
00513
00514 if (cur->running==0)
00515 {
00516 PrintError("station '%s' is not running\n",sta);
00517 continue;
00518 }
00519
00520 if ((cur->oif[ndx_sysd_OsirisPhysicalChannels].valid==0)||
00521 (cur->oif[ndx_sysd_OsirisPhysicalChannels].value.d==0))
00522 {
00523 continue;
00524 }
00525 PrintError(" ok for '%s'\n",sta);
00526 sprintf(line,"%s/%s/requests",omniDir,sta);
00527 mkdir(line,0777);
00528 sprintf(line,"%s/%s/requests/EVT%04d",
00529 omniDir,sta,id);
00530 if (NULL!=(f=fopen(line,"wt")))
00531 {
00532 fprintf(f,"%s",event);
00533 fclose(f);
00534 }
00535 }
00536 }
00537
00540 struct OmniStationType * AddOmniStation(void)
00541 {
00542 struct OmniStationType *o,*cur;
00543 o=malloc(sizeof(struct OmniStationType));
00544 memset(o,0,sizeof(struct OmniStationType));
00545 if (omniStation==NULL)
00546 {
00547 omniStation=o;
00548 }
00549 else
00550 {
00551 for (cur=omniStation; cur->next; cur=cur->next) ;
00552 cur->next=o;
00553 }
00554 return(o);
00555 }
00556
00558 void TroubleShooting(void)
00559 {
00560 void PushHeader(void);
00561 void PushTailer(void);
00562 PushHeader();
00563 puts("<br><br><br>");
00564 puts("To contact Agecodagis SARL: mail to agecodagis@agecodagis.com or call +33 (0)5 61 97 84 46<br>");
00565 puts("<br><br><br>");
00566 puts("<ul>");
00567 puts("<li><b>with Mozilla or Firefox: the tooltip texts do not display errors but only the first line (station name)</b></li><br>");
00568 puts("download and install <a href=https://addons.mozilla.org/en-US/firefox/addon/1715>");
00569 puts("this addon: https://addons.mozilla.org/en-US/firefox/addon/1715</a>\n");
00570 puts("</ul>");
00571 PushTailer();
00572 }
00573
00577 int ParseOmniOptions(char *cmd)
00578 {
00579 char *s=cmd;
00580 int next,error;
00581 if (*s==0)
00582 {
00583 return(0);
00584 }
00585 if (*s!=',')
00586 {
00587 return(-1);
00588 }
00589 while (*s)
00590 {
00591 s++;
00592 PrintDebug("%s\n",s);
00593 next=0;
00594 error=__LINE__;
00595 if (strncmp(s,"verbose",7)==0)
00596 {
00597 verboseMode=1;
00598 error=0;
00599 next=7;
00600 }
00601 if (strncmp(s,"troubleshooting",15)==0)
00602 {
00603 TroubleShooting();
00604 exit(0);
00605 }
00606 if (strncmp(s,"filterpostinput",15)==0)
00607 {
00608 FilterPostInput();
00609 exit(0);
00610 }
00611 if (strncmp(s,"singlestation",13)==0)
00612 {
00613 omniMode=OMNI_SINGLESTATION;
00614 error=0;
00615 next=13;
00616 }
00617 if (strncmp(s,"configurator",12)==0)
00618 {
00619 omniMode=OMNI_CONFIGURATOR;
00620 error=0;
00621 next=12;
00622 }
00623 if (strncmp(s,"supervisor",10)==0)
00624 {
00625 omniMode=OMNI_SUPERVISOR;
00626 error=0;
00627 next=10;
00628 }
00629 if (strncmp(s,"matrix",6)==0)
00630 {
00631 omniMode=OMNI_MATRIX;
00632 error=0;
00633 next=6;
00634 }
00635 if (strncmp(s,"dataselect",10)==0)
00636 {
00637 omniMode=OMNI_DATASELECT;
00638 error=0;
00639 next=10;
00640 }
00641 if (strncmp(s,"map",3)==0)
00642 {
00643 omniMode=OMNI_BUILDMAP;
00644 error=0;
00645 next=3;
00646 }
00647 if (strncmp(s,"main",4)==0)
00648 {
00649 omniMode=OMNI_MAIN;
00650 error=0;
00651 next=4;
00652 }
00653 if (strncmp(s,"topo",4)==0)
00654 {
00655 omniMode=OMNI_BUILDTOPO;
00656 error=0;
00657 next=4;
00658 }
00659 if (strncmp(s,"showevent",9)==0)
00660 {
00661 omniMode=OMNI_SHOWEVENT;
00662 error=0;
00663 next=9;
00664 }
00665 if (strncmp(s,"datacenter",10)==0)
00666 {
00667 omniMode=OMNI_DATACENTER;
00668 error=0;
00669 next=10;
00670 }
00671 if (strncmp(s,"dispatchrequest",15)==0)
00672 {
00673 omniMode=OMNI_DISPATCH;
00674 error=0;
00675 next=15;
00676 }
00677 if (strncmp(s,"header",6)==0)
00678 {
00679 omniMode=OMNI_HEADER;
00680 error=0;
00681 next=6;
00682 }
00683 if (strncmp(s,"tailer",6)==0)
00684 {
00685 omniMode=OMNI_TAILER;
00686 error=0;
00687 next=6;
00688 }
00689 if (strncmp(s,"checkloadavg",12)==0)
00690 {
00691 CheckLoadAvg();
00692 exit(0);
00693 }
00694 if (strncmp(s,"checkalert",12)==0)
00695 {
00696 CheckAlertFiles();
00697 exit(0);
00698 }
00699 if (error)
00700 {
00701 PrintError("could not parse oif option string (error %d)\n",error);
00702 return(-1);
00703 }
00704 s+=next;
00705 }
00706 return(0);
00707 }
00708
00709 char * StationName(struct OmniStationType *cur)
00710 {
00711 static char r[32];
00712 if ((cur->oif[ndx_comd_Hostid].valid)&&(cur->oif[ndx_comd_StationName].valid))
00713 {
00714 if (
00715 (strcmp(cur->oif[ndx_comd_StationName].value.s,cur->name))&&
00716 (strcmp(cur->oif[ndx_comd_Hostid].value.s,cur->name))&&
00717 (strcmp(cur->oif[ndx_comd_StationName].value.s,
00718 cur->oif[ndx_comd_Hostid].value.s))
00719 )
00720 {
00721 sprintf(r,"%s[%s,%s]",cur->name,
00722 cur->oif[ndx_comd_StationName].value.s,
00723 cur->oif[ndx_comd_Hostid].value.s);
00724 return(r);
00725 }
00726 }
00727 if (cur->oif[ndx_comd_StationName].valid)
00728 {
00729 if (strcmp(cur->oif[ndx_comd_StationName].value.s,cur->name))
00730 {
00731 sprintf(r,"%s[%s]",cur->name,cur->oif[ndx_comd_StationName].value.s);
00732 return(r);
00733 }
00734 }
00735 if (cur->oif[ndx_comd_Hostid].valid)
00736 {
00737 if (strcmp(cur->oif[ndx_comd_Hostid].value.s,cur->name))
00738 {
00739 sprintf(r,"%s[%s]",cur->name,cur->oif[ndx_comd_Hostid].value.s);
00740 return(r);
00741 }
00742 }
00743 strcpy(r,cur->name);
00744 return(r);
00745 }
00746
00748 void PushTailer(void)
00749 {
00750 double delta;
00751 puts("<div align=right>");
00752 puts("<a href=http://www.agecodagis.com>");
00753 puts("<img border=0 src=/www/agecodagis.gif><br>");
00754 puts("http://www.agecodagis.com");
00755 puts("</a> </div>");
00756 puts("<center> <font size=-1>");
00757 puts("Osiris Multiscale Network Infrastructure - Agecodagis");
00758 gettimeofday(&tvStop,NULL);
00759 delta=(double)(tvStop.tv_sec-tvStart.tv_sec)+1.e-6*(double)(tvStop.tv_usec-tvStart.tv_usec);
00760 printf("<br>t=%.1f\n",delta);
00761 puts("</font> </body> </html>");
00762 }
00763
00765 void PushHeader(void)
00766 {
00767 char line[256];
00768 char *tmp;
00769 time_t T;
00770 struct tm tm;
00771 FILE *f;
00772 puts("Content-type: text/html\n");
00773 puts("<html>\n");
00774 puts("<head>\n");
00775 puts(" <meta http-equiv=\"Pragma\" content=\"no-cache\">\n");
00776 puts(" <META Http-Equiv=\"Cache-Control\" Content=\"no-cache\">\n");
00777 puts(" <meta http-equiv=\"Expires\" content=\"0\">\n");
00778 puts(" <meta name=\"Author\" content=\"Agecodagis OMNI\">\n");
00779 tmp=MyGetenv("TITLE");
00780 if (tmp)
00781 {
00782 puts(" <title>OMNI - ");
00783 puts(tmp); puts(" </title>\n");
00784 }
00785 puts(" <style type=\"text/css\">\n");
00786 puts(" A:visited {color: blue; text-decoration: none}\n");
00787 puts(" A:active {color: blue; text-decoration: none}\n");
00788 puts(" A:link {color: blue; text-decoration: none}\n");
00789 puts(" </style>\n");
00790 tmp=MyGetenv("REFRESH");
00791 if (tmp)
00792 {
00793 puts(" <meta http-equiv='REFRESH' content='");
00794 puts(tmp); puts("'>\n");
00795 }
00796 puts("</head>\n");
00797 puts("<body>\n");
00798 time(&T);
00799 memcpy(&tm,gmtime(&T),sizeof(struct tm));
00800 puts(OMNI_RELEASE_STR);
00801 strftime(line,127,"current time: %Y.%m.%d-%H:%M:%S",&tm);
00802 tmp=MyGetenv("REMOTE_ADDR");
00803 if (tmp)
00804 {
00805 strcat(line,", client=");
00806 strcat(line,tmp);
00807 }
00808 tmp=MyGetenv("REMOTE_USER");
00809 if (tmp)
00810 {
00811 strcat(line,", user=");
00812 strcat(line,tmp);
00813 strcat(line," <a href=/www/cgi-bin/SwitchUser>switch user </a>\n");
00814 }
00815 puts(line);
00816 f=fopen("/proc/loadavg","rt");
00817 if (f)
00818 {
00819 fgets(line,64,f);
00820 fclose(f);
00821 printf(" load: %s",line);
00822 }
00823 printf(" <a href=TroubleShooting target=TroubleShooting><b>TroubleShooting</b></a>");
00824 puts("<br>\n");
00825 }
00826
00830 int StationDirSelect(const struct dirent* t)
00831 {
00832 char s[128];
00833 sprintf(s,"%s/config",t->d_name);
00834 if (access(s,R_OK)==0)
00835 {
00836 return(1);
00837 }
00838 return(0);
00839 }
00840
00844 time_t TimeOfFile(char *f)
00845 {
00846 struct stat sb;
00847 if (stat(f,&sb)!=0)
00848 {
00849 fprintf(stderr,"%s %m",f);
00850 return(-1);
00851 }
00852 return(sb.st_mtime);
00853 }
00854
00856 time_t TimeOfInfo(struct OmniStationType *o)
00857 {
00858 if (o->oif[ndx_gpsd_SystemTime].valid)
00859 {
00860 return(o->oif[ndx_gpsd_SystemTime].value.d);
00861 }
00862 if (o->oif[ndx_diskmgr_LastAcquisitCorrectedTime].valid)
00863 {
00864 return(o->oif[ndx_diskmgr_LastAcquisitCorrectedTime].value.d);
00865 }
00866 if (o->oif[ndx_acquisit_CorrectedTime].valid)
00867 {
00868 return(o->oif[ndx_acquisit_CorrectedTime].value.d);
00869 }
00870 return(time(NULL)-o->shi.age);
00871 }
00872
00873 void ResetInformation()
00874 {
00875 int i;
00876 for (i=0; i<OIF_FIELDS_NUMBER-1; i++)
00877 {
00878 memset(OIFList[i]->value.s,0,sizeof(OIFList[i]->value.s));
00879 OIFList[i]->valid=0;
00880 }
00881 alertFlag=0;
00882 memset(&(myShi),0,sizeof(struct ShortInfos));
00883 memset(osirisErrorMessage,0,sizeof(osirisErrorMessage));
00884 }
00885
00886 void UpdateMap(gdImagePtr im, double scale, double shape, int mapX, int mapY,
00887 double minLat, double maxLat,
00888 double minLon, double maxLon)
00889 {
00890
00891 int bcolor[2],b,black;
00892 char boundary[2][20] = { "political","marine" };
00893 char tmp[128];
00894 char *ptmp;
00895 FILE *f;
00896 int first=0;
00897 gdPoint points[2];
00898 void ProcessOneMapFile(char *fn,int color)
00899 {
00900 f=fopen(fn,"rb");
00901 first=1;
00902 if (f)
00903 {
00904 double lat,lon;
00905 while (!feof(f))
00906 {
00907 fread(&lon,sizeof(double),1,f);
00908 if (lon>180.) lon-=360.;
00909 if (lon<-180.) lon+=360.;
00910 fread(&lat,sizeof(double),1,f);
00911 if (
00912 (isnan(lat))||(isnan(lon))
00913 ||
00914 (lon<minLon)||(lon>maxLon)
00915 ||
00916 (lat<minLat)||(lat>maxLat)
00917 )
00918 {
00919 first=1;
00920 continue;
00921 }
00922 points[1].x= (int)(scale*(lon-minLon));
00923 points[1].y=mapY-(int)(shape*scale*(lat-minLat));
00924 if (first==0)
00925 {
00926 gdImageOpenPolygon(im,points,2,color);
00927 }
00928 points[0].x=points[1].x;
00929 points[0].y=points[1].y;
00930 first=0;
00931 }
00932 fclose(f);
00933 }
00934 }
00935
00936 black=gdImageColorAllocate(im, 0, 0, 0);
00937 bcolor[0]=gdImageColorAllocate(im, 0, 0, 0);
00938 bcolor[1]=gdImageColorAllocate(im, 0, 0, 255);
00939
00940 for (b=0; b<2; b++)
00941 {
00942
00943 if ((maxLon-minLon>40.)||(maxLat-minLat>40.))
00944 {
00945 sprintf(tmp,"%s/www/mapdata/%s-large.dat",omniDir,boundary[b]);
00946 ProcessOneMapFile(tmp,bcolor[b]);
00947 }
00948
00949 else
00950 {
00951 double bMinLat, bMaxLat, bMinLon, bMaxLon;
00952 int xBlock,yBlock;
00953
00954 for (xBlock=0; xBlock<36; xBlock++)
00955 {
00956 bMinLon=-180.+(double)xBlock*10.0;
00957 bMaxLon=bMinLon+10.;
00958 if ((maxLon<bMinLon)||(minLon>bMaxLon))
00959 {
00960 continue;
00961 }
00962 for (yBlock=0; yBlock<18; yBlock++)
00963 {
00964 bMinLat=80.-(double)yBlock*10.0;
00965 bMaxLat=bMinLat+10.;
00966 if ((maxLat<bMinLat)||(minLat>bMaxLat))
00967 {
00968 continue;
00969 }
00970 sprintf(tmp,"%s/www/mapdata/%s-%02d_%02d.dat",
00971 omniDir,boundary[b],
00972 xBlock,yBlock);
00973 ProcessOneMapFile(tmp,bcolor[b]);
00974 }
00975 }
00976 }
00977 }
00978 ptmp=MyGetenv("REMOTE_HOST");
00979 if (ptmp)
00980 {
00981 sprintf(tmp,"%s/www/mapdata/%s.dat",omniDir,ptmp);
00982 ProcessOneMapFile(tmp,black);
00983 }
00984 }
00985
00986
00987 void BuildTopologyMap()
00988 {
00989 struct NodeType
00990 {
00991 unsigned hostid;
00992 char name[128];
00993 float lat,lon;
00994 int status;
00995 struct OmniStationType *o;
00996 int cluster;
00997 };
00998
00999 FILE *f;
01000 char tmp[256];
01001 struct NodeType *node;
01002 int i,j,cluster,c;
01003 int **contact;
01004 int nodeCnt;
01005 struct OmniStationType *cur;
01006
01007
01008
01009 int FindByHostid(unsigned h)
01010 {
01011 int ii;
01012 for (ii=0; (ii<nodeCnt)&&(node[ii].hostid!=0); ii++)
01013 {
01014 if (node[ii].hostid==h)
01015 {
01016 return(ii);
01017 }
01018 }
01019
01020 node[ii].hostid=h;
01021 sprintf(node[ii].name,"%x",h);
01022 return(ii);
01023 }
01024
01025 void DebugMatrix(void)
01026 {
01027 int _i,_j;
01028 puts("<br><br><br>debug<br>");
01029
01030 for (_i=0; (node[_i].hostid!=0)&&(_i<nodeCnt); _i++)
01031 {
01032
01033 {
01034 printf("%8x:%s[%d] ",node[_i].hostid,node[_i].name,node[_i].cluster);
01035 }
01036 }
01037
01038 puts("<br><pre>");
01039 for (_i=0; (node[_i].hostid!=0)&&(_i<nodeCnt); _i++)
01040 {
01041
01042
01043
01044
01045
01046
01047 for (_j=0; (node[_j].hostid!=0)&&(_j<nodeCnt); _j++)
01048 {
01049
01050
01051
01052
01053
01054
01055 printf("%2x",contact[_i][_j]);
01056 }
01057 printf("\n");
01058 }
01059 puts("</pre>");
01060 }
01061
01062
01063
01064 nodeCnt=0;
01065 for (cur=omniStation; cur; cur=cur->next)
01066 {
01067 nodeCnt++;
01068 }
01069 nodeCnt*=2;
01070
01071 contact=(int **)calloc(2*nodeCnt,sizeof(int*));
01072 if (contact==0)
01073 {
01074 exit(2);
01075 }
01076 for (i=0; i<2*nodeCnt; i++)
01077 {
01078 contact[i]=(int *)calloc(2*nodeCnt,sizeof(int));
01079 if (contact[i]==0)
01080 {
01081 exit(1);
01082 }
01083 }
01084
01085 node=(struct NodeType *)calloc(2*nodeCnt,sizeof(struct NodeType));
01086 if (node==0)
01087 {
01088 exit(1);
01089 }
01090
01091 i=0;
01092 for (cur=omniStation; cur; cur=cur->next)
01093 {
01094
01095 if (cur->running==0)
01096 {
01097 continue;
01098 }
01099 if (1!=sscanf(cur->oif[ndx_comd_Hostid].value.s,"%x",&(node[i].hostid)))
01100 {
01101 continue;
01102 }
01103
01104 if ((cur->oif[ndx_gpsd_AvgLat].valid==1)&&(cur->oif[ndx_gpsd_AvgLon].valid==1))
01105 {
01106 node[i].lat=cur->oif[ndx_gpsd_AvgLat].value.f;
01107 node[i].lon=cur->oif[ndx_gpsd_AvgLon].value.f;
01108 node[i].status=2;
01109 }
01110 node[i].o=cur;
01111 strcpy(node[i].name,cur->name);
01112 i++;
01113 if (i>=nodeCnt)
01114 {
01115 exit(255);
01116 }
01117 }
01118
01119 for (cur=omniStation; cur; cur=cur->next)
01120 {
01121 unsigned myHostid;
01122 int myNode,aNode;
01123 if (cur->running==0)
01124 {
01125 continue;
01126 }
01127 if (sscanf(cur->oif[ndx_comd_Hostid].value.s,"%x",&myHostid)!=1)
01128 {
01129 continue;
01130 }
01131 if (myHostid==0)
01132 {
01133 continue;
01134 }
01135
01136 if (abs(TimeOfInfo(cur)-time(NULL))>3*3600)
01137 {
01138 continue;
01139 }
01140 myNode=FindByHostid(myHostid);
01141
01142 sprintf(tmp,"%s/%s/%s.oif",omniDir,cur->name,cur->name);
01143 f=fopen(tmp,"rt");
01144 if (!f)
01145 {
01146 continue;
01147 }
01148
01149 i=0;
01150 while (!feof(f))
01151 {
01152 tmp[0]=0;
01153 fgets(tmp,255,f);
01154 if (0==strncmp("# Destination Gateway",tmp,26))
01155 {
01156 i=1;
01157 break;
01158 }
01159 }
01160 if (i==0)
01161 {
01162 continue;
01163 }
01164
01165 while (!feof(f))
01166 {
01167 char g[64];
01168 char interface[64];
01169 unsigned h;
01170 tmp[0]=0;
01171 fgets(tmp,255,f);
01172 if (0==strncmp(tmp,"#####################",15))
01173 {
01174 break;
01175 }
01176 g[0]=0;
01177 sscanf(tmp,"%*s %*s %s",g);
01178
01179 if (strcmp(g,"0.0.0.0")!=0)
01180 {
01181 continue;
01182 }
01183 h=0;
01184 interface[i]=0;
01185 if (sscanf(tmp,"%*s %*s %*s %x %*s %*s %*s %s",
01186 &h,interface)!=2)
01187 {
01188 continue;
01189 }
01190 if (h==0)
01191 {
01192 continue;
01193 }
01194 aNode=FindByHostid(h);
01195
01196 if ((aNode>=0)&&(aNode!=myNode))
01197 {
01198 contact[myNode][aNode]|=CONTACT;
01199 if (0==strncmp(interface,"eth",3))
01200 {
01201 contact[myNode][aNode]|=ETHERNET;
01202 }
01203 if (0==strncmp(interface,"ppp",3))
01204 {
01205 contact[myNode][aNode]|=PPP;
01206 }
01207 if (0==strncmp(interface,"wlan",4))
01208 {
01209 contact[myNode][aNode]|=WIRELESS;
01210 }
01211 if (0==strncmp(interface,"tun",3))
01212 {
01213 contact[myNode][aNode]|=VPN;
01214 }
01215 if (0==strncmp(interface,"usb",3))
01216 {
01217 contact[myNode][aNode]|=USB;
01218 }
01219 }
01220 }
01221 fclose(f);
01222
01223 }
01224
01225
01226 for (i=0; (node[i].hostid!=0)&&(i<nodeCnt); i++)
01227 {
01228 for (j=0; (node[j].hostid)&&(j<nodeCnt); j++)
01229 {
01230 contact[i][j]|=contact[j][i];
01231 }
01232 }
01233
01234
01235 cluster=1;
01236
01237 node[0].cluster=contact[0][0]=cluster;
01238 while (1)
01239 {
01240 int cont=0;
01241
01242
01243
01244
01245 for (i=0; i<nodeCnt; i++)
01246 {
01247
01248 if (node[i].cluster==0) continue;
01249
01250 for (j=0; j<nodeCnt; j++)
01251 {
01252
01253 if (node[j].cluster!=0) continue;
01254 if (i==j) continue;
01255 if ((contact[i][j]!=0)||(contact[j][i]!=0))
01256 {
01257 node[j].cluster=node[i].cluster;
01258 contact[j][j]=node[i].cluster;
01259 cont=1;
01260 }
01261 }
01262 }
01263 if (cont) continue;
01264
01265 cluster++;
01266
01267 for (i=0; i<nodeCnt; i++)
01268 {
01269 if (node[i].cluster==0)
01270 {
01271 node[i].cluster=cluster;
01272 cont=1;
01273 break;
01274 }
01275 }
01276 if (cont) continue;
01277
01278 break;
01279 }
01280 #if 0
01281 for (i=0; i<nodeCnt; i++)
01282 {
01283 int alone=1;
01284 int increase=0;
01285 if (node[i].hostid==0) continue;
01286
01287 if (node[i].cluster==0)
01288 {
01289 increase=1;
01290 node[i].cluster=cluster;
01291 contact[i][i]=cluster;
01292 }
01293
01294 for (j=0; j<nodeCnt; j++)
01295 {
01296 if (i==j) continue;
01297
01298 if ((contact[i][j]!=0)||(contact[j][i]!=0))
01299 {
01300 if (node[j].cluster<=0)
01301 {
01302 node[j].cluster=node[i].cluster;
01303 contact[j][j]=node[i].cluster;
01304 }
01305 alone=0;
01306 }
01307 }
01308 if (alone==1)
01309 {
01310 node[i].cluster=0;
01311 }
01312 else
01313 {
01314 cluster+=increase;
01315 }
01316 }
01317 #endif
01318
01319 for (i=0; (node[i].hostid!=0)&&(i<nodeCnt); i++)
01320 {
01321 int cnt;
01322 sprintf(tmp,"%s/%s/%s.geo",omniDir,node[i].name,node[i].name);
01323 f=fopen(tmp,"rt");
01324 if (f)
01325 {
01326 float lat,lon;
01327 if (fscanf(f,"%f %f",&lat,&lon)==2)
01328 {
01329 node[i].lat=lat;
01330 node[i].lon=lon;
01331 node[i].status=2;
01332 }
01333 }
01334 if (node[i].status!=0)
01335 {
01336 continue;
01337 }
01338 node[i].lat=node[i].lon=0.0;
01339 cnt=0;
01340 for (j=0; (node[j].hostid)&&(j<nodeCnt); j++)
01341 {
01342 int k;
01343 if (node[j].status==0)
01344 {
01345 continue;
01346 }
01347 k=contact[i][j]*node[j].status;
01348 node[i].lat+=node[j].lat*(double)k;
01349 node[i].lon+=node[j].lon*(double)k;
01350 cnt+=k;
01351 }
01352 if (cnt>0)
01353 {
01354 node[i].lat/=(double)cnt;
01355 node[i].lon/=(double)cnt;
01356 node[i].status=1;
01357 }
01358 }
01359
01360
01361 puts("<center><h2>Connectivity maps</h2></center>");
01362 puts("<center><a href=/www/cgi-bin/Supervisor>OMNI supervisor page</a></center>");
01363 puts("<br><br>");
01364
01365 for (c=0; c<cluster; c++)
01366 {
01367 double minLon=0.,minLat=0.,maxLon=0.,maxLat=0.,delta,shape,scale;
01368 int first=1;
01369 int mapX,mapY,count;
01370 int white,red,black,blue,grey;
01371 gdImagePtr im;
01372 char *ptmp;
01373
01374 count=0;
01375 for (i=0; (node[i].hostid!=0)&&(i<nodeCnt); i++)
01376 {
01377 if (node[i].cluster==c+1)
01378 {
01379 count++;
01380 }
01381 }
01382 if (count==1)
01383 {
01384 for (i=0; (node[i].hostid!=0)&&(i<nodeCnt); i++)
01385 {
01386 if (node[i].cluster==c+1)
01387 {
01388 node[i].cluster=0;
01389 }
01390 }
01391 }
01392 if (count<=2)
01393 {
01394 continue;
01395 }
01396 if (count<3)
01397 {
01398 printf("Cluster %d contains only ",c+1);
01399 for (i=0; (node[i].hostid!=0)&&(i<nodeCnt); i++)
01400 {
01401 if (node[i].cluster!=c+1) continue;
01402 if (node[i].o)
01403 {
01404 printf("<a href=/www/cgi-bin/SingleStation?%s alt=%s "
01405 "title=\"%s\n%s\">%s </a>\n",
01406 node[i].name,node[i].name,
01407 StationName(node[i].o),
01408 node[i].o->alertTip,StationName(node[i].o));
01409 }
01410 else
01411 {
01412 printf("%s ",node[i].name);
01413 }
01414 }
01415 puts("<br>");
01416 continue;
01417 }
01418
01419 for (i=0; (node[i].hostid!=0)&&(i<nodeCnt); i++)
01420 {
01421
01422 if (node[i].cluster!=c+1)
01423 {
01424 continue;
01425 }
01426
01427 if (node[i].status==0)
01428 {
01429 continue;
01430 }
01431 if (first)
01432 {
01433 minLon=maxLon=node[i].lon;
01434 minLat=maxLat=node[i].lat;
01435 }
01436 first=0;
01437 if (node[i].lon>maxLon) maxLon=node[i].lon;
01438 if (node[i].lat>maxLat) maxLat=node[i].lat;
01439 if (node[i].lon<minLon) minLon=node[i].lon;
01440 if (node[i].lat<minLat) minLat=node[i].lat;
01441 }
01442 shape=1./cos(M_PI*0.5*(maxLat+minLat)/180.);
01443 delta=0.0001+(maxLon-minLon)*0.2;
01444 maxLon+=delta;
01445 minLon-=delta;
01446 delta=0.0001+(maxLat-minLat)*0.2;
01447 maxLat+=delta;
01448 minLat-=delta;
01449
01450
01451 if (((maxLat-minLat)/(maxLon-minLon))<((double)MAPY/(double)MAPX))
01452 {
01453 mapX=(int)((double)MAPX);
01454 scale=(double)mapX/(maxLon-minLon);
01455 mapY=(int)((double)MAPY*
01456 ((maxLat-minLat)/(maxLon-minLon))/
01457 ((double)MAPY/(double)MAPX));
01458 }
01459 else
01460 {
01461 mapY=MAPY;
01462 scale=(double)mapY/(maxLat-minLat);
01463 mapX=(int)((double)MAPX/
01464 (((maxLat-minLat)/(maxLon-minLon))/
01465 ((double)MAPY/(double)MAPX)));
01466 }
01467
01468 mapY=(int)((double)mapY*shape);
01469
01470