Index: /tools/SkyQualityMonitor/Makefile
===================================================================
--- /tools/SkyQualityMonitor/Makefile	(revision 95)
+++ /tools/SkyQualityMonitor/Makefile	(revision 95)
@@ -0,0 +1,16 @@
+CC=g++
+
+PROG=sqm
+INCLUDE=../../drsdaq/
+
+all: $(PROG)
+
+$(PROG): $(PROG).o SlowData.o
+	$(CC) $(PROG).o SlowData.o -o $(PROG)
+
+$(PROG).o : $(PROG).cpp
+	$(CC) $(PROG).cpp -c -I$(INCLUDE)
+
+SlowData.o: ../../drsdaq/SlowData.cc
+	$(CC) ../../drsdaq/SlowData.cc -c -I$(INCLUDE)
+	
Index: /tools/SkyQualityMonitor/sqm.cpp
===================================================================
--- /tools/SkyQualityMonitor/sqm.cpp	(revision 95)
+++ /tools/SkyQualityMonitor/sqm.cpp	(revision 95)
@@ -0,0 +1,135 @@
+/********************************************************************\
+
+  Interface to the sky quality monitor (essentially a socket interface)
+  
+  Writes slow data at given rate. Terminate with CTRL-c.
+  
+  Oliver Grimm, July 2009
+
+\********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <iostream>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <signal.h>
+
+#include "../../drsdaq/SlowData.h"
+
+#define PERIOD 10  	// Measurement period (integer)
+#define READ_CMD "rx"	// Command to read from device
+#define BUF_SIZE 1000	// Read buffer size
+
+int SocketDescriptor;	// Global to be accessible by exit handler
+SlowData *SlowDataClass;
+
+// Close socket descriptor when CTRL-c pressed
+void ExitHandler(int Signal) {
+  if (!close(SocketDescriptor)) printf("Connection closed.\n");
+  delete SlowDataClass;
+  exit(EXIT_SUCCESS);
+}
+
+// Main program
+int main(int argc, char *argv[]) {
+        
+  char Buffer[BUF_SIZE],ServerName[BUF_SIZE]="sqm.ethz.ch";
+  char SlowDir[BUF_SIZE]="/ct3data/SlowData";
+  int DAQPort = 10001, Period = PERIOD;
+  struct sockaddr_in SocketAddress;
+  fd_set ReadFileDescriptor;
+  time_t Time;
+  
+  if (argc != 5) {
+    printf("+++ Sky Quality Monitor Interface +++\n");
+    printf("Usage: %s <server name> <port> <slow data dir> <period (sec)>\n", argv[0]);
+    printf("Taking defaults: <%s> <%d> <%s> <d>\n", ServerName, DAQPort, SlowDir, Period);
+  } 
+  else {
+    snprintf(ServerName, sizeof(ServerName), argv[1]);
+    snprintf(SlowDir, sizeof(SlowDir), argv[3]);
+    DAQPort = atoi(argv[2]);
+    Period = atoi(argv[4]);
+  }
+  
+  // Open socket descriptor
+  if ((SocketDescriptor = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
+    printf("Error: Could not open socket.");
+    exit(EXIT_FAILURE);
+  }
+    
+  // Resolve hostname and try to connect to server
+  struct hostent *hostent = gethostbyname(ServerName);
+  if (hostent==0) {
+    printf("\nCould not resolve host name.\n");
+    close(SocketDescriptor);
+    exit(EXIT_FAILURE);
+  }
+
+  SocketAddress.sin_family = PF_INET;
+  SocketAddress.sin_port = htons((unsigned short) DAQPort);
+  SocketAddress.sin_addr = *(struct in_addr*) hostent->h_addr;
+  
+  if (connect(SocketDescriptor, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress))==-1) {
+    printf("Error: Could not connect to server %s (port %d)\n", ServerName, DAQPort);
+    close(SocketDescriptor);
+    exit(EXIT_FAILURE);
+  }
+  printf("\nConnected to %s (port %d)\n", ServerName, DAQPort);
+  signal(SIGPIPE,SIG_IGN);  // Do not kill process if writing to closed socket
+  signal(SIGINT, &ExitHandler);
+
+  // Create instance of slow data class for monitoring data
+  SlowDataClass = new SlowData("SQM", SlowDir);
+  if(SlowDataClass->ErrorCode != 0) {
+    printf("Error: Could not open slow data file in %s (%s)\n", SlowDir, strerror(SlowDataClass->ErrorCode));
+    exit(EXIT_FAILURE);
+  }
+  SlowDataClass->NewEntry("Data-Info", "Data string as returned by sqm. Commata and the letter 'm' are replaced by whitespaces");
+
+  while(true) {
+    // Write read command to socket
+    if ((write(SocketDescriptor, READ_CMD, strlen(READ_CMD)))<1) { 
+      printf("Error: Could not write read command to socket.\n");
+    }
+    usleep(Period*1e6/2);  // Wait half period here to allow for response
+    
+    // Wait for data from socket with time-out
+    FD_ZERO(&ReadFileDescriptor);   
+    FD_SET(SocketDescriptor, &ReadFileDescriptor);
+    struct timeval WaitTime = {PERIOD, 0};
+    if (select(((int) SocketDescriptor)+1, &ReadFileDescriptor, NULL, NULL, &WaitTime)==-1) {
+      perror("Error with select()");
+      break;
+    }
+
+    if (!FD_ISSET(SocketDescriptor, &ReadFileDescriptor)) { 
+      printf("Time-out of %d seconds expired before receiving response from socket.\n", PERIOD);
+      continue;
+    }
+
+    memset(Buffer, 0, BUF_SIZE);
+    if(read(SocketDescriptor, Buffer, BUF_SIZE)==0) {
+      printf("Server not existing anymore, exiting...\n");
+      break;
+    }
+
+    // Remove letters and commata from string before writing as slow data
+    for (int i=0; i<strlen(Buffer); i++) {
+      if (Buffer[i]=='m' || Buffer[i]==',' || iscntrl(Buffer[i])) Buffer[i] = ' ';
+    }
+    SlowDataClass->NewEntry("Data", Buffer);
+    if(SlowDataClass->ErrorCode != 0) {
+      printf("Error: Could not write to slow data file (%s)\n", strerror(SlowDataClass->ErrorCode));
+      break;
+    }
+    Time = time(NULL);
+    printf("\r%s %s CTRL-c to exit.",Buffer, asctime(localtime(&Time)));
+    fflush(stdout);
+    usleep(Period*1e6/2); // Wait second half period here
+ 
+  } // while()
+  
+  ExitHandler(0);
+}
