Skip the Email header when reading XML input.
[gnucomo.git] / src / gcm_input / message_filter.cpp
1
2 /**************************************************************************
3 **  (c) Copyright 2003, Andromeda Technology & Automation
4 ** This is free software; you can redistribute it and/or modify it under the
5 ** terms of the GNU General Public License, see the file COPYING.
6 ***************************************************************************
7 ** MODULE INFORMATION *
8 ***********************
9 **      FILE NAME      : message_filter.cpp
10 **      SYSTEM NAME    : 
11 **      VERSION NUMBER : $Revision: 1.2 $
12 **
13 **  DESCRIPTION      :  
14 **
15 **  EXPORTED OBJECTS : 
16 **  LOCAL    OBJECTS : 
17 **  MODULES  USED    :
18 ***************************************************************************
19 **  ADMINISTRATIVE INFORMATION *
20 ********************************
21 **      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
22 **      CREATION DATE   : Nov 26, 2003
23 **      LAST UPDATE     : May 02, 2007
24 **      MODIFICATIONS   : 
25 **************************************************************************/
26
27 /*****************************
28    $Log: message_filter.cpp,v $
29    Revision 1.2  2007-05-06 08:39:06  arjen
30    Skip the Email header when reading XML input.
31
32    Revision 1.1  2003/12/04 10:38:09  arjen
33    Major redesign. All input is handled through XML. Raw input data is first
34    transformed into an XML document for further processing.
35    A collection of polymorphic classes handle the transformation of various
36    input formats into XML.
37    Classifying input data is done with a finite improbability calculation.
38
39 *****************************/
40
41 /* static const char *RCSID = "$Id: message_filter.cpp,v 1.2 2007-05-06 08:39:06 arjen Exp $"; */
42
43 #include "message_filter.h"
44
45 extern std::ostream *Log;
46
47 /*=========================================================================
48 **  NAME           : constructXML
49 **  SYNOPSIS       : int constructXML(message_buffer &in, std::strstream &xml)
50 **  PARAMETERS     : 
51 **  RETURN VALUE   : 
52 **
53 **  DESCRIPTION    : Copy the input stream into the internal XML buffer
54 **                   The input is already in XML format, so no real transformation
55 **                   is needed.
56 **
57 **  VARS USED      :
58 **  VARS CHANGED   :
59 **  FUNCTIONS USED :
60 **  SEE ALSO       :
61 **  LAST MODIFIED  : May 02, 2007
62 **=========================================================================
63 */
64
65 void message_filter::construct_XML(message_buffer &in, std::strstream &xml)
66 {
67    String line;
68
69    scan_email_header(in);
70
71    while (in >> line)
72    {
73       xml << line << "\n";
74    }
75 }
76
77 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}");
78 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}");
79 static const regex re_uxmail_from("^From [^ \t]+[ ]+" + unix_date_re);
80 static const regex re_mail_From("^From:[[:blank:]]+");
81 static const regex re_mail_Date("^Date:[[:blank:]]+" + mail_date_re);
82 static const regex re_mail_MsId("^Message-Id:[[:blank:]]+");
83 static const regex re_email_address("[[:alnum:]_.-]+@[[:alnum:]_.-]+");
84 static const regex re_email_user("[[:alnum:]_.-]+@");
85
86 /*=========================================================================
87 **  NAME           : scan_email_header
88 **  SYNOPSIS       : void scan_email_header(message_buffer &in)
89 **  PARAMETERS     : 
90 **  RETURN VALUE   : 
91 **
92 **  DESCRIPTION    : 
93 **
94 **  VARS USED      :
95 **  VARS CHANGED   :
96 **  FUNCTIONS USED :
97 **  SEE ALSO       :
98 **  LAST MODIFIED  : Nov 26, 2003
99 **=========================================================================
100 */
101
102 void message_filter::scan_email_header(message_buffer &in)
103 {
104    String line;
105
106    /*  First, check if the message has a mail header. */
107
108    if (in >> line && line == re_uxmail_from)
109    {
110       String    from_address;
111
112       /*  Scan ahead for the hostname and date of arrival.  */
113
114       while (in >> line && line != "")
115       {
116
117          if (line == re_mail_From)
118          {
119             from_address = line(re_email_address);
120             from_address(re_email_user) = "";            //  Remove the user part;
121             if (from_address != "" && ~hn < ~from_address)
122             {
123                *Log << "Detected hostname " << from_address << "\n";
124                hn = from_address;
125             }
126          }
127          if (line == re_mail_MsId)
128          {
129             from_address = line(re_email_address);
130             from_address(re_email_user) = "";            //  Remove the user part;
131             if (from_address != "" && ~hn < ~from_address)
132             {
133                *Log << "Detected hostname " << from_address << "\n";
134                hn = from_address;
135             }
136          }
137          if (line == re_mail_Date)
138          {
139             ts = UTC(line(regex(mail_date_re)));
140          }
141       }
142    }
143    else
144    {
145       //  Push the first line back, we need to read it again.
146       --in;
147
148    }
149
150 }
151
152 /*=========================================================================
153 **  NAME           : construct_header
154 **  SYNOPSIS       : void construct_header(std::strstream &xml)
155 **  PARAMETERS     : 
156 **  RETURN VALUE   : 
157 **
158 **  DESCRIPTION    : Create the header for a Gnucomo XML document.
159 **
160 **  VARS USED      :
161 **  VARS CHANGED   :
162 **  FUNCTIONS USED :
163 **  SEE ALSO       :
164 **  LAST MODIFIED  : Nov 26, 2003
165 **=========================================================================
166 */
167
168 void message_filter::construct_header(std::strstream &xml)
169 {
170    //xml << "<?xml version='1.0' encoding='utf-8'?>\n";
171    xml << "<?xml version='1.0' encoding='ISO-8859-1'?>\n";
172    xml << "<gcmt:message xmlns:gcmt='http://gnucomo.org/transport/'>\n";
173    xml << "  <gcmt:header>\n";
174    xml << "    <gcmt:messagetype>" << mt << "</gcmt:messagetype>\n";
175    xml << "    <gcmt:hostname>" << hn << "</gcmt:hostname>\n";
176    xml << "    <gcmt:service>" << srv << "</gcmt:service>\n";
177    xml << "    <gcmt:time>" << ts << "</gcmt:time>\n";
178    xml << "  </gcmt:header>\n";
179 }