summaryrefslogtreecommitdiff
path: root/installer
diff options
context:
space:
mode:
Diffstat (limited to 'installer')
-rw-r--r--installer/check.php58
-rw-r--r--installer/config.php54
-rw-r--r--installer/index.php31
-rw-r--r--installer/rcube_install.php278
-rw-r--r--installer/test.php154
5 files changed, 368 insertions, 207 deletions
diff --git a/installer/check.php b/installer/check.php
index 14fc4f06e..ee0c9f367 100644
--- a/installer/check.php
+++ b/installer/check.php
@@ -42,12 +42,13 @@ $ini_checks = array(
'suhosin.session.encrypt' => 0,
'magic_quotes_runtime' => 0,
'magic_quotes_sybase' => 0,
- 'date.timezone' => '-NOTEMPTY-',
);
$optional_checks = array(
// required for utils/modcss.inc, should we require this?
'allow_url_fopen' => 1,
+ 'date.timezone' => '-VALID-',
+ 'register_globals' => 0, // #1489157
);
$source_urls = array(
@@ -64,12 +65,12 @@ $source_urls = array(
'Intl' => 'http://www.php.net/manual/en/book.intl.php',
'Exif' => 'http://www.php.net/manual/en/book.exif.php',
'PDO' => 'http://www.php.net/manual/en/book.pdo.php',
- 'pdo_mysql' => 'http://www.php.net/manual/en/book.pdo-mysql.php',
- 'pdo_pgsql' => 'http://www.php.net/manual/en/book.pdo-pgsql.php',
- 'pdo_sqlite' => 'http://www.php.net/manual/en/book.pdo-sqlite.php',
- 'pdo_sqlite2' => 'http://www.php.net/manual/en/book.pdo-sqlite.php',
- 'pdo_sqlsrv' => 'http://www.php.net/manual/en/book.pdo-sqlsrv.php',
- 'pdo_dblib' => 'http://www.php.net/manual/en/book.pdo-dblib.php',
+ 'pdo_mysql' => 'http://www.php.net/manual/en/ref.pdo-mysql.php',
+ 'pdo_pgsql' => 'http://www.php.net/manual/en/ref.pdo-pgsql.php',
+ 'pdo_sqlite' => 'http://www.php.net/manual/en/ref.pdo-sqlite.php',
+ 'pdo_sqlite2' => 'http://www.php.net/manual/en/ref.pdo-sqlite.php',
+ 'pdo_sqlsrv' => 'http://www.php.net/manual/en/ref.pdo-sqlsrv.php',
+ 'pdo_dblib' => 'http://www.php.net/manual/en/ref.pdo-dblib.php',
'PEAR' => 'http://pear.php.net',
'Net_SMTP' => 'http://pear.php.net/package/Net_SMTP',
'Mail_mime' => 'http://pear.php.net/package/Mail_mime',
@@ -139,10 +140,11 @@ foreach ($RCI->supported_dbs as $database => $ext) {
if (extension_loaded($ext)) {
// MySQL driver requires PHP >= 5.3 (#1488875)
if ($ext == 'pdo_mysql' && version_compare(PHP_VERSION, '5.3.0', '<')) {
- $RCI->fail($database, 'PHP >= 5.3 required');
+ $RCI->fail($database, 'PHP >= 5.3 required', null, true);
}
else {
$RCI->pass($database);
+ $found_db_driver = true;
}
}
else {
@@ -152,6 +154,9 @@ foreach ($RCI->supported_dbs as $database => $ext) {
}
echo '<br />';
}
+if (empty($found_db_driver)) {
+ $RCI->failures++;
+}
?>
@@ -185,23 +190,15 @@ foreach ($ini_checks as $var => $val) {
if ($val === '-NOTEMPTY-') {
if (empty($status)) {
$RCI->fail($var, "empty value detected");
- } else if ($var == 'date.timezone') {
- try {
- $tz = new DateTimeZone($status);
- $RCI->pass($var);
- }
- catch (Exception $e) {
- $RCI->fail($var, "invalid value detected: $status");
- }
- } else {
+ }
+ else {
$RCI->pass($var);
}
- echo '<br />';
- continue;
}
- if ($status == $val) {
+ else if (filter_var($status, FILTER_VALIDATE_BOOLEAN) == $val) {
$RCI->pass($var);
- } else {
+ }
+ else {
$RCI->fail($var, "is '$status', should be '$val'");
}
echo '<br />';
@@ -223,9 +220,24 @@ foreach ($optional_checks as $var => $val) {
echo '<br />';
continue;
}
- if ($status == $val) {
+ if ($val === '-VALID-') {
+ if ($var == 'date.timezone') {
+ try {
+ $tz = new DateTimeZone($status);
+ $RCI->pass($var);
+ }
+ catch (Exception $e) {
+ $RCI->optfail($var, empty($status) ? "not set" : "invalid value detected: $status");
+ }
+ }
+ else {
+ $RCI->pass($var);
+ }
+ }
+ else if (filter_var($status, FILTER_VALIDATE_BOOLEAN) == $val) {
$RCI->pass($var);
- } else {
+ }
+ else {
$RCI->optfail($var, "is '$status', could be '$val'");
}
echo '<br />';
diff --git a/installer/config.php b/installer/config.php
index d6846edc7..f990fc23f 100644
--- a/installer/config.php
+++ b/installer/config.php
@@ -9,13 +9,9 @@ if (!class_exists('rcube_install') || !is_object($RCI)) {
<input type="hidden" name="_step" value="2" />
<?php
-// also load the default config to fill in the fields
-$RCI->load_defaults();
-
// register these boolean fields
$RCI->bool_config_props = array(
'ip_check' => 1,
- 'enable_caching' => 1,
'enable_spellcheck' => 1,
'auto_create_user' => 1,
'smtp_log' => 1,
@@ -28,24 +24,24 @@ $RCI->bool_config_props = array(
$_SESSION['allowinstaller'] = true;
if (!empty($_POST['submit'])) {
-
- echo '<p class="notice">Copy or download the following configurations and save them in two files';
- echo ' (names above the text box) within the <tt>'.RCMAIL_CONFIG_DIR.'</tt> directory of your Roundcube installation.<br/>';
- echo ' Make sure that there are no characters outside the <tt>&lt;?php ?&gt;</tt> brackets when saving the files.</p>';
-
+ echo '<p class="notice">Copy or download the following configuration and save it';
+ echo ' as <tt><b>config.inc.php</b></tt> within the <tt>'.RCUBE_CONFIG_DIR.'</tt> directory of your Roundcube installation.<br/>';
+ echo ' Make sure that there are no characters outside the <tt>&lt;?php ?&gt;</tt> brackets when saving the file.';
+ echo '&nbsp;<input type="button" onclick="location.href=\'index.php?_getconfig=1\'" value="Download" />';
+ if ($RCI->legacy_config) {
+ echo '<br/><br/>Afterwards, please <b>remove</b> the old configuration files <tt>main.inc.php</tt> and <tt>db.inc.php</tt>';
+ echo ' from the config directory.';
+ }
+ echo '</p>';
+
$textbox = new html_textarea(array('rows' => 16, 'cols' => 60, 'class' => "configfile"));
-
- echo '<div><em>main.inc.php (<a href="index.php?_getfile=main">download</a>)</em></div>';
- echo $textbox->show(($_SESSION['main.inc.php'] = $RCI->create_config('main')));
-
- echo '<div style="margin-top:1em"><em>db.inc.php (<a href="index.php?_getfile=db">download</a>)</em></div>';
- echo $textbox->show($_SESSION['db.inc.php'] = $RCI->create_config('db'));
+ echo $textbox->show(($_SESSION['config'] = $RCI->create_config()));
echo '<p class="hint">Of course there are more options to configure.
- Have a look at the config files or visit <a href="http://trac.roundcube.net/wiki/Howto_Config">Howto_Config</a> to find out.</p>';
+ Have a look at the defaults.inc.php file or visit <a href="http://trac.roundcube.net/wiki/Howto_Config">Howto_Config</a> to find out.</p>';
echo '<p><input type="button" onclick="location.href=\'./index.php?_step=3\'" value="CONTINUE" /></p>';
-
+
// echo '<style type="text/css"> .configblock { display:none } </style>';
echo "\n<hr style='margin-bottom:1.6em' />\n";
}
@@ -127,16 +123,6 @@ echo $check_ipcheck->show(intval($RCI->getprop('ip_check')), array('value' => 1)
<p class="hint">This increases security but can cause sudden logouts when someone uses a proxy with changing IPs.</p>
</dd>
-<dt class="propname">enable_caching</dt>
-<dd>
-<?php
-
-$check_caching = new html_checkbox(array('name' => '_enable_caching', 'id' => "cfgcache"));
-echo $check_caching->show(intval($RCI->getprop('enable_caching')), array('value' => 1));
-
-?>
-<label for="cfgcache">Cache messages in local database</label><br />
-</dd>
<dt class="propname">enable_spellcheck</dt>
<dd>
@@ -301,6 +287,18 @@ echo '<label for="cfgdbpass">Database password (omit for sqlite)</label><br />';
?>
</dd>
+
+<dt class="propname">db_prefix</dt>
+<dd>
+<?php
+
+$input_prefix = new html_inputfield(array('name' => '_db_prefix', 'size' => 20, 'id' => "cfgdbprefix"));
+echo $input_prefix->show($RCI->getprop('db_prefix'));
+
+?>
+<div>Optional prefix that will be added to database object names (tables and sequences).</div>
+</dd>
+
</dl>
</fieldset>
@@ -647,7 +645,7 @@ $select_param_folding->add('Full RFC 2231 (Roundcube, Thunderbird)', '0');
$select_param_folding->add('RFC 2047/2231 (MS Outlook, OE)', '1');
$select_param_folding->add('Full RFC 2047 (deprecated)', '2');
-echo $select_param_folding->show(intval($RCI->getprop('mime_param_folding')));
+echo $select_param_folding->show(strval($RCI->getprop('mime_param_folding')));
?>
<div>How to encode attachment long/non-ascii names</div>
diff --git a/installer/index.php b/installer/index.php
index 0e80b1cd6..d084c8aa5 100644
--- a/installer/index.php
+++ b/installer/index.php
@@ -5,7 +5,7 @@
| Roundcube Webmail setup tool |
| Version 0.9-git |
| |
- | Copyright (C) 2009-2012, The Roundcube Dev Team |
+ | Copyright (C) 2009-2013, The Roundcube Dev Team |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU General Public License (with exceptions |
@@ -54,17 +54,18 @@ require_once 'rcube_install.php';
// deprecated aliases (to be removed)
require_once 'bc.php';
-session_start();
+if (function_exists('session_start'))
+ session_start();
$RCI = rcube_install::get_instance();
$RCI->load_config();
-if (isset($_GET['_getfile']) && in_array($_GET['_getfile'], array('main', 'db'))) {
- $filename = $_GET['_getfile'] . '.inc.php';
- if (!empty($_SESSION[$filename])) {
+if (isset($_GET['_getconfig'])) {
+ $filename = 'config.inc.php';
+ if (!empty($_SESSION['config'])) {
header('Content-type: text/plain');
header('Content-Disposition: attachment; filename="'.$filename.'"');
- echo $_SESSION[$filename];
+ echo $_SESSION['config'];
exit;
}
else {
@@ -74,14 +75,14 @@ if (isset($_GET['_getfile']) && in_array($_GET['_getfile'], array('main', 'db'))
}
if ($RCI->configured && ($RCI->getprop('enable_installer') || $_SESSION['allowinstaller']) &&
- isset($_GET['_mergeconfig']) && in_array($_GET['_mergeconfig'], array('main', 'db'))) {
- $filename = $_GET['_mergeconfig'] . '.inc.php';
+ !empty($_GET['_mergeconfig'])) {
+ $filename = 'config.inc.php';
header('Content-type: text/plain');
header('Content-Disposition: attachment; filename="'.$filename.'"');
$RCI->merge_config();
- echo $RCI->create_config($_GET['_mergeconfig'], true);
+ echo $RCI->create_config();
exit;
}
@@ -121,8 +122,16 @@ if ($RCI->configured && empty($_REQUEST['_step'])) {
// exit if installation is complete
if ($RCI->configured && !$RCI->getprop('enable_installer') && !$_SESSION['allowinstaller']) {
// header("HTTP/1.0 404 Not Found");
- echo '<h2 class="error">The installer is disabled!</h2>';
- echo '<p>To enable it again, set <tt>$rcmail_config[\'enable_installer\'] = true;</tt> in RCUBE_CONFIG_DIR/main.inc.php</p>';
+ if ($RCI->configured && $RCI->legacy_config) {
+ echo '<h2 class="error">Your configuration needs to be migrated!</h2>';
+ echo '<p>We changed the configuration files structure and your installation needs to be updated accordingly.</p>';
+ echo '<p>Please run the <tt>bin/update.sh</tt> script from the command line or set <p>&nbsp; <tt>$rcmail_config[\'enable_installer\'] = true;</tt></p>';
+ echo ' in your RCUBE_CONFIG_DIR/main.inc.php to let the installer help you migrating it.</p>';
+ }
+ else {
+ echo '<h2 class="error">The installer is disabled!</h2>';
+ echo '<p>To enable it again, set <tt>$rcmail_config[\'enable_installer\'] = true;</tt> in RCUBE_CONFIG_DIR/config.inc.php</p>';
+ }
echo '</div></body></html>';
exit;
}
diff --git a/installer/rcube_install.php b/installer/rcube_install.php
index d5811ded1..0f1bfe23e 100644
--- a/installer/rcube_install.php
+++ b/installer/rcube_install.php
@@ -28,10 +28,12 @@ class rcube_install
var $failures = 0;
var $config = array();
var $configured = false;
+ var $legacy_config = false;
var $last_error = null;
var $email_pattern = '([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9])';
var $bool_config_props = array();
+ var $local_config = array('db_dsnw', 'default_host', 'support_url', 'des_key', 'plugins');
var $obsolete_config = array('db_backend', 'double_auth');
var $replaced_config = array(
'skin_path' => 'skin',
@@ -44,12 +46,6 @@ class rcube_install
'top_posting' => 'reply_mode',
);
- // these config options are required for a working system
- var $required_config = array(
- 'db_dsnw', 'db_table_contactgroups', 'db_table_contactgroupmembers',
- 'des_key', 'session_lifetime', 'support_url',
- );
-
// list of supported database drivers
var $supported_dbs = array(
'MySQL' => 'pdo_mysql',
@@ -84,43 +80,75 @@ class rcube_install
}
/**
- * Read the default config files and store properties
- */
- function load_defaults()
- {
- $this->_load_config('.php.dist');
- }
-
-
- /**
* Read the local config files and store properties
*/
function load_config()
{
- $this->config = array();
- $this->_load_config('.php');
- $this->configured = !empty($this->config);
+ // defaults
+ if ($config = $this->load_config_file(RCUBE_CONFIG_DIR . 'defaults.inc.php')) {
+ $this->config = (array) $config;
+ $this->defaults = $this->config;
+ }
+
+ $config = null;
+
+ // config
+ if ($config = $this->load_config_file(RCUBE_CONFIG_DIR . 'config.inc.php')) {
+ $this->config = array_merge($this->config, $config);
+ }
+ else {
+ if ($config = $this->load_config_file(RCUBE_CONFIG_DIR . 'main.inc.php')) {
+ $this->config = array_merge($this->config, $config);
+ $this->legacy_config = true;
+ }
+ if ($config = $this->load_config_file(RCUBE_CONFIG_DIR . 'db.inc.php')) {
+ $this->config = array_merge($this->config, $config);
+ $this->legacy_config = true;
+ }
+ }
+
+ $this->configured = !empty($config);
}
/**
* Read the default config file and store properties
- * @access private
*/
- function _load_config($suffix)
+ public function load_config_file($file)
{
- if (is_readable($main_inc = RCUBE_CONFIG_DIR . 'main.inc' . $suffix)) {
- include($main_inc);
- if (is_array($rcmail_config))
- $this->config += $rcmail_config;
- }
- if (is_readable($db_inc = RCUBE_CONFIG_DIR . 'db.inc'. $suffix)) {
- include($db_inc);
- if (is_array($rcmail_config))
- $this->config += $rcmail_config;
+ if (is_readable($file)) {
+ include $file;
+
+ // read comments from config file
+ if (function_exists('token_get_all')) {
+ $tokens = token_get_all(file_get_contents($file));
+ $in_config = false;
+ $buffer = '';
+ for ($i=0; $i < count($tokens); $i++) {
+ $token = $tokens[$i];
+ if ($token[0] == T_VARIABLE && $token[1] == '$config' || $token[1] == '$rcmail_config') {
+ $in_config = true;
+ if ($buffer && $tokens[$i+1] == '[' && $tokens[$i+2][0] == T_CONSTANT_ENCAPSED_STRING) {
+ $propname = trim($tokens[$i+2][1], "'\"");
+ $this->comments[$propname] = $buffer;
+ $buffer = '';
+ $i += 3;
+ }
+ }
+ else if ($in_config && $token[0] == T_COMMENT) {
+ $buffer .= strtr($token[1], array('\n' => "\n"));
+ }
+ }
+ }
+
+ // deprecated name of config variable
+ if (is_array($rcmail_config)) {
+ return $rcmail_config;
+ }
+
+ return $config;
}
}
-
/**
* Getter for a certain config property
*
@@ -140,24 +168,31 @@ class rcube_install
/**
- * Take the default config file and replace the parameters
- * with the submitted form data
+ * Create configuration file that contains parameters
+ * that differ from default values.
*
- * @param string Which config file (either 'main' or 'db')
* @return string The complete config file content
*/
- function create_config($which, $force = false)
+ function create_config()
{
- $out = @file_get_contents(RCUBE_CONFIG_DIR . $which . '.inc.php.dist');
-
- if (!$out)
- return '[Warning: could not read the config template file]';
+ $config = array();
foreach ($this->config as $prop => $default) {
-
$is_default = !isset($_POST["_$prop"]);
$value = !$is_default || $this->bool_config_props[$prop] ? $_POST["_$prop"] : $default;
+ // always disable installer
+ if ($prop == 'enable_installer')
+ $value = false;
+
+ // reset useragent to default (keeps version up-to-date)
+ if ($prop == 'useragent' && stripos($value, 'Roundcube Webmail/') !== false)
+ $value = $this->defaults[$prop];
+
+ // generate new encryption key, never use the default value
+ if ($prop == 'des_key' && $value == $this->defaults[$prop])
+ $value = $this->random_key(24);
+
// convert some form data
if ($prop == 'debug_level' && !$is_default) {
if (is_array($value)) {
@@ -167,7 +202,7 @@ class rcube_install
$value = $val;
}
}
- else if ($which == 'db' && $prop == 'db_dsnw' && !empty($_POST['_dbtype'])) {
+ else if ($prop == 'db_dsnw' && !empty($_POST['_dbtype'])) {
if ($_POST['_dbtype'] == 'sqlite')
$value = sprintf('%s://%s?mode=0646', $_POST['_dbtype'], $_POST['_dbname']{0} == '/' ? '/' . $_POST['_dbname'] : $_POST['_dbname']);
else if ($_POST['_dbtype'])
@@ -212,20 +247,24 @@ class rcube_install
}
// skip this property
- if (!$force && !$this->configured && ($value == $default))
+ if ((!array_key_exists($prop, $this->defaults) || ($value == $this->defaults[$prop])) && !in_array($prop, $this->local_config)) {
continue;
+ }
// save change
$this->config[$prop] = $value;
+ $config[$prop] = $value;
+ }
- // replace the matching line in config file
- $out = preg_replace(
- '/(\$rcmail_config\[\''.preg_quote($prop).'\'\])\s+=\s+(.+);/Uie',
- "'\\1 = ' . rcube_install::_dump_var(\$value, \$prop) . ';'",
- $out);
+ $out = "<?php\n\n";
+ $out .= "/* Local configuration for Roundcube Webmail */\n\n";
+ foreach ($config as $prop => $value) {
+ // copy option descriptions from existing config or defaults.inc.php
+ $out .= $this->comments[$prop];
+ $out .= "\$config['$prop'] = " . rcube_install::_dump_var($value, $prop) . ";\n\n";
}
- return trim($out);
+ return $out;
}
@@ -237,16 +276,13 @@ class rcube_install
*/
function check_config()
{
- $this->config = array();
- $this->load_defaults();
- $defaults = $this->config;
-
$this->load_config();
- if (!$this->configured)
+
+ if (!$this->configured) {
return null;
+ }
$out = $seen = array();
- $required = array_flip($this->required_config);
// iterate over the current configuration
foreach ($this->config as $prop => $value) {
@@ -265,12 +301,6 @@ class rcube_install
$out['obsolete'][] = array('prop' => 'mime_magic', 'explain' => "Set value to null in order to use system default");
}
- // iterate over default config
- foreach ($defaults as $prop => $value) {
- if (!isset($seen[$prop]) && isset($required[$prop]) && !(is_bool($this->config[$prop]) || strlen($this->config[$prop])))
- $out['missing'][] = array('prop' => $prop);
- }
-
// check config dependencies and contradictions
if ($this->config['enable_spellcheck'] && $this->config['spellcheck_engine'] == 'pspell') {
if (!extension_loaded('pspell')) {
@@ -288,7 +318,7 @@ class rcube_install
if ($this->config['log_driver'] == 'syslog') {
if (!function_exists('openlog')) {
$out['dependencies'][] = array('prop' => 'log_driver',
- 'explain' => 'This requires the <tt>sylog</tt> extension which could not be loaded.');
+ 'explain' => 'This requires the <tt>syslog</tt> extension which could not be loaded.');
}
if (empty($this->config['syslog_id'])) {
$out['dependencies'][] = array('prop' => 'syslog_id',
@@ -318,7 +348,6 @@ class rcube_install
{
$current = $this->config;
$this->config = array();
- $this->load_defaults();
foreach ($this->replaced_config as $prop => $replacement) {
if (isset($current[$prop])) {
@@ -346,9 +375,9 @@ class rcube_install
}
}
- $this->config = array_merge($this->config, $current);
+ $this->config = array_merge($this->config, $current);
- foreach ((array)$current['ldap_public'] as $key => $values) {
+ foreach (array_keys((array)$current['ldap_public']) as $key) {
$this->config['ldap_public'][$key] = $current['ldap_public'][$key];
}
}
@@ -357,10 +386,11 @@ class rcube_install
* Compare the local database schema with the reference schema
* required for this version of Roundcube
*
- * @param boolean True if the schema schould be updated
+ * @param rcube_db Database object
+ *
* @return boolean True if the schema is up-to-date, false if not or an error occured
*/
- function db_schema_check($DB, $update = false)
+ function db_schema_check($DB)
{
if (!$this->configured)
return false;
@@ -373,7 +403,7 @@ class rcube_install
$existing_tables = $DB->list_tables();
foreach ($db_schema as $table => $cols) {
- $table = !empty($this->config['db_table_'.$table]) ? $this->config['db_table_'.$table] : $table;
+ $table = $this->config['db_prefix'] . $table;
if (!in_array($table, $existing_tables)) {
$errors[] = "Missing table '".$table."'";
}
@@ -411,6 +441,51 @@ class rcube_install
return $schema;
}
+ /**
+ * Try to detect some file's mimetypes to test the correct behavior of fileinfo
+ */
+ function check_mime_detection()
+ {
+ $files = array(
+ 'installer/images/roundcube_logo.png' => 'image/png',
+ 'program/resources/blank.tif' => 'image/tiff',
+ 'skins/larry/templates/login.html' => 'text/html',
+ );
+
+ $errors = array();
+ foreach ($files as $path => $expected) {
+ $mimetype = rcube_mime::file_content_type(INSTALL_PATH . $path, basename($path));
+ if ($mimetype != $expected) {
+ $errors[] = array($path, $mimetype, $expected);
+ }
+ }
+
+ return $errors;
+ }
+
+ /**
+ * Check the correct configuration of the 'mime_types' mapping option
+ */
+ function check_mime_extensions()
+ {
+ $types = array(
+ 'application/zip' => 'zip',
+ 'application/x-tar' => 'tar',
+ 'application/java-archive' => 'jar',
+ 'image/bmp' => 'bmp',
+ 'image/svg+xml' => 'svg',
+ );
+
+ $errors = array();
+ foreach ($types as $mimetype => $expected) {
+ $ext = rcube_mime::get_mime_extensions($mimetype);
+ if ($ext[0] != $expected) {
+ $errors[] = array($mimetype, $ext, $expected);
+ }
+ }
+
+ return $errors;
+ }
/**
* Getter for the last error message
@@ -452,11 +527,12 @@ class rcube_install
'0.2-alpha', '0.2-beta', '0.2-stable',
'0.3-stable', '0.3.1',
'0.4-beta', '0.4.2',
- '0.5-beta', '0.5', '0.5.1',
+ '0.5-beta', '0.5', '0.5.1', '0.5.2', '0.5.3', '0.5.4',
'0.6-beta', '0.6',
- '0.7-beta', '0.7', '0.7.1', '0.7.2', '0.7.3',
- '0.8-beta', '0.8-rc', '0.8.0', '0.8.1', '0.8.2', '0.8.3', '0.8.4', '0.8.5',
- '0.9-beta', '0.9-rc',
+ '0.7-beta', '0.7', '0.7.1', '0.7.2', '0.7.3', '0.7.4',
+ '0.8-beta', '0.8-rc', '0.8.0', '0.8.1', '0.8.2', '0.8.3', '0.8.4', '0.8.5', '0.8.6',
+ '0.9-beta', '0.9-rc', '0.9-rc2',
+ // Note: Do not add newer versions here
));
return $select;
}
@@ -495,10 +571,13 @@ class rcube_install
* @param string Test name
* @param string Error message
* @param string URL for details
+ * @param bool Do not count this failure
*/
- function fail($name, $message = '', $url = '')
+ function fail($name, $message = '', $url = '', $optional=false)
{
- $this->failures++;
+ if (!$optional) {
+ $this->failures++;
+ }
echo Q($name) . ':&nbsp; <span class="fail">NOT OK</span>';
$this->_showhint($message, $url);
@@ -562,7 +641,8 @@ class rcube_install
}
- static function _dump_var($var, $name=null) {
+ static function _dump_var($var, $name=null)
+ {
// special values
switch ($name) {
case 'syslog_facility':
@@ -575,8 +655,20 @@ class rcube_install
if ($val = $list[$var])
return $val;
break;
- }
+ case 'mail_header_delimiter':
+ $var = str_replace(array("\r", "\n"), array('\r', '\n'), $var);
+ return '"' . $var. '"';
+ break;
+/*
+ // RCMAIL_VERSION is undefined here
+ case 'useragent':
+ if (preg_match('|^(.*)/('.preg_quote(RCMAIL_VERSION, '|').')$|i', $var, $m)) {
+ return '"' . addcslashes($var, '"') . '/" . RCMAIL_VERSION';
+ }
+ break;
+*/
+ }
if (is_array($var)) {
if (empty($var)) {
@@ -584,7 +676,7 @@ class rcube_install
}
else { // check if all keys are numeric
$isnum = true;
- foreach ($var as $key => $value) {
+ foreach (array_keys($var) as $key) {
if (!is_numeric($key)) {
$isnum = false;
break;
@@ -638,8 +730,10 @@ class rcube_install
*/
function update_db($version)
{
- system(INSTALL_PATH . "bin/updatedb.sh --package=roundcube --version=" . $version
- . " --dir=" . INSTALL_PATH . "SQL", $result);
+ system(INSTALL_PATH . "bin/updatedb.sh --package=roundcube"
+ . " --version=" . escapeshellarg($version)
+ . " --dir=" . INSTALL_PATH . "SQL"
+ . " 2>&1", $result);
return !$result;
}
@@ -654,6 +748,7 @@ class rcube_install
*/
function exec_sql($sql, $DB)
{
+ $sql = $this->fix_table_names($sql, $DB);
$buff = '';
foreach (explode("\n", $sql) as $line) {
if (preg_match('/^--/', $line) || trim($line) == '')
@@ -673,6 +768,35 @@ class rcube_install
/**
+ * Parse SQL file and fix table names according to db_prefix
+ * Note: This need to be a complete database initial file
+ */
+ private function fix_table_names($sql, $DB)
+ {
+ if (empty($this->config['db_prefix'])) {
+ return $sql;
+ }
+
+ // replace table names
+ if (preg_match_all('/CREATE TABLE (\[dbo\]\.|IF NOT EXISTS )?[`"\[\]]*([^`"\[\] \r\n]+)/i', $sql, $matches)) {
+ foreach ($matches[2] as $table) {
+ $real_table = $this->config['db_prefix'] . $table;
+ $sql = preg_replace("/([^a-zA-Z0-9_])$table([^a-zA-Z0-9_])/", "\\1$real_table\\2", $sql);
+ }
+ }
+ // replace sequence names
+ if ($DB->db_provider == 'postgres' && preg_match_all('/CREATE SEQUENCE (IF NOT EXISTS )?"?([^" \n\r]+)/i', $sql, $matches)) {
+ foreach ($matches[2] as $sequence) {
+ $real_sequence = $this->config['db_prefix'] . $sequence;
+ $sql = preg_replace("/([^a-zA-Z0-9_])$sequence([^a-zA-Z0-9_])/", "\\1$real_sequence\\2", $sql);
+ }
+ }
+
+ return $sql;
+ }
+
+
+ /**
* Handler for Roundcube errors
*/
function raise_error($p)
diff --git a/installer/test.php b/installer/test.php
index bd49ac523..f834308ad 100644
--- a/installer/test.php
+++ b/installer/test.php
@@ -7,52 +7,44 @@ if (!class_exists('rcube_install') || !is_object($RCI)) {
?>
<form action="index.php?_step=3" method="post">
-<h3>Check config files</h3>
+<h3>Check config file</h3>
<?php
-$read_main = is_readable(RCUBE_CONFIG_DIR . 'main.inc.php');
-$read_db = is_readable(RCUBE_CONFIG_DIR . 'db.inc.php');
-
-if ($read_main && !empty($RCI->config)) {
- $RCI->pass('main.inc.php');
-}
-else if ($read_main) {
- $RCI->fail('main.inc.php', 'Syntax error');
+if ($read_config = is_readable(RCUBE_CONFIG_DIR . 'defaults.inc.php')) {
+ $config = $RCI->load_config_file(RCUBE_CONFIG_DIR . 'defaults.inc.php');
+ if (!empty($config)) {
+ $RCI->pass('defaults.inc.php');
+ }
+ else {
+ $RCI->fail('defaults.inc.php', 'Syntax error');
+ }
}
-else if (!$read_main) {
- $RCI->fail('main.inc.php', 'Unable to read file. Did you create the config files?');
+else {
+ $RCI->fail('defaults.inc.php', 'Unable to read default config file?');
}
echo '<br />';
-if ($read_db && !empty($RCI->config['db_table_users'])) {
- $RCI->pass('db.inc.php');
-}
-else if ($read_db) {
- $RCI->fail('db.inc.php', 'Syntax error');
+if ($read_config = is_readable(RCUBE_CONFIG_DIR . 'config.inc.php')) {
+ $config = $RCI->load_config_file(RCUBE_CONFIG_DIR . 'config.inc.php');
+ if (!empty($config)) {
+ $RCI->pass('config.inc.php');
+ }
+ else {
+ $RCI->fail('config.inc.php', 'Syntax error');
+ }
}
-else if (!$read_db) {
- $RCI->fail('db.inc.php', 'Unable to read file. Did you create the config files?');
+else {
+ $RCI->fail('config.inc.php', 'Unable to read file. Did you create the config file?');
}
+echo '<br />';
-if ($RCI->configured && ($messages = $RCI->check_config())) {
-
- if (is_array($messages['missing'])) {
- echo '<h3 class="warning">Missing config options</h3>';
- echo '<p class="hint">The following config options are not present in the current configuration.<br/>';
- echo 'Please check the default config files and add the missing properties to your local config files.</p>';
-
- echo '<ul class="configwarings">';
- foreach ($messages['missing'] as $msg) {
- echo html::tag('li', null, html::span('propname', $msg['prop']) . ($msg['name'] ? ':&nbsp;' . $msg['name'] : ''));
- }
- echo '</ul>';
- }
+if ($RCI->configured && ($messages = $RCI->check_config())) {
if (is_array($messages['replaced'])) {
echo '<h3 class="warning">Replaced config options</h3>';
echo '<p class="hint">The following config options have been replaced or renamed. ';
echo 'Please update them accordingly in your config files.</p>';
-
+
echo '<ul class="configwarings">';
foreach ($messages['replaced'] as $msg) {
echo html::tag('li', null, html::span('propname', $msg['prop']) .
@@ -64,32 +56,28 @@ if ($RCI->configured && ($messages = $RCI->check_config())) {
if (is_array($messages['obsolete'])) {
echo '<h3>Obsolete config options</h3>';
echo '<p class="hint">You still have some obsolete or inexistent properties set. This isn\'t a problem but should be noticed.</p>';
-
+
echo '<ul class="configwarings">';
foreach ($messages['obsolete'] as $msg) {
echo html::tag('li', null, html::span('propname', $msg['prop']) . ($msg['name'] ? ':&nbsp;' . $msg['name'] : ''));
}
echo '</ul>';
}
-
- echo '<p class="suggestion">OK, lazy people can download the updated config files here: ';
- echo html::a(array('href' => './?_mergeconfig=main'), 'main.inc.php') . ' &nbsp;';
- echo html::a(array('href' => './?_mergeconfig=db'), 'db.inc.php');
+
+ echo '<p class="suggestion">OK, lazy people can download the updated config file here: ';
+ echo html::a(array('href' => './?_mergeconfig=1'), 'config.inc.php') . ' &nbsp;';
echo "</p>";
-
-
+
if (is_array($messages['dependencies'])) {
echo '<h3 class="warning">Dependency check failed</h3>';
echo '<p class="hint">Some of your configuration settings require other options to be configured or additional PHP modules to be installed</p>';
-
+
echo '<ul class="configwarings">';
foreach ($messages['dependencies'] as $msg) {
echo html::tag('li', null, html::span('propname', $msg['prop']) . ': ' . $msg['explain']);
}
echo '</ul>';
}
-
-
}
?>
@@ -98,30 +86,24 @@ if ($RCI->configured && ($messages = $RCI->check_config())) {
<p>Roundcube may need to write/save files into these directories</p>
<?php
-if ($RCI->configured) {
- $pass = false;
-
- $dirs[] = $RCI->config['temp_dir'] ? $RCI->config['temp_dir'] : 'temp';
- if($RCI->config['log_driver'] != 'syslog')
- $dirs[] = $RCI->config['log_dir'] ? $RCI->config['log_dir'] : 'logs';
+$dirs[] = $RCI->config['temp_dir'] ? $RCI->config['temp_dir'] : 'temp';
+if ($RCI->config['log_driver'] != 'syslog')
+ $dirs[] = $RCI->config['log_dir'] ? $RCI->config['log_dir'] : 'logs';
- foreach ($dirs as $dir) {
- $dirpath = $dir[0] == '/' ? $dir : INSTALL_PATH . $dir;
- if (is_writable(realpath($dirpath))) {
- $RCI->pass($dir);
- $pass = true;
- }
- else {
- $RCI->fail($dir, 'not writeable for the webserver');
- }
- echo '<br />';
+foreach ($dirs as $dir) {
+ $dirpath = $dir[0] == '/' ? $dir : INSTALL_PATH . $dir;
+ if (is_writable(realpath($dirpath))) {
+ $RCI->pass($dir);
+ $pass = true;
}
-
- if (!$pass)
- echo '<p class="hint">Use <tt>chmod</tt> or <tt>chown</tt> to grant write privileges to the webserver</p>';
+ else {
+ $RCI->fail($dir, 'not writeable for the webserver');
+ }
+ echo '<br />';
}
-else {
- $RCI->fail('Config', 'Could not read config files');
+
+if (!$pass) {
+ echo '<p class="hint">Use <tt>chmod</tt> or <tt>chown</tt> to grant write privileges to the webserver</p>';
}
?>
@@ -151,7 +133,7 @@ if ($RCI->configured) {
}
}
else {
- $RCI->fail('Config', 'Could not read config files');
+ $RCI->fail('DSN (write)', 'Could not read config file');
}
// initialize db with schema found in /SQL/*
@@ -171,7 +153,7 @@ else if ($db_working && $_POST['updatedb']) {
// test database
if ($db_working) {
- $db_read = $DB->query("SELECT count(*) FROM {$RCI->config['db_table_users']}");
+ $db_read = $DB->query("SELECT count(*) FROM {$RCI->config['db_prefix']}users");
if ($DB->is_error()) {
$RCI->fail('DB Schema', "Database not initialized");
echo '<p><input type="submit" name="initdb" value="Initialize database" /></p>';
@@ -195,11 +177,11 @@ if ($db_working) {
if ($db_working) {
// write test
$insert_id = md5(uniqid());
- $db_write = $DB->query("INSERT INTO {$RCI->config['db_table_session']} (sess_id, created, ip, vars) VALUES (?, ".$DB->now().", '127.0.0.1', 'foo')", $insert_id);
+ $db_write = $DB->query("INSERT INTO {$RCI->config['db_prefix']}session (sess_id, created, ip, vars) VALUES (?, ".$DB->now().", '127.0.0.1', 'foo')", $insert_id);
if ($db_write) {
$RCI->pass('DB Write');
- $DB->query("DELETE FROM {$RCI->config['db_table_session']} WHERE sess_id=?", $insert_id);
+ $DB->query("DELETE FROM {$RCI->config['db_prefix']}session WHERE sess_id=?", $insert_id);
}
else {
$RCI->fail('DB Write', $RCI->get_error());
@@ -225,6 +207,42 @@ if ($db_working) {
?>
+<h3>Test filetype detection</h3>
+
+<p>
+<?php
+
+if ($errors = $RCI->check_mime_detection()) {
+ $RCI->fail('Fileinfo/mime_content_type configuration');
+ if (!empty($RCI->config['mime_magic'])) {
+ echo '<p class="hint">Try setting the <tt>mime_magic</tt> config option to <tt>null</tt>.</p>';
+ }
+ else {
+ echo '<p class="hint">Check the <a href="http://www.php.net/manual/en/function.finfo-open.php">Fileinfo functions</a> of your PHP installation.<br/>';
+ echo 'The path to the magic.mime file can be set using the <tt>mime_magic</tt> config option in Roundcube.</p>';
+ }
+}
+else {
+ $RCI->pass('Fileinfo/mime_content_type configuration');
+}
+
+?>
+</p>
+<p>
+<?php
+
+if ($errors = $RCI->check_mime_extensions()) {
+ $RCI->fail('Mimetype to file extension mapping');
+ echo '<p class="hint">Please set a valid path to your webserver\'s mime.types file to the <tt>mime_types</tt> config option.<br/>';
+ echo 'If you can\'t find such a file, download it from <a href="http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types">svn.apache.org</a>.</p>';
+}
+else {
+ $RCI->pass('Mimetype to file extension mapping');
+}
+
+?>
+
+
<h3>Test SMTP config</h3>
<p>
@@ -427,7 +445,7 @@ if (isset($_POST['imaptest']) && !empty($_POST['_host']) && !empty($_POST['_user
After completing the installation and the final tests please <b>remove</b> the whole
installer folder from the document root of the webserver or make sure that
-<tt>enable_installer</tt> option in config/main.inc.php is disabled.<br />
+<tt>enable_installer</tt> option in <tt>config.inc.php</tt> is disabled.<br />
<br />
These files may expose sensitive configuration data like server passwords and encryption keys