lib/ext lib/init.php lib/plugins

Aleksander Machniak machniak at kolabsys.com
Fri Dec 7 15:18:21 CET 2012


 lib/ext/Roundcube/bootstrap.php                   |    6 
 lib/ext/Roundcube/html.php                        |    2 
 lib/ext/Roundcube/rcube.php                       |   28 ++
 lib/ext/Roundcube/rcube_addressbook.php           |    4 
 lib/ext/Roundcube/rcube_charset.php               |    4 
 lib/ext/Roundcube/rcube_config.php                |    4 
 lib/ext/Roundcube/rcube_contacts.php              |    4 
 lib/ext/Roundcube/rcube_csv2vcard.php             |    2 
 lib/ext/Roundcube/rcube_db.php                    |  100 ++------
 lib/ext/Roundcube/rcube_enriched.php              |  147 +++++++++++
 lib/ext/Roundcube/rcube_imap.php                  |   11 
 lib/ext/Roundcube/rcube_imap_generic.php          |  201 ++++++++--------
 lib/ext/Roundcube/rcube_message.php               |    5 
 lib/ext/Roundcube/rcube_mime.php                  |   85 ++++++
 lib/ext/Roundcube/rcube_output.php                |  271 ++++++++++++++++++++++
 lib/ext/Roundcube/rcube_plugin.php                |   14 -
 lib/ext/Roundcube/rcube_spellchecker.php          |   10 
 lib/ext/Roundcube/rcube_storage.php               |    1 
 lib/ext/Roundcube/rcube_string_replacer.php       |   10 
 lib/ext/Roundcube/rcube_user.php                  |   15 +
 lib/ext/Roundcube/rcube_utils.php                 |   53 ----
 lib/ext/Roundcube/rcube_vcard.php                 |   10 
 lib/ext/enriched.inc                              |  114 ---------
 lib/ext/html2text.php                             |    4 
 lib/init.php                                      |   30 --
 lib/plugins/kolab_folders/kolab_folders.php       |    2 
 lib/plugins/libkolab/lib/kolab_storage.php        |    2 
 lib/plugins/libkolab/lib/kolab_storage_folder.php |    8 
 28 files changed, 718 insertions(+), 429 deletions(-)

New commits:
commit d2c999b7c328b43d7b8f53cdc767219fc2805b21
Author: Aleksander Machniak <alec at alec.pl>
Date:   Fri Dec 7 15:17:51 2012 +0100

    Update Roundcube Framework

diff --git a/lib/ext/Roundcube/bootstrap.php b/lib/ext/Roundcube/bootstrap.php
index 47020c1..eed7db8 100644
--- a/lib/ext/Roundcube/bootstrap.php
+++ b/lib/ext/Roundcube/bootstrap.php
@@ -49,7 +49,7 @@ foreach ($config as $optname => $optval) {
 
 // framework constants
 define('RCUBE_VERSION', '0.9-git');
-define('RCMAIL_CHARSET', 'UTF-8');
+define('RCUBE_CHARSET', 'UTF-8');
 
 if (!defined('RCUBE_LIB_DIR')) {
     define('RCUBE_LIB_DIR', dirname(__FILE__).'/');
@@ -73,8 +73,8 @@ if (!defined('RCUBE_LOCALIZATION_DIR')) {
 
 // set internal encoding for mbstring extension
 if (extension_loaded('mbstring')) {
-    mb_internal_encoding(RCMAIL_CHARSET);
-    @mb_regex_encoding(RCMAIL_CHARSET);
+    mb_internal_encoding(RCUBE_CHARSET);
+    @mb_regex_encoding(RCUBE_CHARSET);
 }
 
 // Register autoloader
diff --git a/lib/ext/Roundcube/html.php b/lib/ext/Roundcube/html.php
index 8ff685a..5fb574b 100644
--- a/lib/ext/Roundcube/html.php
+++ b/lib/ext/Roundcube/html.php
@@ -335,7 +335,7 @@ class html
      */
     public static function quote($str)
     {
-        return @htmlspecialchars($str, ENT_COMPAT, RCMAIL_CHARSET);
+        return @htmlspecialchars($str, ENT_COMPAT, RCUBE_CHARSET);
     }
 }
 
diff --git a/lib/ext/Roundcube/rcube.php b/lib/ext/Roundcube/rcube.php
index c798465..cc4905a 100644
--- a/lib/ext/Roundcube/rcube.php
+++ b/lib/ext/Roundcube/rcube.php
@@ -36,7 +36,7 @@ class rcube
     /**
      * Singleton instace of rcube
      *
-     * @var rcmail
+     * @var rcube
      */
     static protected $instance;
 
@@ -379,7 +379,7 @@ class rcube
     {
         $storage = $this->get_storage();
 
-        $storage->set_charset($this->config->get('default_charset', RCMAIL_CHARSET));
+        $storage->set_charset($this->config->get('default_charset', RCUBE_CHARSET));
 
         if ($default_folders = $this->config->get('default_folders')) {
             $storage->set_default_folders($default_folders);
@@ -894,6 +894,30 @@ class rcube
 
 
     /**
+     * Quote a given string.
+     * Shortcut function for rcube_utils::rep_specialchars_output()
+     *
+     * @return string HTML-quoted string
+     */
+    public static function Q($str, $mode = 'strict', $newlines = true)
+    {
+        return rcube_utils::rep_specialchars_output($str, 'html', $mode, $newlines);
+    }
+
+
+    /**
+     * Quote a given string for javascript output.
+     * Shortcut function for rcube_utils::rep_specialchars_output()
+     *
+     * @return string JS-quoted string
+     */
+    public static function JQ($str)
+    {
+        return rcube_utils::rep_specialchars_output($str, 'js');
+    }
+
+
+    /**
      * Construct shell command, execute it and return output as string.
      * Keywords {keyword} are replaced with arguments
      *
diff --git a/lib/ext/Roundcube/rcube_addressbook.php b/lib/ext/Roundcube/rcube_addressbook.php
index d14fc58..ea8df70 100644
--- a/lib/ext/Roundcube/rcube_addressbook.php
+++ b/lib/ext/Roundcube/rcube_addressbook.php
@@ -209,13 +209,13 @@ abstract class rcube_addressbook
      */
     public function validate(&$save_data, $autofix = false)
     {
-        $rcmail = rcube::get_instance();
+        $rcube = rcube::get_instance();
 
         // check validity of email addresses
         foreach ($this->get_col_values('email', $save_data, true) as $email) {
             if (strlen($email)) {
                 if (!rcube_utils::check_email(rcube_utils::idn_to_ascii($email))) {
-                    $error = $rcmail->gettext(array('name' => 'emailformaterror', 'vars' => array('email' => $email)));
+                    $error = $rcube->gettext(array('name' => 'emailformaterror', 'vars' => array('email' => $email)));
                     $this->set_error(self::ERROR_VALIDATE, $error);
                     return false;
                 }
diff --git a/lib/ext/Roundcube/rcube_charset.php b/lib/ext/Roundcube/rcube_charset.php
index e8cce00..6135a57 100644
--- a/lib/ext/Roundcube/rcube_charset.php
+++ b/lib/ext/Roundcube/rcube_charset.php
@@ -169,7 +169,7 @@ class rcube_charset
      *
      * @param  string Input string
      * @param  string Suspected charset of the input string
-     * @param  string Target charset to convert to; defaults to RCMAIL_CHARSET
+     * @param  string Target charset to convert to; defaults to RCUBE_CHARSET
      *
      * @return string Converted string
      */
@@ -180,7 +180,7 @@ class rcube_charset
         static $mbstring_sch    = null;
         static $conv            = null;
 
-        $to   = empty($to) ? RCMAIL_CHARSET : $to;
+        $to   = empty($to) ? RCUBE_CHARSET : $to;
         $from = self::parse_charset($from);
 
         // It is a common case when UTF-16 charset is used with US-ASCII content (#1488654)
diff --git a/lib/ext/Roundcube/rcube_config.php b/lib/ext/Roundcube/rcube_config.php
index 8112d2e..615faf3 100644
--- a/lib/ext/Roundcube/rcube_config.php
+++ b/lib/ext/Roundcube/rcube_config.php
@@ -101,11 +101,11 @@ class rcube_config
 
         // fix default imap folders encoding
         foreach (array('drafts_mbox', 'junk_mbox', 'sent_mbox', 'trash_mbox') as $folder)
-            $this->prop[$folder] = rcube_charset::convert($this->prop[$folder], RCMAIL_CHARSET, 'UTF7-IMAP');
+            $this->prop[$folder] = rcube_charset::convert($this->prop[$folder], RCUBE_CHARSET, 'UTF7-IMAP');
 
         if (!empty($this->prop['default_folders']))
             foreach ($this->prop['default_folders'] as $n => $folder)
-                $this->prop['default_folders'][$n] = rcube_charset::convert($folder, RCMAIL_CHARSET, 'UTF7-IMAP');
+                $this->prop['default_folders'][$n] = rcube_charset::convert($folder, RCUBE_CHARSET, 'UTF7-IMAP');
 
         // set PHP error logging according to config
         if ($this->prop['debug_level'] & 1) {
diff --git a/lib/ext/Roundcube/rcube_contacts.php b/lib/ext/Roundcube/rcube_contacts.php
index e4500c7..5b4292a 100644
--- a/lib/ext/Roundcube/rcube_contacts.php
+++ b/lib/ext/Roundcube/rcube_contacts.php
@@ -698,7 +698,7 @@ class rcube_contacts extends rcube_addressbook
 
         if ($sql_arr['vcard']) {
             unset($sql_arr['email']);
-            $vcard = new rcube_vcard($sql_arr['vcard'], RCMAIL_CHARSET, false, $this->vcard_fieldmap);
+            $vcard = new rcube_vcard($sql_arr['vcard'], RCUBE_CHARSET, false, $this->vcard_fieldmap);
             $record += $vcard->get_assoc() + $sql_arr;
         }
         else {
@@ -717,7 +717,7 @@ class rcube_contacts extends rcube_addressbook
         $words = '';
 
         // copy values into vcard object
-        $vcard = new rcube_vcard($record['vcard'] ? $record['vcard'] : $save_data['vcard'], RCMAIL_CHARSET, false, $this->vcard_fieldmap);
+        $vcard = new rcube_vcard($record['vcard'] ? $record['vcard'] : $save_data['vcard'], RCUBE_CHARSET, false, $this->vcard_fieldmap);
         $vcard->reset();
         foreach ($save_data as $key => $values) {
             list($field, $section) = explode(':', $key);
diff --git a/lib/ext/Roundcube/rcube_csv2vcard.php b/lib/ext/Roundcube/rcube_csv2vcard.php
index ec7a3ab..850c0c4 100644
--- a/lib/ext/Roundcube/rcube_csv2vcard.php
+++ b/lib/ext/Roundcube/rcube_csv2vcard.php
@@ -265,7 +265,7 @@ class rcube_csv2vcard
         // convert to UTF-8
         $head     = substr($csv, 0, 4096);
         $fallback = rcube::get_instance()->config->get('default_charset', 'ISO-8859-1'); // fallback to Latin-1?
-        $charset  = rcube_charset::detect($head, RCMAIL_CHARSET);
+        $charset  = rcube_charset::detect($head, RCUBE_CHARSET);
         $csv      = rcube_charset::convert($csv, $charset);
         $head     = '';
 
diff --git a/lib/ext/Roundcube/rcube_db.php b/lib/ext/Roundcube/rcube_db.php
index 5d8c4a5..2c471e7 100644
--- a/lib/ext/Roundcube/rcube_db.php
+++ b/lib/ext/Roundcube/rcube_db.php
@@ -37,12 +37,11 @@ class rcube_db
     protected $db_mode;               // Connection mode
     protected $dbh;                   // Connection handle
 
-    protected $db_error        = false;
-    protected $db_error_msg    = '';
-    protected $conn_failure    = false;
-    protected $a_query_results = array('dummy');
-    protected $last_res_id     = 0;
-    protected $db_index        = 0;
+    protected $db_error     = false;
+    protected $db_error_msg = '';
+    protected $conn_failure = false;
+    protected $db_index     = 0;
+    protected $last_result;
     protected $tables;
     protected $variables;
 
@@ -267,14 +266,14 @@ class rcube_db
     /**
      * Getter for error state
      *
-     * @param int $res_id Optional query result identifier
+     * @param mixed $result Optional query result
      *
      * @return string Error message
      */
-    public function is_error($res_id = null)
+    public function is_error($result = null)
     {
-        if ($res_id !== null) {
-            return $this->_get_result($res_id) === false ? $this->db_error_msg : null;
+        if ($result !== null) {
+            return $result === false ? $this->db_error_msg : null;
         }
 
         return $this->db_error ? $this->db_error_msg : null;
@@ -343,7 +342,7 @@ class rcube_db
      * @param int    Number of rows for LIMIT statement
      * @param mixed  Values to be inserted in query
      *
-     * @return int Query handle identifier
+     * @return PDOStatement|bool Query handle or False on error
      */
     public function limitquery()
     {
@@ -363,7 +362,7 @@ class rcube_db
      * @param int    $numrows Number of rows for LIMIT statement
      * @param array  $params  Values to be inserted in query
      *
-     * @return int Query handle identifier
+     * @return PDOStatement|bool Query handle or False on error
      */
     protected function _query($query, $offset, $numrows, $params)
     {
@@ -374,7 +373,7 @@ class rcube_db
 
         // check connection before proceeding
         if (!$this->is_connected()) {
-            return null;
+            return $this->last_result = false;
         }
 
         if ($numrows || $offset) {
@@ -417,20 +416,21 @@ class rcube_db
                 'message' => $this->db_error_msg), true, false);
         }
 
-        // add result, even if it's an error
-        return $this->_add_result($query);
+        $this->last_result = $query;
+
+        return $query;
     }
 
     /**
      * Get number of affected rows for the last query
      *
-     * @param  number $res_id Optional query handle identifier
+     * @param mixed $result Optional query handle
      *
      * @return int Number of rows or false on failure
      */
-    public function affected_rows($res_id = null)
+    public function affected_rows($result = null)
     {
-        if ($result = $this->_get_result($res_id)) {
+        if ($result || ($result === null && ($result = $this->last_result))) {
             return $result->rowCount();
         }
 
@@ -464,13 +464,12 @@ class rcube_db
      * Get an associative array for one row
      * If no query handle is specified, the last query will be taken as reference
      *
-     * @param int $res_id Optional query handle identifier
+     * @param mixed $result Optional query handle
      *
      * @return mixed Array with col values or false on failure
      */
-    public function fetch_assoc($res_id = null)
+    public function fetch_assoc($result = null)
     {
-        $result = $this->_get_result($res_id);
         return $this->_fetch_row($result, PDO::FETCH_ASSOC);
     }
 
@@ -478,31 +477,30 @@ class rcube_db
      * Get an index array for one row
      * If no query handle is specified, the last query will be taken as reference
      *
-     * @param int $res_id Optional query handle identifier
+     * @param mixed $result Optional query handle
      *
      * @return mixed Array with col values or false on failure
      */
-    public function fetch_array($res_id = null)
+    public function fetch_array($result = null)
     {
-        $result = $this->_get_result($res_id);
         return $this->_fetch_row($result, PDO::FETCH_NUM);
     }
 
     /**
      * Get col values for a result row
      *
-     * @param PDOStatement $result Result handle
-     * @param int          $mode   Fetch mode identifier
+     * @param mixed $result Optional query handle
+     * @param int   $mode   Fetch mode identifier
      *
      * @return mixed Array with col values or false on failure
      */
     protected function _fetch_row($result, $mode)
     {
-        if (!is_object($result) || !$this->is_connected()) {
-            return false;
+        if ($result || ($result === null && ($result = $this->last_result))) {
+            return $result->fetch($mode);
         }
 
-        return $result->fetch($mode);
+        return false;
     }
 
     /**
@@ -538,8 +536,8 @@ class rcube_db
         if ($this->tables === null) {
             $q = $this->query('SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES ORDER BY TABLE_NAME');
 
-            if ($res = $this->_get_result($q)) {
-                $this->tables = $res->fetchAll(PDO::FETCH_COLUMN, 0);
+            if ($q) {
+                $this->tables = $q->fetchAll(PDO::FETCH_COLUMN, 0);
             }
             else {
                 $this->tables = array();
@@ -561,8 +559,8 @@ class rcube_db
         $q = $this->query('SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ?',
             array($table));
 
-        if ($res = $this->_get_result($q)) {
-            return $res->fetchAll(PDO::FETCH_COLUMN, 0);
+        if ($q) {
+            return $q->fetchAll(PDO::FETCH_COLUMN, 0);
         }
 
         return array();
@@ -777,42 +775,6 @@ class rcube_db
     }
 
     /**
-     * Adds a query result and returns a handle ID
-     *
-     * @param object $res Query handle
-     *
-     * @return int Handle ID
-     */
-    protected function _add_result($res)
-    {
-        $this->last_res_id = sizeof($this->a_query_results);
-        $this->a_query_results[$this->last_res_id] = $res;
-
-        return $this->last_res_id;
-    }
-
-    /**
-     * Resolves a given handle ID and returns the according query handle
-     * If no ID is specified, the last resource handle will be returned
-     *
-     * @param int $res_id Handle ID
-     *
-     * @return mixed Resource handle or false on failure
-     */
-    protected function _get_result($res_id = null)
-    {
-        if ($res_id == null) {
-            $res_id = $this->last_res_id;
-        }
-
-        if (!empty($this->a_query_results[$res_id])) {
-            return $this->a_query_results[$res_id];
-        }
-
-        return false;
-    }
-
-    /**
      * Return correct name for a specific database table
      *
      * @param string $table Table name
diff --git a/lib/ext/Roundcube/rcube_enriched.php b/lib/ext/Roundcube/rcube_enriched.php
new file mode 100644
index 0000000..8b64fe0
--- /dev/null
+++ b/lib/ext/Roundcube/rcube_enriched.php
@@ -0,0 +1,147 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_enriched.php                                    |
+ |                                                                       |
+ | This file is part of the Roundcube Webmail client                     |
+ | Copyright (C) 2005-2012, The Roundcube Dev Team                       |
+ |                                                                       |
+ | Licensed under the GNU General Public License version 3 or            |
+ | any later version with exceptions for skins & plugins.                |
+ | See the README file for a full license statement.                     |
+ |                                                                       |
+ | PURPOSE:                                                              |
+ |   Helper class to convert Enriched to HTML format (RFC 1523, 1896)    |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Aleksander Machniak <alec at alec.pl>                            |
+ | Author: Ryo Chijiiwa (IlohaMail)                                      |
+ +-----------------------------------------------------------------------+
+*/
+
+
+/**
+ * Class for Enriched to HTML conversion
+ *
+ * @package    Framework
+ * @subpackage Utils
+ */
+class rcube_enriched
+{
+    protected static function convert_newlines($body)
+    {
+        // remove single newlines, convert N newlines to N-1
+        $body = str_replace("\r\n", "\n", $body);
+        $len  = strlen($body);
+        $nl   = 0;
+        $out  = '';
+
+        for ($i=0; $i<$len; $i++) {
+            $c = $body[$i];
+            if (ord($c) == 10)
+                $nl++;
+            if ($nl && ord($c) != 10)
+                $nl = 0;
+            if ($nl != 1)
+                $out .= $c;
+            else
+                $out .= ' ';
+        }
+
+        return $out;
+    }
+
+    protected static function convert_formatting($body)
+    {
+        $replace = array(
+            '<bold>'        => '<b>',            '</bold>'   => '</b>',
+            '<italic>'      => '<i>',            '</italic>' => '</i>',
+            '<fixed>'       => '<tt>',           '</fixed>'  => '</tt>',
+            '<smaller>'     => '<font size=-1>', '</smaller>'=> '</font>',
+            '<bigger>'      => '<font size=+1>', '</bigger>' => '</font>',
+            '<underline>'   => '<span style="text-decoration: underline">', '</underline>'   => '</span>',
+            '<flushleft>'   => '<span style="text-align: left">',           '</flushleft>'   => '</span>',
+            '<flushright>'  => '<span style="text-align: right">',          '</flushright>'  => '</span>',
+            '<flushboth>'   => '<span style="text-align: justified">',      '</flushboth>'   => '</span>',
+            '<indent>'      => '<span style="padding-left: 20px">',         '</indent>'      => '</span>',
+            '<indentright>' => '<span style="padding-right: 20px">',        '</indentright>' => '</span>',
+        );
+
+        return str_ireplace(array_keys($replace), array_values($replace), $body);
+    }
+
+    protected static function convert_font($body)
+    {
+        $pattern = '/(.*)\<fontfamily\>\<param\>(.*)\<\/param\>(.*)\<\/fontfamily\>(.*)/ims';
+
+        while (preg_match($pattern, $body, $a)) {
+            if (count($a) != 5)
+                continue;
+
+            $body = $a[1].'<span style="font-family: '.$a[2].'">'.$a[3].'</span>'.$a[4];
+        }
+
+        return $body;
+    }
+
+    protected static function convert_color($body)
+    {
+        $pattern = '/(.*)\<color\>\<param\>(.*)\<\/param\>(.*)\<\/color\>(.*)/ims';
+
+        while (preg_match($pattern, $body, $a)) {
+            if (count($a) != 5)
+                continue;
+
+            // extract color (either by name, or ####,####,####)
+            if (strpos($a[2],',')) {
+                $rgb   = explode(',',$a[2]);
+                $color = '#';
+                for ($i=0; $i<3; $i++)
+                    $color .= substr($rgb[$i], 0, 2); // just take first 2 bytes
+            }
+            else {
+                $color = $a[2];
+            }
+
+            // put it all together
+            $body = $a[1].'<span style="color: '.$color.'">'.$a[3].'</span>'.$a[4];
+        }
+
+        return $body;
+    }
+
+    protected static function convert_excerpt($body)
+    {
+        $pattern = '/(.*)\<excerpt\>(.*)\<\/excerpt\>(.*)/i';
+
+        while (preg_match($pattern, $body, $a)) {
+            if (count($a) != 4)
+                continue;
+
+            $quoted = '';
+            $lines  = explode('<br>', $a[2]);
+
+            foreach ($lines as $n => $line)
+                $quoted .= '>'.$line.'<br>';
+
+            $body = $a[1].'<span class="quotes">'.$quoted.'</span>'.$a[3];
+        }
+
+        return $body;
+    }
+
+    public static function to_html($body)
+    {
+        $body = str_replace('<<','<',$body);
+        $body = self::convert_newlines($body);
+        $body = str_replace("\n", '<br>', $body);
+        $body = self::convert_formatting($body);
+        $body = self::convert_color($body);
+        $body = self::convert_font($body);
+        $body = self::convert_excerpt($body);
+        //$body = nl2br($body);
+
+        return $body;
+    }
+}
diff --git a/lib/ext/Roundcube/rcube_imap.php b/lib/ext/Roundcube/rcube_imap.php
index ac12ec7..8ca24de 100644
--- a/lib/ext/Roundcube/rcube_imap.php
+++ b/lib/ext/Roundcube/rcube_imap.php
@@ -141,10 +141,10 @@ class rcube_imap extends rcube_storage
             $this->set_debug(true);
 
             $this->options['ident'] = array(
-                'name' => 'Roundcube',
+                'name'    => 'Roundcube',
                 'version' => RCUBE_VERSION,
-                'php' => PHP_VERSION,
-                'os' => PHP_OS,
+                'php'     => PHP_VERSION,
+                'os'      => PHP_OS,
                 'command' => $_SERVER['REQUEST_URI'],
             );
         }
@@ -2051,10 +2051,11 @@ class rcube_imap extends rcube_storage
      * @param  mixed              $print  True to print part, ressource to write part contents in
      * @param  resource           $fp     File pointer to save the message part
      * @param  boolean            $skip_charset_conv Disables charset conversion
+     * @param  int                $max_bytes  Only read this number of bytes
      *
      * @return string Message/part body if not printed
      */
-    public function get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL, $skip_charset_conv=false)
+    public function get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL, $skip_charset_conv=false, $max_bytes=0)
     {
         if (!$this->check_connection()) {
             return null;
@@ -2074,7 +2075,7 @@ class rcube_imap extends rcube_storage
 
         if ($o_part && $o_part->size) {
             $body = $this->conn->handlePartBody($this->folder, $uid, true,
-                $part ? $part : 'TEXT', $o_part->encoding, $print, $fp, $o_part->ctype_primary == 'text');
+                $part ? $part : 'TEXT', $o_part->encoding, $print, $fp, $o_part->ctype_primary == 'text', $max_bytes);
         }
 
         if ($fp || $print) {
diff --git a/lib/ext/Roundcube/rcube_imap_generic.php b/lib/ext/Roundcube/rcube_imap_generic.php
index a0a8f3b..0f32d83 100644
--- a/lib/ext/Roundcube/rcube_imap_generic.php
+++ b/lib/ext/Roundcube/rcube_imap_generic.php
@@ -2206,10 +2206,13 @@ class rcube_imap_generic
                             }
                             break;
                         default:
-                            if (strlen($field) > 2) {
-                                $result[$id]->others[$field] = $string;
+                            if (strlen($field) < 3) {
+                                break;
                             }
-                            break;
+                            if ($result[$id]->others[$field]) {
+                                $string = array_merge((array)$result[$id]->others[$field], (array)$string);
+                            }
+                            $result[$id]->others[$field] = $string;
                         }
                     }
                 }
@@ -2217,7 +2220,6 @@ class rcube_imap_generic
 
             // VANISHED response (QRESYNC RFC5162)
             // Sample: * VANISHED (EARLIER) 300:310,405,411
-
             else if (preg_match('/^\* VANISHED [()EARLIER]*/i', $line, $match)) {
                 $line   = substr($line, strlen($match[0]));
                 $v_data = $this->tokenizeResponse($line, 1);
@@ -2379,7 +2381,7 @@ class rcube_imap_generic
         return $this->handlePartBody($mailbox, $id, $is_uid, $part);
     }
 
-    function handlePartBody($mailbox, $id, $is_uid=false, $part='', $encoding=NULL, $print=NULL, $file=NULL, $formatted=false)
+    function handlePartBody($mailbox, $id, $is_uid=false, $part='', $encoding=NULL, $print=NULL, $file=NULL, $formatted=false, $max_bytes=0)
     {
         if (!$this->select($mailbox)) {
             return false;
@@ -2405,10 +2407,12 @@ class rcube_imap_generic
         // Use BINARY extension when possible (and safe)
         $binary     = $mode && preg_match('/^[0-9.]+$/', $part) && $this->hasCapability('BINARY');
         $fetch_mode = $binary ? 'BINARY' : 'BODY';
+        $partial    = $max_bytes ? sprintf('<0.%d>', $max_bytes) : '';
 
         // format request
-        $key       = $this->nextTag();
-        $request   = $key . ($is_uid ? ' UID' : '') . " FETCH $id ($fetch_mode.PEEK[$part])";
+        $key     = $this->nextTag();
+        $request = $key . ($is_uid ? ' UID' : '') . " FETCH $id ($fetch_mode.PEEK[$part]$partial)";
+        $result  = false;
 
         // send request
         if (!$this->putLine($request)) {
@@ -2421,116 +2425,117 @@ class rcube_imap_generic
             $mode = -1;
         }
 
-        // receive reply line
         do {
-            $line = rtrim($this->readLine(1024));
-            $a    = explode(' ', $line);
-        } while (!($end = $this->startsWith($line, $key, true)) && $a[2] != 'FETCH');
-
-        $len    = strlen($line);
-        $result = false;
+            $line = trim($this->readLine(1024));
 
-        if ($a[2] != 'FETCH') {
-        }
-        // handle empty "* X FETCH ()" response
-        else if ($line[$len-1] == ')' && $line[$len-2] != '(') {
-            // one line response, get everything between first and last quotes
-            if (substr($line, -4, 3) == 'NIL') {
-                // NIL response
-                $result = '';
-            } else {
-                $from = strpos($line, '"') + 1;
-                $to   = strrpos($line, '"');
-                $len  = $to - $from;
-                $result = substr($line, $from, $len);
+            if (!$line) {
+                break;
             }
 
-            if ($mode == 1) {
-                $result = base64_decode($result);
-            }
-            else if ($mode == 2) {
-                $result = quoted_printable_decode($result);
-            }
-            else if ($mode == 3) {
-                $result = convert_uudecode($result);
+            if (!preg_match('/^\* ([0-9]+) FETCH (.*)$/', $line, $m)) {
+                continue;
             }
 
-        } else if ($line[$len-1] == '}') {
-            // multi-line request, find sizes of content and receive that many bytes
-            $from     = strpos($line, '{') + 1;
-            $to       = strrpos($line, '}');
-            $len      = $to - $from;
-            $sizeStr  = substr($line, $from, $len);
-            $bytes    = (int)$sizeStr;
-            $prev     = '';
+            $line = $m[2];
+            $last = substr($line, -1);
 
-            while ($bytes > 0) {
-                $line = $this->readLine(8192);
+            // handle one line response
+            if ($line[0] == '(' && $last == ')') {
+                // tokenize content inside brackets
+                $tokens = $this->tokenizeResponse(preg_replace('/(^\(|\$)/', '', $line));
+                $result = count($tokens) == 1 ? $tokens[0] : false;
 
-                if ($line === NULL) {
-                    break;
+                if ($result !== false) {
+                    if ($mode == 1) {
+                        $result = base64_decode($result);
+                    }
+                    else if ($mode == 2) {
+                        $result = quoted_printable_decode($result);
+                    }
+                    else if ($mode == 3) {
+                        $result = convert_uudecode($result);
+                    }
                 }
+            }
+            // response with string literal
+            else if (preg_match('/\{([0-9]+)\}$/', $line, $m)) {
+                $bytes = (int) $m[1];
+                $prev  = '';
 
-                $len = strlen($line);
+                while ($bytes > 0) {
+                    $line = $this->readLine(8192);
+
+                    if ($line === NULL) {
+                        break;
+                    }
 
-                if ($len > $bytes) {
-                    $line = substr($line, 0, $bytes);
                     $len = strlen($line);
-                }
-                $bytes -= $len;
-
-                // BASE64
-                if ($mode == 1) {
-                    $line = rtrim($line, "\t\r\n\0\x0B");
-                    // create chunks with proper length for base64 decoding
-                    $line = $prev.$line;
-                    $length = strlen($line);
-                    if ($length % 4) {
-                        $length = floor($length / 4) * 4;
-                        $prev = substr($line, $length);
-                        $line = substr($line, 0, $length);
+
+                    if ($len > $bytes) {
+                        $line = substr($line, 0, $bytes);
+                        $len  = strlen($line);
+                    }
+                    $bytes -= $len;
+
+                    // BASE64
+                    if ($mode == 1) {
+                        $line = rtrim($line, "\t\r\n\0\x0B");
+                        // create chunks with proper length for base64 decoding
+                        $line = $prev.$line;
+                        $length = strlen($line);
+                        if ($length % 4) {
+                            $length = floor($length / 4) * 4;
+                            $prev = substr($line, $length);
+                            $line = substr($line, 0, $length);
+                        }
+                        else {
+                            $prev = '';
+                        }
+                        $line = base64_decode($line);
+                    }
+                    // QUOTED-PRINTABLE
+                    else if ($mode == 2) {
+                        $line = rtrim($line, "\t\r\0\x0B");
+                        $line = quoted_printable_decode($line);
+                    }
+                    // UUENCODE
+                    else if ($mode == 3) {
+                        $line = rtrim($line, "\t\r\n\0\x0B");
+                        if ($line == 'end' || preg_match('/^begin\s+[0-7]+\s+.+$/', $line)) {
+                            continue;
+                        }
+                        $line = convert_uudecode($line);
+                    }
+                    // default
+                    else if ($formatted) {
+                        $line = rtrim($line, "\t\r\n\0\x0B") . "\n";
                     }
-                    else
-                        $prev = '';
-                    $line = base64_decode($line);
-                // QUOTED-PRINTABLE
-                } else if ($mode == 2) {
-                    $line = rtrim($line, "\t\r\0\x0B");
-                    $line = quoted_printable_decode($line);
-                // UUENCODE
-                } else if ($mode == 3) {
-                    $line = rtrim($line, "\t\r\n\0\x0B");
-                    if ($line == 'end' || preg_match('/^begin\s+[0-7]+\s+.+$/', $line))
-                        continue;
-                    $line = convert_uudecode($line);
-                // default
-                } else if ($formatted) {
-                    $line = rtrim($line, "\t\r\n\0\x0B") . "\n";
-                }
 
-                if ($file)
-                    fwrite($file, $line);
-                else if ($print)
-                    echo $line;
-                else
-                    $result .= $line;
+                    if ($file) {
+                        if (fwrite($file, $line) === false) {
+                            break;
+                        }
+                    }
+                    else if ($print) {
+                        echo $line;
+                    }
+                    else {
+                        $result .= $line;
+                    }
+                }
             }
-        }
-
-        // read in anything up until last line
-        if (!$end)
-            do {
-                $line = $this->readLine(1024);
-            } while (!$this->startsWith($line, $key, true));
+        } while (!$this->startsWith($line, $key, true));
 
         if ($result !== false) {
             if ($file) {
-                fwrite($file, $result);
-            } else if ($print) {
+                return fwrite($file, $result);
+            }
+            else if ($print) {
                 echo $result;
-            } else
-                return $result;
-            return true;
+                return true;
+            }
+
+            return $result;
         }
 
         return false;
diff --git a/lib/ext/Roundcube/rcube_message.php b/lib/ext/Roundcube/rcube_message.php
index 87319f0..4ef534a 100644
--- a/lib/ext/Roundcube/rcube_message.php
+++ b/lib/ext/Roundcube/rcube_message.php
@@ -173,10 +173,11 @@ class rcube_message
      * @param string   $mime_id           Part MIME-ID
      * @param resource $fp File           pointer to save the message part
      * @param boolean  $skip_charset_conv Disables charset conversion
+     * @param int      $max_bytes         Only read this number of bytes
      *
      * @return string Part content
      */
-    public function get_part_content($mime_id, $fp = null, $skip_charset_conv = false)
+    public function get_part_content($mime_id, $fp = null, $skip_charset_conv = false, $max_bytes = 0)
     {
         if ($part = $this->mime_parts[$mime_id]) {
             // stored in message structure (winmail/inline-uuencode)
@@ -190,7 +191,7 @@ class rcube_message
             // get from IMAP
             $this->storage->set_folder($this->folder);
 
-            return $this->storage->get_message_part($this->uid, $mime_id, $part, NULL, $fp, $skip_charset_conv);
+            return $this->storage->get_message_part($this->uid, $mime_id, $part, NULL, $fp, $skip_charset_conv, $max_bytes);
         }
     }
 
diff --git a/lib/ext/Roundcube/rcube_mime.php b/lib/ext/Roundcube/rcube_mime.php
index 25ee31d..17cb3f0 100644
--- a/lib/ext/Roundcube/rcube_mime.php
+++ b/lib/ext/Roundcube/rcube_mime.php
@@ -59,7 +59,7 @@ class rcube_mime
             return $charset;
         }
 
-        return RCMAIL_CHARSET;
+        return RCUBE_CHARSET;
     }
 
 
@@ -572,8 +572,9 @@ class rcube_mime
      */
     public static function wordwrap($string, $width=75, $break="\n", $cut=false, $charset=null)
     {
-        if ($charset && function_exists('mb_internal_encoding'))
+        if ($charset && function_exists('mb_internal_encoding')) {
             mb_internal_encoding($charset);
+        }
 
         $para   = preg_split('/\r?\n/', $string);
         $string = '';
@@ -629,8 +630,9 @@ class rcube_mime
             }
         }
 
-        if ($charset && function_exists('mb_internal_encoding'))
-            mb_internal_encoding(RCMAIL_CHARSET);
+        if ($charset && function_exists('mb_internal_encoding')) {
+            mb_internal_encoding(RCUBE_CHARSET);
+        }
 
         return $string;
     }
@@ -639,21 +641,22 @@ class rcube_mime
     /**
      * A method to guess the mime_type of an attachment.
      *
-     * @param string $path      Path to the file.
+     * @param string $path      Path to the file or file contents
      * @param string $name      File name (with suffix)
-     * @param string $failover  Mime type supplied for failover.
-     * @param string $is_stream Set to True if $path contains file body
+     * @param string $failover  Mime type supplied for failover
+     * @param boolean $is_stream   Set to True if $path contains file contents
+     * @param boolean $skip_suffix Set to True if the config/mimetypes.php mappig should be ignored
      *
      * @return string
      * @author Till Klampaeckel <till at php.net>
      * @see    http://de2.php.net/manual/en/ref.fileinfo.php
      * @see    http://de2.php.net/mime_content_type
      */
-    public static function file_content_type($path, $name, $failover = 'application/octet-stream', $is_stream = false)
+    public static function file_content_type($path, $name, $failover = 'application/octet-stream', $is_stream = false, $skip_suffix = false)
     {
         $mime_type = null;
         $mime_magic = rcube::get_instance()->config->get('mime_magic');
-        $mime_ext = @include RCUBE_CONFIG_DIR . '/mimetypes.php';
+        $mime_ext = $skip_suffix ? null : @include(RCUBE_CONFIG_DIR . '/mimetypes.php');
 
         // use file name suffix with hard-coded mime-type map
         if (is_array($mime_ext) && $name) {
@@ -693,6 +696,70 @@ class rcube_mime
 
 
     /**
+     * Get mimetype => file extension mapping
+     *
+     * @param string  Mime-Type to get extensions for
+     * @return array  List of extensions matching the given mimetype or a hash array with ext -> mimetype mappings if $mimetype is not given
+     */
+    public static function get_mime_extensions($mimetype = null)
+    {
+        static $mime_types, $mime_extensions;
+
+        // return cached data
+        if (is_array($mime_types)) {
+            return $mimetype ? $mime_types[$mimetype] : $mime_extensions;
+        }
+
+        // load mapping file
+        $file_paths = array();
+
+        if ($mime_types = rcube::get_instance()->config->get('mime_types'))
+            $file_paths[] = $mime_types;
+
+        // try common locations
+        $file_paths[] = '/etc/httpd/mime.types';
+        $file_paths[] = '/etc/httpd2/mime.types';
+        $file_paths[] = '/etc/apache/mime.types';
+        $file_paths[] = '/etc/apache2/mime.types';
+        $file_paths[] = '/usr/local/etc/httpd/conf/mime.types';
+        $file_paths[] = '/usr/local/etc/apache/conf/mime.types';
+
+        foreach ($file_paths as $fp) {
+            if (is_readable($fp)) {
+                $lines = file($fp, FILE_IGNORE_NEW_LINES);
+                break;
+            }
+        }
+
+        $mime_types = $mime_extensions = array();
+        $regex = "/([\w\+\-\.\/]+)\t+([\w\s]+)/i"; 
+        foreach((array)$lines as $line) {
+             // skip comments or mime types w/o any extensions
+            if ($line[0] == '#' || !preg_match($regex, $line, $matches))
+                continue;
+
+            $mime = $matches[1];
+            foreach (explode(' ', $matches[2]) as $ext) {
+                $ext = trim($ext);
+                $mime_types[$mime][] = $ext;
+                $mime_extensions[$ext] = $mime;
+            }
+        }
+
+        // fallback to some well-known types most important for daily emails
+        if (empty($mime_types)) {
+            $mime_extensions = @include(RCUBE_CONFIG_DIR . '/mimetypes.php');
+            $mime_extensions += array('gif' => 'image/gif', 'png' => 'image/png', 'jpg' => 'image/jpg', 'jpeg' => 'image/jpeg', 'tif' => 'image/tiff');
+
+            foreach ($mime_extensions as $ext => $mime)
+                $mime_types[$mime][] = $ext;
+        }
+
+        return $mimetype ? $mime_types[$mimetype] : $mime_extensions;
+    }
+
+
+    /**
      * Detect image type of the given binary data by checking magic numbers.
      *
      * @param string $data  Binary file content
diff --git a/lib/ext/Roundcube/rcube_output.php b/lib/ext/Roundcube/rcube_output.php
new file mode 100644
index 0000000..4ef42f5
--- /dev/null
+++ b/lib/ext/Roundcube/rcube_output.php
@@ -0,0 +1,271 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_output.php                                      |
+ |                                                                       |
+ | This file is part of the Roundcube PHP suite                          |
+ | Copyright (C) 2005-2012 The Roundcube Dev Team                        |
+ |                                                                       |
+ | Licensed under the GNU General Public License version 3 or            |
+ | any later version with exceptions for skins & plugins.                |
+ | See the README file for a full license statement.                     |
+ | CONTENTS:                                                             |
+ |   Abstract class for output generation                                |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube at gmail.com>                        |
+ | Author: Aleksander Machniak <alec at alec.pl>                            |
+ +-----------------------------------------------------------------------+
+*/
+
+/**
+ * Class for output generation
+ *
+ * @package    Framework
+ * @subpackage View
+ */
+abstract class rcube_output
+{
+    public $browser;
+
+    protected $app;
+    protected $config;
+    protected $charset = RCUBE_CHARSET;
+    protected $env = array();
+
+
+    /**
+     * Object constructor
+     */
+    public function __construct()
+    {
+        $this->app     = rcube::get_instance();
+        $this->config  = $this->app->config;
+        $this->browser = new rcube_browser();
+    }
+
+
+    /**
+     * Magic getter
+     */
+    public function __get($var)
+    {
+        // allow read-only access to $env
+        if ($var == 'env')
+            return $this->env;
+
+        return null;
+    }
+
+
+    /**
+     * Setter for output charset.
+     * To be specified in a meta tag and sent as http-header
+     *
+     * @param string $charset Charset name
+     */
+    public function set_charset($charset)
+    {
+        $this->charset = $charset;
+    }
+
+
+    /**
+     * Getter for output charset
+     *
+     * @return string Output charset name
+     */
+    public function get_charset()
+    {
+        return $this->charset;
+    }
+
+
+    /**
+     * Set environment variable
+     *
+     * @param string $name   Property name
+     * @param mixed  $value  Property value
+     */
+    public function set_env($name, $value)
+    {
+        $this->env[$name] = $value;
+    }
+
+
+    /**
+     * Environment variable getter.
+     *
+     * @param string $name  Property name
+     *
+     * @return mixed Property value
+     */
+    public function get_env($name)
+    {
+        return $this->env[$name];
+    }
+
+
+    /**
+     * Delete all stored env variables and commands
+     */
+    public function reset()
+    {
+        $this->env = array();
+    }
+
+
+    /**
+     * Invoke display_message command
+     *
+     * @param string  $message  Message to display
+     * @param string  $type     Message type [notice|confirm|error]
+     * @param array   $vars     Key-value pairs to be replaced in localized text
+     * @param boolean $override Override last set message
+     * @param int     $timeout  Message displaying time in seconds
+     */
+    abstract function show_message($message, $type = 'notice', $vars = null, $override = true, $timeout = 0);
+
+
+    /**
+     * Redirect to a certain url.
+     *
+     * @param mixed $p     Either a string with the action or url parameters as key-value pairs
+     * @param int   $delay Delay in seconds
+     */
+    abstract function redirect($p = array(), $delay = 1);
+
+
+    /**
+     * Send output to the client.
+     */
+    abstract function send();
+
+
+    /**
+     * Send HTTP headers to prevent caching a page
+     */
+    public function nocacheing_headers()
+    {
+        if (headers_sent()) {
+            return;
+        }
+
+        header("Expires: ".gmdate("D, d M Y H:i:s")." GMT");
+        header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
+
+        // Request browser to disable DNS prefetching (CVE-2010-0464)
+        header("X-DNS-Prefetch-Control: off");
+
+        // We need to set the following headers to make downloads work using IE in HTTPS mode.
+        if ($this->browser->ie && rcube_utils::https_check()) {
+            header('Pragma: private');
+            header("Cache-Control: private, must-revalidate");
+        }
+        else {
+            header("Cache-Control: private, no-cache, must-revalidate, post-check=0, pre-check=0");
+            header("Pragma: no-cache");
+        }
+    }
+
+    /**
+     * Send header with expire date 30 days in future
+     *
+     * @param int Expiration time in seconds
+     */
+    public function future_expire_header($offset = 2600000)
+    {
+        if (headers_sent())
+            return;
+
+        header("Expires: " . gmdate("D, d M Y H:i:s", time()+$offset) . " GMT");
+        header("Cache-Control: max-age=$offset");
+        header("Pragma: ");
+    }
+
+
+    /**
+     * Show error page and terminate script execution
+     *
+     * @param int    $code     Error code
+     * @param string $message  Error message
+     */
+    public function raise_error($code, $message)
+    {
+        // STUB: to be overloaded by specific output classes
+        fputs(STDERR, "Error $code: $message\n");
+        exit(-1);
+    }
+
+
+    /**
+     * Create an edit field for inclusion on a form
+     *
+     * @param string col field name
+     * @param string value field value
+     * @param array attrib HTML element attributes for field
+     * @param string type HTML element type (default 'text')
+     *
+     * @return string HTML field definition
+     */
+    public static function get_edit_field($col, $value, $attrib, $type = 'text')
+    {
+        static $colcounts = array();
+
+        $fname = '_'.$col;
+        $attrib['name']  = $fname . ($attrib['array'] ? '[]' : '');
+        $attrib['class'] = trim($attrib['class'] . ' ff_' . $col);
+
+        if ($type == 'checkbox') {
+            $attrib['value'] = '1';
+            $input = new html_checkbox($attrib);
+        }
+        else if ($type == 'textarea') {
+            $attrib['cols'] = $attrib['size'];
+            $input = new html_textarea($attrib);
+        }
+        else if ($type == 'select') {
+            $input = new html_select($attrib);
+            $input->add('---', '');
+            $input->add(array_values($attrib['options']), array_keys($attrib['options']));
+        }
+        else if ($attrib['type'] == 'password') {
+            $input = new html_passwordfield($attrib);
+        }
+        else {
+            if ($attrib['type'] != 'text' && $attrib['type'] != 'hidden') {
+                $attrib['type'] = 'text';
+            }
+            $input = new html_inputfield($attrib);
+        }
+
+        // use value from post
+        if (isset($_POST[$fname])) {
+            $postvalue = rcube_utils::get_input_value($fname, rcube_utils::INPUT_POST, true);
+            $value = $attrib['array'] ? $postvalue[intval($colcounts[$col]++)] : $postvalue;
+        }
+
+        $out = $input->show($value);
+
+        return $out;
+    }
+
+
+    /**
+     * Convert a variable into a javascript object notation
+     *
+     * @param mixed Input value
+     *
+     * @return string Serialized JSON string
+     */
+    public static function json_serialize($input)
+    {
+        $input = rcube_charset::clean($input);
+
+        // sometimes even using rcube_charset::clean() the input contains invalid UTF-8 sequences
+        // that's why we have @ here
+        return @json_encode($input);
+    }
+
+}
diff --git a/lib/ext/Roundcube/rcube_plugin.php b/lib/ext/Roundcube/rcube_plugin.php
index dbb15e8..5db8502 100644
--- a/lib/ext/Roundcube/rcube_plugin.php
+++ b/lib/ext/Roundcube/rcube_plugin.php
@@ -203,23 +203,23 @@ abstract class rcube_plugin
       foreach ($texts as $key => $value)
         $add[$domain.'.'.$key] = $value;
 
-      $rcmail = rcube::get_instance();
-      $rcmail->load_language($lang, $add);
+      $rcube = rcube::get_instance();
+      $rcube->load_language($lang, $add);
 
       // add labels to client
       if ($add2client) {
         $js_labels = is_array($add2client) ? array_map(array($this, 'label_map_callback'), $add2client) : array_keys($add);
-        $rcmail->output->add_label($js_labels);
+        $rcube->output->add_label($js_labels);
       }
     }
   }
 
   /**
-   * Wrapper for rcmail::gettext() adding the plugin ID as domain
+   * Wrapper for rcube::gettext() adding the plugin ID as domain
    *
    * @param string $p Message identifier
    * @return string Localized text
-   * @see rcmail::gettext()
+   * @see rcube::gettext()
    */
   public function gettext($p)
   {
@@ -336,8 +336,8 @@ abstract class rcube_plugin
    */
   public function local_skin_path()
   {
-    $rcmail = rcube::get_instance();
-    foreach (array($rcmail->config->get('skin'), 'larry') as $skin) {
+    $rcube = rcube::get_instance();
+    foreach (array($rcube->config->get('skin'), 'larry') as $skin) {
       $skin_path = 'skins/' . $skin;
       if (is_dir(realpath(slashify($this->home) . $skin_path)))
         break;
diff --git a/lib/ext/Roundcube/rcube_spellchecker.php b/lib/ext/Roundcube/rcube_spellchecker.php
index 30d15d7..fce2cac 100644
--- a/lib/ext/Roundcube/rcube_spellchecker.php
+++ b/lib/ext/Roundcube/rcube_spellchecker.php
@@ -150,7 +150,7 @@ class rcube_spellchecker
     function get_xml()
     {
         // send output
-        $out = '<?xml version="1.0" encoding="'.RCMAIL_CHARSET.'"?><spellresult charschecked="'.mb_strlen($this->content).'">';
+        $out = '<?xml version="1.0" encoding="'.RCUBE_CHARSET.'"?><spellresult charschecked="'.mb_strlen($this->content).'">';
 
         foreach ($this->matches as $item) {
             $out .= '<c o="'.$item[1].'" l="'.$item[2].'">';
@@ -178,7 +178,7 @@ class rcube_spellchecker
                 $word = $item[0];
             }
             else {
-                $word = mb_substr($this->content, $item[1], $item[2], RCMAIL_CHARSET);
+                $word = mb_substr($this->content, $item[1], $item[2], RCUBE_CHARSET);
             }
             $result[$word] = is_array($item[4]) ? implode("\t", $item[4]) : $item[4];
         }
@@ -326,7 +326,7 @@ class rcube_spellchecker
                 return;
             }
 
-            $this->plink = pspell_new($this->lang, null, null, RCMAIL_CHARSET, PSPELL_FAST);
+            $this->plink = pspell_new($this->lang, null, null, RCUBE_CHARSET, PSPELL_FAST);
         }
 
         if (!$this->plink) {
@@ -387,7 +387,7 @@ class rcube_spellchecker
             || !empty($this->options['ignore_caps']) || !empty($this->options['dictionary'])
         ) {
             foreach ($matches as $idx => $m) {
-                $word = mb_substr($text, $m[1], $m[2], RCMAIL_CHARSET);
+                $word = mb_substr($text, $m[1], $m[2], RCUBE_CHARSET);
                 // skip  exceptions
                 if ($this->is_exception($word)) {
                     unset($matches[$idx]);
@@ -416,7 +416,7 @@ class rcube_spellchecker
         $result = array();
 
         foreach ($matches as $m) {
-            $result[] = mb_substr($text, $m[1], $m[2], RCMAIL_CHARSET);
+            $result[] = mb_substr($text, $m[1], $m[2], RCUBE_CHARSET);
         }
 
         return $result;
diff --git a/lib/ext/Roundcube/rcube_storage.php b/lib/ext/Roundcube/rcube_storage.php
index 1556aae..245d911 100644
--- a/lib/ext/Roundcube/rcube_storage.php
+++ b/lib/ext/Roundcube/rcube_storage.php
@@ -64,6 +64,7 @@ abstract class rcube_storage
         'MAIL-FOLLOWUP-TO',
         'MAIL-REPLY-TO',
         'RETURN-PATH',
+        'DELIVERED-TO',
     );
 
     const UNKNOWN       = 0;
diff --git a/lib/ext/Roundcube/rcube_string_replacer.php b/lib/ext/Roundcube/rcube_string_replacer.php
index 9af6b33..584b9f6 100644
--- a/lib/ext/Roundcube/rcube_string_replacer.php
+++ b/lib/ext/Roundcube/rcube_string_replacer.php
@@ -5,7 +5,7 @@
  | program/include/rcube_string_replacer.php                             |
  |                                                                       |
  | This file is part of the Roundcube Webmail client                     |
- | Copyright (C) 2009, The Roundcube Dev Team                            |
+ | Copyright (C) 2009-2012, The Roundcube Dev Team                       |
  |                                                                       |
  | Licensed under the GNU General Public License version 3 or            |
  | any later version with exceptions for skins & plugins.                |
@@ -96,7 +96,7 @@ class rcube_string_replacer
       $i = $this->add($prefix . html::a(array(
           'href' => $url_prefix . $url,
           'target' => '_blank'
-        ), rcmail::Q($url)) . $suffix);
+        ), rcube::Q($url)) . $suffix);
     }
 
     // Return valid link for recognized schemes, otherwise, return the unmodified string for unrecognized schemes.
@@ -113,11 +113,7 @@ class rcube_string_replacer
   {
     $href   = $matches[1];
     $suffix = $this->parse_url_brackets($href);
-
-    $i = $this->add(html::a(array(
-        'href' => 'mailto:' . $href,
-        'onclick' => "return ".rcmail::JS_OBJECT_NAME.".command('compose','".rcmail::JQ($href)."',this)",
-      ), rcmail::Q($href)) . $suffix);
+    $i = $this->add(html::a('mailto:' . $href, rcube::Q($href)) . $suffix);
 
     return $i >= 0 ? $this->get_replacement($i) : '';
   }
diff --git a/lib/ext/Roundcube/rcube_user.php b/lib/ext/Roundcube/rcube_user.php
index 864f2e0..f6b77f5 100644
--- a/lib/ext/Roundcube/rcube_user.php
+++ b/lib/ext/Roundcube/rcube_user.php
@@ -240,10 +240,12 @@ class rcube_user
     /**
      * Return a list of all identities linked with this user
      *
-     * @param string $sql_add Optional WHERE clauses
+     * @param string $sql_add   Optional WHERE clauses
+     * @param bool   $formatted Format identity email and name
+     *
      * @return array List of identities
      */
-    function list_identities($sql_add = '')
+    function list_identities($sql_add = '', $formatted = false)
     {
         $result = array();
 
@@ -255,6 +257,15 @@ class rcube_user
             $this->ID);
 
         while ($sql_arr = $this->db->fetch_assoc($sql_result)) {
+            if ($formatted) {
+                $ascii_email = format_email($sql_arr['email']);
+                $utf8_email  = format_email(rcube_utils::idn_to_utf8($ascii_email));
+
+                $sql_arr['email_ascii'] = $ascii_email;
+                $sql_arr['email']       = $utf8_email;
+                $sql_arr['ident']       = format_email_recipient($ascii_email, $sql_arr['name']);
+            }
+
             $result[] = $sql_arr;
         }
 
diff --git a/lib/ext/Roundcube/rcube_utils.php b/lib/ext/Roundcube/rcube_utils.php
index df77dfe..500f2c3 100644
--- a/lib/ext/Roundcube/rcube_utils.php
+++ b/lib/ext/Roundcube/rcube_utils.php
@@ -434,59 +434,6 @@ class rcube_utils
 
 
     /**
-     * Create an edit field for inclusion on a form
-     *
-     * @param string col field name
-     * @param string value field value
-     * @param array attrib HTML element attributes for field
-     * @param string type HTML element type (default 'text')
-     *
-     * @return string HTML field definition
-     */
-    public static function get_edit_field($col, $value, $attrib, $type = 'text')
-    {
-        static $colcounts = array();
-
-        $fname = '_'.$col;
-        $attrib['name']  = $fname . ($attrib['array'] ? '[]' : '');
-        $attrib['class'] = trim($attrib['class'] . ' ff_' . $col);
-
-        if ($type == 'checkbox') {
-            $attrib['value'] = '1';
-            $input = new html_checkbox($attrib);
-        }
-        else if ($type == 'textarea') {
-            $attrib['cols'] = $attrib['size'];
-            $input = new html_textarea($attrib);
-        }
-        else if ($type == 'select') {
-            $input = new html_select($attrib);
-            $input->add('---', '');
-            $input->add(array_values($attrib['options']), array_keys($attrib['options']));
-        }
-        else if ($attrib['type'] == 'password') {
-            $input = new html_passwordfield($attrib);
-        }
-        else {
-            if ($attrib['type'] != 'text' && $attrib['type'] != 'hidden') {
-                $attrib['type'] = 'text';
-            }
-            $input = new html_inputfield($attrib);
-        }
-
-        // use value from post
-        if (isset($_POST[$fname])) {
-            $postvalue = self::get_input_value($fname, self::INPUT_POST, true);
-            $value = $attrib['array'] ? $postvalue[intval($colcounts[$col]++)] : $postvalue;
-        }
-
-        $out = $input->show($value);
-
-        return $out;
-    }
-
-
-    /**
      * Replace all css definitions with #container [def]
      * and remove css-inlined scripting
      *
diff --git a/lib/ext/Roundcube/rcube_vcard.php b/lib/ext/Roundcube/rcube_vcard.php
index 7b59e20..45ee601 100644
--- a/lib/ext/Roundcube/rcube_vcard.php
+++ b/lib/ext/Roundcube/rcube_vcard.php
@@ -70,7 +70,7 @@ class rcube_vcard
   /**
    * Constructor
    */
-  public function __construct($vcard = null, $charset = RCMAIL_CHARSET, $detect = false, $fieldmap = array())
+  public function __construct($vcard = null, $charset = RCUBE_CHARSET, $detect = false, $fieldmap = array())
   {
     if (!empty($fielmap))
       $this->extend_fieldmap($fieldmap);
@@ -87,7 +87,7 @@ class rcube_vcard
    * @param string Charset of string values
    * @param boolean True if loading a 'foreign' vcard and extra heuristics for charset detection is required
    */
-  public function load($vcard, $charset = RCMAIL_CHARSET, $detect = false)
+  public function load($vcard, $charset = RCUBE_CHARSET, $detect = false)
   {
     self::$values_decoded = false;
     $this->raw = self::vcard_decode($vcard);
@@ -98,7 +98,7 @@ class rcube_vcard
     }
     // vcard has encoded values and charset should be detected
     else if ($detect && self::$values_decoded &&
-      ($detected_charset = self::detect_encoding(self::vcard_encode($this->raw))) && $detected_charset != RCMAIL_CHARSET) {
+      ($detected_charset = self::detect_encoding(self::vcard_encode($this->raw))) && $detected_charset != RCUBE_CHARSET) {
         $this->raw = self::charset_convert($this->raw, $detected_charset);
     }
 
@@ -436,10 +436,10 @@ class rcube_vcard
     if (preg_match('/charset=/i', substr($data, 0, 2048)))
       $charset = null;
     // detect charset and convert to utf-8
-    else if (($charset = self::detect_encoding($data)) && $charset != RCMAIL_CHARSET) {
+    else if (($charset = self::detect_encoding($data)) && $charset != RCUBE_CHARSET) {
       $data = rcube_charset::convert($data, $charset);
       $data = preg_replace(array('/^[\xFE\xFF]{2}/', '/^\xEF\xBB\xBF/', '/^\x00+/'), '', $data); // also remove BOM
-      $charset = RCMAIL_CHARSET;
+      $charset = RCUBE_CHARSET;
     }
 
     $vcard_block = '';
diff --git a/lib/ext/enriched.inc b/lib/ext/enriched.inc
deleted file mode 100644
index e3abd8c..0000000
--- a/lib/ext/enriched.inc
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-/*
-	File:		read_enriched.inc
-	Author: 	Ryo Chijiiwa
-	License:	GPL (part of IlohaMail)
-	Purpose: 	functions for handling text/enriched messages
-	Reference: 	RFC 1523, 1896
-*/
-
-
-function enriched_convert_newlines($str){
-	//remove single newlines, convert N newlines to N-1
-	
-	$str = str_replace("\r\n","\n",$str);
-	$len = strlen($str);
-	
-	$nl = 0;
-	$out = '';
-	for($i=0;$i<$len;$i++){
-		$c = $str[$i];
-		if (ord($c)==10) $nl++;
-		if ($nl && ord($c)!=10) $nl = 0;
-		if ($nl!=1) $out.=$c;
-		else $out.=' ';		
-	}
-	return $out;
-}
-
-function enriched_convert_formatting($body){
-	$a=array('<bold>'=>'<b>','</bold>'=>'</b>','<italic>'=>'<i>',
-			'</italic>'=>'</i>','<fixed>'=>'<tt>','</fixed>'=>'</tt>',
-			'<smaller>'=>'<font size=-1>','</smaller>'=>'</font>',
-			'<bigger>'=>'<font size=+1>','</bigger>'=>'</font>',
-			'<underline>'=>'<span style="text-decoration: underline">',
-			'</underline>'=>'</span>',
-			'<flushleft>'=>'<span style="text-align:left">',
-			'</flushleft>'=>'</span>',
-			'<flushright>'=>'<span style="text-align:right">',
-			'</flushright>'=>'</span>',
-			'<flushboth>'=>'<span style="text-align:justified">',
-			'</flushboth>'=>'</span>',
-			'<indent>'=>'<span style="padding-left: 20px">',
-			'</indent>'=>'</span>',
-			'<indentright>'=>'<span style="padding-right: 20px">',
-			'</indentright>'=>'</span>');
-	
-	while(list($find,$replace)=each($a)){
-		$body = preg_replace('#'.$find.'#i', $replace, $body);
-	}
-	return $body;
-}
-
-function enriched_font($body){
-	$pattern = '/(.*)\<fontfamily\>\<param\>(.*)\<\/param\>(.*)\<\/fontfamily\>(.*)/ims';
-	while(preg_match($pattern,$body,$a)){
-		//print_r($a);
-		if (count($a)!=5) continue;
-		$body=$a[1].'<span style="font-family: '.$a[2].'">'.$a[3].'</span>'.$a[4];
-	}
-
-	return $body;
-}
-
-
-function enriched_color($body){
-	$pattern = '/(.*)\<color\>\<param\>(.*)\<\/param\>(.*)\<\/color\>(.*)/ims';
-	while(preg_match($pattern,$body,$a)){
-		//print_r($a);
-		if (count($a)!=5) continue;
-
-		//extract color (either by name, or ####,####,####)
-		if (strpos($a[2],',')){
-			$rgb = explode(',',$a[2]);
-			$color ='#';
-			for($i=0;$i<3;$i++) $color.=substr($rgb[$i],0,2); //just take first 2 bytes
-		}else{
-			$color = $a[2];
-		}
-		
-		//put it all together
-		$body = $a[1].'<span style="color: '.$color.'">'.$a[3].'</span>'.$a[4];
-	}
-
-	return $body;
-}
-
-function enriched_excerpt($body){
-
-	$pattern = '/(.*)\<excerpt\>(.*)\<\/excerpt\>(.*)/i';
-	while(preg_match($pattern,$body,$a)){
-		//print_r($a);
-		if (count($a)!=4) continue;
-		$quoted = '';
-		$lines = explode('<br>',$a[2]);
-		foreach($lines as $n=>$line) $quoted.='>'.$line.'<br>';
-		$body=$a[1].'<span class="quotes">'.$quoted.'</span>'.$a[3];
-	}
-
-	return $body;
-}
-
-function enriched_to_html($body){
-	$body = str_replace('<<','<',$body);
-	$body = enriched_convert_newlines($body);
-	$body = str_replace("\n", '<br>', $body);
-	$body = enriched_convert_formatting($body);
-	$body = enriched_color($body);
-	$body = enriched_font($body);
-	$body = enriched_excerpt($body);
-	//$body = nl2br($body);
-	return $body;
-}
-
-?>
\ No newline at end of file
diff --git a/lib/ext/html2text.php b/lib/ext/html2text.php
index dd413e0..761d61f 100644
--- a/lib/ext/html2text.php
+++ b/lib/ext/html2text.php
@@ -732,14 +732,14 @@ class html2text
      */
     private function _strtoupper($str)
     {
-        $str = html_entity_decode($str, ENT_COMPAT, RCMAIL_CHARSET);
+        $str = html_entity_decode($str, ENT_COMPAT, RCUBE_CHARSET);
 
         if (function_exists('mb_strtoupper'))
             $str = mb_strtoupper($str);
         else
             $str = strtoupper($str);
 
-        $str = htmlspecialchars($str, ENT_COMPAT, RCMAIL_CHARSET);
+        $str = htmlspecialchars($str, ENT_COMPAT, RCUBE_CHARSET);
 
         return $str;
     }
diff --git a/lib/init.php b/lib/init.php
index 87256c6..5a35fa8 100644
--- a/lib/init.php
+++ b/lib/init.php
@@ -26,8 +26,6 @@
 define('KOLAB_SYNC_START', microtime(true));
 
 // Roundcube Framework constants
-define('RCUBE_VERSION', '0.9-git');
-define('RCMAIL_CHARSET', 'UTF-8');
 define('RCUBE_INSTALL_PATH', realpath(dirname(__FILE__) . '/../') . '/');
 define('RCUBE_PLUGINS_DIR', RCUBE_INSTALL_PATH . 'lib/plugins/');
 
@@ -56,34 +54,6 @@ spl_autoload_register('kolab_sync_autoload');
  */
 function kolab_sync_autoload($classname)
 {
-/*
-    // Roundcube Framework
-    $filename = preg_replace(
-        array(
-            '/Mail_(.+)/',
-            '/Net_(.+)/',
-            '/Auth_(.+)/',
-            '/^html_.+/',
-            '/^rcube(.*)/',
-            '/^utf8$/',
-        ),
-        array(
-            'Mail/\\1',
-            'Net/\\1',
-            'Auth/\\1',
-            'Roundcube/html',
-            'Roundcube/rcube\\1',
-            'utf8.class',
-        ),
-        $classname
-    );
-
-    if ($fp = @fopen("$filename.php", 'r', true)) {
-        fclose($fp);
-        include_once "$filename.php";
-        return true;
-    }
-*/
     // Syncroton, replacement for Zend autoloader
     $filename = str_replace('_', DIRECTORY_SEPARATOR, $classname);
 
diff --git a/lib/plugins/kolab_folders/kolab_folders.php b/lib/plugins/kolab_folders/kolab_folders.php
index ed05122..3688624 100644
--- a/lib/plugins/kolab_folders/kolab_folders.php
+++ b/lib/plugins/kolab_folders/kolab_folders.php
@@ -467,7 +467,7 @@ class kolab_folders extends rcube_plugin
                 $opt_name = 'kolab_folders_' . $type . '_' . $subtype;
                 if ($folder = $this->rc->config->get($opt_name)) {
                     // convert configuration value to UTF7-IMAP charset
-                    $folder = rcube_charset::convert($folder, RCMAIL_CHARSET, 'UTF7-IMAP');
+                    $folder = rcube_charset::convert($folder, RCUBE_CHARSET, 'UTF7-IMAP');
                     // and namespace prefix if needed
                     if ($prefix && strpos($folder, $prefix) === false && $folder != 'INBOX') {
                         $folder = $prefix . $folder;
diff --git a/lib/plugins/libkolab/lib/kolab_storage.php b/lib/plugins/libkolab/lib/kolab_storage.php
index 57e5491..edb512d 100644
--- a/lib/plugins/libkolab/lib/kolab_storage.php
+++ b/lib/plugins/libkolab/lib/kolab_storage.php
@@ -243,7 +243,7 @@ class kolab_storage
     {
         self::setup();
 
-        $folder    = rcube_charset::convert($prop['name'], RCMAIL_CHARSET, 'UTF7-IMAP');
+        $folder    = rcube_charset::convert($prop['name'], RCUBE_CHARSET, 'UTF7-IMAP');
         $oldfolder = $prop['oldname']; // UTF7
         $parent    = $prop['parent']; // UTF7
         $delimiter = self::$imap->get_hierarchy_delimiter();
diff --git a/lib/plugins/libkolab/lib/kolab_storage_folder.php b/lib/plugins/libkolab/lib/kolab_storage_folder.php
index 08bf669..bc47eab 100644
--- a/lib/plugins/libkolab/lib/kolab_storage_folder.php
+++ b/lib/plugins/libkolab/lib/kolab_storage_folder.php
@@ -737,7 +737,7 @@ class kolab_storage_folder
             false,                  // is_file
             '8bit',                 // encoding
             'attachment',           // disposition
-            RCMAIL_CHARSET          // charset
+            RCUBE_CHARSET           // charset
         );
         $part_id++;
 
@@ -749,15 +749,15 @@ class kolab_storage_folder
                 $att['content'] = $this->get_attachment($msguid, $att['id'], $object['_mailbox']);
             }
 
-            $headers = array('Content-ID' => Mail_mimePart::encodeHeader('Content-ID', '<' . $key . '>', RCMAIL_CHARSET, 'quoted-printable'));
+            $headers = array('Content-ID' => Mail_mimePart::encodeHeader('Content-ID', '<' . $key . '>', RCUBE_CHARSET, 'quoted-printable'));
             $name = !empty($att['name']) ? $att['name'] : $key;
 
             if (!empty($att['content'])) {
-                $mime->addAttachment($att['content'], $att['mimetype'], $name, false, 'base64', 'attachment', '', '', '', null, null, '', RCMAIL_CHARSET, $headers);
+                $mime->addAttachment($att['content'], $att['mimetype'], $name, false, 'base64', 'attachment', '', '', '', null, null, '', RCUBE_CHARSET, $headers);
                 $part_id++;
             }
             else if (!empty($att['path'])) {
-                $mime->addAttachment($att['path'], $att['mimetype'], $name, true, 'base64', 'attachment', '', '', '', null, null, '', RCMAIL_CHARSET, $headers);
+                $mime->addAttachment($att['path'], $att['mimetype'], $name, true, 'base64', 'attachment', '', '', '', null, null, '', RCUBE_CHARSET, $headers);
                 $part_id++;
             }
 





More information about the commits mailing list