From 60860ca2ef93b5bca1adfd7f0b95cfd51fc883d5 Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Mon, 03 Sep 2012 13:58:26 -0400
Subject: [PATCH] Fix bug where parentnotwritable error wasn't displayed in the interface
---
program/include/rcmail.php | 204 ++++++++++++++++++++++++++------------------------
1 files changed, 105 insertions(+), 99 deletions(-)
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 1c34759..35e1934 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -129,6 +129,12 @@
private $caches = array();
private $action_map = array();
private $shutdown_functions = array();
+ private $expunge_cache = false;
+
+ const ERROR_STORAGE = -2;
+ const ERROR_INVALID_REQUEST = 1;
+ const ERROR_INVALID_HOST = 2;
+ const ERROR_COOKIES_DISABLED = 3;
/**
@@ -246,14 +252,16 @@
$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');
+ }
}
@@ -338,15 +346,20 @@
$this->memcache = new Memcache;
$this->mc_available = 0;
-
- // add alll configured hosts to pool
+
+ // add all configured hosts to pool
$pconnect = $this->config->get('memcache_pconnect', true);
foreach ($this->config->get('memcache_hosts', array()) as $host) {
- list($host, $port) = explode(':', $host);
- if (!$port) $port = 11211;
+ if (substr($host, 0, 7) != 'unix://') {
+ list($host, $port) = explode(':', $host);
+ if (!$port) $port = 11211;
+ }
+ else {
+ $port = 0;
+ }
$this->mc_available += intval($this->memcache->addServer($host, $port, $pconnect, 1, 1, 15, false, array($this, 'memcache_failure')));
}
-
+
// test connection and failover (will result in $this->mc_available == 0 on complete failure)
$this->memcache->increment('__CONNECTIONTEST__', 1); // NOP if key doesn't exist
@@ -356,14 +369,14 @@
return $this->memcache;
}
-
+
/**
* Callback for memcache failure
*/
public function memcache_failure($host, $port)
{
static $seen = array();
-
+
// only report once
if (!$seen["$host:$port"]++) {
$this->mc_available--;
@@ -555,7 +568,7 @@
$this->output->set_charset(RCMAIL_CHARSET);
// add some basic labels to client
- $this->output->add_label('loading', 'servererror');
+ $this->output->add_label('loading', 'servererror', 'requesttimedout');
return $this->output;
}
@@ -727,11 +740,10 @@
}
else {
$this->set_storage_prop();
- return $storage->is_connected();
}
}
- return false;
+ return $storage->is_connected();
}
@@ -767,8 +779,7 @@
$this->session = new rcube_session($this->get_dbh(), $this->config);
$this->session->register_gc_handler('rcmail_temp_gc');
- if ($this->config->get('enable_caching'))
- $this->session->register_gc_handler('rcmail_cache_gc');
+ $this->session->register_gc_handler(array($this, 'cache_gc'));
// start PHP session (if not in CLI mode)
if ($_SERVER['REMOTE_ADDR'])
@@ -777,6 +788,10 @@
// set initial session vars
if (!$_SESSION['user_id'])
$_SESSION['temp'] = true;
+
+ // restore skin selection after logout
+ if ($_SESSION['temp'] && !empty($_SESSION['skin']))
+ $this->config->set('skin', $_SESSION['skin']);
}
@@ -799,7 +814,7 @@
$this->session->set_keep_alive($keep_alive);
}
- $this->session->set_secret($this->config->get('des_key') . $_SERVER['HTTP_USER_AGENT']);
+ $this->session->set_secret($this->config->get('des_key') . dirname($_SERVER['SCRIPT_NAME']));
$this->session->set_ip_check($this->config->get('ip_check'));
}
@@ -811,12 +826,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;
}
@@ -836,11 +859,18 @@
break;
}
}
- if (!$allowed)
- return false;
+ if (!$allowed) {
+ $host = null;
}
- else if (!empty($config['default_host']) && $host != rcube_parse_host($config['default_host']))
+ }
+ else if (!empty($config['default_host']) && $host != rcube_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);
@@ -871,7 +901,14 @@
// 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
@@ -881,17 +918,13 @@
// Here we need IDNA ASCII
// Only rcube_contacts class is using domain names in Unicode
- $host = rcube_idn_to_ascii($host);
- if (strpos($username, '@')) {
- // lowercase domain name
- list($local, $domain) = explode('@', $username);
- $username = $local . '@' . mb_strtolower($domain);
- $username = rcube_idn_to_ascii($username);
- }
+ $host = rcube_idn_to_ascii($host);
+ $username = rcube_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'];
+ }
if (!$this->storage)
$this->storage_init();
@@ -963,7 +996,7 @@
$_SESSION['storage_port'] = $port;
$_SESSION['storage_ssl'] = $ssl;
$_SESSION['password'] = $this->encrypt($pass);
- $_SESSION['login_time'] = mktime();
+ $_SESSION['login_time'] = time();
if (isset($_REQUEST['_timezone']) && $_REQUEST['_timezone'] != '_default_')
$_SESSION['timezone'] = floatval($_REQUEST['_timezone']);
@@ -978,6 +1011,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;
+ }
+ }
/**
@@ -1014,15 +1064,16 @@
if (is_array($default_host)) {
$post_host = get_input_value('_host', RCUBE_INPUT_POST);
+ $post_user = get_input_value('_user', RCUBE_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))) {
+ if ($default_host[$post_host] || in_array($post_host, $default_host)) {
$host = $post_host;
}
-
// try to select host by mail domain
- list($user, $domain) = explode('@', get_input_value('_user', RCUBE_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;
@@ -1164,7 +1215,7 @@
$this->texts = array_merge($this->texts, $messages);
// include user language files
- if ($lang != 'en' && is_dir(INSTALL_PATH . 'program/localization/' . $lang)) {
+ if ($lang != 'en' && $lang != 'en_US' && is_dir(INSTALL_PATH . 'program/localization/' . $lang)) {
include_once(INSTALL_PATH . 'program/localization/' . $lang . '/labels.inc');
include_once(INSTALL_PATH . 'program/localization/' . $lang . '/messages.inc');
@@ -1221,7 +1272,7 @@
$this->plugins->exec_hook('session_destroy');
$this->session->kill();
- $_SESSION = array('language' => $this->user->language, 'temp' => true);
+ $_SESSION = array('language' => $this->user->language, 'temp' => true, 'skin' => $this->config->get('skin'));
$this->user->reset();
}
@@ -1278,8 +1329,11 @@
$cache->close();
}
- if (is_object($this->storage))
+ if (is_object($this->storage)) {
+ if ($this->expunge_cache)
+ $this->storage->expunge_cache();
$this->storage->close();
+ }
// before closing the database connection, write session data
if ($_SERVER['REMOTE_ADDR'] && is_object($this->session)) {
@@ -1312,6 +1366,18 @@
public function add_shutdown_function($function)
{
$this->shutdown_functions[] = $function;
+ }
+
+
+ /**
+ * Garbage collector for cache entries.
+ * Set flag to expunge caches on shutdown
+ */
+ function cache_gc()
+ {
+ // because this gc function is called before storage is initialized,
+ // we just set a flag to expunge storage cache on shutdown.
+ $this->expunge_cache = true;
}
@@ -1507,73 +1573,13 @@
$url = './';
$delm = '?';
foreach (array_reverse($p) as $key => $val) {
- if ($val !== '') {
+ if ($val !== '' && $val !== null) {
$par = $key[0] == '_' ? $key : '_'.$key;
$url .= $delm.urlencode($par).'='.urlencode($val);
$delm = '&';
}
}
return $url;
- }
-
-
- /**
- * Use imagemagick or GD lib to read image properties
- *
- * @param string Absolute file path
- * @return mixed Hash array with image props like type, width, height or False on error
- */
- public static function imageprops($filepath)
- {
- $rcmail = rcmail::get_instance();
- if ($cmd = $rcmail->config->get('im_identify_path', false)) {
- list(, $type, $size) = explode(' ', strtolower(rcmail::exec($cmd. ' 2>/dev/null {in}', array('in' => $filepath))));
- if ($size)
- list($width, $height) = explode('x', $size);
- }
- else if (function_exists('getimagesize')) {
- $imsize = @getimagesize($filepath);
- $width = $imsize[0];
- $height = $imsize[1];
- $type = preg_replace('!image/!', '', $imsize['mime']);
- }
-
- return $type ? array('type' => $type, 'width' => $width, 'height' => $height) : false;
- }
-
-
- /**
- * Convert an image to a given size and type using imagemagick (ensures input is an image)
- *
- * @param $p['in'] Input filename (mandatory)
- * @param $p['out'] Output filename (mandatory)
- * @param $p['size'] Width x height of resulting image, e.g. "160x60"
- * @param $p['type'] Output file type, e.g. "jpg"
- * @param $p['-opts'] Custom command line options to ImageMagick convert
- * @return Success of convert as true/false
- */
- public static function imageconvert($p)
- {
- $result = false;
- $rcmail = rcmail::get_instance();
- $convert = $rcmail->config->get('im_convert_path', false);
- $identify = $rcmail->config->get('im_identify_path', false);
-
- // imagemagick is required for this
- if (!$convert)
- return false;
-
- if (!(($imagetype = @exif_imagetype($p['in'])) && ($type = image_type_to_extension($imagetype, false))))
- list(, $type) = explode(' ', strtolower(rcmail::exec($identify . ' 2>/dev/null {in}', $p))); # for things like eps
-
- $type = strtr($type, array("jpeg" => "jpg", "tiff" => "tif", "ps" => "eps", "ept" => "eps"));
- $p += array('type' => $type, 'types' => "bmp,eps,gif,jp2,jpg,png,svg,tif", 'quality' => 75);
- $p['-opts'] = array('-resize' => $p['size'].'>') + (array)$p['-opts'];
-
- if (in_array($type, explode(',', $p['types']))) # Valid type?
- $result = rcmail::exec($convert . ' 2>&1 -flatten -auto-orient -colorspace RGB -quality {quality} {-opts} {in} {type}:{out}', $p) === "";
-
- return $result;
}
--
Gitblit v1.9.1