From 15cf4fa9251f01313b5eb5cf1a91ec10643d42cb Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Wed, 21 Nov 2012 13:55:34 -0500
Subject: [PATCH] Rename rcube_bc.inc to bc.php for consistency

---
 program/include/rcmail.php |  255 +++++++++++++++++++++++++++++++++++---------------
 1 files changed, 176 insertions(+), 79 deletions(-)

diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 7f9d7af..99a68e8 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -19,9 +19,6 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  | Author: Aleksander Machniak <alec@alec.pl>                            |
  +-----------------------------------------------------------------------+
-
- $Id$
-
 */
 
 
@@ -61,6 +58,12 @@
 
   const JS_OBJECT_NAME = 'rcmail';
 
+  const ERROR_STORAGE          = -2;
+  const ERROR_INVALID_REQUEST  = 1;
+  const ERROR_INVALID_HOST     = 2;
+  const ERROR_COOKIES_DISABLED = 3;
+
+
   /**
    * This implements the 'singleton' design pattern
    *
@@ -90,9 +93,6 @@
 
     // create user object
     $this->set_user(new rcube_user($_SESSION['user_id']));
-
-    // configure session (after user config merge!)
-    $this->session_configure();
 
     // set task and action properties
     $this->set_task(rcube_utils::get_input_value('_task', rcube_utils::INPUT_GPC));
@@ -154,21 +154,23 @@
       $this->config->set_user_prefs((array)$this->user->get_prefs());
     }
 
-    $_SESSION['language'] = $this->user->language = $this->language_prop($this->config->get('language', $_SESSION['language']));
+    $lang = $this->language_prop($this->config->get('language', $_SESSION['language']));
+    $_SESSION['language'] = $this->user->language = $lang;
 
     // set localization
-    setlocale(LC_ALL, $_SESSION['language'] . '.utf8', 'en_US.utf8');
+    setlocale(LC_ALL, $lang . '.utf8', $lang . '.UTF-8', 'en_US.utf8', 'en_US.UTF-8');
 
     // workaround for http://bugs.php.net/bug.php?id=18556
-    if (in_array($_SESSION['language'], array('tr_TR', 'ku', 'az_AZ')))
-      setlocale(LC_CTYPE, 'en_US' . '.utf8');
+    if (in_array($lang, array('tr_TR', 'ku', 'az_AZ'))) {
+      setlocale(LC_CTYPE, 'en_US.utf8', 'en_US.UTF-8');
+    }
   }
 
 
   /**
    * Return instance of the internal address book class
    *
-   * @param string  Address book identifier
+   * @param string  Address book identifier (-1 for default addressbook)
    * @param boolean True if the address book needs to be writeable
    *
    * @return rcube_contacts Address book object
@@ -177,17 +179,17 @@
   {
     $contacts    = null;
     $ldap_config = (array)$this->config->get('ldap_public');
-    $abook_type  = strtolower($this->config->get('address_book_type'));
 
     // 'sql' is the alias for '0' used by autocomplete
     if ($id == 'sql')
-        $id = '0';
+      $id = '0';
+    else if ($id == -1) {
+      $id = $this->config->get('default_addressbook');
+      $default = true;
+    }
 
     // use existing instance
-    if (isset($this->address_books[$id]) && is_object($this->address_books[$id])
-      && is_a($this->address_books[$id], 'rcube_addressbook')
-      && (!$writeable || !$this->address_books[$id]->readonly)
-    ) {
+    if (isset($this->address_books[$id]) && ($this->address_books[$id] instanceof rcube_addressbook)) {
       $contacts = $this->address_books[$id];
     }
     else if ($id && $ldap_config[$id]) {
@@ -203,14 +205,16 @@
       if ($plugin['instance'] instanceof rcube_addressbook) {
         $contacts = $plugin['instance'];
       }
-      // get first source from the list
-      else if (!$id) {
-        $source = reset($this->get_address_sources($writeable));
-        if (!empty($source)) {
-          $contacts = $this->get_address_book($source['id']);
-          if ($contacts)
-            $id = $source['id'];
-        }
+    }
+
+    // Get first addressbook from the list if configured default doesn't exist
+    // This can happen when user deleted the addressbook (e.g. Kolab folder)
+    if (!$contacts && (!$id || $default)) {
+      $source = reset($this->get_address_sources($writeable));
+      if (!empty($source)) {
+        $contacts = $this->get_address_book($source['id']);
+        if ($contacts)
+          $id = $source['id'];
       }
     }
 
@@ -220,6 +224,10 @@
         'file' => __FILE__, 'line' => __LINE__,
         'message' => "Addressbook source ($id) not found!"),
         true, true);
+    }
+
+    if ($writeable && $contacts->readonly) {
+      return null;
     }
 
     // set configured sort order
@@ -247,8 +255,8 @@
     $autocomplete = (array) $this->config->get('autocomplete_addressbooks');
     $list = array();
 
-    // We are using the DB address book
-    if ($abook_type != 'ldap') {
+    // We are using the DB address book or a plugin address book
+    if ($abook_type != 'ldap' && $abook_type != '') {
       if (!isset($this->address_books['0']))
         $this->address_books['0'] = new rcube_contacts($this->db, $this->get_user_id());
       $list['0'] = array(
@@ -270,7 +278,7 @@
         }
         $list[$id] = array(
           'id'       => $id,
-          'name'     => $prop['name'],
+          'name'     => html::quote($prop['name']),
           'groups'   => is_array($prop['groups']),
           'readonly' => !$prop['writable'],
           'hidden'   => $prop['hidden'],
@@ -297,7 +305,7 @@
 
   /**
    * Init output object for GUI and add common scripts.
-   * This will instantiate a rcmail_template object and set
+   * This will instantiate a rcube_output_html object and set
    * environment vars according to the current session and configuration
    *
    * @param boolean True if this request is loaded in a (i)frame
@@ -309,10 +317,9 @@
     if (!($this->output instanceof rcube_output_html))
       $this->output = new rcube_output_html($this->task, $framed);
 
-    // set keep-alive/check-recent interval
-    if ($this->session && ($keep_alive = $this->session->get_keep_alive())) {
-      $this->output->set_env('keep_alive', $keep_alive);
-    }
+    // set refresh interval
+    $this->output->set_env('refresh_interval', $this->config->get('refresh_interval', 0));
+    $this->output->set_env('session_lifetime', $this->config->get('session_lifetime', 0) * 60);
 
     if ($framed) {
       $this->comm_path .= '&_framed=1';
@@ -325,7 +332,7 @@
     $this->output->set_charset(RCMAIL_CHARSET);
 
     // add some basic labels to client
-    $this->output->add_label('loading', 'servererror', 'requesttimedout');
+    $this->output->add_label('loading', 'servererror', 'requesttimedout', 'refreshing');
 
     return $this->output;
   }
@@ -369,12 +376,20 @@
    * @param string Mail storage (IMAP) user name
    * @param string Mail storage (IMAP) password
    * @param string Mail storage (IMAP) host
+   * @param bool   Enables cookie check
    *
    * @return boolean True on success, False on failure
    */
-  function login($username, $pass, $host=NULL)
+  function login($username, $pass, $host = null, $cookiecheck = false)
   {
+    $this->login_error = null;
+
     if (empty($username)) {
+      return false;
+    }
+
+    if ($cookiecheck && empty($_COOKIE)) {
+      $this->login_error = self::ERROR_COOKIES_DISABLED;
       return false;
     }
 
@@ -394,11 +409,18 @@
           break;
         }
       }
-      if (!$allowed)
-        return false;
+      if (!$allowed) {
+        $host = null;
       }
-    else if (!empty($config['default_host']) && $host != rcube_utils::parse_host($config['default_host']))
+    }
+    else if (!empty($config['default_host']) && $host != rcube_utils::parse_host($config['default_host'])) {
+      $host = null;
+    }
+
+    if (!$host) {
+      $this->login_error = self::ERROR_INVALID_HOST;
       return false;
+    }
 
     // parse $host URL
     $a_host = parse_url($host);
@@ -426,10 +448,21 @@
         $username .= '@'.rcube_utils::parse_host($config['username_domain'], $host);
     }
 
+    if (!isset($config['login_lc'])) {
+      $config['login_lc'] = 2; // default
+    }
+
     // Convert username to lowercase. If storage backend
     // is case-insensitive we need to store always the same username (#1487113)
     if ($config['login_lc']) {
-      $username = mb_strtolower($username);
+      if ($config['login_lc'] == 2 || $config['login_lc'] === true) {
+        $username = mb_strtolower($username);
+      }
+      else if (strpos($username, '@')) {
+        // lowercase domain name
+        list($local, $domain) = explode('@', $username);
+        $username = $local . '@' . mb_strtolower($domain);
+      }
     }
 
     // try to resolve email address from virtuser table
@@ -439,36 +472,18 @@
 
     // Here we need IDNA ASCII
     // Only rcube_contacts class is using domain names in Unicode
-    $host = rcube_utils::idn_to_ascii($host);
-    if (strpos($username, '@')) {
-      // lowercase domain name
-      list($local, $domain) = explode('@', $username);
-      $username = $local . '@' . mb_strtolower($domain);
-      $username = rcube_utils::idn_to_ascii($username);
-    }
+    $host     = rcube_utils::idn_to_ascii($host);
+    $username = rcube_utils::idn_to_ascii($username);
 
     // user already registered -> overwrite username
-    if ($user = rcube_user::query($username, $host))
+    if ($user = rcube_user::query($username, $host)) {
       $username = $user->data['username'];
+    }
 
     $storage = $this->get_storage();
 
     // try to log in
-    if (!($login = $storage->connect($host, $username, $pass, $port, $ssl))) {
-      // try with lowercase
-      $username_lc = mb_strtolower($username);
-      if ($username_lc != $username) {
-        // try to find user record again -> overwrite username
-        if (!$user && ($user = rcube_user::query($username_lc, $host)))
-          $username_lc = $user->data['username'];
-
-        if ($login = $storage->connect($host, $username_lc, $pass, $port, $ssl))
-          $username = $username_lc;
-      }
-    }
-
-    // exit if login failed
-    if (!$login) {
+    if (!$storage->connect($host, $username, $pass, $port, $ssl)) {
       return false;
     }
 
@@ -503,7 +518,6 @@
       // Configure environment
       $this->set_user($user);
       $this->set_storage_prop();
-      $this->session_configure();
 
       // fix some old settings according to namespace prefix
       $this->fix_namespace_settings($user);
@@ -523,9 +537,7 @@
       $_SESSION['login_time']   = time();
 
       if (isset($_REQUEST['_timezone']) && $_REQUEST['_timezone'] != '_default_')
-        $_SESSION['timezone'] = floatval($_REQUEST['_timezone']);
-      if (isset($_REQUEST['_dstactive']) && $_REQUEST['_dstactive'] != '_default_')
-        $_SESSION['dst_active'] = intval($_REQUEST['_dstactive']);
+        $_SESSION['timezone'] = rcube_utils::get_input_value('_timezone', rcube_utils::INPUT_GPC);
 
       // force reloading complete list of subscribed mailboxes
       $storage->clear_cache('mailboxes', true);
@@ -535,6 +547,23 @@
 
     return false;
   }
+
+
+    /**
+     * Returns error code of last login operation
+     *
+     * @return int Error code
+     */
+    public function login_error()
+    {
+        if ($this->login_error) {
+            return $this->login_error;
+        }
+
+        if ($this->storage && $this->storage->get_error_code() < -1) {
+            return self::ERROR_STORAGE;
+        }
+    }
 
 
   /**
@@ -549,15 +578,16 @@
 
     if (is_array($default_host)) {
       $post_host = rcube_utils::get_input_value('_host', rcube_utils::INPUT_POST);
+      $post_user = rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST);
+
+      list($user, $domain) = explode('@', $post_user);
 
       // direct match in default_host array
       if ($default_host[$post_host] || in_array($post_host, array_values($default_host))) {
         $host = $post_host;
       }
-
       // try to select host by mail domain
-      list($user, $domain) = explode('@', rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST));
-      if (!empty($domain)) {
+      else if (!empty($domain)) {
         foreach ($default_host as $storage_host => $mail_domains) {
           if (is_array($mail_domains) && in_array_nocase($domain, $mail_domains)) {
             $host = $storage_host;
@@ -684,8 +714,12 @@
    */
   public function url($p)
   {
-    if (!is_array($p))
+    if (!is_array($p)) {
+      if (strpos($p, 'http') === 0)
+        return $p;
+
       $p = array('_action' => @func_get_arg(0));
+    }
 
     $task = $p['_task'] ? $p['_task'] : ($p['task'] ? $p['task'] : $this->task);
     $p['_task'] = $task;
@@ -736,6 +770,7 @@
     }
   }
 
+
   /**
    * Registers action aliases for current task
    *
@@ -750,6 +785,7 @@
     }
   }
 
+
   /**
    * Returns current action filename
    *
@@ -763,6 +799,7 @@
 
     return strtr($this->action, '-', '_') . '.inc';
   }
+
 
   /**
    * Fixes some user preferences according to namespace handling change.
@@ -1158,7 +1195,7 @@
         }
         else {
             if (!empty($date)) {
-                $timestamp = rcube_strtotime($date);
+                $timestamp = rcube_utils::strtotime($date);
             }
 
             if (empty($timestamp)) {
@@ -1329,11 +1366,12 @@
         $attrib      = $hook['attribs'];
 
         if ($type == 'select') {
+            $attrib['is_escaped'] = true;
             $select = new html_select($attrib);
 
             // add no-selection option
             if ($attrib['noselection']) {
-                $select->add($rcmail->gettext($attrib['noselection']), '');
+                $select->add(html::quote($rcmail->gettext($attrib['noselection'])), '');
             }
 
             $rcmail->render_folder_tree_select($a_mailboxes, $mbox_name, $attrib['maxlength'], $select, $attrib['realnames']);
@@ -1362,7 +1400,7 @@
      */
     public function folder_selector($p = array())
     {
-        $p += array('maxlength' => 100, 'realnames' => false);
+        $p += array('maxlength' => 100, 'realnames' => false, 'is_escaped' => true);
         $a_mailboxes = array();
         $storage = $this->get_storage();
 
@@ -1388,7 +1426,7 @@
         $select = new html_select($p);
 
         if ($p['noselection']) {
-            $select->add($p['noselection'], '');
+            $select->add(html::quote($p['noselection']), '');
         }
 
         $this->render_folder_tree_select($a_mailboxes, $mbox, $p['maxlength'], $select, $p['realnames'], 0, $p);
@@ -1579,7 +1617,7 @@
                 }
             }
 
-            $select->add(str_repeat('&nbsp;', $nestLevel*4) . $foldername, $folder['id']);
+            $select->add(str_repeat('&nbsp;', $nestLevel*4) . html::quote($foldername), $folder['id']);
 
             if (!empty($folder['folders'])) {
                 $out .= $this->render_folder_tree_select($folder['folders'], $mbox_name, $maxlength,
@@ -1722,10 +1760,7 @@
         $err_code = $this->storage->get_error_code();
         $res_code = $this->storage->get_response_code();
 
-        if ($err_code < 0) {
-            $this->output->show_message('storageerror', 'error');
-        }
-        else if ($res_code == rcube_storage::NOPERM) {
+        if ($res_code == rcube_storage::NOPERM) {
             $this->output->show_message('errornoperm', 'error');
         }
         else if ($res_code == rcube_storage::READONLY) {
@@ -1739,6 +1774,9 @@
             else {
                 $this->output->show_message('servererrormsg', 'error', array('msg' => $err_str));
             }
+        }
+        else if ($err_code < 0) {
+            $this->output->show_message('storageerror', 'error');
         }
         else if ($fallback) {
             $this->output->show_message($fallback, 'error', $fallback_args);
@@ -1998,6 +2036,31 @@
     }
 
 
+    /**
+     * Returns real size (calculated) of the message part
+     *
+     * @param rcube_message_part  Message part
+     *
+     * @return string Part size (and unit)
+     */
+    public function message_part_size($part)
+    {
+        if (isset($part->d_parameters['size'])) {
+            $size = $this->show_bytes((int)$part->d_parameters['size']);
+        }
+        else {
+          $size = $part->size;
+          if ($part->encoding == 'base64') {
+            $size = $size / 1.33;
+          }
+
+          $size = '~' . $this->show_bytes($size);
+        }
+
+        return $size;
+    }
+
+
     /************************************************************************
      *********          Deprecated methods (to be removed)          *********
      ***********************************************************************/
@@ -2011,4 +2074,38 @@
     {
         return $this->storage_connect();
     }
+
+    public function imap_init()
+    {
+        return $this->storage_init();
+    }
+
+    /**
+     * Connect to the mail storage server with stored session data
+     *
+     * @return bool True on success, False on error
+     */
+    public function storage_connect()
+    {
+        $storage = $this->get_storage();
+
+        if ($_SESSION['storage_host'] && !$storage->is_connected()) {
+            $host = $_SESSION['storage_host'];
+            $user = $_SESSION['username'];
+            $port = $_SESSION['storage_port'];
+            $ssl  = $_SESSION['storage_ssl'];
+            $pass = $this->decrypt($_SESSION['password']);
+
+            if (!$storage->connect($host, $user, $pass, $port, $ssl)) {
+                if (is_object($this->output)) {
+                    $this->output->show_message('storageerror', 'error');
+                }
+            }
+            else {
+                $this->set_storage_prop();
+            }
+        }
+
+        return $storage->is_connected();
+    }
 }

--
Gitblit v1.9.1