INSTALL
@@ -59,7 +59,7 @@ =================== Roundcube writes internal errors to the 'errors' log file located in the logs directory which can be configured in config/main.inc.php. If you want ordinary directory which can be configured in config/config.inc.php. If you want ordinary PHP errors to be logged there as well, enable the 'php_value error_log' line in the .htaccess file and set the path to the log file accordingly. UPGRADING
@@ -39,7 +39,7 @@ 3. Run ./bin/update.sh from the commandline OR open http://url-to-roundcube/installer/ in a browser and choose "3 Test config". To enable the latter one, you have to temporary set 'enable_installer' to true in your local config/main.inc.php file. to true in your local config/config.inc.php file. WARNING: See SQLite database upgrade below. 4. Let the update script/installer check your configuration and update your config files and database schema as suggested by the updater. bin/installto.sh
@@ -50,7 +50,7 @@ break; } } foreach (array('index.php','.htaccess','config/main.inc.php.dist','config/db.inc.php.dist','CHANGELOG','README.md','UPGRADING','LICENSE') as $file) { foreach (array('index.php','.htaccess','config/defaults.inc.php','CHANGELOG','README.md','UPGRADING','LICENSE') as $file) { if (!system("rsync -av " . INSTALL_PATH . "$file $target_dir/$file")) { $err = true; break; bin/update.sh
@@ -45,22 +45,10 @@ if ($RCI->configured) { $success = true; if ($messages = $RCI->check_config()) { $success = false; $err = 0; // list missing config options if (is_array($messages['missing'])) { echo "WARNING: Missing config options:\n"; echo "(These config options should be present in the current configuration)\n"; foreach ($messages['missing'] as $msg) { echo "- '" . $msg['prop'] . ($msg['name'] ? "': " . $msg['name'] : "'") . "\n"; $err++; } echo "\n"; } // list old/replaced config options if (is_array($messages['replaced'])) { @@ -93,24 +81,27 @@ // positive: let's merge the local config with the defaults if (strtolower($input) == 'y') { $copy1 = $copy2 = $write1 = $write2 = false; $error = $writed = false; // backup current config echo ". backing up the current config files...\n"; $copy1 = copy(RCMAIL_CONFIG_DIR . '/main.inc.php', RCMAIL_CONFIG_DIR . '/main.old.php'); $copy2 = copy(RCMAIL_CONFIG_DIR . '/db.inc.php', RCMAIL_CONFIG_DIR . '/db.old.php'); if ($copy1 && $copy2) { $RCI->merge_config(); echo ". writing " . RCMAIL_CONFIG_DIR . "/main.inc.php...\n"; $write1 = file_put_contents(RCMAIL_CONFIG_DIR . '/main.inc.php', $RCI->create_config('main', true)); echo ". writing " . RCMAIL_CONFIG_DIR . "/main.db.php...\n"; $write2 = file_put_contents(RCMAIL_CONFIG_DIR . '/db.inc.php', $RCI->create_config('db', true)); echo ". backing up the current config file(s)...\n"; foreach (array('config', 'main', 'db') as $file) { if (file_exists(RCMAIL_CONFIG_DIR . '/' . $file . '.inc.php')) if (!copy(RCMAIL_CONFIG_DIR . '/' . $file . '.inc.php', RCMAIL_CONFIG_DIR . '/' . $file . '.old.php')) { $error = true; } } } if (!$error) { $RCI->merge_config(); echo ". writing " . RCMAIL_CONFIG_DIR . "/config.inc.php...\n"; $writed = file_put_contents(RCMAIL_CONFIG_DIR . '/config.inc.php', $RCI->create_config()); } // Success! if ($write1 && $write2) { if ($writed) { echo "Done.\n"; echo "Your configuration files are now up-to-date!\n"; @@ -121,7 +112,7 @@ } } else { echo "Failed to write config files!\n"; echo "Failed to write config file(s)!\n"; echo "Grant write privileges to the current user or update the files manually according to the above messages.\n"; } } config/db.inc.php.dist
File was deleted config/main.inc.php.dist
File was deleted installer/config.php
@@ -9,9 +9,6 @@ <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, @@ -27,24 +24,19 @@ $_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><?php ?></tt> brackets when saving the files.</p>'; echo '<p class="notice">Copy or download the following configuration and save'; echo ' as <tt><b>config.inc.php</b></tt> within the <tt>'.RCMAIL_CONFIG_DIR.'</tt> directory of your Roundcube installation.<br/>'; echo ' Make sure that there are no characters outside the <tt><?php ?></tt> brackets when saving the file.'; echo ' <input type="button" onclick="location.href=\'index.php?_getconfig=1\'" value="Download" /></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"; } 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 | @@ -59,12 +59,12 @@ $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 +74,14 @@ } 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; } @@ -122,7 +122,7 @@ 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>'; 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; } installer/rcube_install.php
@@ -44,11 +44,6 @@ 'top_posting' => 'reply_mode', ); // these config options are required for a working system var $required_config = array( 'db_dsnw', 'des_key', 'session_lifetime', ); // list of supported database drivers var $supported_dbs = array( 'MySQL' => 'pdo_mysql', @@ -83,42 +78,50 @@ } /** * 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); } if ($config = $this->load_config_file(RCUBE_CONFIG_DIR . 'db.inc.php')) { $this->config = array_merge($this->config, $config); } } $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; // deprecated name of config variable if (is_array($rcmail_config)) { return $rcmail_config; } return $config; } } /** * Getter for a certain config property @@ -139,21 +142,16 @@ /** * 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; @@ -211,20 +209,26 @@ } // skip this property if (!$force && !$this->configured && ($value == $default)) if (!array_key_exists($prop, $this->defaults) || ($value == $this->defaults[$prop])) { continue; } // save change $this->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); $config[$prop] = $value; } return trim($out); // sort by option name ksort($config); $out = "<?php\n\n"; foreach ($config as $prop => $value) { // @TODO: copy option descriptions from defaults.inc.php file? $out .= "\$config['$prop'] = " . rcube_install::_dump_var($value, $prop) . ";\n"; } $out .= "\n?>"; return $out; } @@ -236,16 +240,13 @@ */ 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) { @@ -262,12 +263,6 @@ // the old default mime_magic reference is obsolete if ($this->config['mime_magic'] == '/usr/share/misc/magic') { $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 @@ -317,7 +312,6 @@ { $current = $this->config; $this->config = array(); $this->load_defaults(); foreach ($this->replaced_config as $prop => $replacement) { if (isset($current[$prop])) { @@ -345,7 +339,7 @@ } } $this->config = array_merge($this->config, $current); $this->config = array_merge($this->config, $current); foreach (array_keys((array)$current['ldap_public']) as $key) { $this->config['ldap_public'][$key] = $current['ldap_public'][$key]; @@ -563,7 +557,8 @@ } static function _dump_var($var, $name=null) { static function _dump_var($var, $name=null) { // special values switch ($name) { case 'syslog_facility': @@ -576,8 +571,20 @@ 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)) { installer/test.php
@@ -7,52 +7,44 @@ ?> <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'); 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', '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_dsnw'])) { $RCI->pass('db.inc.php'); 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', 'Syntax error'); else { $RCI->fail('config.inc.php', 'Unable to read file. Did you create the config file?'); } else if (!$read_db) { $RCI->fail('db.inc.php', 'Unable to read file. Did you create the config files?'); } 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 set (not present or empty) in the current configuration.<br/>'; echo 'Please check the default config files and set the missing properties in your local config files.</p>'; echo '<ul class="configwarnings">'; foreach ($messages['missing'] as $msg) { echo html::tag('li', null, html::span('propname', $msg['prop']) . ($msg['name'] ? ': ' . $msg['name'] : '')); } echo '</ul>'; } 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 (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'] ? ': ' . $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') . ' '; 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') . ' '; 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 @@ <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 @@ } } 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/* @@ -427,7 +409,7 @@ 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 plugins/additional_message_headers/additional_message_headers.php
@@ -6,7 +6,7 @@ * Very simple plugin which will add additional headers * to or remove them from outgoing messages. * * Enable the plugin in config/main.inc.php and add your desired headers: * Enable the plugin in config.inc.php and add your desired headers: * $rcmail_config['additional_message_headers'] = array('User-Agent'); * * @version @package_version@ @@ -24,7 +24,7 @@ function message_headers($args) { $this->load_config(); $this->load_config(); // additional email headers $additional_headers = rcmail::get_instance()->config->get('additional_message_headers',array()); @@ -39,5 +39,3 @@ return $args; } } ?> plugins/debug_logger/debug_logger.php
@@ -12,7 +12,7 @@ * which can redirect messages to files. The resulting log files * provide timing and tag quantity results. * * Enable the plugin in config/main.inc.php and add your desired * Enable the plugin in config.inc.php and add your desired * log types and files. * * @version @package_version@ @@ -21,7 +21,7 @@ * * Example: * * config/main.inc.php: * config.inc.php: * * // $rcmail_config['debug_logger'][type of logging] = name of file in log_dir * // The 'master' log includes timing information plugins/password/README
@@ -65,7 +65,7 @@ ------------------- You can specify which database to connect by 'password_db_dsn' option and what SQL query to execute by 'password_query'. See main.inc.php.dist file for what SQL query to execute by 'password_query'. See config.inc.php.dist file for more info. Example implementations of an update_passwd function: plugins/show_additional_headers/show_additional_headers.php
@@ -6,7 +6,7 @@ * Proof-of-concept plugin which will fetch additional headers * and display them in the message view. * * Enable the plugin in config/main.inc.php and add your desired headers: * Enable the plugin in config.inc.php and add your desired headers: * $rcmail_config['show_additional_headers'] = array('User-Agent'); * * @version @package_version@ plugins/subscriptions_option/subscriptions_option.php
@@ -7,7 +7,7 @@ * It includes a toggle on the settings page under "Server Settings". * The preference can also be locked * * Add it to the plugins list in config/main.inc.php to enable the user option * Add it to the plugins list in config.inc.php to enable the user option * The user option can be hidden and set globally by adding 'use_subscriptions' * to the 'dont_override' configure line: * $rcmail_config['dont_override'] = array('use_subscriptions'); plugins/virtuser_file/virtuser_file.php
@@ -3,7 +3,7 @@ /** * File based User-to-Email and Email-to-User lookup * * Add it to the plugins list in config/main.inc.php and set * Add it to the plugins list in config.inc.php and set * path to a virtuser table file to resolve user names and e-mail * addresses * $rcmail_config['virtuser_file'] = ''; plugins/virtuser_query/virtuser_query.php
@@ -3,7 +3,7 @@ /** * DB based User-to-Email and Email-to-User lookup * * Add it to the plugins list in config/main.inc.php and set * Add it to the plugins list in config.inc.php and set * SQL queries to resolve usernames, e-mail addresses and hostnames from the database * %u will be replaced with the current username for login. * %m will be replaced with the current e-mail address for login. program/lib/Roundcube/rcube_config.php
@@ -69,13 +69,19 @@ */ private function load() { // load main config file if (!$this->load_from_file(RCUBE_CONFIG_DIR . 'main.inc.php')) $this->errors[] = 'main.inc.php was not found.'; // Load default settings if (!$this->load_from_file(RCUBE_CONFIG_DIR . 'defaults.inc.php')) { $this->errors[] = 'defaults.inc.php was not found.'; } // load database config if (!$this->load_from_file(RCUBE_CONFIG_DIR . 'db.inc.php')) $this->errors[] = 'db.inc.php was not found.'; // load main config file if (!$this->load_from_file(RCUBE_CONFIG_DIR . 'config.inc.php')) { $this->errors[] = 'config.inc.php was not found.'; // Old configuration files $this->load_from_file(RCUBE_CONFIG_DIR . 'main.inc.php'); $this->load_from_file(RCUBE_CONFIG_DIR . 'db.inc.php'); } // load host-specific configuration $this->load_host_config(); @@ -175,7 +181,12 @@ include($fpath); ob_end_clean(); if (is_array($rcmail_config)) { if (is_array($config)) { $this->merge($config); return true; } // deprecated name of config variable else if (is_array($rcmail_config)) { $this->merge($rcmail_config); return true; }