Changeset 224 for Evidence/Evidence.cc


Ignore:
Timestamp:
06/17/10 09:00:51 (14 years ago)
Author:
ogrimm
Message:
Message severity encoded now using standard DIM structure, other updates
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Evidence/Evidence.cc

    r222 r224  
    55  - The server is started with the given name.
    66  - DIM exit and error handlers are implemented.
    7   - The Message service is published (special format, see below).
    8     It can be updated with the Message() method. The text will also be logged.
     7  - A Message service is published with severity encoding. It can be updated
     8    with the Message() method. The text will also be logged.
    99  - If the severity of a Message() call is FATAL, exit() will be called (with
    1010    this severity, the call to Message() is guranteed not to return).
     
    1616    DIMInfo service into text
    1717  - A terminate-handler is installed for catching unhandled C++ exceptions.
    18  
    19   All memory allocated by the non-static methods will be freed by the
     18
     19  Memory allocated by the non-static methods will be freed by the
    2020  class destructor.
    2121 
    22   Oliver Grimm, March 2009
     22  Oliver Grimm, June 2010
    2323 
    2424\********************************************************************/
     
    3737
    3838  // Initialize
    39   Status = NULL;
    40   StdOutText = NULL;
     39  MessageService = NULL;
     40  MessageData = NULL;
    4141  ExitRequest = false;
    4242  ThisServer = this;
     
    5454  // Subscribe to modify service for keeping track of config file changes
    5555  ModifyInfo = new class ConfigUpdate();
    56  
     56
     57  // Message service and initial message
     58  MessageService = new DimService((ServerName+"/Message").c_str(), (char *) "I:1;C", NULL, 0);
     59
     60  string Rev(EVIDENCE_REVISION);
     61  Message(INFO, "Server started (%s, compiled %s %s)", (Rev.substr(1, Rev.size()-3)).c_str(),__DATE__, __TIME__);
     62
    5763  // Start server
    58   string Rev(EVIDENCE_REVISION);
    59   Rev = Rev.substr(1, Rev.size()-3);
    60   snprintf(InitMsg, sizeof(InitMsg), "Server started (%s, compiled %s %s)", Rev.c_str(),__DATE__, __TIME__);
    61  
    62   Status = new DimService((ServerName+"/Message").c_str(), (char *) "C", InitMsg, strlen(InitMsg)+1);
    63   StdOut = new DimService((ServerName+"/Textout").c_str(), (char *) "");
    64 
    6564  start(Name);
    66   addExitHandler(this);
     65  addExitHandler(this); 
    6766}
    6867
     
    7271  Message(INFO, "Server stopped");
    7372 
    74   for (unsigned int i=0; i<ConfigList.size(); i++) {
    75         delete[] ConfigList[i].Value;
    76   }
     73  for (unsigned int i=0; i<ConfigList.size(); i++) delete[] ConfigList[i].Value;
    7774  delete ModifyInfo;
    78  
    79   delete Status;
    80   delete StdOut;
     75  delete MessageService;
     76  delete MessageData;
    8177}
    8278
     
    9086// DIM error handler
    9187void EvidenceServer::errorHandler(int Severity, int Code, char *Text) {   
    92   Message(ERROR, "%s (DIM error code %d, severity %d)\n", Text, Code, Severity);
    93 }
    94 
    95 // Set status of server
    96 //
    97 // The message format is special: after the string-terminating '\0' the Severity
    98 // is given, terminated by another '\0'  The buffer for the DIM service must have
    99 // the same lifetime as the DIM service. If Severity is FATAL, exit() will be invoked.
     88  Message(ERROR, "%s (DIM error code %d, DIM severity %d)\n", Text, Code, Severity);
     89}
     90
     91// Set server message (if Severity is FATAL, exit() will be invoked)
    10092void EvidenceServer::Message(MessageType Severity, const char *Format, ...) {
    10193
    10294  static const char* StateString[] = {"Info", "Warn", "Error", "Fatal"};
    10395  static char ErrorString[] = "vasprintf() failed in Message()";
    104   static char SBuf[STATUS_SIZE];
    105   char TBuf[STATUS_SIZE];
    106   char *Tmp;
     96  char *Text;
    10797 
    10898  // Assemble message from application
    10999  va_list ArgumentPointer;
    110100  va_start(ArgumentPointer, Format);
    111   if (vasprintf(&Tmp, Format, ArgumentPointer) == -1) Tmp = ErrorString;
     101  if (vasprintf(&Text, Format, ArgumentPointer) == -1) {
     102        Text = ErrorString;
     103        Severity = ERROR;
     104  }
    112105  va_end(ArgumentPointer);
    113106
    114   // Create normal string
    115   snprintf(TBuf, sizeof(TBuf), "%s (%s): %s", Status->getName(), StateString[Severity], Tmp);
    116 
    117   // Create string with severity encoding
    118   snprintf(SBuf, sizeof(SBuf), "%s*", Tmp);
    119   SBuf[strlen(SBuf)-1] = '\0';          // new string terminiation replaces '*'
    120   SBuf[strlen(SBuf)+1] = Severity;      // Severity after new string termination
    121 
    122   if (Tmp != ErrorString) free(Tmp);
     107  // Generate new Message structure and free text
     108  struct Message *NewMsg = (struct Message *) new char [sizeof(struct Message)+strlen(Text)+1];
     109  NewMsg->Severity = Severity;
     110  strcpy(NewMsg->Text, Text);
     111  if (Text != ErrorString) free(Text);
    123112 
    124113  // Send message to console and log file
    125   printf("%s\n", TBuf);
    126   DimClient::sendCommandNB("DColl/Log", TBuf);
    127 
    128   // Update DIM status service (including severity encoding)
    129   if (Status != NULL) Status->updateService(SBuf, strlen(SBuf)+2);
    130 
    131   // Terminate if message type is fatal
     114  printf("%s (%s): %s\n", MessageService->getName(), StateString[Severity], NewMsg->Text);
     115  SendToLog("%s (%s): %s", MessageService->getName(), StateString[Severity], NewMsg->Text);
     116
     117  // Update DIM message service, then delete old message
     118  if (MessageService != NULL) {
     119        MessageService->updateService(NewMsg, sizeof(struct Message)+strlen(NewMsg->Text)+1);
     120  }
     121  delete MessageData;
     122  MessageData = NewMsg;
     123
     124  // Terminate if severity if FATAL 
    132125  if (Severity == FATAL) exit(EXIT_FAILURE);
    133126}
    134127
    135 // Set text of StdOut service
    136 void EvidenceServer::SetStdOut(char *Text) {
    137 
    138   // Copy text to permanent buffer
    139   char *Tmp = new char[strlen(Text)+1];
    140   strcpy(Tmp, Text);
    141   StdOut->updateService(Tmp);
    142 
    143   // Delete old buffer and save new buffer pointer
    144   delete[] StdOutText;
    145   StdOutText = Tmp;   
    146 }
     128
     129// Set to central logging server with non-blocking command (may be used in DIM handler)
     130void EvidenceServer::SendToLog(const char *Format, ...) {
     131
     132  char *Buffer;
     133  int Ret;
     134
     135  // Evaluate variable argument list
     136  va_list ArgumentPointer;
     137  va_start(ArgumentPointer, Format);
     138  Ret = vasprintf(&Buffer, Format, ArgumentPointer);
     139  va_end(ArgumentPointer);
     140
     141  // Send to logger
     142  if (Ret != -1) {
     143        DimClient::sendCommandNB("DColl/Log", Buffer);
     144        free (Buffer);
     145  }
     146  else Message(ERROR, "Could not create logging text in SendToLog(), vasprintf() failed");
     147}
     148
    147149
    148150// Get configuration data
     
    191193
    192194  // Create new entry in item list, allocate memory and copy data to this memory
     195  ConfigList[ItemNo].Name = Item;
    193196  ConfigList[ItemNo].Value = new char [strlen(Result)+1];
    194   ConfigList[ItemNo].Name = Item;
    195197  strcpy(ConfigList[ItemNo].Value, Result);
    196198  ConfigList[ItemNo].Time = ModifyInfo->LastModifyTime;
     
    208210  static bool Called = false;
    209211
     212  // At first invocation just request exit
    210213  if (!Called) {
    211214        Called = true;
     
    226229
    227230  if (Terminating) {
    228         snprintf(Msg, sizeof(Msg), "%s: Terminate() called recursively, calling abort()", ThisServer->Status->getName());
     231        snprintf(Msg, sizeof(Msg), "%s: Terminate() called recursively, calling abort()", ThisServer->MessageService->getName());
    229232        printf("%s\n", Msg);
    230233        DimClient::sendCommandNB("DColl/Log", Msg);
     
    259262
    260263// Translates DIMInfo to string (memory has to be freed by caller)
    261 // Static method: it cannot report memory allocation errors via Message()
     264// Static method, cannot report memory allocation errors via Message() but returns NULL
    262265char *EvidenceServer::ToString(DimInfo *Item) {
    263266
     
    266269  // Safety check
    267270  if (Item->getSize() < 1) return NULL;
     271
     272  // Message structure format handled
     273  if (strcmp(Item->getFormat(), "I:1;C") == 0) {
     274        struct Message *Msg = (struct Message *) Item->getData();
     275        if (asprintf(&Text, "%d %s", Msg->Severity, Msg->Text) == -1) return NULL;
     276        else return Text;
     277  }
    268278 
    269279  // Structure: print hex representation (3 characters per byte) 
Note: See TracChangeset for help on using the changeset viewer.