+ if ($this->_split_multipart($this->headers, $this->body)) {
+ $this->set_body_to_part(0);
+ } else {
+ $this->_split_multipart($mpart_type[1], $mpart_boundary[1]);
+ $this->_find_uuencode();
+ $this->_fix_charset();
+ }
+ }
+
+ /** find and add uuencoded attachments
+ */
+ function _find_uuencode()
+ {
+ if (preg_match_all('@\n(begin \d+ ([^\r\n]+)\r?(?:\n(?!end)[^\n]*)*\nend)@', $this->body, $matches, PREG_SET_ORDER)) {
+ foreach ($matches as $match) {
+ $mime = trim(exec('echo '.escapeshellarg($match[1]).' | uudecode -o /dev/stdout | file -bi -'));
+ if ($mime != 'application/x-empty') {
+ $this->body = trim(str_replace($match[0], '', $this->body));
+ $body = $match[1];
+ $header['content-type'] = $mime.'; name="'.$match[2].'"';
+ $header['content-transfer-encoding'] = 'x-uuencode';
+ $header['content-disposition'] = 'attachment; filename="'.$match[2].'"';
+ $this->_add_attachment(Array('headers' => $header, 'body' => $body));
+ }
+ }
+ }
+ }
+
+ /** split multipart messages
+ * @param $type STRING multipart type description
+ * @param $boundary STRING multipart boundary identification string
+ */
+ function _split_multipart($headers, $body)
+ {
+ if (!preg_match("@multipart/([^;]+);@", $headers['content-type'], $type)) {
+ return false;
+ }
+
+ preg_match("/boundary=\"?([^ \"]+)\"?/", $headers['content-type'], $boundary);
+ $boundary = $boundary[1];
+ $type = $type[1];
+ $parts = preg_split("@\n--$boundary(--|\n)@", $body);
+ foreach ($parts as $part) {
+ $part = $this->_get_part($part);
+ $local_header = $part['headers'];
+ $local_body = $part['body'];
+ if (!$this->_split_multipart($local_header, $local_body)) {
+ $is_text = isset($local_header['content-type']) && preg_match("@text/([^;]+);@", $local_header['content-type'])
+ && (!isset($local_header['content-disposition']) || !preg_match('@attachment@', $local_header['content-disposition']));
+
+ // alternative ==> multiple formats for messages
+ if ($type == 'alternative' && $is_text) {
+ array_push($this->messages, $part);
+
+ // !alternative ==> une body, others are attachments
+ } else if ($is_text) {
+ if (count($this->messages) == 0) {
+ $this->body = $local_body;
+ foreach (array_keys($local_header) as $key) {
+ $this->header[$key] = $local_header[$key];
+ }
+ array_push($this->messages, $part);
+ } else {
+ $this->_add_attachment($part);
+ }
+ } else {
+ $this->_add_attachment($part);
+ }
+ }
+ }
+ return true;
+ }
+
+ /** extract new headers from the part
+ * @param $part STRING part of a multipart message
+ */
+ function _get_part($part)
+ {
+ global $banana;
+
+ $lines = split("\n", $part);
+ while (count($lines)) {
+ $line = array_shift($lines);
+ if ($line != "") {
+ if (preg_match('@^[\t\r ]+@', $line) && isset($hdr)) {
+ $local_headers[$hdr] .= ' '.trim($line);
+ } else {
+ list($hdr, $val) = split(":[ \t\r]*", $line, 2);
+ $hdr = strtolower($hdr);
+ if (in_array($hdr, $banana->parse_hdr)) {
+ $local_headers[$hdr] = $val;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ $local_body = join("\n", $lines);
+ if (preg_match("/quoted-printable/", $local_headers['content-transfer-encoding'])) {
+ $local_body = quoted_printable_decode($local_body);
+ }
+ return Array('headers' => $local_headers, 'body' => $local_body);
+ }
+
+ /** add an attachment
+ */
+ function _add_attachment($part)
+ {
+ $local_header = $part['headers'];
+ $local_body = $part['body'];
+
+ if ((isset($local_header['content-disposition']) && preg_match("/filename=\"?([^\"]+)\"?/", $local_header['content-disposition'], $filename))
+ || (isset($local_header['content-type']) && preg_match("/name=\"?([^\"]+)\"?/", $local_header['content-type'], $filename))) {
+ $filename = $filename[1];
+ }
+ if (!isset($filename)) {
+ $filename = "attachment".count($pj);
+ }
+
+ if (isset($local_header['content-type'])) {
+ if (preg_match("/^\\s*([^ ;]+);/", $local_header['content-type'], $mimetype)) {
+ $mimetype = $mimetype[1];
+ }
+ }
+ if (!isset($mimetype)) {
+ return false;
+ }
+
+ array_push($this->pj, Array('MIME' => $mimetype,
+ 'filename' => $filename,
+ 'encoding' => strtolower($local_header['content-transfer-encoding']),
+ 'data' => $local_body));
+ return true;
+ }
+
+ /** Fix body charset (convert body to utf8)
+ * @return false if failed
+ */
+ function _fix_charset()
+ {
+ if (preg_match('!charset="?([^;"]*)"?\s*(;|$)?!', $this->headers['content-type'], $matches)) {
+ $body = iconv($matches[1], 'utf-8', $this->body);
+ if (strlen($body) == 0) {
+ return false;
+ }
+ $this->body = $body;
+ } else {
+ $this->body = utf8_encode($this->body);