Changeset 221


Ignore:
Timestamp:
Jun 7, 2010, 3:00:41 PM (10 years ago)
Author:
ogrimm
Message:
Added Bridge server, History service separated from DColl
Location:
Evidence
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • Evidence

    • Property svn:ignore
      •  

        old new  
        22Config
        33DColl
         4Bridge
         5History
  • Evidence/Config.cc

    r216 r221  
    4848
    4949    void rpcHandler();
    50  
     50        void AddItem(string, string, string);
     51        string RemoveSpaces(string &);
     52
    5153  public:
    5254    EvidenceConfig(const char *);
     
    168170
    169171  stringstream In(FileContent), Out;
    170   string Line;
    171   struct Item New;
    172   size_t Pos;
     172  string Section, Item, Line, Data;
    173173 
    174174  // First clean up and concatenate lines
     
    178178    // Replace all tabs by spaces
    179179    while (Line.find("\t") != string::npos) Line[Line.find("\t")] = ' ';
    180         // Remove leading spaces
    181         while (!Line.empty() && isspace(Line[0])) Line.erase(0, 1);
    182         // Remove trailing spaces
    183         while (!Line.empty() && isspace(Line[Line.size()-1])) Line.erase(Line.size()-1);
    184180        // Remove empty lines
    185         if (Line.empty()) continue;
    186         // Concatenate if line ends with '+'
    187     if (Line[Line.size()-1] != '+') Out << Line << endl;
     181        if (RemoveSpaces(Line).empty()) continue;
     182        // Concatenate if line ends with '\'
     183    if (Line[Line.size()-1] != '\\') Out << Line << endl;
    188184        else Out << Line.erase(Line.size()-1);
    189185  };
     
    194190  // Interpret data
    195191  while (getline(In, Line).good()) {
    196     // Remove multiple spaces
    197     while (Line.find("  ") != string::npos) Line.erase(Line.find("  "), 1);
    198 
    199         // Find second space character
    200     Pos = Line.find(" ", Line.find(" ") + 1);
    201         if(Pos == string::npos) continue;
    202 
    203         // Extract configuration name and data
    204         New.Name = string(Line, 0, Pos);
    205         New.Data = string(Line, Pos+1);
    206 
    207         // Add to configuration list
    208         if (pthread_mutex_lock(&Mutex) != 0) Message(ERROR, "pthread_mutex_lock() failed in ConfigChanged()");
    209         List.push_back(New);
    210         if (pthread_mutex_unlock(&Mutex) != 0) Message(ERROR, "pthread_mutex_unlock() failed in ConfigChanged()");
    211   };
    212 }
    213 
     192
     193        // Check if current line is section heading (contains only [xxx])
     194        if (Line.find('[')==0 && Line.find(']')==Line.size()-1) {
     195          // Add previous item to list (if any)
     196          AddItem(Section, Item, Data);
     197          Item.clear();
     198          Data.clear();
     199          // Extract new section name
     200          Section = Line.substr(1, Line.size()-2);
     201          continue;
     202        }
     203
     204        // Check if current line contains equal sign (defines new item name)
     205        if((Line.find('=')) != string::npos) {
     206          // Add previous item to list
     207          AddItem(Section, Item, Data);
     208          // Extract parameter name and data
     209          Item = string(Line, 0, Line.find('=')-1);
     210          Data = string(Line, Line.find('=')+1, string::npos);
     211        }
     212        else Data += ' ' + Line; // Concatenate lines
     213  }
     214  // Add last item
     215  AddItem(Section, Item, Data);
     216}
     217
     218// Add item to configuration list
     219void EvidenceConfig::AddItem(string Section, string Parameter, string Data) {
     220
     221  // Clean up strings
     222  RemoveSpaces(Parameter);
     223  RemoveSpaces(Data);
     224  if (Section.empty() || Parameter.empty() || Data.empty()) return;
     225
     226  // Prepare new item of configuration list
     227  struct Item New;
     228  New.Name = Section + ' ' + Parameter;
     229  New.Data = Data;
     230
     231  // Add to configuration list
     232  if (pthread_mutex_lock(&Mutex) != 0) Message(ERROR, "pthread_mutex_lock() failed in ConfigChanged()");
     233  List.push_back(New);
     234  if (pthread_mutex_unlock(&Mutex) != 0) Message(ERROR, "pthread_mutex_unlock() failed in ConfigChanged()");
     235}
     236
     237// Removes whitespace
     238string EvidenceConfig::RemoveSpaces(string &Text) {
     239
     240  // Remove leading spaces
     241  while (!Text.empty() && isspace(Text[0])) Text.erase(0, 1);
     242  // Remove trailing spaces
     243  while (!Text.empty() && isspace(Text[Text.size()-1])) Text.erase(Text.size()-1);
     244  // Remove multiple spaces
     245  while (Text.find("  ") != string::npos) Text.erase(Text.find("  "), 1);
     246 
     247  return Text;
     248}
    214249
    215250//         
  • Evidence/DColl.cc

    r216 r221  
    66    server and writes these to the data file at every update.
    77  - One data file per day is generated.
    8   - A history of events is kept within a ring buffer for each service. Each
    9         entry will be the result of a conversion to double of the text
    10         written to the data file. Only if the new value has changed by a
    11         minimum amout it will be added to the ring buffer. The history is
    12         available via an rpc call.
    13   - The history buffers are written to disk at program termination and
    14     are tired to be read when adding a service.
    158  - The command 'DColl/Log' writes the associated string to the log file
    169 
    17   Oliver Grimm, May 2010
     10  Oliver Grimm, June 2010
    1811
    1912\********************************************************************/
    2013
    2114#define SERVER_NAME "DColl"
    22 
    23 #define MIN_HIST_SIZE 1024      // Minimum history buffer in bytes (> 3*sizeof(int) !)
    2415#define LOG_FILENAME "Evidence.log"
    2516
     
    2920#include <sstream>
    3021#include <vector>
    31 #include <iomanip>
    32 
    33 #include <math.h>
    34 #include <float.h>
    3522#include <sys/stat.h>
    36 #include <ctype.h>
    37 #include <sys/types.h>
    3823#include <regex.h>
    3924
     
    4328// Class declaration
    4429//
    45 class DataHandler:      public DimRpc, public DimClient, public DimBrowser,
    46                                         public EvidenceServer {
     30class DataHandler:      public DimClient, public EvidenceServer {
    4731
    4832        struct Item {
    4933          DimStampedInfo *DataItem;
    50           char *Buffer;
    51           unsigned int HistSize;
    52           int Next;
    53           double LastValue;
    54           double MinAbsChange;
     34          bool Exclude;
    5535        };
    5636        vector<struct Item> List;
    5737       
    5838        DimCommand *LogCommand;
     39        DimInfo *ServerList;
    5940               
    6041    FILE *DataFile;
     
    6950        int RollOver;
    7051
    71         int RegExCount;
    72         regex_t *RegEx;
    73         double *MinChange;
    74     unsigned int *HistSize;
     52        vector<regex_t> RegEx;
    7553       
    7654    void infoHandler();
    77     void rpcHandler();
    7855    void commandHandler();
    7956        void AddService(string);
    8057        void RemoveService(string);
    8158        off_t FileSize(FILE *);
    82         FILE *OpenHistFile(string, const char *);
    8359   
    8460  public:
     
    9066// Constructor
    9167//
    92 DataHandler::DataHandler(): DimRpc("ServiceHistory", "C", "C"), EvidenceServer(SERVER_NAME) {
     68DataHandler::DataHandler(): EvidenceServer(SERVER_NAME) {
    9369
    9470  // Initialization to prevent freeing unallocated memory
     
    11389    Message(FATAL, "Could not open log file (%s)", strerror(errno));
    11490  }
    115 
    116   // Provide logging command   
    117   LogCommand = new DimCommand("DColl/Log", (char *) "C", this);
    11891             
    11992  // Create services for file sizes and data file name
     
    12699  DataFilename = new DimService(SERVER_NAME "/CurrentFile", (char *) "");
    127100
    128   // Count how many minimum change regular expressions are present
    129   char *Change = GetConfig("items");
    130   RegExCount = 0;
    131   char *Token = strtok(Change, "\t ");
     101  // Compile regular expressions
     102  char *Exclude = GetConfig("exclude");
     103  char *Token = strtok(Exclude, "\t ");
     104  regex_t R;
     105
    132106  while (Token != NULL) {
    133         RegExCount++;
     107        int Ret = regcomp(&R, Token, REG_EXTENDED|REG_NOSUB);
     108        if (Ret != 0) {
     109          char Err[200];
     110          regerror(Ret, &R, Err, sizeof(Err));
     111          Message(ERROR, "Error compiling regular expression '%s' (%s)", Token, Err);
     112        }
     113        else RegEx.push_back(R);
     114
    134115        Token = strtok(NULL, "\t ");
    135116  }
    136117 
    137   // Allocate memory for regular expressions, minimum change and history size
    138   RegEx = new regex_t [RegExCount];
    139   MinChange = new double [RegExCount];
    140   HistSize = new unsigned int [RegExCount];
    141 
    142   // Compile regular expressions and extract minimum change and history size
    143   int Pos = 0;
    144   for (int i=0; i<RegExCount; i++) {
    145     int Len = strlen(Change+Pos) + 1;
    146     Token = strtok(Change + Pos, ": \t");
    147 
    148     int Ret = regcomp(&RegEx[i], Token, REG_EXTENDED|REG_NOSUB);
    149         if (Ret != 0) {
    150           char ErrMsg[200];
    151           regerror(Ret, &RegEx[i], ErrMsg, sizeof(ErrMsg));
    152           RegExCount--;
    153           i--;
    154           Message(ERROR, "Error compiling regular expression '%s' (%s)", Token, ErrMsg);
    155         }
    156         else {
    157           if ((Token=strtok(NULL, ": \t")) != NULL) MinChange[i] = atof(Token);
    158           else MinChange[i] = 0;
    159 
    160           if ((Token=strtok(NULL, "")) != NULL) HistSize[i] = atoi(Token)*1024;
    161           else HistSize[i] = 0;
    162         }
    163         Pos += Len;
    164   }
    165 
    166   // Subscribe to list of servers at DIS_DNS
    167   AddService("DIS_DNS/SERVER_LIST");
     118  // Provide logging command   
     119  LogCommand = new DimCommand("DColl/Log", (char *) "C", this);
     120
     121  // Subsribe to top-level server list (not via AddService() due to thread issue)
     122  ServerList = new DimInfo((char *) "DIS_DNS/SERVER_LIST", NO_LINK, this);
    168123}
    169124
     
    174129
    175130  // Delete all DIM subscriptions
     131  delete ServerList;
    176132  while (List.size() != 0) RemoveService(List[0].DataItem->getName());
    177133 
     
    192148
    193149  // Free memory for regular expressions handling
    194   for (int i=0; i<RegExCount; i++) {
    195     regfree(&RegEx[i]);
    196   }
    197   delete[] MinChange;
    198   delete[] RegEx;
     150  for (int i=0; i<RegEx.size(); i++) regfree(&RegEx[i]);
    199151}
    200152
     
    206158void DataHandler::infoHandler() {
    207159
    208   DimInfo *Info = getInfo();
     160  DimInfo *I = getInfo();
    209161
    210162  // Check if service available
    211   if (!ServiceOK(Info)) return;
     163  if (!ServiceOK(I)) return;
    212164
    213165  //
     
    217169 
    218170  // If service is DIS_DNS/SERVER_LIST, subscribe to all SERVICE_LIST services
    219   if (strcmp(Info->getName(), "DIS_DNS/SERVER_LIST") == 0) {   
    220         char *Token = strtok(Info->getString(), "+-!@");       
     171  if (strcmp(I->getName(), "DIS_DNS/SERVER_LIST") == 0) {       
     172        char *Token = strtok(I->getString(), "+-!@");   
    221173        while (Token != NULL) {
    222174          AddService(string(Token)+"/SERVICE_LIST"); // 'add' also for '-' and '!'
     
    229181  // If service is SERVICE_LIST of any server, scan all services.
    230182  // Subscribe to all services (but not to commands and RPCs)
    231   if (strstr(Info->getName(), "/SERVICE_LIST") != NULL) {
    232         char *Name = strtok(Info->getString(), "+-!|");
     183  if (strstr(I->getName(), "/SERVICE_LIST") != NULL) {
     184        char *Name = strtok(I->getString(), "+-!|");
    233185        while (Name != NULL) {
    234186          // Check if item is a service
     
    242194
    243195  //
    244   // ====== Part B: Handle opening data files ===
     196  // ====== Part B: Handle opening of data files ===
    245197  //
    246198
     
    297249
    298250  // Identify index of service
    299   int Service;
    300   for (Service=0; Service<List.size(); Service++) if (Info == List[Service].DataItem) break;
    301   if (Service == List.size()) return;  // Service not found
    302 
    303   // If negative value for absolute change, do not write to file
    304   if (List[Service].MinAbsChange >= 0) {
     251  for (int Service=0; Service<List.size(); Service++) if (I == List[Service].DataItem) {
     252
     253        // Service excluded from writing?
     254        if (List[Service].Exclude) return;
     255       
    305256        // Write data header
    306         time_t RawTime = Info->getTimestamp();
     257        time_t RawTime = I->getTimestamp();
    307258        struct tm *TM = localtime(&RawTime);
    308259
    309         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());
     260        fprintf(DataFile, "%s %d %d %d %d %d %d %d %d %lu ", I->getName(), I->getQuality(), TM->tm_year+1900, TM->tm_mon+1, TM->tm_mday, TM->tm_hour, TM->tm_min, TM->tm_sec, I->getTimestampMillisecs(), I->getTimestamp());
    310261
    311262        // Translate data into ASCII
    312         char *Text = EvidenceServer::ToString(Info);
     263        char *Text = EvidenceServer::ToString(I);
    313264
    314265        if (Text != NULL) {
     
    343294        } 
    344295  } // Check for disk writing
    345 
    346   //
    347   // ====== Part D: Handle history service ===
    348   //
    349 
    350   if (Info->getSize()==0 || Info->getTimestamp()==0) return;
    351 
    352   // Check if data should be added to history buffer
    353   if (strcmp(Info->getFormat(),"C") != 0 && strlen(Info->getFormat())==1) {
    354         // Calculate sum of all number in array
    355         char *Text = EvidenceServer::ToString(Info);
    356         char *Token = strtok(Text, " ");
    357         double Sum = 0;
    358         while (Token != NULL) {
    359           Sum += atof(Token);
    360       Token = strtok(NULL, " ");
    361         }
    362         free(Text);
    363         // Minimum change?
    364         if (fabs(Sum-List[Service].LastValue) < fabs(List[Service].MinAbsChange)) return;
    365         List[Service].LastValue = Sum;
    366   }
    367  
    368   // Check if data fits into buffer
    369   if (List[Service].HistSize < Info->getSize() + sizeof(int)+ 2*sizeof(EvidenceHistory::Item)) return;
    370 
    371   int Size = Info->getSize() + 2*sizeof(EvidenceHistory::Item), Next = List[Service].Next;
    372   void *WrapPos = NULL;
    373   char *Buffer = List[Service].Buffer;
    374   int Oldest = *(int *) Buffer;
    375 
    376   // Check if buffer wrap-around (write wrap mark after Oldest is adjusted)
    377   if (Next + Size >= List[Service].HistSize) {
    378     WrapPos = Buffer + Next;
    379     Next = 4;
    380   }
    381 
    382   // Adapt pointer to oldest entry
    383   while ((Oldest < Next + Size) &&
    384                  (Oldest + *((int *) (Buffer + Oldest) + 1) + 2*sizeof(int) > Next)) {
    385         // Check for wrap-around
    386         if (memcmp(Buffer + Oldest, &EvidenceHistory::WrapMark, sizeof(EvidenceHistory::WrapMark)) == 0) {
    387           Oldest = 4;
    388           continue;
    389         }
    390         // Check if end marker reached, then only one event fits buffer
    391         if (memcmp(Buffer + Oldest, &EvidenceHistory::EndMark, sizeof(EvidenceHistory::EndMark)) == 0) {
    392           Oldest = Next;
    393           break;
    394         }
    395         // Move to next entry
    396     Oldest += *((int *) (Buffer + Oldest) + 1) + 2*sizeof(int);
    397   }
    398   // Update pointer in buffer
    399   *(int *) Buffer = Oldest;
    400 
    401   // Write wrap mark if necessary
    402   if (WrapPos != NULL) memcpy(WrapPos, &EvidenceHistory::WrapMark, sizeof(EvidenceHistory::WrapMark));
    403 
    404   // Copy data into ring buffer
    405   *((int *) (Buffer + Next)) = Info->getTimestamp();
    406   *((int *) (Buffer + Next + sizeof(int))) = Info->getSize();
    407   memcpy(Buffer + Next + 2*sizeof(int), Info->getData(), Info->getSize());
    408 
    409   // Adjust pointer for next entry and write end marker to buffer
    410   Next += Info->getSize() + sizeof(EvidenceHistory::Item);
    411   memcpy(Buffer + Next, &EvidenceHistory::EndMark, sizeof(EvidenceHistory::EndMark));
    412  
    413   List[Service].Next = Next;
    414296}
    415297
     
    454336
    455337//
    456 // Implementation of history buffer distribution
    457 //
    458 void DataHandler::rpcHandler() {
    459 
    460   // Search for history buffer
    461   for (int i=0; i<List.size(); i++) {
    462     if (strcmp(List[i].DataItem->getName(), getString()) == 0) {
    463           setData((void *) List[i].Buffer, List[i].HistSize);
    464           return;
    465         }
    466   }
    467 
    468   // Try to open history file if not found in memory
    469   FILE *File = OpenHistFile(getString(), "rb");
    470   if (File == NULL) {
    471     setData(NULL, 0);
    472         return;
    473   }
    474 
    475   // Read history file
    476   off_t Size = FileSize(File);
    477   if (Size != -1) {
    478         char *Buffer = new char [Size-sizeof(int)];
    479         fseek(File, sizeof(int), SEEK_SET);
    480         fread(Buffer, sizeof(char), Size-sizeof(int), File);
    481         if (ferror(File) != 0) {
    482           Message(WARN, "Error reading history file '%s' in rpcHandler()", getString());
    483           setData(NULL, 0);             // Default response
    484         }
    485         else setData((void *) Buffer, Size);
    486         delete[] Buffer;
    487   }
    488  
    489   if (fclose(File) != 0) Message(WARN, "Error closing history file '%s' in rpcHandler()", getString());
    490 }
    491 
    492 
    493 //
    494338// Add service to watch list
    495339//
    496340void DataHandler::AddService(string Name) {
     341
     342  struct Item New;
    497343
    498344  // Check if already subscribed to this service
     
    500346        if (Name == List[i].DataItem->getName()) return;
    501347  }
    502 
    503   // Set minimum required change by comparing to regular expressions
    504   struct Item New;
    505   New.MinAbsChange = 0;
    506   New.HistSize = 0;
    507   for (int i=0; i<RegExCount; i++) {
    508     if (regexec(&RegEx[i], Name.c_str(), (size_t) 0, NULL, 0) == 0) {
    509           New.MinAbsChange = MinChange[i];
    510           if (HistSize[i] != 0) New.HistSize = HistSize[i];
    511         }
    512   }
    513 
    514   // At least 3*sizeof(int)
    515   if (New.HistSize < MIN_HIST_SIZE) New.HistSize = MIN_HIST_SIZE;
    516 
    517   // Create history service
    518   New.Buffer = new char [New.HistSize];
    519   memset(New.Buffer, 0, New.HistSize);
    520   *(int *) New.Buffer = 4;
    521   New.Next = 4;
    522   New.LastValue = DBL_MAX;
    523 
    524   // Load history buffer from file if existing
    525   FILE *File = OpenHistFile(Name, "rb");
    526   if (File != NULL) {
    527     // Only load if current buffer size is equal or larger
    528     if (FileSize(File) <= New.HistSize*sizeof(char)+sizeof(New.Next) && FileSize(File) != -1) {
    529       fread(&New.Next, sizeof(New.Next), 1, File);
    530       fread(New.Buffer, sizeof(char), New.HistSize, File);
    531           if (ferror(File) != 0) Message(WARN, "Error reading history file '%s' in AddService()", Name.c_str());
    532       if (fclose(File) != 0) Message(WARN, "Error closing history file '%s' in AddService()", Name.c_str());;
    533         }
     348 
     349  // Should service be ignored?
     350  New.Exclude = false;
     351  for (int i=0; i<RegEx.size(); i++) {
     352    if (regexec(&RegEx[i], Name.c_str(), (size_t) 0, NULL, 0) == 0) New.Exclude = true;
    534353  }
    535354
     
    537356  New.DataItem = new DimStampedInfo(Name.c_str(), NO_LINK, this);
    538357
    539   // Add item to list
    540358  List.push_back(New);
    541359}
     
    550368  vector<struct Item>::iterator E;
    551369  for (E=List.begin(); E<List.end(); ++E) if (Name == (*E).DataItem->getName()) {
    552         // Delete subscription first so handler and not called anymore
    553         delete (*E).DataItem;
    554 
    555         // Save history buffer
    556         FILE *File = OpenHistFile(Name, "wb");
    557         if (File != NULL) {
    558       fwrite(&(*E).Next, sizeof((*E).Next), 1, File);
    559       fwrite((*E).Buffer, sizeof(char), (*E).HistSize, File);
    560           if (ferror(File) != 0) Message(WARN, "Error writing history file '%s' in RemoveService()", Name.c_str());
    561       if (fclose(File) != 0) Message(WARN, "Error closing history file '%s' in RemoveService()", Name.c_str());;
    562         }
    563        
    564         // Delete history service and free memory
    565     delete[] (*E).Buffer;
     370        delete (*E).DataItem;   
    566371        List.erase(E);
    567372  }
     
    579384         return -1;
    580385  }
    581 
    582386  return FileStatus.st_size;
    583387}
    584388
    585 //
    586 // Open file for service history
    587 //
    588 FILE *DataHandler::OpenHistFile(string Service, const char *Mode) {
    589 
    590   string Dir = string(BaseDir) + "/Histories/";
    591 
    592   // Create directory if not yet existing
    593   if(mkdir(Dir.c_str(), S_IRWXU|S_IRWXG)==-1 && errno!=EEXIST) return NULL;
    594 
    595   // Replace all '/' by '_' in string and open file
    596   for (int i=0; i<Service.size(); i++) if (Service[i] == '/') Service[i] = '_';
    597   return fopen((Dir + Service).c_str(), Mode);
    598 }
    599389
    600390//         
     
    604394       
    605395  // Static ensures calling of destructor by exit()
    606   static DataHandler Data;
     396  static DataHandler DataInstance;
    607397 
    608398  // Sleep until signal caught
  • Evidence/Edd/Edd.cc

    r216 r221  
    7373  ShowAsTime = false;
    7474  setFrame(false);
     75  setAttribute(Qt::WA_DeleteOnClose);
    7576 
    7677  // Connect to DIM handler
     
    11451146
    11461147  QGridLayout *Layout = new QGridLayout(this);
     1148  setAttribute(Qt::WA_DeleteOnClose);
    11471149
    11481150  // Status display
     
    11711173
    11721174  QGridLayout *Layout = new QGridLayout(this);
     1175  setAttribute(Qt::WA_DeleteOnClose);
    11731176  EddLineDisplay *Line;
    11741177 
     
    12031206TP_Feedback::TP_Feedback() {
    12041207
     1208  setAttribute(Qt::WA_DeleteOnClose);
    12051209  QGridLayout *Layout = new QGridLayout(this);
    12061210  EddLineDisplay *Line;
     
    12371241void TP_Feedback::FeedbackDetails() {
    12381242
     1243  setAttribute(Qt::WA_DeleteOnClose);
    12391244  EddLineDisplay *Line;
    12401245  QWidget *Widget = new QWidget();
     
    12571262TP_DAQ::TP_DAQ() {
    12581263
     1264  setAttribute(Qt::WA_DeleteOnClose);
    12591265  QGridLayout *Layout = new QGridLayout(this);
    12601266
     
    14031409TP_Evidence::TP_Evidence() {
    14041410
     1411  setAttribute(Qt::WA_DeleteOnClose);
    14051412  QGridLayout *Layout = new QGridLayout(this);
    14061413  EddLineDisplay *Line;
     
    14731480  setCentralWidget(Central);
    14741481  setStatusBar(new QStatusBar(this));
    1475   setGeometry(100, 100, 800, 650);
    14761482  setWindowTitle("Edd - Evidence Data Display");
    14771483
    14781484  // Arrangement in tabs
    14791485  TabWidget = new QTabWidget(Central);
     1486  TabWidget->setTabsClosable(true);
     1487  connect(TabWidget, SIGNAL(tabCloseRequested(int)), SLOT(DetachTab(int)));
    14801488  TabWidget->addTab(new TP_DAQ, "Event scope");
    1481   TabWidget->addTab(new TP_Bias, "&Bias");
    1482   TabWidget->addTab(new TP_Feedback, "&Feedback");
    1483   TabWidget->addTab(new TP_Environment, "&Environment");
     1489  TabWidget->addTab(new TP_Bias, "Bias");
     1490  TabWidget->addTab(new TP_Feedback, "Feedback");
     1491  TabWidget->addTab(new TP_Environment, "Environment");
    14841492  TabWidget->addTab(new TP_Evidence, "Evidence");
    14851493
     
    14941502
    14951503  // Show main window
     1504  resize(TabWidget->sizeHint()*1.1);
    14961505  show();
    14971506
     
    15401549}
    15411550
     1551// Open tab as separate window
     1552void GUI::DetachTab(int Tab) {
     1553
     1554  QWidget *W = NULL;
     1555  QMainWindow *M = new QMainWindow;
     1556
     1557  M->setCentralWidget(new QWidget(M));
     1558  M->setStatusBar(new QStatusBar(M));
     1559
     1560  switch(Tab) {
     1561        case 0: W = new TP_DAQ; break;
     1562        case 1: W = new TP_Bias; break;
     1563        case 2: W = new TP_Feedback; break;
     1564        case 3: W = new TP_Environment; break;
     1565        case 4: W = new TP_Evidence; break;
     1566        default: break;
     1567  }
     1568
     1569  if (W == NULL) {
     1570    delete M->centralWidget();
     1571        delete M;
     1572        return;
     1573  }
     1574
     1575  W->setParent(M);
     1576  M->resize(size());
     1577  M->setWindowTitle("Edd - " + TabWidget->tabText(Tab));
     1578  M->show();
     1579}
     1580
    15421581// Quit application when clicking close button on window
    15431582void GUI::closeEvent(QCloseEvent *) {
  • Evidence/Edd/Edd.h

    r216 r221  
    374374    void MenuAbout();
    375375    void MenuNewHistory();
     376        void DetachTab(int);
    376377};
    377378
  • Evidence/Evidence.cc

    r216 r221  
    174174  // Terminate if not successful
    175175  if (!EvidenceServer::ServiceOK(&Config)) {
    176     Message(FATAL, "Configuration server unreachable, can't get '%s'", Item.c_str());
     176    if (Default == NULL) Message(FATAL, "Configuration server unreachable, can't get '%s'", Item.c_str());
     177        Result = (char *) Default;
    177178  }
    178179
  • Evidence/Makefile

    r152 r221  
    44PROG2=DColl
    55PROG3=Alarm
     6PROG4=Bridge
     7PROG5=History
    68
    79CPPFLAGS += -I$(DIMDIR)/dim/
    810LDLIBS += -lpthread $(DIMDIR)/linux/libdim.a
    911
    10 all: $(PROG1) $(PROG2) $(PROG3)
     12all: $(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5)
    1113         
    1214$(PROG1): $(PROG1).o Evidence.o
     
    1618$(PROG3): $(PROG3).o Evidence.o
    1719
     20$(PROG4): $(PROG4).o Evidence.o
     21
     22$(PROG5): $(PROG5).o Evidence.o
     23
    1824clean:
    1925        @rm -f $(PROG1) $(PROG1).o
    2026        @rm -f $(PROG2) $(PROG2).o
    2127        @rm -f $(PROG3) $(PROG3).o
     28        @rm -f $(PROG4) $(PROG4).o
     29        @rm -f $(PROG5) $(PROG5).o
    2230        @rm -f Evidence.o       
  • Evidence/readme.txt

    r216 r221  
    3131                        yet in memory, reading from history file is tried. Improved error handling of
    3232                        history files.
    33 28/5/2010       Changed name of 'State' service to 'Message' to better reflect its functionality. Added client information to log file entries.                 
     3328/5/2010       Changed name of 'State' service to 'Message' to better reflect its functionality.
     34                        Added client information to log file entries.                   
     3530/5/2010       Created Bridge server that repeats services from one DNS to another.
     36                        Service quality now also written to slow data file.
     3731/5/2010       Configuration file format now follows semi-standard INI format.
     387/6/2010        Separated History service from DColl.
    3439
    3540
    36 Preliminary firewall settings (rule 9 for DIM, rule 10 for X11 over ssh)
     41Preliminary firewall settings on eth-vme02 (rule 5 for DIM, rule 6 for X11 over ssh)
    3742
    3843Chain INPUT (policy ACCEPT)
    3944num  target     prot opt source               destination
    40 1    RH-Firewall-1-INPUT  all  --  anywhere             anywhere
     451    RH-Firewall-1-INPUT  all  --  0.0.0.0/0            0.0.0.0/0
    4146
    4247Chain FORWARD (policy ACCEPT)
    4348num  target     prot opt source               destination
    44 1    RH-Firewall-1-INPUT  all  --  anywhere             anywhere
     491    RH-Firewall-1-INPUT  all  --  0.0.0.0/0            0.0.0.0/0
    4550
    4651Chain OUTPUT (policy ACCEPT)
     
    4954Chain RH-Firewall-1-INPUT (2 references)
    5055num  target     prot opt source               destination
    51 1    ACCEPT     icmp --  anywhere             anywhere            icmp any
    52 2    ACCEPT     ipv6-crypt--  anywhere             anywhere
    53 3    ACCEPT     ipv6-auth--  anywhere             anywhere
    54 4    ACCEPT     udp  --  anywhere             224.0.0.251         udp dpt:5353
    55 5    ACCEPT     udp  --  anywhere             anywhere            udp dpt:ipp
    56 6    ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
    57 7    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
    58 8    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:sieve
    59 9    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpts:5100:x11
    60 10   ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpts:x11:6063
    61 11   REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited
     561    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           icmp type 255
     572    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
     583    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22
     594    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:2000
     605    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpts:5100:6000 state NEW
     616    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpts:6000:6063 state NEW
     627    REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited
Note: See TracChangeset for help on using the changeset viewer.