Debug output to the log stream instead of cerr.
authorarjen <arjen>
Tue, 5 Aug 2003 08:15:00 +0000 (08:15 +0000)
committerarjen <arjen>
Tue, 5 Aug 2003 08:15:00 +0000 (08:15 +0000)
Fixed namespace problems in XPath searches of the DOM.
Moved string utility functions to a separate file.

src/gcm_input/message.cpp
src/gcm_input/string_utils.cpp [new file with mode: 0644]

index 5951f21..363aaa2 100644 (file)
@@ -8,7 +8,7 @@
 ***********************
 **      FILE NAME      : message.cpp
 **      SYSTEM NAME    : Gnucomo - Gnu Computer Monitoring
-**      VERSION NUMBER : $Revision: 1.10 $
+**      VERSION NUMBER : $Revision: 1.11 $
 **
 **  DESCRIPTION      :  Implementation of the message handling classes
 **
 ********************************
 **      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
 **      CREATION DATE   : Sep 16, 2002
-**      LAST UPDATE     : Apr 29, 2003
+**      LAST UPDATE     : Jul 24, 2003
 **      MODIFICATIONS   : 
 **************************************************************************/
 
 /*****************************
    $Log: message.cpp,v $
-   Revision 1.10  2003-04-29 09:16:44  arjen
+   Revision 1.11  2003-08-05 08:15:00  arjen
+   Debug output to the log stream instead of cerr.
+   Fixed namespace problems in XPath searches of the DOM.
+   Moved string utility functions to a separate file.
+
+   Revision 1.10  2003/04/29 09:16:44  arjen
    Read XML input,
    Only cooked log entries for now.
 
@@ -65,7 +70,7 @@
 
 *****************************/
 
-static const char *RCSID = "$Id: message.cpp,v 1.10 2003-04-29 09:16:44 arjen Exp $";
+static const char *RCSID = "$Id: message.cpp,v 1.11 2003-08-05 08:15:00 arjen Exp $";
 
 #include <algorithm>
 #include <libxml/xpath.h>
@@ -74,10 +79,12 @@ static const char *RCSID = "$Id: message.cpp,v 1.10 2003-04-29 09:16:44 arjen Ex
 
 extern bool verbose;   /*  Defined in the main application */
 extern bool testmode;
+extern bool incremental;
+extern std::ostream *log;
 
 /*   Utility functions   */
 
-String SQL_Escape(String s);
+extern String SQL_Escape(String s);
 
 /*=========================================================================
 **  NAME           : operator >>
@@ -155,7 +162,7 @@ static const regex re_mail_Date("^Date:[[:blank:]]+" + mail_date_re);
 static const regex re_mail_MsId("^Message-Id:[[:blank:]]+");
 static const regex re_email_address("[[:alnum:]_.-]+@[[:alnum:]_.-]+");
 static const regex re_email_user("[[:alnum:]_.-]+@");
-static const regex re_xml_header("\?xml .*\?>$");
+static const regex re_xml_header("xml .*\?>$");
 
 /*=========================================================================
 **  NAME           : readXMLinput
@@ -169,7 +176,7 @@ static const regex re_xml_header("\?xml .*\?>$");
 **  VARS CHANGED   :
 **  FUNCTIONS USED :
 **  SEE ALSO       :
-**  LAST MODIFIED  : Apr 28, 2003
+**  LAST MODIFIED  : Jul 24, 2003
 **=========================================================================
 */
 
@@ -178,6 +185,7 @@ int client_message::readXMLinput(String first_line)
    xmlParserCtxtPtr ctxt;
    String           line;
    xmlNodePtr       root, item;
+   xmlNsPtr         namespaces[1];
 
    xmlXPathObjectPtr res;
    xmlXPathContextPtr pathcontext;
@@ -193,29 +201,53 @@ int client_message::readXMLinput(String first_line)
    xmlFreeParserCtxt(ctxt);
 
    root = xmlDocGetRootElement(xmlDom);
+   namespaces[0] = root->ns;
+
    //TODO Ought to check  root->name and  root->ns->href 
 
    pathcontext = xmlXPathNewContext(xmlDom);
    pathcontext->node = xmlDocGetRootElement(xmlDom);
+   pathcontext->namespaces = namespaces;
+   pathcontext->nsNr       = 1;
 
-   res = xmlXPathEval((const xmlChar *)"header/messagetype/text()", pathcontext);
+#ifdef DEBUG
+   xmlDebugDumpNodeList(stdout, pathcontext->node, 0);
+#endif
+
+   res = xmlXPathEval((const xmlChar *)"gcmt:header/gcmt:messagetype/text()", pathcontext);
    if (res->nodesetval != NULL)
    {
+#ifdef DEBUG
+      xmlDebugDumpNodeList(stdout, *res->nodesetval->nodeTab, 0);
+#endif
       item = *res->nodesetval->nodeTab;
    }
-   res = xmlXPathEval((const xmlChar *)"header/hostname/text()", pathcontext);
+   else
+   {
+      *log << "Message type not found in XML header.\n";
+   }
+
+   res = xmlXPathEval((const xmlChar *)"gcmt:header/gcmt:hostname/text()", pathcontext);
    if (res->nodesetval != NULL)
    {
+#ifdef DEBUG
+      xmlDebugDumpNodeList(stdout, *res->nodesetval->nodeTab, 0);
+#endif
       item = *res->nodesetval->nodeTab;
       hostname = (const char *)item->content;
    }
-   res = xmlXPathEval((const xmlChar *)"header/service/text()", pathcontext);
+   else
+   {
+      *log << "Hostname not found in XML header.\n";
+   }
+
+   res = xmlXPathEval((const xmlChar *)"gcmt:header/gcmt:service/text()", pathcontext);
    if (res->nodesetval != NULL)
    {
       item = *res->nodesetval->nodeTab;
       service = (const char *)item->content;
    }
-   res = xmlXPathEval((const xmlChar *)"header/time/text()", pathcontext);
+   res = xmlXPathEval((const xmlChar *)"gcmt:header/gcmt:time/text()", pathcontext);
    if (res->nodesetval != NULL)
    {
       item = *res->nodesetval->nodeTab;
@@ -266,8 +298,9 @@ double client_message::classify(String host, UTC arriv, String serv)
          {
             from_address = line(re_email_address);
             from_address(re_email_user) = "";            //  Remove the user part;
-            if (from_address != "")
+            if (from_address != "" && ~hostname < ~from_address)
             {
+               *log << "Detected hostname " << from_address << "\n";
                hostname = from_address;
             }
          }
@@ -275,9 +308,10 @@ double client_message::classify(String host, UTC arriv, String serv)
          {
             from_address = line(re_email_address);
             from_address(re_email_user) = "";            //  Remove the user part;
-            if (from_address != "")
+            if (from_address != "" && ~hostname < ~from_address)
             {
-              hostname = from_address;
+               *log << "Detected hostname " << from_address << "\n";
+               hostname = from_address;
             }
          }
          if (line == re_mail_Date)
@@ -303,7 +337,7 @@ double client_message::classify(String host, UTC arriv, String serv)
    {
       if (verbose)
       {
-         std::cout << "  testing: " << line << "\n";
+         *log << "  testing: " << line << "\n";
       }
 
       if (line == re_xml_header)
@@ -312,7 +346,7 @@ double client_message::classify(String host, UTC arriv, String serv)
          classification = XML;
          if (verbose)
          {
-            std::cout << "XML input detected.\n";
+            *log << "XML input detected.\n";
          }
          readXMLinput(line);
       }
@@ -322,7 +356,7 @@ double client_message::classify(String host, UTC arriv, String serv)
          classification = SYSLOG;
          if (verbose)
          {
-            std::cout << "Syslog detected.\n";
+            *log << "Syslog detected.\n";
          }
       }
       else if (line == re_syslog_irix)
@@ -331,21 +365,21 @@ double client_message::classify(String host, UTC arriv, String serv)
          classification = SYSLOG_IRIX;
          if (verbose)
          {
-            std::cout << "IRIX Syslog detected.\n";
+            *log << "IRIX Syslog detected.\n";
          }
       }
       else if (line == re_PGP)
       {
          certainty = 1.0;
          gpg_encrypted = true;
-         std::cerr << "The message is PGP/GnuPG encrypted.\n";
+         *log << "The message is PGP/GnuPG encrypted.\n";
       }
       else if (line == re_dump)
       {
           certainty = 1.0;
           if (verbose)
           {
-             std::cout << "DUMP output detected.\n";
+             *log << "DUMP output detected.\n";
           }
       }
       else if (line == re_accesslog)
@@ -355,7 +389,7 @@ double client_message::classify(String host, UTC arriv, String serv)
           service = "httpd";
           if (verbose)
           {
-             std::cout << "HTTP access log detected.\n";
+             *log << "HTTP access log detected.\n";
           }
       }
       else if (line == re_errorlog)
@@ -365,7 +399,7 @@ double client_message::classify(String host, UTC arriv, String serv)
           service = "httpd";
           if (verbose)
           {
-             std::cout << "HTTP error log detected.\n";
+             *log << "HTTP error log detected.\n";
           }
       }
       else if (line == re_rpm)
@@ -375,7 +409,7 @@ double client_message::classify(String host, UTC arriv, String serv)
           service = "";
           if (verbose)
           {
-             std::cout << "RPM package list detected.\n";
+             *log << "RPM package list detected.\n";
           }
       }
    }
@@ -383,12 +417,12 @@ double client_message::classify(String host, UTC arriv, String serv)
 
    if (hostname == "")
    {
-      std::cerr <<  "Can not determine the hostname where the message came from.\n";
+      *log <<  "Can not determine the hostname where the message came from.\n";
       certainty = 0.0;
    }
    else if (!arrival.proper())
    {
-      std::cerr << "Arrival time is not knwon.\n";
+      *log << "Arrival time is not knwon.\n";
       certainty = 0.0;
    }
    else
@@ -412,7 +446,7 @@ double client_message::classify(String host, UTC arriv, String serv)
 **  VARS CHANGED   :
 **  FUNCTIONS USED :
 **  SEE ALSO       :
-**  LAST MODIFIED  : Apr 29, 2003
+**  LAST MODIFIED  : Jul 24, 2003
 **=========================================================================
 */
 
@@ -420,6 +454,7 @@ void client_message::enterXML()
 {
    xmlXPathObjectPtr res;
    xmlXPathContextPtr pathcontext;
+   xmlNsPtr           namespaces[1];
 
    /*  Try to find the host in the database */
 
@@ -428,17 +463,21 @@ void client_message::enterXML()
    objectid = database.find_host(hostname);
    if (objectid == "")
    {
-      std::cerr << "Please define the host " << hostname << " in the database.\n";
+      *log << "Please define the host " << hostname << " in the database.\n";
       return;
    }
    if (verbose)
    {
-      std::cout << "Object id for " << hostname << " is " << objectid << "\n";
+      *log << "Object id for " << hostname << " is " << objectid << "\n";
    }
 
    pathcontext = xmlXPathNewContext(xmlDom);
    pathcontext->node = xmlDocGetRootElement(xmlDom);
-   res = xmlXPathEval((const xmlChar *)"data/node()", pathcontext);
+   namespaces[0] = pathcontext->node->ns;
+   pathcontext->namespaces = namespaces;
+   pathcontext->nsNr       = 1;
+
+   res = xmlXPathEval((const xmlChar *)"gcmt:data/node()", pathcontext);
 
    if (res->nodesetval != NULL)
    {
@@ -460,7 +499,7 @@ void client_message::enterXML()
             {
                if (strcmp((char *)node->name, "raw") == 0)
                {
-                  std::cerr << "Can not cook <raw> log elements yet.\n";
+                  *log << "Can not cook <raw> log elements yet.\n";
                }
                else if (strcmp((char *)node->name, "cooked") == 0)
                {
@@ -474,7 +513,7 @@ void client_message::enterXML()
 
                   if (verbose)
                   {
-                     std::cout << "Analyzing cooked element.\n";
+                     *log << "Analyzing cooked element.\n";
                   }
                   pathcontext->node = node;
 
@@ -485,7 +524,7 @@ void client_message::enterXML()
                      log_hostname = (const char *)item->content;
                      if (log_hostname != hostname(0, ~log_hostname))
                      {
-                        std::cerr << "Hostname " << log_hostname << " does not match.\n";
+                        *log << "Hostname " << log_hostname << " does not match.\n";
                         log_hostname = "";
                      }
                   }
@@ -513,7 +552,7 @@ void client_message::enterXML()
                   }
                   else
                   {
-                     std::cerr << "<timestamp> missing from cooked log element.\n";
+                     *log << "<timestamp> missing from cooked log element.\n";
                   }
 
                   res = xmlXPathEval((const xmlChar *)"raw/text()", pathcontext);
@@ -524,7 +563,7 @@ void client_message::enterXML()
                   }
                   else
                   {
-                     std::cerr << "<raw> missing from cooked log element.\n";
+                     *log << "<raw> missing from cooked log element.\n";
                   }
 
                   if (raw != "" && log_hostname != "" && log_date.proper())
@@ -543,7 +582,7 @@ void client_message::enterXML()
 
                      if (testmode)
                      {
-                        std::cout << insertion << "\n";
+                        *log << insertion << "\n";
                      }
                      else
                      {
@@ -552,7 +591,7 @@ void client_message::enterXML()
 
                      if (verbose)
                      {
-                        std::cout << "\n\n";
+                        *log << "\n\n";
                      }
                   }
                }
@@ -562,12 +601,12 @@ void client_message::enterXML()
       }
       else
       {
-         std::cerr << "Data element " << node->name << " is not supported.\n";
+         *log << "Data element " << node->name << " is not supported.\n";
       }
    }
    else
    {
-      std::cerr << "Data node not found.\n";
+      *log << "Data node not found.\n";
    }
 }
 
@@ -583,7 +622,7 @@ void client_message::enterXML()
 **  VARS CHANGED   :
 **  FUNCTIONS USED :
 **  SEE ALSO       :
-**  LAST MODIFIED  : Mar 28, 2003
+**  LAST MODIFIED  : Jul 24, 2003
 **=========================================================================
 */
 
@@ -627,12 +666,12 @@ int client_message::enter()
    objectid = database.find_host(hostname);
    if (objectid == "")
    {
-      std::cerr << "Please define the host " << hostname << " in the database.\n";
+      *log << "Please define the host " << hostname << " in the database.\n";
       return 0;
    }
    if (verbose)
    {
-      std::cout << "Object id for " << hostname << " is " << objectid << "\n";
+      *log << "Object id for " << hostname << " is " << objectid << "\n";
    }
 
    if (classification == RPMLIST)
@@ -648,12 +687,16 @@ int client_message::enter()
       n_packages = database.Query(qry);
       initial_entry = n_packages == 0;
 
-      std::cout << n_packages << " packages in database.\n";
+#ifdef DEBUG
+      *log << n_packages << " packages in database.\n";
+#endif
       for (int t = 0; t < n_packages; t++)
       {
          packages.push_back(database.Field(t, "name"));
       }
-      std::cout << "Package list built: " << packages.size() << ".\n";
+#ifdef DEBUG
+      *log << "Package list built: " << packages.size() << ".\n";
+#endif
    }
 
    /*  Scan the input line by line, entring records into the database */
@@ -664,7 +707,7 @@ int client_message::enter()
    {
       if (verbose)
       {
-         std::cout << line << "\n";
+         *log << line << "\n";
       }
 
 
@@ -704,8 +747,9 @@ int client_message::enter()
          switch (classification)
          {
          case SYSLOG:
-            log_date = line;
-            log_time = line;
+            datestring = line(0,16);
+            log_date = datestring;
+            log_time = datestring;
             if (log_date.Year() < 0 || log_date.Year() > 2500)
             {
                //  The year is not in the log file. Assume the year of arrival,
@@ -721,7 +765,7 @@ int client_message::enter()
 
             if (verbose)
             {
-               std::cout << "   Log timestamp  = " << log_date << " " << log_time << "\n";
+               *log << "   Log timestamp  = " << log_date << " " << log_time << "\n";
             }
             rest = line << 16;
             i = rest.index(' ');
@@ -730,13 +774,13 @@ int client_message::enter()
                rest <<= i + 1;
                if (verbose)
                {
-                  std::cout << "   Hostname matches.\n";
-                  std::cout << "   rest = " << rest << "\n";
+                  *log << "   Hostname matches.\n";
+                  *log << "   rest = " << rest << "\n";
                }
                for (i = 0; isalpha(rest[i]) && i < ~rest; i++);
                if (verbose)
                {
-                  std::cout << "   Service name = " << rest(0,i) << "\n";
+                  *log << "   Service name = " << rest(0,i) << "\n";
                }
 
                /*   Insert a new record into the log table   */
@@ -750,7 +794,7 @@ int client_message::enter()
 
                if (testmode)
                {
-                  std::cout << insertion << "\n";
+                  *log << insertion << "\n";
                }
                else
                {
@@ -759,20 +803,21 @@ int client_message::enter()
 
                if (verbose)
                {
-                  std::cout << "\n\n";
+                  *log << "\n\n";
                }
 
                nr_lines++;
             }
             else
             {
-               std::cerr << "   Hostname " << rest(0,i) << " does not match.\n";
+               *log << "   Hostname " << rest(0,i) << " does not match.\n";
             }
             break;
 
          case SYSLOG_IRIX:
-            log_date = line;
-            log_time = line;
+            datestring = line(0,16);
+            log_date = datestring;
+            log_time = datestring;
             if (log_date.Year() < 0 || log_date.Year() > 2500)
             {
                //  The year is not in the log file. Assume the year of arrival,
@@ -788,7 +833,7 @@ int client_message::enter()
 
             if (verbose)
             {
-               std::cout << "   Log timestamp  = " << log_date << " " << log_time << "\n";
+               *log << "   Log timestamp  = " << log_date << " " << log_time << "\n";
             }
             rest = line << 19;
             i = rest.index(' ');
@@ -797,13 +842,13 @@ int client_message::enter()
                rest <<= i + 1;
                if (verbose)
                {
-                  std::cout << "   Hostname matches.\n";
-                  std::cout << "   rest = " << rest << "\n";
+                  *log << "   Hostname matches.\n";
+                  *log << "   rest = " << rest << "\n";
                }
                for (i = 0; isalpha(rest[i]) && i < ~rest; i++);
                if (verbose)
                {
-                  std::cout << "   Service name = " << rest(0,i) << "\n";
+                  *log << "   Service name = " << rest(0,i) << "\n";
                }
 
                /*   Insert a new record into the log table   */
@@ -817,7 +862,7 @@ int client_message::enter()
 
                if (testmode)
                {
-                  std::cout << insertion << "\n";
+                  *log << insertion << "\n";
                }
                else
                {
@@ -826,14 +871,14 @@ int client_message::enter()
 
                if (verbose)
                {
-                  std::cout << "\n\n";
+                  *log << "\n\n";
                }
 
                nr_lines++;
             }
             else
             {
-               std::cerr << "   Hostname " << rest(0,i) << " does not match.\n";
+               *log << "   Hostname " << rest(0,i) << " does not match.\n";
             }
             break;
 
@@ -846,7 +891,7 @@ int client_message::enter()
             log_time = datestring;
             if (verbose)
             {
-               std::cout << "   Log timestamp  = " << log_date << " " << log_time << "\n";
+               *log << "   Log timestamp  = " << log_date << " " << log_time << "\n";
             }
             insertion += "'" + objectid + "',";
             insertion += "'" + service + "',";
@@ -857,7 +902,7 @@ int client_message::enter()
 
             if (testmode)
             {
-               std::cout << insertion << "\n";
+               *log << insertion << "\n";
             }
             else
             {
@@ -866,7 +911,7 @@ int client_message::enter()
 
             if (verbose)
             {
-               std::cout << "\n\n";
+               *log << "\n\n";
             }
 
             nr_lines++;
@@ -880,7 +925,7 @@ int client_message::enter()
             log_time = datestring;
             if (verbose)
             {
-               std::cout << "   Log timestamp  = " << log_date << " " << log_time << "\n";
+               *log << "   Log timestamp  = " << log_date << " " << log_time << "\n";
             }
             insertion += "'" + objectid + "',";
             insertion += "'" + service + "',";
@@ -891,7 +936,7 @@ int client_message::enter()
 
             if (testmode)
             {
-               std::cout << insertion << "\n";
+               *log << insertion << "\n";
             }
             else
             {
@@ -900,7 +945,7 @@ int client_message::enter()
 
             if (verbose)
             {
-               std::cout << "\n\n";
+               *log << "\n\n";
             }
 
             nr_lines++;
@@ -951,8 +996,8 @@ int client_message::enter()
 
             if (verbose)
             {
-               std::cout << "Package is " << package;
-               std::cout << ", version is " << version << "\n";
+               *log << "Package is " << package;
+               *log << ", version is " << version << "\n";
             }
 
             //  Construct a qry to check the package's existance
@@ -972,7 +1017,7 @@ int client_message::enter()
                }
                else
                {
-                  std::cerr <<  "Could NOT find " << package << " in list.\n";
+                  *log <<  "Could NOT find " << package << " in list.\n";
                }
 
                paramid = database.Field(0, "paramid");
@@ -980,14 +1025,14 @@ int client_message::enter()
                qry += paramid + "' and name='version'";
                if (database.Query(qry) == 0)
                {
-                  std::cerr << "Database corruption: Package " << package;
-                  std::cerr << " does not have a 'version' property.\n";
+                  *log << "Database corruption: Package " << package;
+                  *log << " does not have a 'version' property.\n";
                }
                else if (database.Field(0, "value") != version)
                {
                   if (verbose)
                   {
-                     std::cout << "  Parameter " << package << " has different version\n";
+                     *log << "  Parameter " << package << " has different version\n";
                   }
                   insertion = "update property set value='";
                   insertion += version + "' where paramid='";
@@ -1017,14 +1062,14 @@ int client_message::enter()
                   }
                   else
                   {
-                     std::cerr << "gcm_input ERROR: Cannot create 'property modified' notification.\n";
+                     *log << "gcm_input ERROR: Cannot create 'property modified' notification.\n";
                   }
                }
                else
                {
                   if (verbose)
                   {
-                     std::cout << "   Parameter " << package << " has not changed.\n";
+                     *log << "   Parameter " << package << " has not changed.\n";
                   }
                }
             }
@@ -1033,7 +1078,7 @@ int client_message::enter()
 
                if (verbose)
                {
-                  std::cout << "  Parameter " << package << " does not exist.\n";
+                  *log << "  Parameter " << package << " does not exist.\n";
                }
                //  Create a new package parameter, including version property and history record
 
@@ -1042,7 +1087,7 @@ int client_message::enter()
                if (testmode)
                {
                   paramid = "0";
-                  std::cout << insertion << "\n";
+                  *log << insertion << "\n";
                }
                else
                {
@@ -1064,7 +1109,7 @@ int client_message::enter()
 
                if (testmode)
                {
-                  std::cout << insertion << "\n" << insert_h << "\n";
+                  *log << insertion << "\n" << insert_h << "\n";
                }
                else
                {
@@ -1087,7 +1132,7 @@ int client_message::enter()
                      }
                      else
                      {
-                        std::cerr << "gcm_input ERROR: Cannot create 'parameter created' notification.\n";
+                        *log << "gcm_input ERROR: Cannot create 'parameter created' notification.\n";
                      }
                   }
                }
@@ -1095,7 +1140,7 @@ int client_message::enter()
 
             if (verbose)
             {
-               std::cout << "\n";
+               *log << "\n";
             }
 
             nr_lines++;
@@ -1105,11 +1150,11 @@ int client_message::enter()
       }
       else
       {
-         std::cerr << "gcm_input WARNING: Not a valid line: " << line << "\n";
+         *log << "gcm_input WARNING: Not a valid line: " << line << "\n";
       }
    }
 
-   if (classification == RPMLIST)
+   if (classification == RPMLIST && !incremental)
    {
       std::list<String>::iterator  lp;
       String     remove_notification("");
@@ -1138,13 +1183,13 @@ int client_message::enter()
             qry += paramid + "' order by modified desc";
             if (database.Query(qry) <= 0)
             {
-               std::cerr << "Database ERROR: no history record for parameter " << *lp << ".\n";
+               *log << "Database ERROR: no history record for parameter " << *lp << ".\n";
             }
             else if (database.Field(0, "change_nature") != "REMOVED")
             {
                if (verbose)
                {
-                 std::cout << "Removing parameter " << *lp << ".\n";
+                 *log << "Removing parameter " << *lp << ".\n";
                }
 
                insert = "insert into history (paramid, modified, change_nature)";
@@ -1169,7 +1214,7 @@ int client_message::enter()
                }
                else
                {
-                  std::cerr << "gcm_input ERROR: Cannot create 'parameter removed' notification.\n";
+                  *log << "gcm_input ERROR: Cannot create 'parameter removed' notification.\n";
                }
             }
          }
@@ -1178,39 +1223,7 @@ int client_message::enter()
 
    if (verbose)
    {
-      std::cout << nr_lines << " lines parsed from the log file.\n";
+      *log << 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/string_utils.cpp b/src/gcm_input/string_utils.cpp
new file mode 100644 (file)
index 0000000..56010a1
--- /dev/null
@@ -0,0 +1,115 @@
+
+/**************************************************************************
+**  (c) Copyright 2003, Andromeda Technology & Automation
+** This is free software; you can redistribute it and/or modify it under the
+** terms of the GNU General Public License, see the file COPYING.
+***************************************************************************
+** MODULE INFORMATION *
+***********************
+**      FILE NAME      : string_utils.cpp
+**      SYSTEM NAME    : Gnucomo - Gnu Computer Monitoring
+**      VERSION NUMBER : $Revision: 1.1 $
+**
+**  DESCRIPTION      :  Utility functions for Strings
+**
+**  EXPORTED OBJECTS : 
+**  LOCAL    OBJECTS : 
+**  MODULES  USED    :
+***************************************************************************
+**  ADMINISTRATIVE INFORMATION *
+********************************
+**      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
+**      CREATION DATE   : Jul 31, 2003
+**      LAST UPDATE     : Jul 31, 2003
+**      MODIFICATIONS   : 
+**************************************************************************/
+
+/*****************************
+   $Log: string_utils.cpp,v $
+   Revision 1.1  2003-08-05 08:15:01  arjen
+   Debug output to the log stream instead of cerr.
+   Fixed namespace problems in XPath searches of the DOM.
+   Moved string utility functions to a separate file.
+
+*****************************/
+
+static const char *RCSID = "$Id: string_utils.cpp,v 1.1 2003-08-05 08:15:01 arjen Exp $";
+
+#include <AXE/String.h>
+
+/*=========================================================================
+**  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;
+}
+
+/*=========================================================================
+**  NAME           : XML_Entities
+**  SYNOPSIS       : String XML_Entities(String)
+**  PARAMETERS     : 
+**  RETURN VALUE   : 
+**
+**  DESCRIPTION    : Replace special characters for XML with their entity codes:
+**                          "<"  =>   "&lt;"
+**                          ">"  =>   "&gt;"
+**                          "&"  =>   "&amp;"
+**
+**  VARS USED      :
+**  VARS CHANGED   :
+**  FUNCTIONS USED :
+**  SEE ALSO       :
+**  LAST MODIFIED  : 
+**=========================================================================
+*/
+
+String XML_Entities(String s)
+{
+   int i;
+
+   for (i = 0; i < ~s; i++)
+   {
+      switch (s[i])
+      {
+      case '&':
+         s(i,1) = "&amp;";
+         i++;
+         break;
+      case '<':
+         s(i,1) = "&lt;";
+         i++;
+         break;
+      case '>':
+         s(i,1) = "&gt;";
+         i++;
+         break;
+      }
+   }
+
+   return s;
+}