Changeset 172
- Timestamp:
- 03/02/10 13:24:35 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Evidence/DColl.cc
r160 r172 22 22 #define SERVER_NAME "DColl" 23 23 24 #define DATE_ROLLOVER 12 // localtime hour after which next date is used 24 #define DATE_ROLLOVER 12 // localtime hour after which next date is used 25 #define MIN_HIST_SIZE 1024 // Minimum history buffer in bytes (> 3*sizeof(int) !) 25 26 26 27 #include "Evidence.h" … … 50 51 DimService *HistService; 51 52 char *Buffer; 53 unsigned int HistSize; 52 54 int Next; 53 55 double LastValue; … … 66 68 DimService *LogSizeService, *DataSizeService, *DataFilename; 67 69 string HistDir; 68 int HistSize;69 70 int SizeUpdateDelay; 70 71 int TimeForNextFile; … … 73 74 regex_t *RegEx; 74 75 double *MinChange; 76 unsigned int *HistSize; 75 77 76 78 void infoHandler(); 77 79 void commandHandler(); 78 80 void AddService(string); 81 void RemoveService(string); 79 82 float FileSize(FILE *); 80 83 … … 102 105 103 106 // Request configuration data 104 char *Change = GetConfig(SERVER_NAME " minchange");107 char *Change = GetConfig(SERVER_NAME " items"); 105 108 DataDir = GetConfig(SERVER_NAME " datadir"); 106 109 char *Logname = GetConfig(SERVER_NAME " logfile"); 107 110 SizeUpdateDelay = atoi(GetConfig(SERVER_NAME " sizeupdate")); 108 HistSize = atoi(GetConfig(SERVER_NAME " histsize"));109 if (HistSize < 3*sizeof(int)) HistSize = 3*sizeof(int);110 111 HistDir = GetConfig(SERVER_NAME " histdir"); 111 112 … … 135 136 } 136 137 137 // Allocate memory for regular expressions and minimum change values138 // Allocate memory for regular expressions, minimum change and history size 138 139 RegEx = new regex_t[RegExCount]; 139 140 MinChange = new double [RegExCount]; 140 141 // Compile regular expressions 141 HistSize = new unsigned int [RegExCount]; 142 143 // Compile regular expressions and extract minimum change and history size 142 144 int Pos = 0; 143 145 for (int i=0; i<RegExCount; i++) { … … 152 154 } 153 155 else { 154 if ((Token=strtok(NULL, " ")) != NULL) MinChange[i] = atof(Token);156 if ((Token=strtok(NULL, ": \t")) != NULL) MinChange[i] = atof(Token); 155 157 else MinChange[i] = 0; 158 if ((Token=strtok(NULL, "")) != NULL) HistSize[i] = atoi(Token)*1024; 159 else HistSize[i] = MIN_HIST_SIZE; 160 if (HistSize[i] < MIN_HIST_SIZE) HistSize[i] = MIN_HIST_SIZE; 156 161 } 157 162 Pos += Len; … … 167 172 DataHandler::~DataHandler() { 168 173 169 // Delete DIM subscriptions and command first so handlers and not called anymore 170 for (int i=0; i<List.size(); i++) { 171 delete List[i].DataItem; 172 } 174 // Delete all DIM subscriptions 175 while (List.size() != 0) RemoveService(List[0].DataItem->getName()); 176 173 177 delete LogCommand; 174 175 // Save history buffers to files (replace '/' by '_')176 State(INFO, "Writing history buffers to files");177 178 for (int i=0; i<List.size(); i++) {179 string Name = List[i].HistService->getName();180 for (int j=0; j<Name.size(); j++) if (Name[j] == '/') Name[j] = '_';181 FILE *File = fopen((HistDir + "/" + Name).c_str(), "wb");182 if (File != NULL) {183 fwrite(&List[i].Next, sizeof(List[i].Next), 1, File);184 fwrite(List[i].Buffer, sizeof(char), HistSize, File);185 fclose(File);186 }187 delete List[i].HistService;188 delete[] List[i].Buffer;189 }190 191 178 delete DataFilename; 192 179 delete[] Filename; … … 232 219 // If service is DIS_DNS/SERVER_LIST, subscribe to all SERVICE_LIST services 233 220 if (strcmp(Info->getName(), "DIS_DNS/SERVER_LIST") == 0) { 234 char *Token = strtok(Info->getString(), " @");221 char *Token = strtok(Info->getString(), "+-!@"); 235 222 while (Token != NULL) { 236 if (isalpha(*Token) == 0) Token++; // Name can start with +,-,! 237 238 AddService(string(Token)+"/SERVICE_LIST"); 239 240 Token = strtok(NULL, "|"); 241 Token = strtok(NULL, "|@"); // ???? Why needed ????? 223 if (*Info->getString()=='-' || *Info->getString()=='!') RemoveService(string(Token)+"/SERVICE_LIST"); 224 else AddService(string(Token)+"/SERVICE_LIST"); 225 Token = strtok(NULL, "|"); // Skip server IP address 226 Token = strtok(NULL, "@"); 242 227 } 243 228 return; … … 247 232 // Subscribe to all services (but not to commands and RPCs) 248 233 if (strstr(Info->getName(), "/SERVICE_LIST") != NULL) { 249 250 char *Name = strtok(Info->getString(), "|"); 234 char *Name = strtok(Info->getString(), "+-!|"); 251 235 while (Name != NULL) { 236 // Check if item is a service 252 237 char *Type = strtok(NULL, "\n"); 253 238 if (Type == NULL) return; // for safety, should not happen 254 if (isalpha(*Name) == 0) Name++; // Name can start with +,-,!255 239 if (strstr(Type, "|CMD")==NULL && strstr(Type, "|RPC")==NULL) { 256 AddService(Name); 240 // Add or remove service 241 if (*Info->getString()=='-' || *Info->getString()=='!') RemoveService(Name); 242 else AddService(Name); 257 243 } 258 244 Name = strtok(NULL, "|"); … … 323 309 // If negative value for absolute change, do not write to file 324 310 if (List[Service].MinAbsChange >= 0) { 325 326 // Write data header 327 time_t RawTime = Info->getTimestamp(); 328 struct tm *TM = localtime(&RawTime); 329 330 fprintf(DataFile, "%s %d %d %d %d %d %d %d %lu ", Info->getName(), TM->tm_year+1900, TM->tm_mon+1, TM->tm_mday, TM->tm_hour, TM->tm_min, TM->tm_sec, Info->getTimestampMillisecs(), Info->getTimestamp()); 331 332 // Translate data into ASCII 333 char *Text = EvidenceServer::ToString(Info); 334 335 if (Text != NULL) { 336 // Replace all control characters by white space 337 for (int i=0; i<strlen(Text); i++) if (iscntrl(Text[i])) Text[i] = ' '; 338 339 // Write to file 340 fprintf(DataFile, "%s\n", Text); 341 311 // Write data header 312 time_t RawTime = Info->getTimestamp(); 313 struct tm *TM = localtime(&RawTime); 314 315 fprintf(DataFile, "%s %d %d %d %d %d %d %d %lu ", Info->getName(), TM->tm_year+1900, TM->tm_mon+1, TM->tm_mday, TM->tm_hour, TM->tm_min, TM->tm_sec, Info->getTimestampMillisecs(), Info->getTimestamp()); 316 317 // Translate data into ASCII 318 char *Text = EvidenceServer::ToString(Info); 319 320 if (Text != NULL) { 321 // Replace all control characters by white space 322 for (int i=0; i<strlen(Text); i++) if (iscntrl(Text[i])) Text[i] = ' '; 323 324 // Write to file 325 fprintf(DataFile, "%s\n", Text); 326 327 free(Text); 328 } 329 else fprintf(DataFile, "Cannot interpret format identifier\n"); 330 331 // Terminate if error because otherwise infinite loop might result as 332 // next call to this infoHandler() will try to (re-)open file 333 if(ferror(DataFile)) { 334 fclose(DataFile); 335 DataFile = NULL; 336 State(FATAL, "Error writing to data file, closed file (%s)", strerror(errno)); 337 } 338 339 // Update datafile size service (not every time to avoid infinite loop) 340 if (time(NULL) - DataSizeLastUpdate > SizeUpdateDelay) { 341 fflush(DataFile); // not continuously to reduce load 342 343 DataSizekB = FileSize(DataFile); 344 DataSizeService->updateService(); 345 DataSizeLastUpdate = time(NULL); 346 } 347 } // Check for disk writing 348 349 // 350 // ====== Part D: Handle history service === 351 // 352 353 if (Info->getSize() == 0) return; 354 355 // Check if data should be added to history buffer 356 if (strcmp(Info->getFormat(),"C") != 0 && strlen(Info->getFormat())==1) { 357 // Calculate sum of all number in array 358 char *Text = EvidenceServer::ToString(Info); 359 char *Token = strtok(Text, " "); 360 double Sum = 0; 361 while (Token != NULL) { 362 Sum += atof(Token); 363 Token = strtok(NULL, " "); 364 } 342 365 free(Text); 343 } 344 else fprintf(DataFile, "Cannot interpret format identifier\n"); 345 346 // Terminate if error because otherwise infinite loop might result as 347 // next call to this infoHandler() will try to (re-)open file 348 if(ferror(DataFile)) { 349 fclose(DataFile); 350 DataFile = NULL; 351 State(FATAL, "Error writing to data file, closed file (%s)", strerror(errno)); 352 } 353 354 // Update datafile size service (not every time to avoid infinite loop) 355 if (time(NULL) - DataSizeLastUpdate > SizeUpdateDelay) { 356 fflush(DataFile); // not continuously to reduce load 357 358 DataSizekB = FileSize(DataFile); 359 DataSizeService->updateService(); 360 DataSizeLastUpdate = time(NULL); 361 } 362 363 } // Check for MinAbsChange 364 365 // 366 // ====== Part D: Handle history service === 367 // 368 369 if (Info->getSize() == 0) return; 370 371 // Check if data should be added to history buffer 372 char *Text = EvidenceServer::ToString(Info); 373 if (Text != NULL && strcmp(Info->getFormat(),"C") != 0 374 && fabs(atof(Text)-List[Service].LastValue) < fabs(List[Service].MinAbsChange)) { 375 free(Text); 376 return; 377 } 378 free(Text); 379 366 // Minimum change? 367 if (fabs(Sum-List[Service].LastValue) < fabs(List[Service].MinAbsChange)) return; 368 List[Service].LastValue = Sum; 369 } 370 380 371 // Check if data fits into buffer 381 if ( HistSize < Info->getSize() + 5*sizeof(int)) return;372 if (List[Service].HistSize < Info->getSize() + 5*sizeof(int)) return; 382 373 383 374 int Size = Info->getSize() + 4*sizeof(int), Next = List[Service].Next; … … 387 378 388 379 // Check if buffer wrap-around (write wrap mark after Oldest is adjusted) 389 if (Next + Size >= HistSize) {380 if (Next + Size >= List[Service].HistSize) { 390 381 WrapPos = Buffer + Next; 391 382 Next = 4; … … 482 473 // Set minimum required change by comparing to regular expressions 483 474 New.MinAbsChange = 0; 475 New.HistSize = MIN_HIST_SIZE; 484 476 for (int i=0; i<RegExCount; i++) { 485 477 if (regexec(&RegEx[i], Name.c_str(), (size_t) 0, NULL, 0) == 0) { 486 478 New.MinAbsChange = MinChange[i]; 479 New.HistSize = HistSize[i]; 487 480 } 488 481 } 489 482 490 483 // Create history service 491 New.Buffer = new char [ HistSize];492 memset(New.Buffer, 0, HistSize);484 New.Buffer = new char [New.HistSize]; 485 memset(New.Buffer, 0, New.HistSize); 493 486 *(int *) New.Buffer = 4; 494 487 New.Next = 4; 495 488 New.LastValue = DBL_MAX; 496 489 New.HistService = new DimService ((Name+".hist").c_str(), (char *) "C", 497 New.Buffer, HistSize);490 New.Buffer, New.HistSize); 498 491 499 492 // Load history buffer from file if existing … … 503 496 if (File != NULL) { 504 497 // Only load if current buffer size if equal or larger 505 if (FileSize(File) <= HistSize*sizeof(char)+sizeof(New.Next) && FileSize(File) != -1) {498 if (FileSize(File) <= New.HistSize*sizeof(char)+sizeof(New.Next) && FileSize(File) != -1) { 506 499 fread(&New.Next, sizeof(New.Next), 1, File); 507 fread(New.Buffer, sizeof(char), HistSize, File);500 fread(New.Buffer, sizeof(char), New.HistSize, File); 508 501 fclose(File); 509 502 } … … 516 509 List.push_back(New); 517 510 } 511 512 513 // 514 // Remove service from watch list 515 // 516 void DataHandler::RemoveService(string Name) { 517 518 // Find service index 519 vector<struct Item>::iterator E; 520 for (E=List.begin(); E<List.end(); ++E) if (Name == (*E).DataItem->getName()) { 521 // Delete subscription first so handler and not called anymore 522 delete (*E).DataItem; 523 524 // Save history buffer (replace '/' by '_') 525 string Name = (*E).HistService->getName(); 526 for (int j=0; j<Name.size(); j++) if (Name[j] == '/') Name[j] = '_'; 527 FILE *File = fopen((HistDir + "/" + Name).c_str(), "wb"); 528 if (File != NULL) { 529 fwrite(&(*E).Next, sizeof((*E).Next), 1, File); 530 fwrite((*E).Buffer, sizeof(char), (*E).HistSize, File); 531 fclose(File); 532 } 533 534 // Delete history service and free memory 535 delete (*E).HistService; 536 delete[] (*E).Buffer; 537 List.erase(E); 538 } 539 } 540 518 541 519 542 //
Note:
See TracChangeset
for help on using the changeset viewer.