3 * FusionForge mail parser
5 * Copyright 2004, GForge, LLC
7 * This file is part of FusionForge. FusionForge is free software;
8 * you can redistribute it and/or modify it under the terms of the
9 * GNU General Public License as published by the Free Software
10 * Foundation; either version 2 of the Licence, or (at your option)
13 * FusionForge is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 require_once $gfcommon.'include/FFError.class.php';
25 class MailParser extends FFError {
27 var $max_file_size = 2000000;
31 function __construct($input_file) {
32 parent::__construct();
33 $size = filesize($input_file);
34 if ($size > $this->max_file_size) {
35 $this->setError(_("Error: file too large"));
38 $fo = fopen($input_file, 'r');
39 $input_data = fread($fo, $size);
42 $lines = explode("\n",$input_data);
43 $linecount = count($lines);
47 // Read the message line-by-line
52 for ($i = 0; $i < ($linecount-1); $i++) {
54 // Still reading headers
58 // If we hit a blank line, end of headers
60 if (strlen($lines[$i]) < 2) {
64 // See if line starts with tab, if so ignore it for now
66 if (!preg_match('/^[A-z]/', $lines[$i])) {
67 $lheader[$lastheader] = $lheader[$lastheader]."\n".$lines[$i];
69 $pos = (strpos($lines[$i],':'));
70 $lheader[substr($lines[$i],0,$pos)] = trim(substr($lines[$i], $pos+2, (strlen($lines[$i]) - $pos -2)));
71 $lastheader = substr($lines[$i], 0, $pos);
75 $lbody .= $lines[$i]."\r\n";
78 $this->body =& $lbody;
79 $this->headers =& $lheader;
81 if ($lheader['Content-Type']) {
82 $hdr = strtolower($lheader['Content-Type']);
83 if (strpos($hdr,'text/plain') !== false) {
86 $this->setError(_('Error - only text/plain supported at this time'));
97 function &getHeader($header) {
98 return $this->headers[$header];
101 function getSubject() {
102 return $this->getHeader('Subject');
105 function getFromEmail() {
106 $mail = $this->getHeader('From');
107 if (strpos($mail,'(') !== false) {
108 $email = substr($mail,0,strpos($mail,' '));
109 } elseif (strpos($mail,'<') !== false) {
110 $begin=(strpos($mail,'<')+1);
111 $end = strpos($mail,'>');
112 $email = substr($mail,$begin,($end-$begin));
116 $email = str_replace('"','',$email);
118 //echo "***$mail*$begin*$end**".$email."*****";
119 //system("echo \"mp: email".$email."\n\" >> /tmp/forum.log");
123 /*------------------------------------------------------------------------
124 * MIME decoding functions
125 *-----------------------------------------------------------------------*/
127 * Subject and From decode implementation of RFC 2047
129 * @param string one or more encoded strings
130 * @return string strcat of all texts. Ignore all charsets
132 function mime_header_decode_string($string) {
134 $decoded_arr = $this->mime_header_decode($string);
136 $return_string = $decoded_arr[0]['text'];
139 for ($i=1; $i<count($decoded_arr); $i++) {
140 $return_string.=$decoded_arr[$i]['text'];
143 DBG("mime_header: $string -> $return_string \n");
145 return $return_string;
149 * Mime header decoding
151 * @param $string String to decode
152 * @return array Decoded String Array. return['charset'] and retutn['text']
154 *# FIXME: Should we use imap_mime_headres_decode? It's too havey to install
155 * See http://us2.php.net/manual/en/function.imap-mime-header-decode.php
158 function mime_header_decode($string) {
159 /* We expecting series of encoded-word:
160 * encoded-word = "=?" charset "?" encoding "?" encoded-text "?="
161 * See more detail in RFC 2407
164 $strlen = strlen($string);
165 $encoded_word_arr = array();
167 for ($i=0; $i < $strlen; $i++) {
168 /* Start seperation */
169 if (!strcmp($string{$i} . $string{$i+1}, "=?")) {
174 if( !strcmp($string{$i} . $string{$i+1}, "?=")) {
175 $encoded_word_arr[$count].=$string{$i};
176 $encoded_word_arr[$count].=$string{++$i};
177 $count++; /* Null array should be OK */
181 $encoded_word_arr[$count].=$string{$i};
184 for ($i=0; $i<count($encoded_word_arr); $i++) {
185 $return_arr[$i] = $this->mime_header_one_word_decode($encoded_word_arr[$i]);
192 * one word decode implementation of RFC 2047
193 * @param string $string
196 function mime_header_one_word_decode($string) {
197 /* Default charset */
200 /* We expecting : encoded-word = "=?" charset "?" encoding "?" encoded-text "?="
201 * See more detail in RFC 2407
204 /* No encoded-word, return default */
205 if (strncmp($string, "=?", 2)) {
206 return array("charset"=>$charset, "text" => $string);
210 * Expecting [0]='=', [1]=charset, [2]=B|Q, [3]=encoded-text
212 $string_arr = explode('?', $string);
214 if (!strcasecmp($string_arr[2], "B") && $string_arr[3]) {
215 $string = base64_decode($string_arr[3]);
216 $charset = $string_arr[1];
217 } elseif (!strcasecmp($string_arr[2], "Q") && $string_arr[3]) {
218 $string = quoted_printable_decode($string_arr[3]);
219 $charset = $string_arr[1];
222 /* Return what we have */
223 $ret_arr = array("charset"=>$charset, "text" => $string);
231 // c-file-style: "bsd"