Creation of gcm_input and a first approach to a web interface V0_0_1
authorarjen <arjen>
Sat, 5 Oct 2002 10:25:48 +0000 (10:25 +0000)
committerarjen <arjen>
Sat, 5 Oct 2002 10:25:48 +0000 (10:25 +0000)
28 files changed:
src/gcm_input/gcm_input.cpp [new file with mode: 0644]
src/gcm_input/makefile [new file with mode: 0644]
src/gcm_input/message.cpp [new file with mode: 0644]
src/gcm_input/message.h [new file with mode: 0644]
src/gnucomo.conf [new file with mode: 0644]
src/include/database.h [new file with mode: 0644]
src/include/gnucomo_config.h [new file with mode: 0644]
src/lib/database.cpp [new file with mode: 0644]
src/lib/gnucomo_config.cpp [new file with mode: 0644]
src/phpclasses/configuration.class.php [new file with mode: 0644]
src/phpclasses/gnucomo_config.php [new file with mode: 0644]
src/web/change.png [new file with mode: 0644]
src/web/classes/configuration.class.php [new file with mode: 0644]
src/web/classes/gnucomo_config.php [new file with mode: 0644]
src/web/closed_package.png [new file with mode: 0644]
src/web/exit.png [new file with mode: 0644]
src/web/functions.php [new file with mode: 0755]
src/web/gnucomo.css [new file with mode: 0644]
src/web/harddisk.png [new file with mode: 0644]
src/web/index.html [new file with mode: 0644]
src/web/log.png [new file with mode: 0644]
src/web/login.php [new file with mode: 0755]
src/web/menu.html [new file with mode: 0644]
src/web/open_package.png [new file with mode: 0644]
src/web/password.png [new file with mode: 0644]
src/web/server.png [new file with mode: 0644]
src/web/service.png [new file with mode: 0644]
src/web/user.png [new file with mode: 0644]

diff --git a/src/gcm_input/gcm_input.cpp b/src/gcm_input/gcm_input.cpp
new file mode 100644 (file)
index 0000000..51fa9b7
--- /dev/null
@@ -0,0 +1,183 @@
+
+/**************************************************************************
+**  (c) Copyright 2002, Andromeda Technology & Automation
+***************************************************************************
+** MODULE INFORMATION *
+***********************
+**      FILE NAME      : gcm_input.cpp
+**      SYSTEM NAME    : Gnucomo - Gnu Computer Monitoring
+**      VERSION NUMBER : $Revision: 1.1 $
+**
+**  DESCRIPTION      :  Application to store client messages into the database
+**                      The client message contains a log file from one of the
+**                      system logs. Gcm_input parses the log file and enters
+**                      the raw data into the 'log' table of the gnucomo database.
+**
+**                      The system log may arrive in one of several forms:
+**                      1. Log file (archived or not) from a client machine.
+**                      2. Log file from a client system, arriving in a clear Email.
+**                      3. Log file from a client machine, arriving in an
+**                         encrypted Email.
+**
+**                      additional information we need that may not be availble in
+**                      the content of the log is:
+**                      - FQDN of the client.
+**                      - Time of arrival of the log
+**                      - Service that created the log.
+**
+**                      If the log arrives in an Email, these items probably are
+**                      available in the mail header. Otherwise, they have to be
+**                      provided as command line arguments.
+**
+**                      Command line arguments:
+**                      -c <name>        Configuration name (default = gnucomo).
+**                      -d <date>        Date and time of log arrival.
+**                      -h <hostname>    FQDN of the client.
+**                      -s <service>     Service that created the log.
+**                      -T               Test mode. Do not alter the database.
+**                      -v               Verbose (debug) output.
+**                      -V               Print version and exit.
+**
+**  EXPORTED OBJECTS : 
+**  LOCAL    OBJECTS : 
+**  MODULES  USED    :
+***************************************************************************
+**  ADMINISTRATIVE INFORMATION *
+********************************
+**      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
+**      CREATION DATE   : Aug 29, 2002
+**      LAST UPDATE     : Sep 30, 2002
+**      MODIFICATIONS   : 
+**************************************************************************/
+
+/*****************************
+   $Log: gcm_input.cpp,v $
+   Revision 1.1  2002-10-05 10:25:49  arjen
+   Creation of gcm_input and a first approach to a web interface
+
+*****************************/
+
+static const char *RCSID = "$Id: gcm_input.cpp,v 1.1 2002-10-05 10:25:49 arjen Exp $";
+
+#include <getopt.h>
+
+#include "message.h"
+
+bool verbose = false;
+bool testmode = false;
+
+static char *Version = "gcm_input version 0.0.3 - Sep 30, 2002";
+
+
+/*=========================================================================
+**  NAME           : main
+**  SYNOPSIS       : int main(int argc, char *argv[])
+**  PARAMETERS     : 
+**  RETURN VALUE   : 
+**
+**  DESCRIPTION    : Parse command line arguments and establish a connection
+**                   to the database.
+**                   When we have a database connection, parse the log file
+**                   from stdin.
+**
+**  VARS USED      :
+**  VARS CHANGED   :
+**  FUNCTIONS USED :
+**  SEE ALSO       :
+**  LAST MODIFIED  : Sep 30, 2002
+**=========================================================================
+*/
+
+int main(int argc, char *argv[])
+{
+   const char *usage = "Usage: gcm_input [-c configname] [-h hostname] [-d date]"
+                       " [-s service] [-T] [-v] [-V]\n";
+
+   gnucomo_config    cfg;
+   char             *config_name = "gnucomo";
+
+   /*   Parse command line arguments */
+
+   UTC    arrival = Now();
+   String  hostname(""), service("");
+   int     option;
+
+   while ((option = getopt(argc, argv, "c:h:d:s:TvV")) != -1)
+   {
+      switch (option)
+      {
+      case 'c':
+         config_name = optarg;
+         break;
+
+      case 'h':
+         hostname = optarg;
+         break;
+
+      case 'd':
+         arrival = String(optarg);
+         if (!arrival.proper())
+         {
+            cerr << "gcm_input: Invalid date string: " << optarg << ".\n";
+            exit(1);
+         }
+         break;
+
+      case 's':
+         service = optarg;
+         break;
+
+      case 'T':
+         testmode = true;
+         break;
+
+      case 'v':
+         verbose = true;
+         break;
+
+      case 'V':
+         cout << Version << "\n";
+         exit(0);
+
+      case '?':
+      case ':':
+         cerr << usage;
+         exit(1);
+      }
+   }
+
+   if (verbose)
+   {
+      cout << "Hostname = " << hostname;
+      cout << " Arrival = " << arrival;
+      cout << " Service = " << service << "\n";
+   }
+
+   /*  Get the configuration file */
+
+   if (!cfg.read(config_name))
+   {
+      cerr << "Can not read Gnucomo configuration file for " << config_name << ".\n";
+      exit(1);
+   }
+
+   if (verbose)
+   {
+      cout << "Config OK.\n";
+   }
+
+   /*  Try to connect to the database */
+
+   gnucomo_database db(&cfg);
+
+   client_message  msg(&cin, db);
+
+   if (msg.classify(hostname, arrival, service) > 0.9)
+   {
+      msg.enter();
+   }
+
+   return 0;
+}
+
diff --git a/src/gcm_input/makefile b/src/gcm_input/makefile
new file mode 100644 (file)
index 0000000..4341009
--- /dev/null
@@ -0,0 +1,13 @@
+CXXFLAGS = -I/usr/include/gnome-xml -g
+
+GCMINPUT_O = gcm_input.o gnucomo_config.o database.o message.o
+
+gcm_input :  $(GCMINPUT_O)
+       $(CXX) -o gcm_input $(GCMINPUT_O) -lAXE -lxml -lpq++
+
+gcm_input.o : message.h database.h
+database.o  : database.h
+message.o   : message.h
+
+clean:
+       rm -f gcm_input $(GCMINPUT_O)
diff --git a/src/gcm_input/message.cpp b/src/gcm_input/message.cpp
new file mode 100644 (file)
index 0000000..9b1ef1a
--- /dev/null
@@ -0,0 +1,510 @@
+
+/**************************************************************************
+**  (c) Copyright 2002, Andromeda Technology & Automation
+***************************************************************************
+** MODULE INFORMATION *
+***********************
+**      FILE NAME      : message.cpp
+**      SYSTEM NAME    : Gnucomo - Gnu Computer Monitoring
+**      VERSION NUMBER : $Revision: 1.1 $
+**
+**  DESCRIPTION      :  Implementation of the message handling classes
+**
+**  EXPORTED OBJECTS : 
+**  LOCAL    OBJECTS : 
+**  MODULES  USED    :
+***************************************************************************
+**  ADMINISTRATIVE INFORMATION *
+********************************
+**      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
+**      CREATION DATE   : Sep 16, 2002
+**      LAST UPDATE     : Oct 05, 2002
+**      MODIFICATIONS   : 
+**************************************************************************/
+
+/*****************************
+   $Log: message.cpp,v $
+   Revision 1.1  2002-10-05 10:25:49  arjen
+   Creation of gcm_input and a first approach to a web interface
+
+*****************************/
+
+static const char *RCSID = "$Id: message.cpp,v 1.1 2002-10-05 10:25:49 arjen Exp $";
+
+#include "message.h"
+
+extern bool verbose;   /*  Defined in the main application */
+extern bool testmode;
+
+/*   Utility functions   */
+
+String SQL_Escape(String s);
+
+/*=========================================================================
+**  NAME           : operator >>
+**  SYNOPSIS       : bool operator >> (message_buffer &, String &)
+**  PARAMETERS     : 
+**  RETURN VALUE   : True if input was available.
+**
+**  DESCRIPTION    : Input operator. Read the next line from the message.
+**
+**  VARS USED      :
+**  VARS CHANGED   :
+**  FUNCTIONS USED :
+**  SEE ALSO       :
+**  LAST MODIFIED  : Sep 30, 2002
+**=========================================================================
+*/
+
+bool operator >> (message_buffer &b, String &s)
+{
+   bool   input_ok = false;
+
+   if (b.next_line == b.buffer.end())
+   {
+      String   l;
+
+      //cout << "     buffer is depleted.\n";
+      if (*(b.input) >> l)
+      {
+         b.buffer.push_back(l);
+
+         //   next_line keeps pointing to the end.
+         s = l;
+         input_ok = true;
+         //cout << "     new line from input.\n";
+      }
+   }
+   else
+   {
+      //cout << "    reading from cache.\n";
+      s = *(b.next_line);
+      b.next_line++;
+      input_ok = true;
+   }
+   return input_ok;
+}
+
+client_message::client_message(istream *in, gnucomo_database db)
+{
+   input.from(in);
+   database = db;
+
+   hostname = "";
+   mail_header   = false;
+   gpg_encrypted = false;
+   classification = UNKNOWN;
+   certainty      = 0.0;
+}
+
+static const String syslog_date_re("[[:alpha:]]{3} [ 123][0-9] [0-9]{2}:[0-9]{2}:[0-9]{2}");
+static const String mail_date_re("[[:alpha:]]{3}, [ 123]?[0-9] [[:alpha:]]{3} [0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2} [+-][0-9]{4}");
+static const String unix_date_re("[[:alpha:]]{3} [[:alpha:]]{3} [ 123][0-9] [0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{4}");
+
+static const regex re_syslog(syslog_date_re + " [a-z]+ [[:alpha:]]+.*:.+");
+static const regex re_PGP("-----BEGIN PGP MESSAGE-----");
+static const regex re_dump("^ *DUMP: Date of this level");
+static const regex re_accesslog("(GET|POST) .+ HTTP");
+static const regex re_errorlog("^\\[" + unix_date_re + "\\] \\[(error|notice)\\] .+");
+
+static const regex re_syslog_date("[[:alpha:]]{3} [ 123][0-9] [0-9]{2}:[0-9]{2}:[0-9]{2}");
+static const regex re_uxmail_from("^From - " + unix_date_re);
+static const regex re_mail_From("^From:[[:blank:]]+");
+static const regex re_mail_Date("^Date:[[:blank:]]+" + mail_date_re);
+static const regex re_email_address("[[:alnum:]_.-]+@[[:alnum:]_.-]+");
+static const regex re_email_user("[[:alnum:]_.-]+@");
+
+/*=========================================================================
+**  NAME           : classify
+**  SYNOPSIS       : double classify(String host, date arriv_d, hour arriv_t, String serv)
+**  PARAMETERS     : 
+**  RETURN VALUE   : The certainty with which the message is classified.
+**
+**  DESCRIPTION    : 
+**
+**  VARS USED      :
+**  VARS CHANGED   :
+**  FUNCTIONS USED :
+**  SEE ALSO       :
+**  LAST MODIFIED  : Oct 05, 2002
+**=========================================================================
+*/
+
+double client_message::classify(String host, UTC arriv, String serv)
+{
+   String    line;
+
+   hostname    = host;
+   arrival     = arriv;
+   service     = serv;
+
+   /*  First, check if the message has a mail header. */
+
+   if (input >> line && line == re_uxmail_from)
+   {
+      String    from_address;
+
+      mail_header = true;
+
+      /*  Scan ahead for the hostname and date of arrival.  */
+
+      while (input >> line && line != "")
+      {
+         if (line == re_mail_From)
+         {
+            from_address = line(re_email_address);
+            from_address(re_email_user) = "";            //  Remove the user part;
+            hostname = from_address;
+         }
+         if (line == re_mail_Date)
+         {
+            arrival = UTC(line(regex(mail_date_re)));
+         }
+      }
+   }
+   else
+   {
+      //  Push the first line back, we need to read it again.
+      --input;
+   }
+
+   /*
+    *  Now that we have the mail header out of the way, try to figure
+    *  out what the content of the message is.
+    */
+
+
+   while (input >> line && certainty < 0.9)
+   {
+      cout << "  testing: " << line << "\n";
+      if (line == re_syslog)
+      {
+         certainty = 1.0;
+         classification = SYSLOG;
+         if (verbose)
+         {
+            cout << "Syslog detected.\n";
+         }
+      }
+      else if (line == re_PGP)
+      {
+         certainty = 1.0;
+         gpg_encrypted = true;
+         cerr << "The message is PGP/GnuPG encrypted.\n";
+      }
+      else if (line == re_dump)
+      {
+          certainty = 1.0;
+          if (verbose)
+          {
+             cout << "DUMP output detected.\n";
+          }
+      }
+      else if (line == re_accesslog)
+      {
+          certainty = 1.0;
+          classification = ACCESSLOG;
+          service = "httpd";
+          if (verbose)
+          {
+             cout << "HTTP access log detected.\n";
+          }
+      }
+      else if (line == re_errorlog)
+      {
+          certainty = 1.0;
+          classification = ERRORLOG;
+          service = "httpd";
+          if (verbose)
+          {
+             cout << "HTTP error log detected.\n";
+          }
+      }
+   }
+   input.rewind();
+
+   if (hostname == "")
+   {
+      cerr <<  "Can not determine the hostname where the message came from.\n";
+      certainty = 0.0;
+   }
+   else if (!arrival.proper())
+   {
+      cerr << "Arrival time is not knwon.\n";
+      certainty = 0.0;
+   }
+   else
+   {
+      certainty = 1.0;
+   }
+
+   return certainty;
+}
+
+/*=========================================================================
+**  NAME           : enter
+**  SYNOPSIS       : int enter()
+**  PARAMETERS     : 
+**  RETURN VALUE   : The number of lines successfully parsed from the input
+**
+**  DESCRIPTION    : 
+**
+**  VARS USED      :
+**  VARS CHANGED   :
+**  FUNCTIONS USED :
+**  SEE ALSO       :
+**  LAST MODIFIED  : Oct 05, 2002
+**=========================================================================
+*/
+
+int client_message::enter()
+{
+   long   nr_lines = 0;
+   String line;
+
+   /*  Double-check the classification of the message */
+
+   if (classification == UNKNOWN || certainty < 0.9 || gpg_encrypted)
+   {
+      return 0;
+   }
+
+   if (mail_header)
+   {
+      //  Skip the mail header.
+      while (input >> line && line != "");
+   }
+
+   /*  Try to find the host in the database */
+
+   String objectid;
+
+   objectid = database.find_host(hostname);
+   if (objectid == "")
+   {
+      cerr << "Please define the host " << hostname << " in the database.\n";
+      return 0;
+   }
+   if (verbose)
+   {
+      cout << "Object id for " << hostname << " is " << objectid << "\n";
+   }
+
+   /*  Scan the input line by line, entring records into the database */
+
+   String rest;   //  Rest of the line to be parsed
+
+   while (input >> line)
+   {
+      if (verbose)
+      {
+         cout << line << "\n";
+      }
+
+
+      /*  Check each line if it contains valid information */
+
+      const regex *check;
+
+      switch (classification)
+      {
+      case SYSLOG:
+            check = &re_syslog;
+            break;
+      case ACCESSLOG:
+            check = &re_accesslog;
+            break;
+      case ERRORLOG:
+            check = &re_errorlog;
+            break;
+      }
+
+      if (line == *check)
+      {
+         date   log_date;
+         hour   log_time;
+         int    i;
+
+         String insertion("insert into log (objectid, servicecode,"
+                           " object_timestamp, timestamp, rawdata) values (");
+         String datestring;
+
+         switch (classification)
+         {
+         case SYSLOG:
+            log_date = line;
+            log_time = line;
+            if (log_date.Year() < 0 || log_date.Year() > 2500)
+            {
+               //  The year is not in the log file. Assume the year of arrival
+
+               log_date = date(log_date.Day(), log_date.Month(), date(arrival).Year());
+            }
+
+            if (verbose)
+            {
+               cout << "   Log timestamp  = " << log_date << " " << log_time << "\n";
+            }
+            rest = line << 16;
+            i = rest.index(' ');
+            if (rest(0,i) == hostname(0,i))
+            {
+               rest <<= i + 1;
+               if (verbose)
+               {
+                  cout << "   Hostname matches.\n";
+                  cout << "   rest = " << rest << "\n";
+               }
+               for (i = 0; isalpha(rest[i]) && i < ~rest; i++);
+               if (verbose)
+               {
+                  cout << "   Service name = " << rest(0,i) << "\n";
+               }
+
+               /*   Insert a new record into the log table   */
+
+               insertion += "'" + objectid + "',";
+               insertion += "'" + rest(0,i) + "',";
+               insertion += "'" + log_date.format() + " " + log_time.format() + "',";
+               insertion += "'" + arrival.format() + "',";
+               insertion += "'" + SQL_Escape(line) + "'";
+               insertion += ")";
+            
+               if (testmode)
+               {
+                  cout << insertion << "\n";
+               }
+               else
+               {
+                  database.Query(insertion);
+               }
+
+               if (verbose)
+               {
+                  cout << "\n\n";
+               }
+
+               nr_lines++;
+            }
+            else
+            {
+               cerr << "   Hostname " << rest(0,i) << " does not match.\n";
+            }
+            break;
+
+         case ACCESSLOG:
+            datestring = line(regex("\\[.+\\]"));
+            datestring <<= 1;
+            datestring >>= 1;
+            datestring[datestring.index(':')] = ' ';
+            log_date = datestring;
+            log_time = datestring;
+            if (verbose)
+            {
+               cout << "   Log timestamp  = " << log_date << " " << log_time << "\n";
+            }
+            insertion += "'" + objectid + "',";
+            insertion += "'" + service + "',";
+            insertion += "'" + log_date.format() + " " + log_time.format() + "',";
+            insertion += "'" + arrival.format() + "',";
+            insertion += "'" + SQL_Escape(line) + "'";
+            insertion += ")";
+            
+            if (testmode)
+            {
+               cout << insertion << "\n";
+            }
+            else
+            {
+               database.Query(insertion);
+            }
+
+            if (verbose)
+            {
+               cout << "\n\n";
+            }
+
+            nr_lines++;
+            break;
+
+         case ERRORLOG:
+            datestring = line(regex("\\[.+\\]"));
+            datestring <<= 1;
+            datestring >>= 1;
+            log_date = datestring;
+            log_time = datestring;
+            if (verbose)
+            {
+               cout << "   Log timestamp  = " << log_date << " " << log_time << "\n";
+            }
+            insertion += "'" + objectid + "',";
+            insertion += "'" + service + "',";
+            insertion += "'" + log_date.format() + " " + log_time.format() + "',";
+            insertion += "'" + arrival.format() + "',";
+            insertion += "'" + SQL_Escape(line) + "'";
+            insertion += ")";
+            
+            if (testmode)
+            {
+               cout << insertion << "\n";
+            }
+            else
+            {
+               database.Query(insertion);
+            }
+
+            if (verbose)
+            {
+               cout << "\n\n";
+            }
+
+            nr_lines++;
+            break;
+         }
+      }
+      else
+      {
+         cerr << "gcm_input WARNING: Not a valid line: " << line << "\n";
+      }
+   }
+
+   if (verbose)
+   {
+      cout << nr_lines << " lines parsed from the log file.\n";
+   }
+   return nr_lines;
+}
+
+/*=========================================================================
+**  NAME           : SQL_Escape
+**  SYNOPSIS       : String SQL_Escape(String)
+**  PARAMETERS     : 
+**  RETURN VALUE   : 
+**
+**  DESCRIPTION    : Insert backslashes before single quotes.
+**
+**  VARS USED      :
+**  VARS CHANGED   :
+**  FUNCTIONS USED :
+**  SEE ALSO       :
+**  LAST MODIFIED  : 
+**=========================================================================
+*/
+
+String SQL_Escape(String s)
+{
+   int i;
+
+   for (i = 0; i < ~s; i++)
+   {
+      if (s[i] == '\'')
+      {
+         s(i,0) = "\\";
+         i++;
+      }
+   }
+
+   return s;
+}
diff --git a/src/gcm_input/message.h b/src/gcm_input/message.h
new file mode 100644 (file)
index 0000000..03a8209
--- /dev/null
@@ -0,0 +1,150 @@
+
+/**************************************************************************
+**  (c) Copyright 2002, Andromeda Technology & Automation
+***************************************************************************
+** MODULE INFORMATION *
+***********************
+**      FILE NAME      : message.h
+**      SYSTEM NAME    : 
+**      VERSION NUMBER : $Revision: 1.1 $
+**
+**  DESCRIPTION      :  Classes to for handling client messages
+**
+**  EXPORTED OBJECTS : 
+**  LOCAL    OBJECTS : 
+**  MODULES  USED    :
+***************************************************************************
+**  ADMINISTRATIVE INFORMATION *
+********************************
+**      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
+**      CREATION DATE   : Sep 16, 2002
+**      LAST UPDATE     : Oct 05, 2002
+**      MODIFICATIONS   : 
+**************************************************************************/
+
+/*****************************
+   $Log: message.h,v $
+   Revision 1.1  2002-10-05 10:25:49  arjen
+   Creation of gcm_input and a first approach to a web interface
+
+*****************************/
+
+/* static const char *RCSID = "$Id: message.h,v 1.1 2002-10-05 10:25:49 arjen Exp $"; */
+
+#include <iostream>
+#include <list>
+#include <AXE/String.h>
+#include <AXE/date.h>
+
+#include "database.h"
+
+/*
+///////////////////////////////////////////////////////////////////////////
+//  NAME           : message_buffer
+//  BASECLASS      : 
+//  MEMBERS        :
+//  OPERATORS      :
+//  METHODS        : rewind()
+//
+//  DESCRIPTION    : 
+//
+//  RELATIONS      :
+//  SEE ALSO       :
+//  LAST MODIFIED  : Sep 30, 2002
+///////////////////////////////////////////////////////////////////////////
+*/
+
+class message_buffer
+{
+   istream       *input;
+   list<String>  buffer;
+
+   list<String>::iterator   next_line;
+
+public:
+
+   message_buffer()
+   {
+      input = 0;
+      next_line = buffer.begin();
+   }
+
+   message_buffer(istream *in)
+   {
+      input = in;
+      next_line = buffer.begin();
+   }
+
+   void from(istream *in)
+   {
+      input = in;
+   }
+
+   friend bool operator >> (message_buffer &, String &);
+
+   void rewind()
+   {
+      next_line = buffer.begin();
+   }
+
+   void operator ++()
+   {
+      if (next_line != buffer.end())
+      {
+         next_line++;
+      }
+   }
+
+   void operator --()
+   {
+      if (next_line != buffer.begin())
+      {
+         next_line--;
+      }
+   }
+};
+
+/*
+///////////////////////////////////////////////////////////////////////////
+//  NAME           : client_message
+//  BASECLASS      : 
+//  MEMBERS        :
+//  OPERATORS      :
+//  METHODS        : classify()
+//                   enter()
+//
+//  DESCRIPTION    : 
+//
+//  RELATIONS      :
+//  SEE ALSO       :
+//  LAST MODIFIED  : Oct 05, 2002
+///////////////////////////////////////////////////////////////////////////
+*/
+
+class client_message
+{
+   String     hostname;      //  Where the message came from (FQDN)
+   UTC        arrival;       //  When we got the message.
+   String     service;       //  Service that created the message
+
+   bool       mail_header;   //  Does the message contain a mail header ?
+   bool       gpg_encrypted; //  Is the message encrypted ?
+
+   double     certainty;     //  How certain are we about the message
+   enum
+   {
+      UNKNOWN, SYSLOG, ACCESSLOG, ERRORLOG
+   }  classification;
+
+
+   message_buffer    input;
+   gnucomo_database  database;
+
+public:
+
+   client_message(istream *in, gnucomo_database db);
+
+   double classify(String host, UTC arrival = Now(), String serv = "");
+   int    enter();
+};
+
diff --git a/src/gnucomo.conf b/src/gnucomo.conf
new file mode 100644 (file)
index 0000000..90499ef
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version='1.0'?>
+<gnucomo version='0.0.0'>
+   <database>
+      <type>PostgreSQL</type>
+      <name>gnucomo</name>
+      <user>arjen</user>
+      <password>guess again :-)</password>
+      <host>localhost</host>
+      <port>5432</port>
+   </database>
+</gnucomo>
+
diff --git a/src/include/database.h b/src/include/database.h
new file mode 100644 (file)
index 0000000..5fb2323
--- /dev/null
@@ -0,0 +1,91 @@
+
+/**************************************************************************
+**  (c) Copyright 2002, Andromeda Technology & Automation
+***************************************************************************
+** MODULE INFORMATION *
+***********************
+**      FILE NAME      : database.h
+**      SYSTEM NAME    : 
+**      VERSION NUMBER : $Revision: 1.1 $
+**
+**  DESCRIPTION      :  Classes to provide an abstract layer on the Gnucomo
+**                      database.
+**
+**  EXPORTED OBJECTS : 
+**  LOCAL    OBJECTS : 
+**  MODULES  USED    :
+***************************************************************************
+**  ADMINISTRATIVE INFORMATION *
+********************************
+**      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
+**      CREATION DATE   : Sep 10, 2002
+**      LAST UPDATE     : 
+**      MODIFICATIONS   : 
+**************************************************************************/
+
+/*****************************
+   $Log: database.h,v $
+   Revision 1.1  2002-10-05 10:25:49  arjen
+   Creation of gcm_input and a first approach to a web interface
+
+*****************************/
+
+/* static const char *RCSID = "$Id: database.h,v 1.1 2002-10-05 10:25:49 arjen Exp $"; */
+
+#include <libpq++/pgdatabase.h>
+#include "gnucomo_config.h"
+
+/*
+///////////////////////////////////////////////////////////////////////////
+//  NAME           : gnucomo_database
+//  BASECLASS      : configuration
+//  MEMBERS        :
+//  OPERATORS      :
+//  METHODS        : Database - Obtain the database access string
+//
+//  DESCRIPTION    : 
+//
+//  RELATIONS      :
+//  SEE ALSO       :
+//  LAST MODIFIED  : Sep 16, 2002
+///////////////////////////////////////////////////////////////////////////
+*/
+
+class gnucomo_database
+{
+   gnucomo_config    *cfg;
+   PgDatabase        *db;
+
+public:
+
+   gnucomo_database()
+   {
+      cfg = 0;
+      db  = 0;
+   }
+
+   gnucomo_database(gnucomo_config *c);  // Use the configuration to connect to the database
+
+   //  Low-level database access functions
+
+   int Query(String qry)
+   {
+      ExecStatusType  result;
+
+      result = db->Exec(qry);
+      if (result == PGRES_TUPLES_OK || result == PGRES_COMMAND_OK)
+      {
+         return db->Tuples();
+      }
+      else
+      {
+         cerr << "Database query error: " << db->ErrorMessage() << "\n";
+         return -1;
+      }
+   }
+
+   //  Return the objectid of the host given its name.
+
+   String find_host(const String hostname);
+};
+
diff --git a/src/include/gnucomo_config.h b/src/include/gnucomo_config.h
new file mode 100644 (file)
index 0000000..4c854be
--- /dev/null
@@ -0,0 +1,59 @@
+
+/**************************************************************************
+**  (c) Copyright 2002, Andromeda Technology & Automation
+***************************************************************************
+** MODULE INFORMATION *
+***********************
+**      FILE NAME      : gnucomo.h
+**      SYSTEM NAME    : 
+**      VERSION NUMBER : $Revision: 1.1 $
+**
+**  DESCRIPTION      :  
+**
+**  EXPORTED OBJECTS : 
+**  LOCAL    OBJECTS : 
+**  MODULES  USED    :
+***************************************************************************
+**  ADMINISTRATIVE INFORMATION *
+********************************
+**      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
+**      CREATION DATE   : Jul 24, 2002
+**      LAST UPDATE     : 
+**      MODIFICATIONS   : 
+**************************************************************************/
+
+/*****************************
+   $Log: gnucomo_config.h,v $
+   Revision 1.1  2002-10-05 10:25:49  arjen
+   Creation of gcm_input and a first approach to a web interface
+
+*****************************/
+
+/* static const char *RCSID = "$Id: gnucomo_config.h,v 1.1 2002-10-05 10:25:49 arjen Exp $"; */
+
+#include <AXE/configuration.h>
+
+/*
+///////////////////////////////////////////////////////////////////////////
+//  NAME           : gnucomo_config
+//  BASECLASS      : configuration
+//  MEMBERS        :
+//  OPERATORS      :
+//  METHODS        : Database - Obtain the database access string
+//
+//  DESCRIPTION    : 
+//
+//  RELATIONS      :
+//  SEE ALSO       :
+//  LAST MODIFIED  :
+///////////////////////////////////////////////////////////////////////////
+*/
+
+class gnucomo_config : public configuration
+{
+
+public:
+
+   String   Database();  // Return the database access string.
+};
+
diff --git a/src/lib/database.cpp b/src/lib/database.cpp
new file mode 100644 (file)
index 0000000..134a536
--- /dev/null
@@ -0,0 +1,106 @@
+
+/**************************************************************************
+**  (c) Copyright 2002, Andromeda Technology & Automation
+***************************************************************************
+** MODULE INFORMATION *
+***********************
+**      FILE NAME      : database.cpp
+**      SYSTEM NAME    : Gnucomo - Gnu Computer Monitoring
+**      VERSION NUMBER : $Revision: 1.1 $
+**
+**  DESCRIPTION      :  Implementation of the gnucomo database classes
+**
+**  EXPORTED OBJECTS : 
+**  LOCAL    OBJECTS : 
+**  MODULES  USED    :
+***************************************************************************
+**  ADMINISTRATIVE INFORMATION *
+********************************
+**      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
+**      CREATION DATE   : Sep 10, 2002
+**      LAST UPDATE     : Sep 26, 2002
+**      MODIFICATIONS   : 
+**************************************************************************/
+
+/*****************************
+   $Log: database.cpp,v $
+   Revision 1.1  2002-10-05 10:25:49  arjen
+   Creation of gcm_input and a first approach to a web interface
+
+*****************************/
+
+static const char *RCSID = "$Id: database.cpp,v 1.1 2002-10-05 10:25:49 arjen Exp $";
+
+#include "database.h"
+
+extern bool verbose;   /*  Defined in the main application */
+
+/*=========================================================================
+**  NAME           : gnucomo_database
+**  SYNOPSIS       : gnucomo_database(gnucomo_config &c);
+**  PARAMETERS     : 
+**  RETURN VALUE   : Database constructor. Establishes a connection with
+**                   the database server.
+**
+**  DESCRIPTION    : 
+**
+**  VARS USED      :
+**  VARS CHANGED   :
+**  FUNCTIONS USED :
+**  SEE ALSO       :
+**  LAST MODIFIED  : Sep 26, 2002
+**=========================================================================
+*/
+
+gnucomo_database::gnucomo_database(gnucomo_config *c)
+{
+   cfg = c;
+
+   if (verbose)
+   {
+      cout <<  "Database connection string = " << cfg->Database() << "\n";
+   }
+
+   db = new PgDatabase(cfg->Database());
+
+   if (db->ConnectionBad())
+   {
+      cerr << "Can not connect to database: " << db->ErrorMessage();
+   }
+}
+
+/*=========================================================================
+**  NAME           : find_host
+**  SYNOPSIS       : String gnucomo_database::find_host(String hostname);
+**  PARAMETERS     : 
+**  RETURN VALUE   : Find a hostname in the 'object' table of the gnucomo database
+**                   and return its object id.
+**                   Return an empty string as objectid if the hostname is
+**                   not found.
+**
+**  DESCRIPTION    : 
+**
+**  VARS USED      :
+**  VARS CHANGED   :
+**  FUNCTIONS USED :
+**  SEE ALSO       :
+**  LAST MODIFIED  : Sep 16, 2002
+**=========================================================================
+*/
+
+String gnucomo_database::find_host(const String hostname)
+{
+   String objectid("");
+   String check_host("select objectid from object where ");
+
+   check_host += "objectname = '";
+   check_host += hostname;
+   check_host += "'";
+
+   if (Query(check_host) > 0)
+   {
+      objectid = String(db->GetValue(0, "objectid"));
+   }
+
+   return objectid;
+}
diff --git a/src/lib/gnucomo_config.cpp b/src/lib/gnucomo_config.cpp
new file mode 100644 (file)
index 0000000..794241e
--- /dev/null
@@ -0,0 +1,91 @@
+
+/**************************************************************************
+**  (c) Copyright 2002, Andromeda Technology & Automation
+***************************************************************************
+** MODULE INFORMATION *
+***********************
+**      FILE NAME      : gnucomo_config.cpp
+**      SYSTEM NAME    : Gnucomo - Gnu Computer Monitoring
+**      VERSION NUMBER : $Revision: 1.1 $
+**
+**  DESCRIPTION      :  Implementation of the gnucomo_config class.
+**
+**  EXPORTED OBJECTS : 
+**  LOCAL    OBJECTS : 
+**  MODULES  USED    :
+***************************************************************************
+**  ADMINISTRATIVE INFORMATION *
+********************************
+**      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
+**      CREATION DATE   : Jul 24, 2002
+**      LAST UPDATE     : Jul 24, 2002
+**      MODIFICATIONS   : 
+**************************************************************************/
+
+/*****************************
+   $Log: gnucomo_config.cpp,v $
+   Revision 1.1  2002-10-05 10:25:49  arjen
+   Creation of gcm_input and a first approach to a web interface
+
+*****************************/
+
+static const char *RCSID = "$Id: gnucomo_config.cpp,v 1.1 2002-10-05 10:25:49 arjen Exp $";
+
+#include "gnucomo_config.h"
+
+
+
+/*=========================================================================
+**  NAME           : Database
+**  SYNOPSIS       : String gnucomo_config::Database()
+**  PARAMETERS     : 
+**  RETURN VALUE   : The database access string
+**
+**  DESCRIPTION    : 
+**
+**  VARS USED      :
+**  VARS CHANGED   :
+**  FUNCTIONS USED :
+**  SEE ALSO       :
+**  LAST MODIFIED  : 
+**=========================================================================
+*/
+
+String gnucomo_config::Database()
+{
+   String param;
+   String access_string("");
+
+   param = find_parameter("database", "name");
+   if (param != "")
+   {
+      access_string += "dbname=" + param;
+   }
+
+   param = find_parameter("database", "user");
+   if (param != "")
+   {
+      access_string += " user=" + param;
+   }
+   param = find_parameter("database", "password");
+   if (param != "")
+   {
+      access_string += " password=" + param;
+   }
+
+   /*  FIXME: This needs a fix in the AXE library first */
+
+   /*
+   param = find_parameter("database", "host");
+   if (param != "")
+   {
+      access_string += " host=" + param;
+   }
+   param = find_parameter("database", "port");
+   if (param != "")
+   {
+      access_string += " port=" + param;
+   }
+*/
+   return access_string;
+}
diff --git a/src/phpclasses/configuration.class.php b/src/phpclasses/configuration.class.php
new file mode 100644 (file)
index 0000000..5d5968e
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+
+
+/*
+///////////////////////////////////////////////////////////////////////////
+//  NAME           : configuration
+//  BASECLASS      :
+//  MEMBERS        : 
+//  OPERATORS      :
+//  METHODS        : read
+//
+//  DESCRIPTION    : Handle configurational parameters for the application.
+//                   Many applications need some permanently stored configurational
+//                   data. The information is usually stored in two places: A system-
+//                   wide configuration file and a configuration file per user.
+//                   The content of the configuration file is in XML format.
+//                   The configuration base class takes care of finding the configuration
+//                   files, e.g. in /etc/app.conf or in /usr/loca/etc/app.conf
+//                   The config files are parsed with the gnome XML parser and a
+//                   framework is provided to find configurational items.
+//
+//  RELATIONS      : 
+//  SEE ALSO       :
+//  LAST MODIFIED  : Jul 29, 2002
+///////////////////////////////////////////////////////////////////////////
+*/
+
+
+class configuration
+{
+   var   $system, $user;
+
+   function configuration()
+   {
+      $system = false;
+      $user   = false;
+   }
+
+   function xmlFindTag($node, $tag)
+   {
+      $element = false;
+      $i = 0;
+
+      while (!$element && $i < sizeof($node))
+      {
+         if ($node[$i]->type == XML_ELEMENT_NODE && $node[$i]->tagname == $tag)
+         {
+            $element = $node[$i];
+         }
+         $i++;
+      }
+
+      return $element;
+   }
+
+   function read($app_name)
+   {
+      $filename = "/etc/" . $app_name . ".conf";
+      $this->system = xmldocfile($filename);
+
+      if (!$this->system)
+      {
+         $filename = "/usr/local/etc/" . $app_name . ".conf";
+         $this->system = xmldocfile($filename);
+      }
+
+      if ($this->system)
+      {
+         $root = $this->system->root();
+
+         if ($root->tagname != $app_name)
+         {
+            print("Configuration error: Wrong configuration file.<br>");
+            $this->system = false;
+         }
+      }
+      else
+      {
+         print("Configuration error: Configuration file for $app_name not found.<br>");
+      }
+   }
+
+   function find_parameter($section, $parameter)
+   {
+      $param_value = "";
+
+      if ($this->system)
+      {
+         $root_node = $this->system->root();
+         $section_node = $this->xmlFindTag($root_node->children(), $section);
+         if ($section_node)
+         {
+            $param_node = $this->xmlFindTag($section_node->children(), $parameter);
+            if ($param_node)
+            {
+               $param_node = $param_node->children();
+            }
+            if ($param_node && $param_node[0]->type == XML_TEXT_NODE)
+            {
+               $param_value = $param_node[0]->content;
+            }
+         }
+      }
+
+      return $param_value;
+   }
+}
+
+?>
diff --git a/src/phpclasses/gnucomo_config.php b/src/phpclasses/gnucomo_config.php
new file mode 100644 (file)
index 0000000..ea57c2f
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+
+require_once('configuration.class.php');
+
+/*
+///////////////////////////////////////////////////////////////////////////
+//  NAME           : gnucomo_config
+//  BASECLASS      : configuration
+//  MEMBERS        :
+//  OPERATORS      :
+//  METHODS        : Database - Obtain the database access string
+//
+//  DESCRIPTION    : 
+//
+//  RELATIONS      :
+//  SEE ALSO       :
+//  LAST MODIFIED  :
+///////////////////////////////////////////////////////////////////////////
+*/
+
+class gnucomo_config extends configuration
+{
+
+   // Return the database access string.
+
+   function Database()
+   {
+      $access_string = "";
+
+      $param = $this->find_parameter("database", "name");
+      if ($param != "")
+      {
+         $access_string .= "dbname=" . $param;
+      }
+
+      $param = $this->find_parameter("database", "user");
+      if ($param != "")
+      {
+         $access_string .= " user=" . $param;
+      }
+
+      $param = $this->find_parameter("database", "password");
+      if ($param != "")
+      {
+         $access_string .= " password=" . $param;
+      }
+
+      $param = $this->find_parameter("database", "host");
+      if ($param != "")
+      {
+         $access_string .= " host=" . $param;
+      }
+
+      $param = $this->find_parameter("database", "port");
+      if ($param != "")
+      {
+         $access_string .= " port=" . $param;
+      }
+      return $access_string;
+   }
+};
+?>
diff --git a/src/web/change.png b/src/web/change.png
new file mode 100644 (file)
index 0000000..d413512
Binary files /dev/null and b/src/web/change.png differ
diff --git a/src/web/classes/configuration.class.php b/src/web/classes/configuration.class.php
new file mode 100644 (file)
index 0000000..5d5968e
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+
+
+/*
+///////////////////////////////////////////////////////////////////////////
+//  NAME           : configuration
+//  BASECLASS      :
+//  MEMBERS        : 
+//  OPERATORS      :
+//  METHODS        : read
+//
+//  DESCRIPTION    : Handle configurational parameters for the application.
+//                   Many applications need some permanently stored configurational
+//                   data. The information is usually stored in two places: A system-
+//                   wide configuration file and a configuration file per user.
+//                   The content of the configuration file is in XML format.
+//                   The configuration base class takes care of finding the configuration
+//                   files, e.g. in /etc/app.conf or in /usr/loca/etc/app.conf
+//                   The config files are parsed with the gnome XML parser and a
+//                   framework is provided to find configurational items.
+//
+//  RELATIONS      : 
+//  SEE ALSO       :
+//  LAST MODIFIED  : Jul 29, 2002
+///////////////////////////////////////////////////////////////////////////
+*/
+
+
+class configuration
+{
+   var   $system, $user;
+
+   function configuration()
+   {
+      $system = false;
+      $user   = false;
+   }
+
+   function xmlFindTag($node, $tag)
+   {
+      $element = false;
+      $i = 0;
+
+      while (!$element && $i < sizeof($node))
+      {
+         if ($node[$i]->type == XML_ELEMENT_NODE && $node[$i]->tagname == $tag)
+         {
+            $element = $node[$i];
+         }
+         $i++;
+      }
+
+      return $element;
+   }
+
+   function read($app_name)
+   {
+      $filename = "/etc/" . $app_name . ".conf";
+      $this->system = xmldocfile($filename);
+
+      if (!$this->system)
+      {
+         $filename = "/usr/local/etc/" . $app_name . ".conf";
+         $this->system = xmldocfile($filename);
+      }
+
+      if ($this->system)
+      {
+         $root = $this->system->root();
+
+         if ($root->tagname != $app_name)
+         {
+            print("Configuration error: Wrong configuration file.<br>");
+            $this->system = false;
+         }
+      }
+      else
+      {
+         print("Configuration error: Configuration file for $app_name not found.<br>");
+      }
+   }
+
+   function find_parameter($section, $parameter)
+   {
+      $param_value = "";
+
+      if ($this->system)
+      {
+         $root_node = $this->system->root();
+         $section_node = $this->xmlFindTag($root_node->children(), $section);
+         if ($section_node)
+         {
+            $param_node = $this->xmlFindTag($section_node->children(), $parameter);
+            if ($param_node)
+            {
+               $param_node = $param_node->children();
+            }
+            if ($param_node && $param_node[0]->type == XML_TEXT_NODE)
+            {
+               $param_value = $param_node[0]->content;
+            }
+         }
+      }
+
+      return $param_value;
+   }
+}
+
+?>
diff --git a/src/web/classes/gnucomo_config.php b/src/web/classes/gnucomo_config.php
new file mode 100644 (file)
index 0000000..ea57c2f
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+
+require_once('configuration.class.php');
+
+/*
+///////////////////////////////////////////////////////////////////////////
+//  NAME           : gnucomo_config
+//  BASECLASS      : configuration
+//  MEMBERS        :
+//  OPERATORS      :
+//  METHODS        : Database - Obtain the database access string
+//
+//  DESCRIPTION    : 
+//
+//  RELATIONS      :
+//  SEE ALSO       :
+//  LAST MODIFIED  :
+///////////////////////////////////////////////////////////////////////////
+*/
+
+class gnucomo_config extends configuration
+{
+
+   // Return the database access string.
+
+   function Database()
+   {
+      $access_string = "";
+
+      $param = $this->find_parameter("database", "name");
+      if ($param != "")
+      {
+         $access_string .= "dbname=" . $param;
+      }
+
+      $param = $this->find_parameter("database", "user");
+      if ($param != "")
+      {
+         $access_string .= " user=" . $param;
+      }
+
+      $param = $this->find_parameter("database", "password");
+      if ($param != "")
+      {
+         $access_string .= " password=" . $param;
+      }
+
+      $param = $this->find_parameter("database", "host");
+      if ($param != "")
+      {
+         $access_string .= " host=" . $param;
+      }
+
+      $param = $this->find_parameter("database", "port");
+      if ($param != "")
+      {
+         $access_string .= " port=" . $param;
+      }
+      return $access_string;
+   }
+};
+?>
diff --git a/src/web/closed_package.png b/src/web/closed_package.png
new file mode 100644 (file)
index 0000000..d786cca
Binary files /dev/null and b/src/web/closed_package.png differ
diff --git a/src/web/exit.png b/src/web/exit.png
new file mode 100644 (file)
index 0000000..86d9c47
Binary files /dev/null and b/src/web/exit.png differ
diff --git a/src/web/functions.php b/src/web/functions.php
new file mode 100755 (executable)
index 0000000..61e64a8
--- /dev/null
@@ -0,0 +1,77 @@
+<? 
+/******************************************************************************************/
+/* global parameters                                                                      */
+/******************************************************************************************/
+       //$pgsqlhost  = "10.10.10.145"; // PostgreSQL server
+       //$pgsqlport  = "5432";         // PostgreSQL port
+       //$dbname     = "gnucomo";      // PostgreSQL database name
+
+/******************************************************************************************/
+/* string function login_form( void )                                                     */
+/*                                                                                        */
+/* returns the login form                                                                 */
+/******************************************************************************************/
+function login_form() {
+
+       $login  = "<div class='login'>";
+       $login .= "<h1 align=\"center\">GNU Computer Monitoring</h1>";
+       $login .= "<center><table>";
+       $login .= "<tr>";
+       $login .= "<td width='50%'><img src='../doc/logo.png' alt='GnuCoMo logo'></td>";
+       $login .= "<td><form name=\"login\" method=\"POST\" action=\"login.php\">";
+       $login .= "    <table>";
+       $login .= "    <tr>";
+       $login .= "    <td>Username</td>";
+       $login .= "    <td><input type=\"text\" name=\"username\"></td>";
+       $login .= "    </tr>";
+       $login .= "    <tr>";
+       $login .= "    <td>Password</td>";
+       $login .= "    <td><input type=\"password\" name=\"password\"></td>";
+       $login .= "    </tr>";
+       $login .= "    <tr>";
+       $login .= "    <td>&nbsp;</td>";
+       $login .= "    <td align=\"right\"><input type=\"submit\" value=\"signin\"></td>";
+       $login .= "    </tr>";
+       $login .= "    </table>";
+       $login .= "    </form>";
+       $login .= "</td>";
+       $login .= "</tr>";
+       $login .= "</table></center>";
+       $login .= "</div>";
+
+       return $login;
+}
+
+/******************************************************************************************/
+/* array function query( resource connection, string sqlquery )                           */
+/*                                                                                        */
+/* gives an array return.                                                                 */
+/* arr[0] = boolean if action completed whitout error, return true otherwise false        */
+/* arr[1] = result  sql query result                                                      */
+/* arr[2] = int     number of rows                                                        */
+/* arr[3] = string  error information                                                     */
+/******************************************************************************************/
+function query( $conn, $sql ) {
+
+       $query_result = pg_exec( $conn, $sql );
+
+       if( $query_result != FALSE ) {
+               $query_nRows = pg_NumRows($query_result);
+               $query_error = pg_errormessage( $conn );
+               return array( TRUE, $query_result, $query_nRows, "" );
+       } else {
+               $query_error = @pg_errormessage( $conn );
+               return array( FALSE, $query_result, 0, $query_error );
+       }
+}
+
+/******************************************************************************************/
+/* void function pgsql_error( string error )                                              */
+/*                                                                                        */
+/* prints an error message                                                                */
+/******************************************************************************************/
+function pgsql_error( $err ) {
+       echo "An error occured. Please contact your systemadministrator.<br>";
+       echo "Error: $err";
+}
+?>
diff --git a/src/web/gnucomo.css b/src/web/gnucomo.css
new file mode 100644 (file)
index 0000000..f4a27fb
--- /dev/null
@@ -0,0 +1,47 @@
+
+body
+{
+   background-color : rgb(80, 120, 100);
+}
+
+h1
+{
+   font-family : sans-serif ;
+   text-align : center ;
+}
+
+h2
+{
+   font-family : sans-serif ;
+}
+
+div.login
+{
+   background : rgb(80, 120, 150) ;
+   border: solid;
+   border-width: thick;
+   border-color : cyan ;
+   padding : 1em;
+   margin : 10% ;
+   width: 80%;
+   text-align : center ;
+}
+table
+{
+   width : 80% ;
+   border-width : medium ;
+   border-style : none ;
+   border-collapse : collapse;
+   padding : 1px ;
+}
+
+td
+{
+   font-family : sans-serif ;
+}
+
+th
+{
+   border-width : thin ;
+   border-style : solid ;
+}
diff --git a/src/web/harddisk.png b/src/web/harddisk.png
new file mode 100644 (file)
index 0000000..981b148
Binary files /dev/null and b/src/web/harddisk.png differ
diff --git a/src/web/index.html b/src/web/index.html
new file mode 100644 (file)
index 0000000..b7a4b12
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel='stylesheet' href='gnucomo.css' type='text/css'>
+<title>GnuCoMo Web Interface</title>
+</head>
+  <frameset rows="80,*" border='0'>
+    <frame name="menubar" frameborder='0' src="menu.html" scrolling="no" noresize>
+    <frame name="main" frameborder='0' src="login.php">
+  </frameset>
+</html>
diff --git a/src/web/log.png b/src/web/log.png
new file mode 100644 (file)
index 0000000..b0783b0
Binary files /dev/null and b/src/web/log.png differ
diff --git a/src/web/login.php b/src/web/login.php
new file mode 100755 (executable)
index 0000000..871bd10
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+session_start();
+require_once('gnucomo_config.php');
+include "functions.php";
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel='stylesheet' href='gnucomo.css' type='text/css'>
+<title>GNUCoMo login</title>
+</head>
+<body>
+<?php
+if( isset($_POST["username"]) and isset($_POST["password"]) and isset($_SESSION['login']) ) {
+       $name   = $_POST["username"];   // PostgreSQL username
+       $passw  = $_POST["password"];   // PostgreSQL user password
+
+   $config = new gnucomo_config;
+
+   $config->read("gnucomo");
+   //echo "Database Access string = " . $config->Database();
+
+   $conn = pg_connect($config->Database());
+
+       // connect to the database
+       //$conn = pg_Connect( "host=$pgsqlhost port=$pgsqlport dbname=$dbname user=$name password=$passw" );
+       if( !$conn ) {
+               echo "Error connecting, try again.";
+               echo login_form();
+               $_SESSION["login"] = true;
+       } else {
+               $sql = "SELECT * FROM user_gnucomo WHERE username='$name' and password='$passw'";
+               $res = query( $conn, $sql );
+
+               if( $res[0] ) {
+                   if ($res[2] == 1)
+                   {
+                       $arr = pg_fetch_array( $res[1], 0 );
+                       $_SESSION["login.ini"] = $arr;
+                   }
+                   else
+                   {
+                       echo "Login incorrect.<br>";
+                   }
+
+                       // user is authorised, step to next page.
+                       echo "Ok!";
+               } else {
+                       pgsql_error( "SQL: error.<br>" . $res[3] );
+               }
+       }
+} else {
+       echo login_form();
+       $_SESSION["login"] = true;
+}
+?>
+</body>
+</html>
diff --git a/src/web/menu.html b/src/web/menu.html
new file mode 100644 (file)
index 0000000..64a9019
--- /dev/null
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel='stylesheet' href='gnucomo.css' type='text/css'>
+<title>GnuCoMo Web Interface</title>
+</head>
+<body>
+   <img src='server.png' alt='Objects'>
+   <img src='user.png' alt='Users'>
+   <img src='closed_package.png' alt='Packages'>
+   <img src='password.png' alt='Change Password'>
+   <img src='exit.png' alt='Logout'>
+   <hr>
+
+</body>
+</html>
diff --git a/src/web/open_package.png b/src/web/open_package.png
new file mode 100644 (file)
index 0000000..62500ad
Binary files /dev/null and b/src/web/open_package.png differ
diff --git a/src/web/password.png b/src/web/password.png
new file mode 100644 (file)
index 0000000..b14045b
Binary files /dev/null and b/src/web/password.png differ
diff --git a/src/web/server.png b/src/web/server.png
new file mode 100644 (file)
index 0000000..d1ade39
Binary files /dev/null and b/src/web/server.png differ
diff --git a/src/web/service.png b/src/web/service.png
new file mode 100644 (file)
index 0000000..41e5f6b
Binary files /dev/null and b/src/web/service.png differ
diff --git a/src/web/user.png b/src/web/user.png
new file mode 100644 (file)
index 0000000..40ac51e
Binary files /dev/null and b/src/web/user.png differ