Aleksander Machniak
2013-10-17 037af6890fe6fdb84a08d3c86083e847c90ec0ad
program/lib/Roundcube/rcube_imap_generic.php
@@ -702,18 +702,11 @@
     */
    function connect($host, $user, $password, $options=null)
    {
        // set options
        if (is_array($options)) {
            $this->prefs = $options;
        }
        // set auth method
        if (!empty($this->prefs['auth_type'])) {
            $auth_method = strtoupper($this->prefs['auth_type']);
        } else {
            $auth_method = 'CHECK';
        }
        // configure
        $this->set_prefs($options);
        $result = false;
        $auth_method = $this->prefs['auth_type'];
        $result      = false;
        // initialize connection
        $this->error    = '';
@@ -746,7 +739,7 @@
        }
        if ($this->prefs['timeout'] <= 0) {
            $this->prefs['timeout'] = ini_get('default_socket_timeout');
            $this->prefs['timeout'] = max(0, intval(ini_get('default_socket_timeout')));
        }
        // Connect
@@ -892,6 +885,31 @@
    }
    /**
     * Initializes environment
     */
    protected function set_prefs($prefs)
    {
        // set preferences
        if (is_array($prefs)) {
            $this->prefs = $prefs;
        }
        // set auth method
        if (!empty($this->prefs['auth_type'])) {
            $this->prefs['auth_type'] = strtoupper($this->prefs['auth_type']);
        }
        else {
            $this->prefs['auth_type'] = 'CHECK';
        }
        // additional message flags
        if (!empty($this->prefs['message_flags'])) {
            $this->flags = array_merge($this->flags, $this->prefs['message_flags']);
            unset($this->prefs['message_flags']);
        }
    }
    /**
     * Checks connection status
     *
     * @return bool True if connection is active and user is logged in, False otherwise.
@@ -906,7 +924,7 @@
     */
    function closeConnection()
    {
        if ($this->putLine($this->nextTag() . ' LOGOUT')) {
        if ($this->logged && $this->putLine($this->nextTag() . ' LOGOUT')) {
            $this->readReply();
        }
@@ -1077,7 +1095,7 @@
        }
        if (!$this->data['READ-WRITE']) {
            $this->setError(self::ERROR_READONLY, "Mailbox is read-only", 'EXPUNGE');
            $this->setError(self::ERROR_READONLY, "Mailbox is read-only");
            return false;
        }
@@ -1933,7 +1951,7 @@
        }
        if (!$this->data['READ-WRITE']) {
            $this->setError(self::ERROR_READONLY, "Mailbox is read-only", 'STORE');
            $this->setError(self::ERROR_READONLY, "Mailbox is read-only");
            return false;
        }
@@ -1995,7 +2013,7 @@
        }
        if (!$this->data['READ-WRITE']) {
            $this->setError(self::ERROR_READONLY, "Mailbox is read-only", 'STORE');
            $this->setError(self::ERROR_READONLY, "Mailbox is read-only");
            return false;
        }
@@ -2130,14 +2148,18 @@
                    else if ($name == 'RFC822') {
                        $result[$id]->body = $value;
                    }
                    else if ($name == 'BODY') {
                        $body = $this->tokenizeResponse($line, 1);
                        if ($value[0] == 'HEADER.FIELDS')
                            $headers = $body;
                        else if (!empty($value))
                            $result[$id]->bodypart[$value[0]] = $body;
                    else if (stripos($name, 'BODY[') === 0) {
                        $name = str_replace(']', '', substr($name, 5));
                        if ($name == 'HEADER.FIELDS') {
                            // skip ']' after headers list
                            $this->tokenizeResponse($line, 1);
                            $headers = $this->tokenizeResponse($line, 1);
                        }
                        else if (strlen($name))
                            $result[$id]->bodypart[$name] = $value;
                        else
                            $result[$id]->body = $body;
                            $result[$id]->body = $value;
                    }
                }
@@ -2237,24 +2259,53 @@
        return $result;
    }
    function fetchHeaders($mailbox, $message_set, $is_uid = false, $bodystr = false, $add = '')
    /**
     * Returns message(s) data (flags, headers, etc.)
     *
     * @param string $mailbox     Mailbox name
     * @param mixed  $message_set Message(s) sequence identifier(s) or UID(s)
     * @param bool   $is_uid      True if $message_set contains UIDs
     * @param bool   $bodystr     Enable to add BODYSTRUCTURE data to the result
     * @param array  $add_headers List of additional headers
     *
     * @return bool|array List of rcube_message_header elements, False on error
     */
    function fetchHeaders($mailbox, $message_set, $is_uid = false, $bodystr = false, $add_headers = array())
    {
        $query_items = array('UID', 'RFC822.SIZE', 'FLAGS', 'INTERNALDATE');
        if ($bodystr)
        $headers     = array('DATE', 'FROM', 'TO', 'SUBJECT', 'CONTENT-TYPE', 'CC', 'REPLY-TO',
            'LIST-POST', 'DISPOSITION-NOTIFICATION-TO', 'X-PRIORITY');
        if (!empty($add_headers)) {
            $add_headers = array_map('strtoupper', $add_headers);
            $headers     = array_unique(array_merge($headers, $add_headers));
        }
        if ($bodystr) {
            $query_items[] = 'BODYSTRUCTURE';
        $query_items[] = 'BODY.PEEK[HEADER.FIELDS ('
            . 'DATE FROM TO SUBJECT CONTENT-TYPE CC REPLY-TO LIST-POST DISPOSITION-NOTIFICATION-TO X-PRIORITY'
            . ($add ? ' ' . trim($add) : '')
            . ')]';
        }
        $query_items[] = 'BODY.PEEK[HEADER.FIELDS (' . implode(' ', $headers) . ')]';
        $result = $this->fetch($mailbox, $message_set, $is_uid, $query_items);
        return $result;
    }
    function fetchHeader($mailbox, $id, $uidfetch=false, $bodystr=false, $add='')
    /**
     * Returns message data (flags, headers, etc.)
     *
     * @param string $mailbox     Mailbox name
     * @param int    $id          Message sequence identifier or UID
     * @param bool   $is_uid      True if $id is an UID
     * @param bool   $bodystr     Enable to add BODYSTRUCTURE data to the result
     * @param array  $add_headers List of additional headers
     *
     * @return bool|rcube_message_header Message data, False on error
     */
    function fetchHeader($mailbox, $id, $is_uid = false, $bodystr = false, $add_headers = array())
    {
        $a = $this->fetchHeaders($mailbox, $id, $uidfetch, $bodystr, $add);
        $a = $this->fetchHeaders($mailbox, $id, $is_uid, $bodystr, $add_headers);
        if (is_array($a)) {
            return array_shift($a);
        }
@@ -2418,6 +2469,7 @@
        $key     = $this->nextTag();
        $request = $key . ($is_uid ? ' UID' : '') . " FETCH $id ($fetch_mode.PEEK[$part]$partial)";
        $result  = false;
        $found   = false;
        // send request
        if (!$this->putLine($request)) {
@@ -2437,18 +2489,25 @@
                break;
            }
            if (!preg_match('/^\* ([0-9]+) FETCH (.*)$/', $line, $m)) {
            // skip irrelevant untagged responses (we have a result already)
            if ($found || !preg_match('/^\* ([0-9]+) FETCH (.*)$/', $line, $m)) {
                continue;
            }
            $line = $m[2];
            $last = substr($line, -1);
            // handle one line response
            if ($line[0] == '(' && $last == ')') {
            if ($line[0] == '(' && substr($line, -1) == ')') {
                // tokenize content inside brackets
                $tokens = $this->tokenizeResponse(preg_replace('/(^\(|\$)/', '', $line));
                $result = count($tokens) == 1 ? $tokens[0] : false;
                $tokens = $this->tokenizeResponse(preg_replace('/(^\(|\)$)/', '', $line));
                for ($i=0; $i<count($tokens); $i+=2) {
                    if (preg_match('/^(BODY|BINARY)/i', $tokens[$i])) {
                        $result = $tokens[$i+1];
                        $found  = true;
                        break;
                    }
                }
                if ($result !== false) {
                    if ($mode == 1) {
@@ -2466,8 +2525,13 @@
            else if (preg_match('/\{([0-9]+)\}$/', $line, $m)) {
                $bytes = (int) $m[1];
                $prev  = '';
                $found = true;
                while ($bytes > 0) {
                // empty body
                if (!$bytes) {
                    $result = '';
                }
                else while ($bytes > 0) {
                    $line = $this->readLine(8192);
                    if ($line === NULL) {
@@ -2942,7 +3006,7 @@
        }
        foreach ($entries as $name => $value) {
            $entries[$name] = $this->escape($name) . ' ' . $this->escape($value);
            $entries[$name] = $this->escape($name) . ' ' . $this->escape($value, true);
        }
        $entries = implode(' ', $entries);
@@ -3439,25 +3503,24 @@
            // Parenthesized list
            case '(':
            case '[':
                $str = substr($str, 1);
                $result[] = self::tokenizeResponse($str);
                break;
            case ')':
            case ']':
                $str = substr($str, 1);
                return $result;
                break;
            // String atom, number, NIL, *, %
            // String atom, number, astring, NIL, *, %
            default:
                // empty string
                if ($str === '' || $str === null) {
                    break 2;
                }
                // excluded chars: SP, CTL, ), [, ]
                if (preg_match('/^([^\x00-\x20\x29\x5B\x5D\x7F]+)/', $str, $m)) {
                // excluded chars: SP, CTL, ), DEL
                // we do not exclude [ and ] (#1489223)
                if (preg_match('/^([^\x00-\x20\x29\x7F]+)/', $str, $m)) {
                    $result[] = $m[1] == 'NIL' ? NULL : $m[1];
                    $str = substr($str, strlen($m[1]));
                }