+
+/**************************************************************************
+** (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 : message_filter.cpp
+** 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 : Nov 26, 2003
+** LAST UPDATE : Nov 26, 2003
+** MODIFICATIONS :
+**************************************************************************/
+
+/*****************************
+ $Log: message_filter.cpp,v $
+ Revision 1.1 2003-12-04 10:38:09 arjen
+ Major redesign. All input is handled through XML. Raw input data is first
+ transformed into an XML document for further processing.
+ A collection of polymorphic classes handle the transformation of various
+ input formats into XML.
+ Classifying input data is done with a finite improbability calculation.
+
+*****************************/
+
+/* static const char *RCSID = "$Id: message_filter.cpp,v 1.1 2003-12-04 10:38:09 arjen Exp $"; */
+
+#include "message_filter.h"
+
+extern std::ostream *Log;
+
+/*=========================================================================
+** NAME : constructXML
+** SYNOPSIS : int constructXML(message_buffer &in, std::strstream &xml)
+** PARAMETERS :
+** RETURN VALUE :
+**
+** DESCRIPTION : Copy the input stream into the internal XML buffer
+** The input is already in XML format, so no real transformation
+** is needed.
+**
+** VARS USED :
+** VARS CHANGED :
+** FUNCTIONS USED :
+** SEE ALSO :
+** LAST MODIFIED : Nov 26, 2003
+**=========================================================================
+*/
+
+void message_filter::construct_XML(message_buffer &in, std::strstream &xml)
+{
+ String line;
+
+ while (in >> line)
+ {
+ xml << line << "\n";
+ }
+}
+
+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_uxmail_from("^From [^ \t]+[ ]+" + 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_mail_MsId("^Message-Id:[[:blank:]]+");
+static const regex re_email_address("[[:alnum:]_.-]+@[[:alnum:]_.-]+");
+static const regex re_email_user("[[:alnum:]_.-]+@");
+
+/*=========================================================================
+** NAME : scan_email_header
+** SYNOPSIS : void scan_email_header(message_buffer &in)
+** PARAMETERS :
+** RETURN VALUE :
+**
+** DESCRIPTION :
+**
+** VARS USED :
+** VARS CHANGED :
+** FUNCTIONS USED :
+** SEE ALSO :
+** LAST MODIFIED : Nov 26, 2003
+**=========================================================================
+*/
+
+void message_filter::scan_email_header(message_buffer &in)
+{
+ String line;
+
+ /* First, check if the message has a mail header. */
+
+ if (in >> line && line == re_uxmail_from)
+ {
+ String from_address;
+
+ /* Scan ahead for the hostname and date of arrival. */
+
+ while (in >> line && line != "")
+ {
+
+ if (line == re_mail_From)
+ {
+ from_address = line(re_email_address);
+ from_address(re_email_user) = ""; // Remove the user part;
+ if (from_address != "" && ~hn < ~from_address)
+ {
+ *Log << "Detected hostname " << from_address << "\n";
+ hn = from_address;
+ }
+ }
+ if (line == re_mail_MsId)
+ {
+ from_address = line(re_email_address);
+ from_address(re_email_user) = ""; // Remove the user part;
+ if (from_address != "" && ~hn < ~from_address)
+ {
+ *Log << "Detected hostname " << from_address << "\n";
+ hn = from_address;
+ }
+ }
+ if (line == re_mail_Date)
+ {
+ ts = UTC(line(regex(mail_date_re)));
+ }
+ }
+ }
+ else
+ {
+ // Push the first line back, we need to read it again.
+ --in;
+
+ }
+
+}
+
+/*=========================================================================
+** NAME : construct_header
+** SYNOPSIS : void construct_header(std::strstream &xml)
+** PARAMETERS :
+** RETURN VALUE :
+**
+** DESCRIPTION : Create the header for a Gnucomo XML document.
+**
+** VARS USED :
+** VARS CHANGED :
+** FUNCTIONS USED :
+** SEE ALSO :
+** LAST MODIFIED : Nov 26, 2003
+**=========================================================================
+*/
+
+void message_filter::construct_header(std::strstream &xml)
+{
+ //xml << "<?xml version='1.0' encoding='utf-8'?>\n";
+ xml << "<?xml version='1.0' encoding='ISO-8859-1'?>\n";
+ xml << "<gcmt:message xmlns:gcmt='http://gnucomo.org/transport/'>\n";
+ xml << " <gcmt:header>\n";
+ xml << " <gcmt:messagetype>" << mt << "</gcmt:messagetype>\n";
+ xml << " <gcmt:hostname>" << hn << "</gcmt:hostname>\n";
+ xml << " <gcmt:service>" << srv << "</gcmt:service>\n";
+ xml << " <gcmt:time>" << ts << "</gcmt:time>\n";
+ xml << " </gcmt:header>\n";
+}