| | |
| | | | program/include/rcube_imap.php | |
| | | | | |
| | | | This file is part of the Roundcube Webmail client | |
| | | | Copyright (C) 2005-2010, Roundcube Dev. - Switzerland | |
| | | | Copyright (C) 2005-2010, The Roundcube Dev Team | |
| | | | Licensed under the GNU GPL | |
| | | | | |
| | | | PURPOSE: | |
| | |
| | | |
| | | $this->options['port'] = $port; |
| | | |
| | | if ($this->options['debug']) { |
| | | $this->conn->setDebug(true, array($this, 'debug_handler')); |
| | | |
| | | $this->options['ident'] = array( |
| | | 'name' => 'Roundcube Webmail', |
| | | 'version' => RCMAIL_VERSION, |
| | | 'php' => PHP_VERSION, |
| | | 'os' => PHP_OS, |
| | | 'command' => $_SERVER['REQUEST_URI'], |
| | | ); |
| | | } |
| | | |
| | | $attempt = 0; |
| | | do { |
| | | $data = rcmail::get_instance()->plugins->exec_hook('imap_connect', |
| | |
| | | */ |
| | | function get_error_code() |
| | | { |
| | | return ($this->conn) ? $this->conn->errornum : 0; |
| | | return $this->conn->errornum; |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | function get_error_str() |
| | | { |
| | | return ($this->conn) ? $this->conn->error : null; |
| | | return $this->conn->error; |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | function get_response_code() |
| | | { |
| | | if (!$this->conn) |
| | | return self::UNKNOWN; |
| | | |
| | | switch ($this->conn->resultcode) { |
| | | case 'NOPERM': |
| | | return self::NOPERM; |
| | |
| | | */ |
| | | function get_response_str() |
| | | { |
| | | return ($this->conn) ? $this->conn->result : null; |
| | | return $this->conn->result; |
| | | } |
| | | |
| | | |
| | |
| | | { |
| | | $this->threading = false; |
| | | |
| | | if ($enable) { |
| | | if ($this->get_capability('THREAD=REFS')) |
| | | if ($enable && ($caps = $this->get_capability('THREAD'))) { |
| | | if (in_array('REFS', $caps)) |
| | | $this->threading = 'REFS'; |
| | | else if ($this->get_capability('THREAD=REFERENCES')) |
| | | else if (in_array('REFERENCES', $caps)) |
| | | $this->threading = 'REFERENCES'; |
| | | else if ($this->get_capability('THREAD=ORDEREDSUBJECT')) |
| | | else if (in_array('ORDEREDSUBJECT', $caps)) |
| | | $this->threading = 'ORDEREDSUBJECT'; |
| | | } |
| | | |
| | |
| | | $imap_shared = $config->get('imap_ns_shared'); |
| | | $imap_delimiter = $config->get('imap_delimiter'); |
| | | |
| | | if ($imap_delimiter) { |
| | | $this->delimiter = $imap_delimiter; |
| | | } |
| | | |
| | | if (!$this->conn) |
| | | if (!$this->conn->connected()) |
| | | return; |
| | | |
| | | $ns = $this->conn->getNamespace(); |
| | | |
| | | // NAMESPACE supported |
| | | // Set namespaces (NAMESPACE supported) |
| | | if (is_array($ns)) { |
| | | $this->namespace = $ns; |
| | | |
| | | if (empty($this->delimiter)) |
| | | $this->delimiter = $ns['personal'][0][1]; |
| | | if (empty($this->delimiter)) |
| | | $this->delimiter = $this->conn->getHierarchyDelimiter(); |
| | | if (empty($this->delimiter)) |
| | | $this->delimiter = '/'; |
| | | } |
| | | // not supported, get namespace from config |
| | | else if ($imap_personal !== null || $imap_shared !== null || $imap_other !== null) { |
| | | if (empty($this->delimiter)) |
| | | $this->delimiter = $this->conn->getHierarchyDelimiter(); |
| | | if (empty($this->delimiter)) |
| | | $this->delimiter = '/'; |
| | | |
| | | else { |
| | | $this->namespace = array( |
| | | 'personal' => NULL, |
| | | 'other' => NULL, |
| | | 'shared' => NULL, |
| | | ); |
| | | } |
| | | |
| | | if ($imap_personal !== null) { |
| | | foreach ((array)$imap_personal as $dir) { |
| | | $this->namespace['personal'][] = array($dir, $this->delimiter); |
| | | if ($imap_delimiter) { |
| | | $this->delimiter = $imap_delimiter; |
| | | } |
| | | if (empty($this->delimiter)) { |
| | | $this->delimiter = $this->namespace['personal'][0][1]; |
| | | } |
| | | if (empty($this->delimiter)) { |
| | | $this->delimiter = $this->conn->getHierarchyDelimiter(); |
| | | } |
| | | if (empty($this->delimiter)) { |
| | | $this->delimiter = '/'; |
| | | } |
| | | |
| | | // Overwrite namespaces |
| | | if ($imap_personal !== null) { |
| | | $this->namespace['personal'] = NULL; |
| | | foreach ((array)$imap_personal as $dir) { |
| | | $this->namespace['personal'][] = array($dir, $this->delimiter); |
| | | } |
| | | } |
| | | if ($imap_other !== null) { |
| | | $this->namespace['other'] = NULL; |
| | | foreach ((array)$imap_other as $dir) { |
| | | if ($dir) { |
| | | $this->namespace['other'][] = array($dir, $this->delimiter); |
| | | } |
| | | } |
| | | if ($imap_other !== null) { |
| | | foreach ((array)$imap_other as $dir) { |
| | | if ($dir) { |
| | | $this->namespace['other'][] = array($dir, $this->delimiter); |
| | | } |
| | | } |
| | | } |
| | | if ($imap_shared !== null) { |
| | | foreach ((array)$imap_shared as $dir) { |
| | | if ($dir) { |
| | | $this->namespace['shared'][] = array($dir, $this->delimiter); |
| | | } |
| | | } |
| | | if ($imap_shared !== null) { |
| | | $this->namespace['shared'] = NULL; |
| | | foreach ((array)$imap_shared as $dir) { |
| | | if ($dir) { |
| | | $this->namespace['shared'][] = array($dir, $this->delimiter); |
| | | } |
| | | } |
| | | } |
| | |
| | | return false; |
| | | } |
| | | |
| | | $struct = &$this->_structure_part($structure); |
| | | $struct = &$this->_structure_part($structure, 0, '', $headers); |
| | | $struct->headers = get_object_vars($headers); |
| | | |
| | | // don't trust given content-type |
| | |
| | | $struct->charset = $struct->ctype_parameters['charset']; |
| | | } |
| | | |
| | | // #1487700: workaround for lack of charset in malformed structure |
| | | if (empty($struct->charset) && !empty($mime_headers) && $mime_headers->charset) { |
| | | $struct->charset = $mime_headers->charset; |
| | | } |
| | | |
| | | // read content encoding |
| | | if (!empty($part[5]) && $part[5]!='NIL') { |
| | | $struct->encoding = strtolower($part[5]); |
| | |
| | | $mime_headers = $this->conn->fetchPartHeader( |
| | | $this->mailbox, $this->_msg_id, false, $struct->mime_id); |
| | | } |
| | | $struct->headers = $this->_parse_headers($mime_headers) + $struct->headers; |
| | | |
| | | if (is_string($mime_headers)) |
| | | $struct->headers = $this->_parse_headers($mime_headers) + $struct->headers; |
| | | else if (is_object($mime_headers)) |
| | | $struct->headers = get_object_vars($mime_headers) + $struct->headers; |
| | | |
| | | // get real content-type of message/rfc822 |
| | | if ($struct->mimetype == 'message/rfc822') { |
| | |
| | | // If folder contains namespace prefix, don't modify it |
| | | if (is_array($this->namespace['shared'])) { |
| | | foreach ($this->namespace['shared'] as $ns) { |
| | | foreach ((array)$ns as $root) { |
| | | if ($root[0] && strpos($mbox_name, $root[0]) === 0) { |
| | | return $mbox_name; |
| | | } |
| | | if ($ns[0] && strpos($mbox_name, $ns[0]) === 0) { |
| | | return $mbox_name; |
| | | } |
| | | } |
| | | } |
| | | if (is_array($this->namespace['other'])) { |
| | | foreach ($this->namespace['other'] as $ns) { |
| | | foreach ((array)$ns as $root) { |
| | | if ($root[0] && strpos($mbox_name, $root[0]) === 0) { |
| | | return $mbox_name; |
| | | } |
| | | if ($ns[0] && strpos($mbox_name, $ns[0]) === 0) { |
| | | return $mbox_name; |
| | | } |
| | | } |
| | | } |
| | | if (is_array($this->namespace['personal'])) { |
| | | foreach ($this->namespace['personal'] as $ns) { |
| | | foreach ((array)$ns as $root) { |
| | | if ($root[0] && strpos($mbox_name, $root[0]) === 0) { |
| | | return $mbox_name; |
| | | } |
| | | if ($ns[0] && strpos($mbox_name, $ns[0]) === 0) { |
| | | return $mbox_name; |
| | | } |
| | | } |
| | | // Add prefix if first personal namespace is non-empty |
| | | if ($this->namespace['personal'][0][0]) { |
| | | if ($mbox_name != 'INBOX' && $this->namespace['personal'][0][0]) { |
| | | return $this->namespace['personal'][0][0].$mbox_name; |
| | | } |
| | | } |
| | |
| | | private function _parse_address_list($str, $decode=true) |
| | | { |
| | | // remove any newlines and carriage returns before |
| | | $a = rcube_explode_quoted_string('[,;]', preg_replace( "/[\r\n]/", " ", $str)); |
| | | $str = preg_replace('/\r?\n(\s|\t)?/', ' ', $str); |
| | | |
| | | // extract list items, remove comments |
| | | $str = self::explode_header_string(',;', $str, true); |
| | | $result = array(); |
| | | |
| | | foreach ($a as $key => $val) { |
| | | foreach ($str as $key => $val) { |
| | | $name = ''; |
| | | $address = ''; |
| | | $val = trim($val); |
| | |
| | | return $result; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Explodes header (e.g. address-list) string into array of strings |
| | | * using specified separator characters with proper handling |
| | | * of quoted-strings and comments (RFC2822) |
| | | * |
| | | * @param string $separator String containing separator characters |
| | | * @param string $str Header string |
| | | * @param bool $remove_comments Enable to remove comments |
| | | * |
| | | * @return array Header items |
| | | */ |
| | | static function explode_header_string($separator, $str, $remove_comments=false) |
| | | { |
| | | $length = strlen($str); |
| | | $result = array(); |
| | | $quoted = false; |
| | | $comment = 0; |
| | | $out = ''; |
| | | |
| | | for ($i=0; $i<$length; $i++) { |
| | | // we're inside a quoted string |
| | | if ($quoted) { |
| | | if ($str[$i] == '"') { |
| | | $quoted = false; |
| | | } |
| | | else if ($str[$i] == '\\') { |
| | | if ($comment <= 0) { |
| | | $out .= '\\'; |
| | | } |
| | | $i++; |
| | | } |
| | | } |
| | | // we're inside a comment string |
| | | else if ($comment > 0) { |
| | | if ($str[$i] == ')') { |
| | | $comment--; |
| | | } |
| | | else if ($str[$i] == '(') { |
| | | $comment++; |
| | | } |
| | | else if ($str[$i] == '\\') { |
| | | $i++; |
| | | } |
| | | continue; |
| | | } |
| | | // separator, add to result array |
| | | else if (strpos($separator, $str[$i]) !== false) { |
| | | if ($out) { |
| | | $result[] = $out; |
| | | } |
| | | $out = ''; |
| | | continue; |
| | | } |
| | | // start of quoted string |
| | | else if ($str[$i] == '"') { |
| | | $quoted = true; |
| | | } |
| | | // start of comment |
| | | else if ($remove_comments && $str[$i] == '(') { |
| | | $comment++; |
| | | } |
| | | |
| | | if ($comment <= 0) { |
| | | $out .= $str[$i]; |
| | | } |
| | | } |
| | | |
| | | if ($out && $comment <= 0) { |
| | | $result[] = $out; |
| | | } |
| | | |
| | | return $result; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * This is our own debug handler for the IMAP connection |
| | | * @access public |
| | | */ |
| | | public function debug_handler(&$imap, $message) |
| | | { |
| | | write_log('imap', $message); |
| | | } |
| | | |
| | | } // end class rcube_imap |
| | | |
| | | |