Index: Evidence/Alarm.cc
===================================================================
--- Evidence/Alarm.cc	(revision 144)
+++ Evidence/Alarm.cc	(revision 144)
@@ -0,0 +1,171 @@
+/********************************************************************\
+
+  Alarm handler of the Evidence Control System
+
+  - Checks periodically if all required servers are up
+    (later it should try to start them if not)
+  - Listens to the 'Status' service of each server.
+  - A text describing the state of all servers is published as DIM service.
+    The states are described in StateString[].
+  - A master alarm (indicating most severe of individual alarms) is published. 
+    
+  Oliver Grimm, January 2010
+
+\********************************************************************/
+
+#define SERVER_NAME "Alarm"
+#include "../Evidence.h"
+
+#define SUMMARYSIZE 10000	// Bytes for alarm summary text
+
+const char* StateString[] = {"OK", "WARN", "ERROR", "FATAL", "UNAVAILABLE"};
+
+//
+// Data handling class
+//
+class AlarmHandler : public DimClient, public EvidenceServer {
+    
+    DimStampedInfo **StatusService;
+
+    void infoHandler();
+
+  public:
+    AlarmHandler();
+    ~AlarmHandler();
+
+	DimService *Summary, *Master;
+	
+	char *AlarmSummary;
+	int MasterAlarm;
+	int *State;    
+    char **Server;
+    unsigned int NumServers;
+    char *ServerList; 
+	
+	void UpdateAlarmSummary();
+}; 
+
+// Constructor
+AlarmHandler::AlarmHandler(): EvidenceServer(SERVER_NAME) {
+
+  AlarmSummary = new char [SUMMARYSIZE];
+  MasterAlarm = 0;
+  
+  char *ServerNames = GetConfig(SERVER_NAME " servers");
+
+  // Create DIM services
+  Summary = new DimService(SERVER_NAME"/Summary", AlarmSummary);
+  Master = new DimService(SERVER_NAME"/MasterAlarm", MasterAlarm);
+
+  // Copy original list of servers to observe
+  ServerList = new char [strlen(ServerNames)+1];
+  strcpy(ServerList, ServerNames);
+  
+  // Extract DIM servers to observe
+  Server = new char* [strlen(ServerNames)];
+  NumServers = 0;
+  char *NextToken = strtok(ServerNames, " \t");
+  while (NextToken != NULL) {
+    Server[NumServers++] = NextToken; // Subscribe with handler
+    NextToken = strtok(NULL, " \t");     
+  }
+
+  // Subscribe with handler to 'Status' service of all servers
+  StatusService = new DimStampedInfo* [NumServers];
+  State = new int [NumServers];
+  
+  for (int i=0; i<NumServers; i++) {
+    char *Buffer = new char [strlen(Server[i])+10];
+    strcpy(Buffer, Server[i]);
+    strcat(Buffer, "/Status");
+    StatusService[i] = new DimStampedInfo(Buffer, NO_LINK, this);
+    delete[] Buffer;
+	
+	State[i] = 0;
+  }
+}
+
+// Destructor
+AlarmHandler::~AlarmHandler() {
+
+  for (int i=0; i<NumServers; i++) delete StatusService[i];
+  delete[] StatusService;
+  delete Master;
+  delete Summary;
+  delete[] State;
+  delete[] Server;
+  delete[] ServerList;
+  delete[] AlarmSummary;
+}
+
+// Print messages of status changes to screen and update status string
+void AlarmHandler::infoHandler() {
+
+  // Identify status service
+  for (int i=0; i<NumServers; i++) if (getInfo() == StatusService[i]) {
+
+	// Ignore DIS_DNS (has no status service)
+	if (strcmp(getInfo()->getName(),"DIS_DNS/Status") == 0) return;
+	
+	// Update State: unavailable or current severity of status  
+	if (getInfo()->getSize()==strlen(NO_LINK)+1 &&
+		strcmp(getInfo()->getString(), NO_LINK)==0) State[i] = 4;
+	else {
+	  State[i] = *(getInfo()->getString()+getInfo()->getSize());
+
+	  // Print message
+	  time_t RawTime = getInfo()->getTimestamp();
+	  struct tm *TM = localtime(&RawTime);
+	  printf("%s (%02d:%02d:%02d): %s\n", getInfo()->getName(), TM->tm_hour,
+		TM->tm_min, TM->tm_sec, getInfo()->getString());	  
+	}
+	UpdateAlarmSummary();
+  }  
+}
+
+
+// Update alarm status summary
+void AlarmHandler::UpdateAlarmSummary() {
+  
+  int Offset = 0;
+  MasterAlarm = 0;
+   
+  for (int i=0; i<NumServers; i++) {
+    snprintf(AlarmSummary+Offset, SUMMARYSIZE-Offset, "%s: %s (%d)\n", Server[i], State[i]<=4 ? StateString[State[i]] : "unknown", State[i]);
+	Offset += strlen(AlarmSummary+Offset);
+	if (State[i] > MasterAlarm) MasterAlarm = State[i];
+  }
+  Summary->updateService();
+  Master->updateService();
+}
+
+//	    
+// Main program
+//
+int main() {
+    
+  DimBrowser Browser;
+  char *ServerName, *Node;
+  bool Exists;
+  
+  // Static declaration ensures calling of destructor by exit()
+  static AlarmHandler Alarm; 
+  
+  // Request configuration data
+  unsigned int Period = atoi(Alarm.GetConfig(SERVER_NAME " period"));
+
+  // Check periodically if servers are up
+  while(!EvidenceServer::ExitRequest) {
+    for (int i=0; i<Alarm.NumServers; i++) {
+      Exists = false;
+      Browser.getServers();
+      while (Browser.getNextServer(ServerName, Node) == 1) {
+        if (strcmp(ServerName, Alarm.Server[i]) == 0) Exists = true;
+      }
+      if (!Exists) Alarm.State[i] = 4;
+    }
+    
+    Alarm.UpdateAlarmSummary();
+    sleep(Period);
+  }
+}
Index: Evidence/Alarm/Alarm.cc
===================================================================
--- Evidence/Alarm/Alarm.cc	(revision 142)
+++ 	(revision )
@@ -1,171 +1,0 @@
-/********************************************************************\
-
-  Alarm handler of the Evidence Control System
-
-  - Checks periodically if all required servers are up
-    (later it should try to start them if not)
-  - Listens to the 'Status' service of each server.
-  - A text describing the state of all servers is published as DIM service.
-    The states are described in StateString[].
-  - A master alarm (indicating most severe of individual alarms) is published. 
-    
-  Oliver Grimm, January 2010
-
-\********************************************************************/
-
-#define SERVER_NAME "Alarm"
-#include "../Evidence.h"
-
-#define SUMMARYSIZE 10000	// Bytes for alarm summary text
-
-const char* StateString[] = {"OK", "WARN", "ERROR", "FATAL", "UNAVAILABLE"};
-
-//
-// Data handling class
-//
-class AlarmHandler : public DimClient, public EvidenceServer {
-    
-    DimStampedInfo **StatusService;
-
-    void infoHandler();
-
-  public:
-    AlarmHandler();
-    ~AlarmHandler();
-
-	DimService *Summary, *Master;
-	
-	char *AlarmSummary;
-	int MasterAlarm;
-	int *State;    
-    char **Server;
-    unsigned int NumServers;
-    char *ServerList; 
-	
-	void UpdateAlarmSummary();
-}; 
-
-// Constructor
-AlarmHandler::AlarmHandler(): EvidenceServer(SERVER_NAME) {
-
-  AlarmSummary = new char [SUMMARYSIZE];
-  MasterAlarm = 0;
-  
-  char *ServerNames = GetConfig(SERVER_NAME " servers");
-
-  // Create DIM services
-  Summary = new DimService(SERVER_NAME"/Summary", AlarmSummary);
-  Master = new DimService(SERVER_NAME"/MasterAlarm", MasterAlarm);
-
-  // Copy original list of servers to observe
-  ServerList = new char [strlen(ServerNames)+1];
-  strcpy(ServerList, ServerNames);
-  
-  // Extract DIM servers to observe
-  Server = new char* [strlen(ServerNames)];
-  NumServers = 0;
-  char *NextToken = strtok(ServerNames, " \t");
-  while (NextToken != NULL) {
-    Server[NumServers++] = NextToken; // Subscribe with handler
-    NextToken = strtok(NULL, " \t");     
-  }
-
-  // Subscribe with handler to 'Status' service of all servers
-  StatusService = new DimStampedInfo* [NumServers];
-  State = new int [NumServers];
-  
-  for (int i=0; i<NumServers; i++) {
-    char *Buffer = new char [strlen(Server[i])+10];
-    strcpy(Buffer, Server[i]);
-    strcat(Buffer, "/Status");
-    StatusService[i] = new DimStampedInfo(Buffer, NO_LINK, this);
-    delete[] Buffer;
-	
-	State[i] = 0;
-  }
-}
-
-// Destructor
-AlarmHandler::~AlarmHandler() {
-
-  for (int i=0; i<NumServers; i++) delete StatusService[i];
-  delete[] StatusService;
-  delete Master;
-  delete Summary;
-  delete[] State;
-  delete[] Server;
-  delete[] ServerList;
-  delete[] AlarmSummary;
-}
-
-// Print messages of status changes to screen and update status string
-void AlarmHandler::infoHandler() {
-
-  // Identify status service
-  for (int i=0; i<NumServers; i++) if (getInfo() == StatusService[i]) {
-
-	// Ignore DIS_DNS (has no status service)
-	if (strcmp(getInfo()->getName(),"DIS_DNS/Status") == 0) return;
-	
-	// Update State if server is unavailable or with current severity of status  
-	if (getInfo()->getSize()==strlen(NO_LINK)+1 &&
-		strcmp(getInfo()->getString(), NO_LINK)==0) State[i] = 4;
-	else {
-	  State[i] = *(getInfo()->getString()+strlen(getInfo()->getString())+2);
-
-	  // Print message
-	  time_t RawTime = getInfo()->getTimestamp();
-	  struct tm *TM = localtime(&RawTime);
-	  printf("%s (%02d:%02d:%02d): %s\n", getInfo()->getName(), TM->tm_hour,
-		TM->tm_min, TM->tm_sec, getInfo()->getString());	  
-	}
-	UpdateAlarmSummary();
-  }  
-}
-
-
-// Update alarm status summary
-void AlarmHandler::UpdateAlarmSummary() {
-  
-  int Offset = 0;
-  MasterAlarm = 0;
-   
-  for (int i=0; i<NumServers; i++) {
-    snprintf(AlarmSummary+Offset, SUMMARYSIZE-Offset, "%s: %s\n", Server[i], StateString[State[i]]);
-	Offset += strlen(AlarmSummary+Offset);
-	if (State[i] > MasterAlarm) MasterAlarm = State[i];
-  }
-  Summary->updateService();
-  Master->updateService();
-}
-
-//	    
-// Main program
-//
-int main() {
-    
-  DimBrowser Browser;
-  char *ServerName, *Node;
-  bool Exists;
-  
-  // Static declaration ensures calling of destructor by exit()
-  static AlarmHandler Alarm; 
-  
-  // Request configuration data
-  unsigned int Period = atoi(Alarm.GetConfig(SERVER_NAME " period"));
-
-  // Check periodically if servers are up
-  while(!EvidenceServer::ExitRequest) {
-    for (int i=0; i<Alarm.NumServers; i++) {
-      Exists = false;
-      Browser.getServers();
-      while (Browser.getNextServer(ServerName, Node) == 1) {
-        if (strcmp(ServerName, Alarm.Server[i]) == 0) Exists = true;
-      }
-      if (!Exists) Alarm.State[i] = 4;
-    }
-    
-    Alarm.UpdateAlarmSummary();
-    sleep(Period);
-  }
-}
Index: Evidence/Alarm/Makefile
===================================================================
--- Evidence/Alarm/Makefile	(revision 142)
+++ 	(revision )
@@ -1,10 +1,0 @@
-CC=g++
-
-PROG=Alarm
-CPPFLAGS += -I../DIM	
-LDLIBS += -lpthread
-
-$(PROG): $(PROG).o ../Evidence.o ../DIM/libdim.a
-
-clean:
-	@rm -f $(PROG) $(PROG).o *.d *~
Index: Evidence/Config.cc
===================================================================
--- Evidence/Config.cc	(revision 144)
+++ Evidence/Config.cc	(revision 144)
@@ -0,0 +1,170 @@
+/********************************************************************\
+
+  Configuration server for the Evidence Control System
+
+  - The configuration file is opened without buffering to catch changes
+    without closing/opening.
+  - The name of a configuration file can be given as command line argument
+  - If a configuration file change is detected through inotify, the service
+    "Config/ModifyTime" is updated with the current UNIX time to inform applications.
+	The initial value of the server is the last file modification time. 
+  - The employed line buffer has conservatively at least the size of the
+    configuration file. If needed, it will be enlarged.
+         
+  Oliver Grimm, November 2009
+
+\********************************************************************/
+
+#define DEFAULT_CONFIG "../../config/Evidence.conf"
+#define SERVER_NAME "Config"
+
+#include "../Evidence.h"
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/inotify.h>
+
+//
+// Class derived from DimRpc
+//
+class EvidenceConfig: public DimRpc, public EvidenceServer {
+
+  private:
+    FILE *File;	
+    char *Buffer;
+    unsigned int BufferLength;
+    DimService *ConfigModified;
+    int ModifyTime;
+	
+    void rpcHandler();
+  
+  public:
+    EvidenceConfig(const char *);
+    ~EvidenceConfig();
+	
+	void ConfigChanged(); 
+};
+
+// Constructor
+EvidenceConfig::EvidenceConfig(const char *Filename):
+	DimRpc("ConfigRequest", "C", "C"), EvidenceServer(SERVER_NAME) {
+
+  // Open configuration file
+  if ((File = fopen(Filename, "r")) == NULL) {
+    State(FATAL, "Could not open configuration file '%s' (%s)\n", Filename, strerror(errno));
+  }
+
+  // Create DIM service to indicate changes of configuration file
+  struct stat Stat;
+  if (stat(Filename, &Stat) == -1) {
+    State(WARN, "Could not read last modification time of configuration file '%s' (%s)", Filename, strerror(errno));
+	ModifyTime = 0;
+  }
+  else ModifyTime = Stat.st_mtime;   
+  ConfigModified = new DimService (SERVER_NAME"/ModifyTime", ModifyTime);
+
+  // Disable buffering, so file modifications are immediately seen
+  if (setvbuf(File, NULL, _IONBF, 0) != 0) {
+    State(WARN, "Error setting configuration file '%s' to unbuffered mode", Filename);
+  }
+    
+  Buffer = NULL;    // Will be allocated in rpcHandler()
+  BufferLength = 0;
+}
+
+// Destructor
+EvidenceConfig::~EvidenceConfig() {
+
+  if (File != NULL) fclose(File);  
+  delete[] Buffer;
+}
+
+// Implementation of response to configuration request
+void EvidenceConfig::rpcHandler() {
+
+  char *Token1,*Token2,*Token3, *Request = getString();
+  struct stat FileStatus;
+  
+  // Check if Buffer[] is large enough to hold full file, enlarge if necessary
+  if (fstat(fileno(File), &FileStatus) == -1) {
+     State(FATAL, "Could not determine size of configuration file to allocate buffer (%s)", strerror(errno));
+  }
+  else if(BufferLength < FileStatus.st_size) {
+    delete[] Buffer;
+    Buffer = new char [FileStatus.st_size];
+    BufferLength = FileStatus.st_size;   
+  }
+  
+  // Search for configuration item
+  rewind(File);
+  while (fgets(Buffer, BufferLength, File) != NULL) {
+    
+    // Combine lines that end with '+'
+    while (Buffer[strlen(Buffer)-2] == '+') {
+      if (fgets(Buffer+strlen(Buffer)-2, BufferLength-(strlen(Buffer)-2), File) == NULL) break;
+    }
+    
+    // Ignore comments
+    for (int i=0; i<strlen(Buffer); i++) if (Buffer[i] == '#') Buffer[i] = '\0';
+    
+    // Extract tokens
+    Token1 = strtok(Buffer, " \t:");
+    Token2 = strtok(NULL, " \t:");
+    Token3 = strtok(NULL, "\n");
+    
+    // Check if all tokens existing
+    if(Token1==NULL || Token2==NULL || Token3==NULL) continue;
+
+    // Check for match and then send data (removing trainlin whitespace)
+    if (strstr(Request, Token1)!=NULL && strstr(Request, Token2)!=NULL) {
+	  while (isspace(*Token3) != 0) Token3++;
+      setData(Token3);
+      break;
+    }
+  }
+  
+  // If configuration data not found, send empty string
+  if (feof(File)!=0) setData((char *) "");
+  
+  State(INFO, "Client '%s' (ID %d) requested '%s'. Send '%s'.",
+		DimServer::getClientName(),
+		DimServer::getClientId(), 
+		Request, feof(File)!=0 ? "n/a" : Token3);
+}
+
+// Signalisation of configuration change
+void EvidenceConfig::ConfigChanged() {
+
+  ModifyTime = time(NULL);
+  ConfigModified->updateService();
+}
+
+//	    
+// Declaring class static ensures destructor is called when exit() is invoked 
+//
+int main(int argc, char *argv[]) {
+        
+  static EvidenceConfig Config(argc<2 ? DEFAULT_CONFIG : argv[1]);
+
+  int Notify;
+  struct inotify_event Event;
+  
+  if ((Notify = inotify_init()) == -1) {
+    Config.State(EvidenceConfig::WARN, "inotify_init() failed, cannot monitor changes of configuration file (%s)\n", strerror(errno));
+  }
+  else if (inotify_add_watch(Notify, argc<2 ? DEFAULT_CONFIG : argv[1], IN_MODIFY) == -1) { 
+      Config.State(EvidenceConfig::WARN, "Could not set inotify watch on configuration file (%s)\n", strerror(errno));
+	  close(Notify);
+	  Notify = -1;
+  }
+
+  // Sleep until file changes or signal caught 
+  while (!EvidenceServer::ExitRequest) {
+    if (Notify != -1) {
+	  read(Notify, &Event, sizeof(Event));
+	  Config.ConfigChanged();
+	}
+    else pause();	  
+  }
+  
+  if (Notify != -1) close(Notify);
+}
Index: Evidence/Config/Config.cc
===================================================================
--- Evidence/Config/Config.cc	(revision 142)
+++ 	(revision )
@@ -1,170 +1,0 @@
-/********************************************************************\
-
-  Configuration server for the Evidence Control System
-
-  - The configuration file is opened without buffering to catch changes
-    without closing/opening.
-  - The name of a configuration file can be given as command line argument
-  - If a configuration file change is detected through inotify, the service
-    "Config/ModifyTime" is updated with the current UNIX time to inform applications.
-	The initial value of the server is the last file modification time. 
-  - The employed line buffer has conservatively at least the size of the
-    configuration file. If needed, it will be enlarged.
-         
-  Oliver Grimm, November 2009
-
-\********************************************************************/
-
-#define DEFAULT_CONFIG "configuration.txt"
-#define SERVER_NAME "Config"
-
-#include "../Evidence.h"
-#include <ctype.h>
-#include <sys/stat.h>
-#include <sys/inotify.h>
-
-//
-// Class derived from DimRpc
-//
-class EvidenceConfig: public DimRpc, public EvidenceServer {
-
-  private:
-    FILE *File;	
-    char *Buffer;
-    unsigned int BufferLength;
-    DimService *ConfigModified;
-    int ModifyTime;
-	
-    void rpcHandler();
-  
-  public:
-    EvidenceConfig(const char *);
-    ~EvidenceConfig();
-	
-	void ConfigChanged(); 
-};
-
-// Constructor
-EvidenceConfig::EvidenceConfig(const char *Filename):
-	DimRpc("ConfigRequest", "C", "C"), EvidenceServer(SERVER_NAME) {
-
-  // Open configuration file
-  if ((File = fopen(Filename, "r")) == NULL) {
-    State(FATAL, "Could not open configuration file '%s' (%s)\n", Filename, strerror(errno));
-  }
-
-  // Create DIM service to indicate changes of configuration file
-  struct stat Stat;
-  if (stat(Filename, &Stat) == -1) {
-    State(WARN, "Could not read last modification time of configuration file '%s' (%s)", Filename, strerror(errno));
-	ModifyTime = 0;
-  }
-  else ModifyTime = Stat.st_mtime;   
-  ConfigModified = new DimService (SERVER_NAME"/ModifyTime", ModifyTime);
-
-  // Disable buffering, so file modifications are immediately seen
-  if (setvbuf(File, NULL, _IONBF, 0) != 0) {
-    State(WARN, "Error setting configuration file '%s' to unbuffered mode", Filename);
-  }
-    
-  Buffer = NULL;    // Will be allocated in rpcHandler()
-  BufferLength = 0;
-}
-
-// Destructor
-EvidenceConfig::~EvidenceConfig() {
-
-  if (File != NULL) fclose(File);  
-  delete[] Buffer;
-}
-
-// Implementation of response to configuration request
-void EvidenceConfig::rpcHandler() {
-
-  char *Token1,*Token2,*Token3, *Request = getString();
-  struct stat FileStatus;
-  
-  // Check if Buffer[] is large enough to hold full file, enlarge if necessary
-  if (fstat(fileno(File), &FileStatus) == -1) {
-     State(FATAL, "Could not determine size of configuration file to allocate buffer (%s)", strerror(errno));
-  }
-  else if(BufferLength < FileStatus.st_size) {
-    delete[] Buffer;
-    Buffer = new char [FileStatus.st_size];
-    BufferLength = FileStatus.st_size;   
-  }
-  
-  // Search for configuration item
-  rewind(File);
-  while (fgets(Buffer, BufferLength, File) != NULL) {
-    
-    // Combine lines that end with '+'
-    while (Buffer[strlen(Buffer)-2] == '+') {
-      if (fgets(Buffer+strlen(Buffer)-2, BufferLength-(strlen(Buffer)-2), File) == NULL) break;
-    }
-    
-    // Ignore comments
-    for (int i=0; i<strlen(Buffer); i++) if (Buffer[i] == '#') Buffer[i] = '\0';
-    
-    // Extract tokens
-    Token1 = strtok(Buffer, " \t:");
-    Token2 = strtok(NULL, " \t:");
-    Token3 = strtok(NULL, "\n");
-    
-    // Check if all tokens existing
-    if(Token1==NULL || Token2==NULL || Token3==NULL) continue;
-
-    // Check for match and then send data (removing trainlin whitespace)
-    if (strstr(Request, Token1)!=NULL && strstr(Request, Token2)!=NULL) {
-	  while (isspace(*Token3) != 0) Token3++;
-      setData(Token3);
-      break;
-    }
-  }
-  
-  // If configuration data not found, send empty string
-  if (feof(File)!=0) setData((char *) "");
-  
-  State(INFO, "Client '%s' (ID %d) requested '%s'. Send '%s'.",
-		DimServer::getClientName(),
-		DimServer::getClientId(), 
-		Request, feof(File)!=0 ? "n/a" : Token3);
-}
-
-// Signalisation of configuration change
-void EvidenceConfig::ConfigChanged() {
-
-  ModifyTime = time(NULL);
-  ConfigModified->updateService();
-}
-
-//	    
-// Declaring class static ensures destructor is called when exit() is invoked 
-//
-int main(int argc, char *argv[]) {
-        
-  static EvidenceConfig Config(argc<2 ? DEFAULT_CONFIG : argv[1]);
-
-  int Notify;
-  struct inotify_event Event;
-  
-  if ((Notify = inotify_init()) == -1) {
-    Config.State(EvidenceConfig::WARN, "inotify_init() failed, cannot monitor changes of configuration file (%s)\n", strerror(errno));
-  }
-  else if (inotify_add_watch(Notify, argc<2 ? DEFAULT_CONFIG : argv[1], IN_MODIFY) == -1) { 
-      Config.State(EvidenceConfig::WARN, "Could not set inotify watch on configuration file (%s)\n", strerror(errno));
-	  close(Notify);
-	  Notify = -1;
-  }
-
-  // Sleep until file changes or signal caught 
-  while (!EvidenceServer::ExitRequest) {
-    if (Notify != -1) {
-	  read(Notify, &Event, sizeof(Event));
-	  Config.ConfigChanged();
-	}
-    else pause();	  
-  }
-  
-  if (Notify != -1) close(Notify);
-}
Index: Evidence/Config/Makefile
===================================================================
--- Evidence/Config/Makefile	(revision 142)
+++ 	(revision )
@@ -1,11 +1,0 @@
-CC=g++
-
-PROG=Config
-CPPFLAGS += -I../DIM/
-LDLIBS += -lpthread
-
-$(PROG): $(PROG).o ../Evidence.o ../DIM/libdim.a
-
-clean:
-	@rm -f $(PROG) $(PROG).o
-	
Index: Evidence/Config/configuration.txt
===================================================================
--- Evidence/Config/configuration.txt	(revision 142)
+++ 	(revision )
@@ -1,29 +1,0 @@
-# Configuration data for the Evidence Control System
-#
-# The first entry of each line gives the requester for the parameter in
-# the second entry. The remaining text of the line is send in reponse
-# to the configuration request.
-# A plus sign before the line break signals continuation of the line.
-
-
-# Sky Quality Monitor
-
-SQM address	sqm.ethz.ch
-SQM port	10001
-SQM period	10
-
-
-# Central Data Collector
-
-DColl items	SQM/NSB Alarm/Servers Alarm/State +
-		Config/Status DColl/Status Alarm/Status SMQ/Status +
-		BIAS/VOLT/ID00/*-*
-DColl datadir	../../../no_back/EvidenceData
-DColl logfile	../../../no_back/EvidenceData/Evidence.log
-DColl histsize	1000 # Number of items in history buffer
-
-
-# Alarm Handler
-
-Alarm servers	DIS_DNS DColl SQM Config
-Alarm period	10 # Check interval in seconds
Index: Evidence/DColl.cc
===================================================================
--- Evidence/DColl.cc	(revision 144)
+++ Evidence/DColl.cc	(revision 144)
@@ -0,0 +1,430 @@
+/********************************************************************\
+
+  Central data collector of the Evidence Control System
+  
+  - DColl subscribes to all services given by the configuration
+    server and writes these to the data file at every update.
+  - One data file per day is generated, with roll-over at 13:00 local time.
+  - For each service, it creates a new service with '.hist' appended
+	that contains a history of events kept within a ring buffer. Each
+	entry will be the result of a conversion to double of the text 
+	written to the data file. Only if the new value has changed by a
+	minimum amout it will be added to the ring buffer.
+  - The command 'DColl/Log' writes the associated string to the log 
+    file specified in the configuration.
+  
+  Oliver Grimm, December 2009
+
+\********************************************************************/
+
+#define SERVER_NAME "DColl"
+
+#define DATE_ROLLOVER 12 // localtime hour after which next date is used
+
+#include "../Evidence.h"
+#include <math.h>
+#include <float.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <regex.h>
+
+//
+// Class declaration
+//
+class DataHandler:	public DimClient, public DimBrowser,
+					public EvidenceServer {
+
+	struct Item {
+	  DimStampedInfo *DataItem;
+      DimService *HistService;
+	  struct EvidenceHistoryItem *HistBuffer;
+	  int HistPointer;
+	  double LastValue;
+	  double MinAbsChange;
+	} *List;
+
+	DimCommand *LogCommand;
+		
+    unsigned int NumItems;
+    FILE *DataFile;
+    FILE *LogFile;
+	float DataSizekB, LogSizekB;
+	int DataSizeLastUpdate, LogSizeLastUpdate;
+	char *DataDir;
+    DimService *LogSizeService, *DataSizeService;
+    int HistSize;
+	int SizeUpdateDelay;
+	int TimeForNextFile;
+	
+	int RegExCount;
+	regex_t *RegEx;
+	double *MinChange;
+	
+    void infoHandler();
+    void commandHandler();
+	void AddService(char *);
+	float FileSize(FILE *);
+	    
+  public:
+    DataHandler();
+    ~DataHandler();
+}; 
+
+//
+// Constructor
+//
+DataHandler::DataHandler(): EvidenceServer(SERVER_NAME) {
+
+  // Initialization to prevent freeing unallocated memory 
+  DataFile = NULL;
+  LogFile = NULL;
+  List = NULL;
+  LogSizeService = NULL;
+  DataSizeService = NULL;
+  
+  DataSizeLastUpdate = 0;
+  LogSizeLastUpdate = 0;
+  TimeForNextFile = 0;
+
+  // Request configuration data
+  char *Change = GetConfig(SERVER_NAME " minchange");
+  DataDir = GetConfig(SERVER_NAME " datadir");
+  char *Logname = GetConfig(SERVER_NAME " logfile");
+  SizeUpdateDelay = atoi(GetConfig(SERVER_NAME " sizeupdate"));
+  HistSize = atoi(GetConfig(SERVER_NAME " histsize"));
+  if (HistSize < 1) HistSize = 1; // Minimum one items
+   
+  // Open log file
+  if ((LogFile = fopen(Logname, "a")) == NULL) {
+    State(FATAL, "Could not open log file '%s' (%s)", Logname, strerror(errno));
+  }
+
+  // Provide logging command   
+  LogCommand = new DimCommand("DColl/Log", (char *) "C", this);
+              
+  // Create services for file sizes
+  DataSizekB = 0;
+  DataSizeService = new DimService(SERVER_NAME "/DataSizekB", DataSizekB);
+  
+  LogSizekB = FileSize(LogFile);
+  LogSizeService = new DimService(SERVER_NAME "/LogSizekB", LogSizekB);
+
+  // Count how many minimum change value regular expressions are present
+  RegExCount = 0;
+  char *Token = strtok(Change, "\t ");
+  while (Token != NULL) {
+	RegExCount++;
+	Token = strtok(NULL, "\t ");
+  }
+  
+  // Allocate memory for regular expressions and minimum change values
+  RegEx = new regex_t[RegExCount];
+  MinChange = new double [RegExCount];
+
+  // Compile regular expressions
+  int Pos = 0;
+  for (int i=0; i<RegExCount; i++) {
+    int Len = strlen(Change+Pos) + 1;
+    Token = strtok(Change + Pos, ": \t");
+
+    int Ret = regcomp(&RegEx[i], Token, REG_EXTENDED|REG_NOSUB);
+	if (Ret != 0) {
+	  char ErrMsg[200];
+	  regerror(Ret, &RegEx[i], ErrMsg, sizeof(ErrMsg));
+	  State(WARN, "Error compiling regular expression '%s' (%s)", Token, ErrMsg);
+	}
+	else {
+	  if ((Token=strtok(NULL, "")) != NULL) MinChange[i] = atof(Token);
+	  else MinChange[i] = 0;
+	}
+	Pos += Len;
+  }
+
+  // Subscribe to list of servers at DIS_DNS 
+  AddService((char *) "DIS_DNS/SERVER_LIST");
+
+  DimClient::sendCommand("DColl/Log", SERVER_NAME" *** Logging started ***");
+}
+
+//
+// Destructor: Close files and free memory
+//
+DataHandler::~DataHandler() {
+
+  // Delete DIM services and command first so handlers and not called anymore
+  for (int i=0; i<NumItems; i++) {
+	delete List[i].HistService;
+    delete List[i].DataItem;
+    delete[] List[i].HistBuffer;
+  }
+  free(List);
+
+  //delete LogSizeService; // These create segmentation faults?!
+  //delete DataSizeService;
+
+  delete LogCommand;
+
+  // Close files
+  if (LogFile != NULL) if (fclose(LogFile) != 0) {
+	State(ERROR, "Could not close log file (%s)", strerror(errno));
+  }
+  if (DataFile != NULL && fclose(DataFile) != 0) {
+	State(ERROR, "Error: Could not close data file (%s)", strerror(errno));
+  }
+
+  // Free memory for regular expressions handling
+  for (int i=0; i<RegExCount; i++) {
+    regfree(&RegEx[i]);
+  }
+  delete[] MinChange;
+  delete[] RegEx;
+}
+
+//
+// Implementation of data handling
+//
+// DIM ensures infoHandler() is called serialized, therefore
+// no mutex is needed to serialize writing to the file
+void DataHandler::infoHandler() {
+
+  DimInfo *Info = getInfo();
+
+  // Check if service available
+  if (Info->getSize()==strlen(NO_LINK)+1 && strcmp(Info->getString(), NO_LINK)==0) return;
+
+  // If service is DIS_DNS/SERVER_LIST, subscribe to all SERVICE_LIST services
+  if (strcmp(Info->getName(), "DIS_DNS/SERVER_LIST") == 0) {	
+	char *Token = strtok(Info->getString(), "+-!|@");	
+	while (Token != NULL) {
+	  char *Buf;
+	  if (MakeString(&Buf, "%s/SERVICE_LIST", Token) != -1) {
+	    AddService(Buf);
+		free(Buf);
+	  }
+	  else State(ERROR, "MakeString() failed for server %s", Token);
+	  
+  	  Token = strtok(NULL, "|");
+	  Token = strtok(NULL, "+-!|@");	
+	}	
+	return;
+  }
+
+  // If service is SERVICE_LIST of any server, scan all services.
+  // Subscribe to all services (but not to commands and RPCs)
+  if (strstr(Info->getName(), "/SERVICE_LIST") != NULL) {
+	char *Name = strtok(Info->getString(), "+-!|");
+	while (Name != NULL) {
+	  char *Type = strtok(NULL, "\n");
+	  if (Type == NULL) return; // for safety, should not happen
+      if (strstr(Type, "|CMD")==NULL && strstr(Type, "|RPC")==NULL) {
+		AddService(Name);
+	  }
+	  Name = strtok(NULL, "+-!|");
+	}
+	return;
+  }
+
+  // If it is time to open new data file, close the current one 
+  if (time(NULL) >= TimeForNextFile) {
+	if (DataFile != NULL && fclose(DataFile) != 0) {
+	  State(ERROR, "Error: Could not close data file (%s)", strerror(errno));
+	}
+	DataFile = NULL;
+  }
+  
+  // Open new data file if necessary
+  if (DataFile == NULL) {
+	time_t Time = time(NULL);
+	struct tm *T = localtime(&Time);
+	
+	if(T->tm_hour >= DATE_ROLLOVER) T->tm_mday++;
+	if (mktime(T) == -1) State(ERROR, "mktime() failed, check filename");
+
+	char *Filename;
+	if (MakeString(&Filename, "%s/%d%02d%02d.slow", DataDir, T->tm_year+1900, T->tm_mon+1, T->tm_mday) == -1) State(FATAL, "Could not create filename, MakeString() failed");
+	if ((DataFile = fopen(Filename, "a")) == NULL) {
+      State(FATAL, "Could not open data file '%s' (%s)", Filename, strerror(errno));
+	}
+	else State(INFO, "Opened data file '%s'", Filename);
+	free(Filename);
+	
+	// Calculate time for next file opening
+	T->tm_sec = 0;
+	T->tm_min = 0;
+	T->tm_hour = DATE_ROLLOVER;
+	TimeForNextFile = mktime(T);
+  }
+   
+  // Identify index of service
+  int Service;  
+  for (Service=0; Service<NumItems; Service++) if (Info == List[Service].DataItem) break;
+  if (Service == NumItems) return;  // Service not found
+
+  // If negative value for absolute change, ignore this entry
+  if (List[Service].MinAbsChange < 0) return;
+
+  // Write data header
+  time_t RawTime = Info->getTimestamp();
+  struct tm *TM = localtime(&RawTime);
+
+  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());
+
+  // Translate data into ASCII
+  char *Text = EvidenceServer::ToString(Info);
+  if (Text != NULL) {
+	// Replace all control characters by white space
+	for (int i=0; i<strlen(Text); i++) if (iscntrl(Text[i])) Text[i] = ' ';
+	
+	// Write to file
+    fprintf(DataFile, "%s\n", Text);
+	
+	// Add to history buffer if change large enough
+	if ((fabs(atof(Text)-List[Service].LastValue) > List[Service].MinAbsChange)) {
+	  List[Service].HistBuffer[List[Service].HistPointer].Seconds = Info->getTimestamp();
+      List[Service].HistBuffer[List[Service].HistPointer].Value = atof(Text);
+      List[Service].HistService->updateService();
+	  List[Service].HistPointer++;
+	  if (List[Service].HistPointer >= HistSize) List[Service].HistPointer = 0;
+	  List[Service].LastValue = atof(Text);
+	}
+	free(Text);
+  }
+  else fprintf(DataFile, "Cannot interpret format identifier\n");
+ 
+  fflush(DataFile);
+
+  // Terminate if error because otherwise infinite loop might result as
+  // next call to this infoHandler() will try to (re-)open file
+  if(ferror(DataFile)) {
+    fclose(DataFile);
+	DataFile = NULL;
+	State(FATAL, "Error writing to data file, closed file (%s)", strerror(errno));
+  }
+
+  // Update datafile size service
+  if (time(NULL) - DataSizeLastUpdate > SizeUpdateDelay) {
+	DataSizekB = FileSize(DataFile);
+	DataSizeService->updateService();
+	DataSizeLastUpdate = time(NULL);
+  }
+}
+
+//
+// Implementation of log writing
+//
+void DataHandler::commandHandler() {
+ 
+  if (getCommand() != LogCommand || LogFile == NULL) return;
+
+  // Replace all carriage-return by line feed and non-printable characters
+  char *Text = getCommand()->getString();
+  for (unsigned int i=0; i<strlen(Text); i++) {
+    if (Text[i] == '\r') Text[i] = '\n';
+	if(isprint(Text[i])==0 && isspace(Text[i])==0) Text[i] = ' ';
+  }
+ 
+  time_t RawTime = time(NULL);
+  struct tm *TM = localtime(&RawTime);
+
+  fprintf(LogFile, "%d/%d/%d %d:%d:%d: %s\n",
+  		TM->tm_mday, TM->tm_mon+1, TM->tm_year+1900,
+		TM->tm_hour, TM->tm_min, TM->tm_sec, Text);
+
+  fflush(LogFile);
+  
+  // If error close file (otherwise infinite loop because State() also writes to log) 
+  if(ferror(LogFile)) {
+    fclose(LogFile);
+	LogFile = NULL;
+    State(ERROR, "Error writing to log file, closing file (%s)", strerror(errno));
+  }
+    
+  // Update logfile size service
+  if (time(NULL) - LogSizeLastUpdate > SizeUpdateDelay) {
+	LogSizekB = FileSize(LogFile);
+	LogSizeService->updateService();
+	LogSizeLastUpdate = time(NULL);
+  }
+}
+
+
+//
+// Add service to watch list
+//
+void DataHandler::AddService(char *Name) {
+
+  // Do not subscribe to history services (otherwise infinite loop)
+  if (strstr(Name, ".hist") != NULL) return;
+
+  // Check if already subscribed to this service
+  for (int i=0; i<NumItems; i++) {
+	if(strcmp(Name, List[i].DataItem->getName()) == 0) return;
+  }
+
+  // Increase capacity of item list			
+  struct Item *New = (struct Item *) realloc(List, (NumItems+1)*sizeof(struct Item));
+  if (New != NULL) List = New;
+  else {
+	State(ERROR, "Could not allocate memory for item list, service '' not added (%s)", Name, strerror(errno));
+	return;
+  }
+  
+  // Set minimum required change by comparing to regular expressions
+  List[NumItems].MinAbsChange = 0;
+  for (int i=0; i<RegExCount; i++) {
+    if (regexec(&RegEx[i], Name, (size_t) 0, NULL, 0) == 0) {
+	  List[NumItems].MinAbsChange = MinChange[i];
+	}
+  }
+  
+  List[NumItems].LastValue = DBL_MAX;
+		
+  // Create history service
+  List[NumItems].HistBuffer = new struct EvidenceHistoryItem [HistSize];
+  memset(List[NumItems].HistBuffer, 0, HistSize*sizeof(EvidenceHistoryItem));
+  List[NumItems].HistPointer = 0;
+
+  char *Buf;
+  if (MakeString(&Buf, "%s.hist", Name) == -1) {
+    State(ERROR, "Could not create history service for '%s', MakeString() failed", Name);
+  }
+  else {
+	List[NumItems].HistService = new DimService (Buf, (char *) "C",
+  					  List[NumItems].HistBuffer, HistSize*sizeof(EvidenceHistoryItem));
+    free(Buf);
+  }
+
+  // Subscribe to service
+  List[NumItems].DataItem = new DimStampedInfo(Name, NO_LINK, this);
+
+  // Increase number only after all set-up
+  NumItems++;
+}
+
+//
+// Determine size of file in kB
+//
+float DataHandler::FileSize(FILE *File) {
+
+  struct stat FileStatus;
+
+  if (fstat(fileno(File), &FileStatus) == -1) {
+     State(WARN, "Could not determine size of file (%s)", strerror(errno));
+	 return -1;
+  }
+
+  return (float) FileStatus.st_size/1024;
+}
+
+//	    
+// Main program
+//
+int main() {
+        
+  // Static ensures calling of destructor by exit()
+  static DataHandler Data;
+  
+  // Sleep until signal caught
+  pause();
+}
Index: Evidence/DColl/DColl.cc
===================================================================
--- Evidence/DColl/DColl.cc	(revision 142)
+++ 	(revision )
@@ -1,430 +1,0 @@
-/********************************************************************\
-
-  Central data collector of the Evidence Control System
-  
-  - DColl subscribes to all services given by the configuration
-    server and writes these to the data file at every update.
-  - One data file per day is generated, with roll-over at 13:00 local time.
-  - For each service, it creates a new service with '.hist' appended
-	that contains a history of events kept within a ring buffer. Each
-	entry will be the result of a conversion to double of the text 
-	written to the data file. Only if the new value has changed by a
-	minimum amout it will be added to the ring buffer.
-  - The command 'DColl/Log' writes the associated string to the log 
-    file specified in the configuration.
-  
-  Oliver Grimm, December 2009
-
-\********************************************************************/
-
-#define SERVER_NAME "DColl"
-
-#define DATE_ROLLOVER 12 // localtime hour after which next date is used
-
-#include "../Evidence.h"
-#include <math.h>
-#include <float.h>
-#include <sys/stat.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <regex.h>
-
-//
-// Class declaration
-//
-class DataHandler:	public DimClient, public DimBrowser,
-					public EvidenceServer {
-
-	struct Item {
-	  DimStampedInfo *DataItem;
-      DimService *HistService;
-	  struct EvidenceHistoryItem *HistBuffer;
-	  int HistPointer;
-	  double LastValue;
-	  double MinAbsChange;
-	} *List;
-
-	DimCommand *LogCommand;
-		
-    unsigned int NumItems;
-    FILE *DataFile;
-    FILE *LogFile;
-	float DataSizekB, LogSizekB;
-	int DataSizeLastUpdate, LogSizeLastUpdate;
-	char *DataDir;
-    DimService *LogSizeService, *DataSizeService;
-    int HistSize;
-	int SizeUpdateDelay;
-	int TimeForNextFile;
-	
-	int RegExCount;
-	regex_t *RegEx;
-	double *MinChange;
-	
-    void infoHandler();
-    void commandHandler();
-	void AddService(char *);
-	float FileSize(FILE *);
-	    
-  public:
-    DataHandler();
-    ~DataHandler();
-}; 
-
-//
-// Constructor
-//
-DataHandler::DataHandler(): EvidenceServer(SERVER_NAME) {
-
-  // Initialization to prevent freeing unallocated memory 
-  DataFile = NULL;
-  LogFile = NULL;
-  List = NULL;
-  LogSizeService = NULL;
-  DataSizeService = NULL;
-  
-  DataSizeLastUpdate = 0;
-  LogSizeLastUpdate = 0;
-  TimeForNextFile = 0;
-
-  // Request configuration data
-  char *Change = GetConfig(SERVER_NAME " minchange");
-  DataDir = GetConfig(SERVER_NAME " datadir");
-  char *Logname = GetConfig(SERVER_NAME " logfile");
-  SizeUpdateDelay = atoi(GetConfig(SERVER_NAME " sizeupdate"));
-  HistSize = atoi(GetConfig(SERVER_NAME " histsize"));
-  if (HistSize < 1) HistSize = 1; // Minimum one items
-   
-  // Open log file
-  if ((LogFile = fopen(Logname, "a")) == NULL) {
-    State(FATAL, "Could not open log file '%s' (%s)", Logname, strerror(errno));
-  }
-
-  // Provide logging command   
-  LogCommand = new DimCommand("DColl/Log", (char *) "C", this);
-              
-  // Create services for file sizes
-  DataSizekB = 0;
-  DataSizeService = new DimService(SERVER_NAME "/DataSizekB", DataSizekB);
-  
-  LogSizekB = FileSize(LogFile);
-  LogSizeService = new DimService(SERVER_NAME "/LogSizekB", LogSizekB);
-
-  // Count how many minimum change value regular expressions are present
-  RegExCount = 0;
-  char *Token = strtok(Change, "\t ");
-  while (Token != NULL) {
-	RegExCount++;
-	Token = strtok(NULL, "\t ");
-  }
-  
-  // Allocate memory for regular expressions and minimum change values
-  RegEx = new regex_t[RegExCount];
-  MinChange = new double [RegExCount];
-
-  // Compile regular expressions
-  int Pos = 0;
-  for (int i=0; i<RegExCount; i++) {
-    int Len = strlen(Change+Pos) + 1;
-    Token = strtok(Change + Pos, ": \t");
-
-    int Ret = regcomp(&RegEx[i], Token, REG_EXTENDED|REG_NOSUB);
-	if (Ret != 0) {
-	  char ErrMsg[200];
-	  regerror(Ret, &RegEx[i], ErrMsg, sizeof(ErrMsg));
-	  State(WARN, "Error compiling regular expression '%s' (%s)", Token, ErrMsg);
-	}
-	else {
-	  if ((Token=strtok(NULL, "")) != NULL) MinChange[i] = atof(Token);
-	  else MinChange[i] = 0;
-	}
-	Pos += Len;
-  }
-
-  // Subscribe to list of servers at DIS_DNS 
-  AddService((char *) "DIS_DNS/SERVER_LIST");
-
-  DimClient::sendCommand("DColl/Log", SERVER_NAME" *** Logging started ***");
-}
-
-//
-// Destructor: Close files and free memory
-//
-DataHandler::~DataHandler() {
-
-  // Delete DIM services and command first so handlers and not called anymore
-  for (int i=0; i<NumItems; i++) {
-	delete List[i].HistService;
-    delete List[i].DataItem;
-    delete[] List[i].HistBuffer;
-  }
-  free(List);
-
-  //delete LogSizeService; // These create segmentation faults?!
-  //delete DataSizeService;
-
-  delete LogCommand;
-
-  // Close files
-  if (LogFile != NULL) if (fclose(LogFile) != 0) {
-	State(ERROR, "Could not close log file (%s)", strerror(errno));
-  }
-  if (DataFile != NULL && fclose(DataFile) != 0) {
-	State(ERROR, "Error: Could not close data file (%s)", strerror(errno));
-  }
-
-  // Free memory for regular expressions handling
-  for (int i=0; i<RegExCount; i++) {
-    regfree(&RegEx[i]);
-  }
-  delete[] MinChange;
-  delete[] RegEx;
-}
-
-//
-// Implementation of data handling
-//
-// DIM ensures infoHandler() is called serialized, therefore
-// no mutex is needed to serialize writing to the file
-void DataHandler::infoHandler() {
-
-  DimInfo *Info = getInfo();
-
-  // Check if service available
-  if (Info->getSize()==strlen(NO_LINK)+1 && strcmp(Info->getString(), NO_LINK)==0) return;
-
-  // If service is DIS_DNS/SERVER_LIST, subscribe to all SERVICE_LIST services
-  if (strcmp(Info->getName(), "DIS_DNS/SERVER_LIST") == 0) {	
-	char *Token = strtok(Info->getString(), "+-!|@");	
-	while (Token != NULL) {
-	  char *Buf;
-	  if (MakeString(&Buf, "%s/SERVICE_LIST", Token) != -1) {
-	    AddService(Buf);
-		free(Buf);
-	  }
-	  else State(ERROR, "MakeString() failed for server %s", Token);
-	  
-  	  Token = strtok(NULL, "|");
-	  Token = strtok(NULL, "+-!|@");	
-	}	
-	return;
-  }
-
-  // If service is SERVICE_LIST of any server, scan all services.
-  // Subscribe to all services (but not to commands and RPCs)
-  if (strstr(Info->getName(), "/SERVICE_LIST") != NULL) {
-	char *Name = strtok(Info->getString(), "+-!|");
-	while (Name != NULL) {
-	  char *Type = strtok(NULL, "\n");
-	  if (Type == NULL) return; // for safety, should not happen
-      if (strstr(Type, "|CMD")==NULL && strstr(Type, "|RPC")==NULL) {
-		AddService(Name);
-	  }
-	  Name = strtok(NULL, "+-!|");
-	}
-	return;
-  }
-
-  // If it is time to open new data file, close the current one 
-  if (time(NULL) >= TimeForNextFile) {
-	if (DataFile != NULL && fclose(DataFile) != 0) {
-	  State(ERROR, "Error: Could not close data file (%s)", strerror(errno));
-	}
-	DataFile = NULL;
-  }
-  
-  // Open new data file if necessary
-  if (DataFile == NULL) {
-	time_t Time = time(NULL);
-	struct tm *T = localtime(&Time);
-	
-	if(T->tm_hour >= DATE_ROLLOVER) T->tm_mday++;
-	if (mktime(T) == -1) State(ERROR, "mktime() failed, check filename");
-
-	char *Filename;
-	if (MakeString(&Filename, "%s/%d%02d%02d.slow", DataDir, T->tm_year+1900, T->tm_mon+1, T->tm_mday) == -1) State(FATAL, "Could not create filename, MakeString() failed");
-	if ((DataFile = fopen(Filename, "a")) == NULL) {
-      State(FATAL, "Could not open data file '%s' (%s)", Filename, strerror(errno));
-	}
-	else State(INFO, "Opened data file '%s'", Filename);
-	free(Filename);
-	
-	// Calculate time for next file opening
-	T->tm_sec = 0;
-	T->tm_min = 0;
-	T->tm_hour = DATE_ROLLOVER;
-	TimeForNextFile = mktime(T);
-  }
-   
-  // Identify index of service
-  int Service;  
-  for (Service=0; Service<NumItems; Service++) if (Info == List[Service].DataItem) break;
-  if (Service == NumItems) return;  // Service not found
-
-  // If negative value for absolute change, ignore this entry
-  if (List[Service].MinAbsChange < 0) return;
-
-  // Write data header
-  time_t RawTime = Info->getTimestamp();
-  struct tm *TM = localtime(&RawTime);
-
-  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());
-
-  // Translate data into ASCII
-  char *Text = EvidenceServer::ToString(Info);
-  if (Text != NULL) {
-	// Replace all control characters by white space
-	for (int i=0; i<strlen(Text); i++) if (iscntrl(Text[i])) Text[i] = ' ';
-	
-	// Write to file
-    fprintf(DataFile, "%s\n", Text);
-	
-	// Add to history buffer if change large enough
-	if ((fabs(atof(Text)-List[Service].LastValue) > List[Service].MinAbsChange)) {
-	  List[Service].HistBuffer[List[Service].HistPointer].Seconds = Info->getTimestamp();
-      List[Service].HistBuffer[List[Service].HistPointer].Value = atof(Text);
-      List[Service].HistService->updateService();
-	  List[Service].HistPointer++;
-	  if (List[Service].HistPointer >= HistSize) List[Service].HistPointer = 0;
-	  List[Service].LastValue = atof(Text);
-	}
-	free(Text);
-  }
-  else fprintf(DataFile, "Cannot interpret format identifier\n");
- 
-  fflush(DataFile);
-
-  // Terminate if error because otherwise infinite loop might result as
-  // next call to this infoHandler() will try to (re-)open file
-  if(ferror(DataFile)) {
-    fclose(DataFile);
-	DataFile = NULL;
-	State(FATAL, "Error writing to data file, closed file (%s)", strerror(errno));
-  }
-
-  // Update datafile size service
-  if (time(NULL) - DataSizeLastUpdate > SizeUpdateDelay) {
-	DataSizekB = FileSize(DataFile);
-	DataSizeService->updateService();
-	DataSizeLastUpdate = time(NULL);
-  }
-}
-
-//
-// Implementation of log writing
-//
-void DataHandler::commandHandler() {
- 
-  if (getCommand() != LogCommand || LogFile == NULL) return;
-
-  // Replace all carriage-return by line feed and non-printable characters
-  char *Text = getCommand()->getString();
-  for (unsigned int i=0; i<strlen(Text); i++) {
-    if (Text[i] == '\r') Text[i] = '\n';
-	if(isprint(Text[i])==0 && isspace(Text[i])==0) Text[i] = ' ';
-  }
- 
-  time_t RawTime = time(NULL);
-  struct tm *TM = localtime(&RawTime);
-
-  fprintf(LogFile, "%d/%d/%d %d:%d:%d: %s\n",
-  		TM->tm_mday, TM->tm_mon+1, TM->tm_year+1900,
-		TM->tm_hour, TM->tm_min, TM->tm_sec, Text);
-
-  fflush(LogFile);
-  
-  // If error close file (otherwise infinite loop because State() also writes to log) 
-  if(ferror(LogFile)) {
-    fclose(LogFile);
-	LogFile = NULL;
-    State(ERROR, "Error writing to log file, closing file (%s)", strerror(errno));
-  }
-    
-  // Update logfile size service
-  if (time(NULL) - LogSizeLastUpdate > SizeUpdateDelay) {
-	LogSizekB = FileSize(LogFile);
-	LogSizeService->updateService();
-	LogSizeLastUpdate = time(NULL);
-  }
-}
-
-
-//
-// Add service to watch list
-//
-void DataHandler::AddService(char *Name) {
-
-  // Do not subscribe to history services (otherwise infinite loop)
-  if (strstr(Name, ".hist") != NULL) return;
-
-  // Check if already subscribed to this service
-  for (int i=0; i<NumItems; i++) {
-	if(strcmp(Name, List[i].DataItem->getName()) == 0) return;
-  }
-
-  // Increase capacity of item list			
-  struct Item *New = (struct Item *) realloc(List, (NumItems+1)*sizeof(struct Item));
-  if (New != NULL) List = New;
-  else {
-	State(ERROR, "Could not allocate memory for item list, service '' not added (%s)", Name, strerror(errno));
-	return;
-  }
-  
-  // Set minimum required change by comparing to regular expressions
-  List[NumItems].MinAbsChange = 0;
-  for (int i=0; i<RegExCount; i++) {
-    if (regexec(&RegEx[i], Name, (size_t) 0, NULL, 0) == 0) {
-	  List[NumItems].MinAbsChange = MinChange[i];
-	}
-  }
-  
-  List[NumItems].LastValue = DBL_MAX;
-		
-  // Create history service
-  List[NumItems].HistBuffer = new struct EvidenceHistoryItem [HistSize];
-  memset(List[NumItems].HistBuffer, 0, HistSize*sizeof(EvidenceHistoryItem));
-  List[NumItems].HistPointer = 0;
-
-  char *Buf;
-  if (MakeString(&Buf, "%s.hist", Name) == -1) {
-    State(ERROR, "Could not create history service for '%s', MakeString() failed", Name);
-  }
-  else {
-	List[NumItems].HistService = new DimService (Buf, (char *) "C",
-  					  List[NumItems].HistBuffer, HistSize*sizeof(EvidenceHistoryItem));
-    free(Buf);
-  }
-
-  // Subscribe to service
-  List[NumItems].DataItem = new DimStampedInfo(Name, NO_LINK, this);
-
-  // Increase number only after all set-up
-  NumItems++;
-}
-
-//
-// Determine size of file in kB
-//
-float DataHandler::FileSize(FILE *File) {
-
-  struct stat FileStatus;
-
-  if (fstat(fileno(File), &FileStatus) == -1) {
-     State(WARN, "Could not determine size of file (%s)", strerror(errno));
-	 return -1;
-  }
-
-  return (float) FileStatus.st_size/1024;
-}
-
-//	    
-// Main program
-//
-int main() {
-        
-  // Static ensures calling of destructor by exit()
-  static DataHandler Data;
-  
-  // Sleep until signal caught
-  pause();
-}
Index: Evidence/DColl/Makefile
===================================================================
--- Evidence/DColl/Makefile	(revision 142)
+++ 	(revision )
@@ -1,11 +1,0 @@
-CC=g++
-
-PROG=DColl
-CPPFLAGS += -I../DIM
-LDLIBS += -lpthread
-
-$(PROG): $(PROG).o ../Evidence.o ../DIM/libdim.a
-
-clean:
-	@rm -f $(PROG) $(PROG).o
-	
Index: Evidence/Edd/Edd.pro
===================================================================
--- Evidence/Edd/Edd.pro	(revision 142)
+++ Evidence/Edd/Edd.pro	(revision 144)
@@ -6,8 +6,8 @@
 TARGET = 
 DEPENDPATH += .
-INCLUDEPATH += . /usr/local/qwt-5.2.0/include ../DIM/ ..
+INCLUDEPATH += . .. /usr/local/qwt-5.2.0/include $(DIMDIR)/dim
 
 # Input
 HEADERS += Edd.h
 SOURCES += Edd.cc ../Evidence.cc
-LIBS += -L/usr/local/qwt-5.2.0/lib -lqwt ../DIM/libdim.a
+LIBS += -L/usr/local/qwt-5.2.0/lib -lqwt $(DIMDIR)/linux/libdim.a
Index: Evidence/Evidence.cc
===================================================================
--- Evidence/Evidence.cc	(revision 142)
+++ Evidence/Evidence.cc	(revision 144)
@@ -95,7 +95,7 @@
   va_end(ArgumentPointer);
 
-  snprintf(TBuf, sizeof(TBuf), "%s (%s): %s", StatusName, StateString[Severity], Tmp);
-  snprintf(SBuf, sizeof(SBuf), "%s\0%d", Tmp);
-
+  snprintf(TBuf, sizeof(TBuf), "%s (%s): %s", StatusName, StateString[Severity], Tmp); // Normal string
+  snprintf(SBuf, sizeof(SBuf), "%s*%c", Tmp, (char) Severity);
+  *(strrchr(SBuf, '*')) = '\0';  // String with severity encoding
   if (Tmp != ErrorString) free(Tmp);
   
@@ -122,5 +122,5 @@
   
   // Check if configuration request already in list
-  for (int i=0; i<ConfigNum; i++) {
+  for (unsigned int i=0; i<ConfigNum; i++) {
     if (strcmp(ConfigList[i].Name, Item) == 0) {
 	  // Return original value if still up to date
Index: Evidence/Makefile
===================================================================
--- Evidence/Makefile	(revision 144)
+++ Evidence/Makefile	(revision 144)
@@ -0,0 +1,22 @@
+CC=g++
+
+PROG1=Config
+PROG2=DColl
+PROG3=Alarm
+
+CPPFLAGS += -I$(DIMDIR)/dim/
+LDLIBS += -lpthread $(DIMDIR)/linux/libdim.a
+
+all: $(PROG1) $(PROG2) $(PROG3)
+	 
+$(PROG1): $(PROG1).o Evidence.o
+
+$(PROG2): $(PROG2).o Evidence.o
+
+$(PROG3): $(PROG3).o Evidence.o
+
+clean:
+	@rm -f $(PROG1) $(PROG1).o
+	@rm -f $(PROG2) $(PROG2).o
+	@rm -f $(PROG3) $(PROG3).o
+	
Index: Evidence/start
===================================================================
--- Evidence/start	(revision 142)
+++ 	(revision )
@@ -1,13 +1,0 @@
-#!/bin/bash
-
-# Script to start Evidence control system
-
-export DIM_DNS_NODE=ihp-pc26.ethz.ch 
-
-xterm -T 'FConSys: Config' -e 'cd Config; Config' &
-sleep 0.5
-
-xterm -T 'FConSys: DColl' -e 'cd DColl; DColl' &
-sleep 0.5
-
-xterm -T 'FConSys: Alarm' -e 'cd Alarm; Alarm' &
