From ac9759b6a4e2eec68dda27f81d8001c9d4e18f9f Mon Sep 17 00:00:00 2001 From: alecpl <alec@alec.pl> Date: Thu, 28 Jan 2010 07:55:26 -0500 Subject: [PATCH] - oops, last commit fix --- program/include/rcube_imap.php | 142 ++++++++++++++++++++++++++++------------------- 1 files changed, 84 insertions(+), 58 deletions(-) diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 9ca1167..9137ada 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -105,14 +105,15 @@ if ($use_ssl && extension_loaded('openssl')) $ICL_SSL = $use_ssl == 'imaps' ? 'ssl' : $use_ssl; else if ($use_ssl) { - raise_error(array('code' => 403, 'type' => 'imap', 'file' => __FILE__, - 'message' => 'Open SSL not available;'), TRUE, FALSE); + raise_error(array('code' => 403, 'type' => 'imap', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Open SSL not available"), TRUE, FALSE); $port = 143; } $ICL_PORT = $port; $IMAP_USE_INTERNAL_DATE = false; - + $attempt = 0; do { $data = rcmail::get_instance()->plugins->exec_hook('imap_connect', array('host' => $host, 'user' => $user, 'attempt' => ++$attempt)); @@ -136,21 +137,21 @@ else if (!$this->conn && $GLOBALS['iil_error']) { $this->error_code = $GLOBALS['iil_errornum']; - raise_error(array('code' => 403, - 'type' => 'imap', - 'message' => $GLOBALS['iil_error']), TRUE, FALSE); + raise_error(array('code' => 403, 'type' => 'imap', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => $GLOBALS['iil_error']), TRUE, FALSE); } // get server properties if ($this->conn) { - if (!empty($this->conn->delimiter)) - $this->delimiter = $this->conn->delimiter; if (!empty($this->conn->rootdir)) { $this->set_rootdir($this->conn->rootdir); $this->root_ns = preg_replace('/[.\/]$/', '', $this->conn->rootdir); } + if (empty($this->delimiter)) + $this->get_hierarchy_delimiter(); } return $this->conn ? TRUE : FALSE; @@ -603,21 +604,23 @@ { if ($this->skip_deleted) { // @TODO: this could be cached - $msg_index = $this->_search_index($mailbox, 'ALL UNDELETED'); - $max = max($msg_index); - list($begin, $end) = $this->_get_message_range(count($msg_index), $page); - $msg_index = array_slice($msg_index, $begin, $end-$begin); + if ($msg_index = $this->_search_index($mailbox, 'ALL UNDELETED')) { + $max = max($msg_index); + list($begin, $end) = $this->_get_message_range(count($msg_index), $page); + $msg_index = array_slice($msg_index, $begin, $end-$begin); + } } else if ($max = iil_C_CountMessages($this->conn, $mailbox)) { list($begin, $end) = $this->_get_message_range($max, $page); $msg_index = range($begin+1, $end); } else - return array(); + $msg_index = array(); if ($slice) $msg_index = array_slice($msg_index, ($this->sort_order == 'DESC' ? 0 : -$slice), $slice); // fetch reqested headers from server - $this->_fetch_headers($mailbox, join(",", $msg_index), $a_msg_headers, $cache_key); + if ($msg_index) + $this->_fetch_headers($mailbox, join(",", $msg_index), $a_msg_headers, $cache_key); } // use SORT command else if ($this->get_capability('sort') && ($msg_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : ''))) @@ -633,13 +636,8 @@ $this->_fetch_headers($mailbox, join(',', $msg_index), $a_msg_headers, $cache_key); } // fetch specified header for all messages and sort - else + else if ($a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", $this->sort_field, $this->skip_deleted)) { - $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", $this->sort_field, $this->skip_deleted); - - if (empty($a_index)) - return array(); - asort($a_index); // ASC $msg_index = array_keys($a_index); $max = max($msg_index); @@ -1226,17 +1224,15 @@ else $this->struct_charset = $this->_structure_charset($structure); - /* - @TODO: here we can recognize malformed BODYSTRUCTURE and parse - the message in other way to create our own message structure. - Example of structure for malformed MIME message: - ("text" "plain" ("charset" "us-ascii") NIL NIL "7bit" 2154 70 NIL NIL NIL) - - if ($headers->ctype != 'text/plain' - && !is_array($structure[0]) && $structure[0] == 'text' - && !is_array($structure[1]) && $structure[1] == 'plain') - { } - */ + // Here we can recognize malformed BODYSTRUCTURE and + // 1. [@TODO] parse the message in other way to create our own message structure + // 2. or just show the raw message body. + // Example of structure for malformed MIME message: + // ("text" "plain" ("charset" "us-ascii") NIL NIL "7bit" 2154 70 NIL NIL NIL) + if ($headers->ctype && $headers->ctype != 'text/plain' + && $structure[0] == 'text' && $structure[1] == 'plain') { + return false; + } $struct = &$this->_structure_part($structure); $struct->headers = get_object_vars($headers); @@ -1263,7 +1259,7 @@ * * @access private */ - function &_structure_part($part, $count=0, $parent='', $raw_headers=null) + function &_structure_part($part, $count=0, $parent='', $mime_headers=null, $raw_headers=null) { $struct = new rcube_message_part; $struct->mime_id = empty($parent) ? (string)$count : "$parent.$count"; @@ -1285,28 +1281,43 @@ // build parts list for headers pre-fetching for ($i=0, $count=0; $i<count($part); $i++) - if (is_array($part[$i]) && count($part[$i]) > 3) - // fetch message headers if message/rfc822 or named part (could contain Content-Location header) - if (strtolower($part[$i][0]) == 'message' || - (in_array('name', (array)$part[$i][2]) && (empty($part[$i][3]) || $part[$i][3]=='NIL'))) { - $part_headers[] = $struct->mime_id ? $struct->mime_id.'.'.($i+1) : $i+1; - } - + if (is_array($part[$i]) && count($part[$i]) > 3) { + // fetch message headers if message/rfc822 or named part (could contain Content-Location header) + if (!is_array($part[$i][0])) { + $tmp_part_id = $struct->mime_id ? $struct->mime_id.'.'.($i+1) : $i+1; + if (strtolower($part[$i][0]) == 'message' && strtolower($part[$i][1]) == 'rfc822') { + $raw_part_headers[] = $tmp_part_id; + $mime_part_headers[] = $tmp_part_id; + } + else if (in_array('name', (array)$part[$i][2]) && (empty($part[$i][3]) || $part[$i][3]=='NIL')) { + $mime_part_headers[] = $tmp_part_id; + } + } + } + // pre-fetch headers of all parts (in one command for better performance) - if ($part_headers) - $part_headers = iil_C_FetchMIMEHeaders($this->conn, $this->mailbox, $this->_msg_id, $part_headers); + // @TODO: we could do this before _structure_part() call, to fetch + // headers for parts on all levels + if ($mime_part_headers) + $mime_part_headers = iil_C_FetchMIMEHeaders($this->conn, $this->mailbox, + $this->_msg_id, $mime_part_headers); + // we'll need a real content-type of message/rfc822 part + if ($raw_part_headers) + $raw_part_headers = iil_C_FetchMIMEHeaders($this->conn, $this->mailbox, + $this->_msg_id, $raw_part_headers, false); $struct->parts = array(); for ($i=0, $count=0; $i<count($part); $i++) if (is_array($part[$i]) && count($part[$i]) > 3) { + $tmp_part_id = $struct->mime_id ? $struct->mime_id.'.'.($i+1) : $i+1; $struct->parts[] = $this->_structure_part($part[$i], ++$count, $struct->mime_id, - $part_headers[$struct->mime_id ? $struct->mime_id.'.'.($i+1) : $i+1]); + $mime_part_headers[$tmp_part_id], $raw_part_headers[$tmp_part_id]); } return $struct; } - - + + // regular part $struct->ctype_primary = strtolower($part[0]); $struct->ctype_secondary = strtolower($part[1]); @@ -1367,18 +1378,30 @@ // fetch message headers if message/rfc822 or named part (could contain Content-Location header) if ($struct->ctype_primary == 'message' || ($struct->ctype_parameters['name'] && !$struct->content_id)) { - if (empty($raw_headers)) - $raw_headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, false, $struct->mime_id); - $struct->headers = $this->_parse_headers($raw_headers) + $struct->headers; - } + if (empty($mime_headers)) + $mime_headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, false, $struct->mime_id); + $struct->headers = $this->_parse_headers($mime_headers) + $struct->headers; + + // get real headers for message of type 'message/rfc822' + if ($struct->mimetype == 'message/rfc822') { + if (empty($raw_headers)) + $raw_headers = iil_C_FetchMIMEHeaders($this->conn, $this->mailbox, $this->_msg_id, (array)$struct->mime_id, false); + $struct->real_headers = $this->_parse_headers($raw_headers); + + // get real content-type of message/rfc822 + if (preg_match('/^([a-z0-9_\/-]+)/i', $struct->real_headers['content-type'], $matches)) { + $struct->real_mimetype = strtolower($matches[1]); + } + } + } if ($struct->ctype_primary=='message') { - if (is_array($part[8]) && empty($struct->parts)) + if (is_array($part[8]) && $di != 8 && empty($struct->parts)) $struct->parts[] = $this->_structure_part($part[8], ++$count, $struct->mime_id); - } + } // normalize filename property - $this->_set_part_filename($struct, $raw_headers); + $this->_set_part_filename($struct, $mime_headers); return $struct; } @@ -1716,8 +1739,8 @@ // make sure mailbox exists if ($to_mbox != 'INBOX' && !in_array($to_mbox, $this->_list_mailboxes())) { - if (in_array($to_mbox_in, $this->default_folders)) - $this->create_mailbox($to_mbox_in, TRUE); + if (in_array($tbox, $this->default_folders)) + $this->create_mailbox($tbox, TRUE); else return FALSE; } @@ -2871,11 +2894,13 @@ if ((!empty($this->root_ns) && $this->root_ns == $mbox_name) || $mbox_name == 'INBOX') return $mbox_name; - if (!empty($this->root_dir) && $mode=='in') - $mbox_name = $this->root_dir.$this->delimiter.$mbox_name; - else if (strlen($this->root_dir) && $mode=='out') - $mbox_name = substr($mbox_name, strlen($this->root_dir)+1); - + if (!empty($this->root_dir)) { + if ($mode=='in') + $mbox_name = $this->root_dir.$this->delimiter.$mbox_name; + else if (!empty($mbox_name)) // $mode=='out' + $mbox_name = substr($mbox_name, strlen($this->root_dir)+1); + } + return $mbox_name; } @@ -3086,6 +3111,7 @@ private function _parse_headers($headers) { $a_headers = array(); + $headers = preg_replace('/\r?\n(\t| )+/', ' ', $headers); $lines = explode("\n", $headers); $c = count($lines); for ($i=0; $i<$c; $i++) -- Gitblit v1.9.1