# HG changeset patch # User Dan # Date 1194364413 18000 # Node ID a78537db2850ba2f7eff5b651c60a26697728d1b # Parent b11a2f1353c00a7a2bbd5325110e4ebd3a0af28e# Parent c26308d8188276accb639b153a08c28d6c57949a Merge in new installer framework from stable diff -r b11a2f1353c0 -r a78537db2850 .htaccess diff -r b11a2f1353c0 -r a78537db2850 .htaccess.new diff -r b11a2f1353c0 -r a78537db2850 README --- a/README Sat Nov 03 14:30:53 2007 -0400 +++ b/README Tue Nov 06 10:53:33 2007 -0500 @@ -1,25 +1,80 @@ Enano CMS -Version 1.0.1 +Version 1.0.2 ----------------------------- Thanks for downloading Enano! If you're looking for an installation guide, -you can find it at . +you can find it at . COPYRIGHT ----------------------------- +Enano CMS +Copyright (C) 2006-2007 Dan Fuhry. All rights except those explicitly granted +by the included license agreement reserved. + +PHILOSOPHY +----------------------------- + We strongly believe in the idea of Free Software. Enano is released under the GNU General Public License; see the file GPL included with this release for details. +LICENSING +----------------------------- + +This program is Free Software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to: + + Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor + Boston, MA 02110-1301, USA + +----------------------------- + Most of the PHP code in Enano was written by Dan Fuhry. Some parts were borrowed from other projects that are also released under Free licenses; see the various files under the licenses/ directory included with this release for details. +If you are planning to make a commercial fork of Enano, all of the software and +libraries included with Enano are available under licenses that allow you to do +so; however, in compliance with the GPL, you must: + +a) provide attribution to the Enano team in source code files and on the + (renamed) Special:About_Enano page, +b) remove all instances of the word Enano and the Enano logo from your + derivative work, with the exception of the following phrase, which must + be shown on the (renamed) Special:About_Enano page: + + "The software used on this website was based on Enano CMS. Copyright + (C) 2006-2007 Enano Foundation." + + The words "Enano CMS" must link to the page . You may + (at your option) also include a notice of non-endorsement by the Enano + Foundation, unless you're lucky enough to become an official fork + maintainer. + +c) Provide the complete source code for your modified version of Enano under + the terms of the GNU General Public License, and +d) Include the complete and unmodified licenses/ directory, which contains + licensing information for third-party libraries that Enano uses. + +As permitted by the GPL, you may charge for the service of downloading Enano +from your server; however, you may not prevent others from distributing Enano +or any modified version. + CHANGES IN THIS RELEASE ----------------------------- -Please see for a list of changes in +Please see for a list of changes in this release. UPGRADING FROM PREVIOUS RELEASES @@ -44,15 +99,22 @@ You can find more themes for Enano at . Again, we're still working on packaging up themes and creating pages for them, -so try to be patient. We have quite a few themes in the works. +so try to be patient. We have quite a few themes in the works. You can create +your own themes too; for more information, see Chapter V of the Enano +Administrator's handbook, at . GETTING SUPPORT ----------------------------- +Before contacting support, have a look at the Enano Documentation at +. Most of Enano's features are documented with +step-by-step guides at this site; if you encounter a problem, then please +contact the Enano team as instructed below. + Support for Enano is available via the Enano forums at . You can also use our IRC channel -(irc.freenode.net #enano) or purchase paid support via instant messaging for -US$20 an hour. +(irc.freenode.net #enano) or purchase paid one-on-one support via instant +messaging for US$20 an hour. Have fun with Enano! diff -r b11a2f1353c0 -r a78537db2850 config.new.php diff -r b11a2f1353c0 -r a78537db2850 config.php diff -r b11a2f1353c0 -r a78537db2850 includes/functions.php --- a/includes/functions.php Sat Nov 03 14:30:53 2007 -0400 +++ b/includes/functions.php Tue Nov 06 10:53:33 2007 -0500 @@ -3019,7 +3019,7 @@ * @return int */ -function password_score($password, &$debug = false) +function password_score($password, &$debug) { if ( !is_string($password) ) { diff -r b11a2f1353c0 -r a78537db2850 includes/pageutils.php --- a/includes/pageutils.php Sat Nov 03 14:30:53 2007 -0400 +++ b/includes/pageutils.php Tue Nov 06 10:53:33 2007 -0500 @@ -842,7 +842,7 @@ return 'The page "' . $name . '" has been undeleted according to the log created at ' . $rb['date_string'] . '.'; break; case "reupload": - if ( !$session->get_permissions('history_rollbacks_extra') ) + if ( !$session->get_permissions('history_rollback_extra') ) { return 'Administrative privileges are required for file rollbacks.'; } diff -r b11a2f1353c0 -r a78537db2850 includes/paths.php --- a/includes/paths.php Sat Nov 03 14:30:53 2007 -0400 +++ b/includes/paths.php Tue Nov 06 10:53:33 2007 -0500 @@ -54,7 +54,7 @@ $session->register_acl_type('mod_comments', AUTH_DISALLOW, 'perm_mod_comments', Array('edit_comments'), 'Article|User|Project|Template|File|Help|System|Category'); $session->register_acl_type('history_view', AUTH_WIKIMODE, 'perm_history_view', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); $session->register_acl_type('history_rollback', AUTH_DISALLOW, 'perm_history_rollback', Array('history_view'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('history_rollback_extra', AUTH_DISALLOW, 'perm_history_rollback_extra', Array('history_rollback'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('history_rollback_extra', AUTH_DISALLOW, 'perm_history_rollback_extra', Array('history_rollback'), 'Article|User|Project|Template|File|Help|System|Category|Special'); $session->register_acl_type('protect', AUTH_DISALLOW, 'perm_protect', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); $session->register_acl_type('rename', AUTH_WIKIMODE, 'perm_rename', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); $session->register_acl_type('clear_logs', AUTH_DISALLOW, 'perm_clear_logs', Array('read', 'protect', 'even_when_protected'), 'Article|User|Project|Template|File|Help|System|Category'); diff -r b11a2f1353c0 -r a78537db2850 install.php --- a/install.php Sat Nov 03 14:30:53 2007 -0400 +++ b/install.php Tue Nov 06 10:53:33 2007 -0500 @@ -64,6 +64,527 @@ require('includes/functions.php'); strip_magic_quotes_gpc(); +$neutral_color = 'C'; + +// +// INSTALLER LIBRARY +// + +function run_installer_stage($stage_id, $stage_name, $function, $failure_explanation, $allow_skip = true) +{ + static $resumed = false; + static $resume_stack = array(); + + if ( empty($resume_stack) && isset($_POST['resume_stack']) && preg_match('/[a-z_]+((\|[a-z_]+)+)/', $_POST['resume_stack']) ) + { + $resume_stack = explode('|', $_POST['resume_stack']); + } + + $already_run = false; + if ( in_array($stage_id, $resume_stack) ) + { + $already_run = true; + } + + if ( !$resumed ) + { + if ( !isset($_GET['stage']) ) + $resumed = true; + if ( isset($_GET['stage']) && $_GET['stage'] == $stage_id ) + { + $resumed = true; + } + } + if ( !$resumed && $allow_skip ) + { + echo_stage_success($stage_id, "[dbg: skipped] $stage_name"); + return false; + } + if ( !function_exists($function) ) + die('libenanoinstall: CRITICAL: function "' . $function . '" for ' . $stage_id . ' doesn\'t exist'); + $result = @call_user_func($function, false, $already_run); + if ( $result ) + { + echo_stage_success($stage_id, $stage_name); + $resume_stack[] = $stage_id; + return true; + } + else + { + echo_stage_failure($stage_id, $stage_name, $failure_explanation, $resume_stack); + return false; + } +} + +function start_install_table() +{ + echo '' . "\n"; +} + +function close_install_table() +{ + echo '
' . "\n\n"; +} + +function echo_stage_success($stage_id, $stage_name) +{ + global $neutral_color; + $neutral_color = ( $neutral_color == 'A' ) ? 'C' : 'A'; + ob_start(); + echo '' . htmlspecialchars($stage_name) . 'Done' . "\n"; + ob_end_flush(); +} + +function echo_stage_failure($stage_id, $stage_name, $failure_explanation, $resume_stack) +{ + global $neutral_color; + + $neutral_color = ( $neutral_color == 'A' ) ? 'C' : 'A'; + ob_start(); + echo '' . htmlspecialchars($stage_name) . 'Failed' . "\n"; + ob_end_flush(); + close_install_table(); + $post_data = ''; + $mysql_error = mysql_error(); + foreach ( $_POST as $key => $value ) + { + $value = htmlspecialchars($value); + $key = htmlspecialchars($key); + $post_data .= " \n"; + } + echo '
+ ' . $post_data . ' + +

Enano installation failed.

+

' . $failure_explanation . '

+ ' . ( !empty($mysql_error) ? "

The error returned from MySQL was: $mysql_error

" : '' ) . ' +

When you have corrected the error, click the button below to attempt to continue the installation.

+

+
'; + global $template, $template_bak; + if ( is_object($template_bak) ) + $template_bak->footer(); + else + $template->footer(); + exit; +} + +// +// INSTALLER STAGES +// + +function stg_mysql_connect($act_get = false) +{ + static $conn = false; + if ( $act_get ) + return $conn; + + $db_user = mysql_real_escape_string($_POST['db_user']); + $db_pass = mysql_real_escape_string($_POST['db_pass']); + $db_name = mysql_real_escape_string($_POST['db_name']); + + if ( !preg_match('/^[a-z0-9_]+$/', $db_name) ) + die("

SECURITY: malformed database name

"); + + // First, try to connect using the normal credentials + $conn = @mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']); + if ( !$conn ) + { + // Connection failed. Do we have the root username and password? + if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) + { + $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); + if ( !$conn_root ) + { + // Couldn't connect using either set of credentials. Bail out. + return false; + } + // Create the user account + $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'localhost' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root); + if ( !$q ) + { + return false; + } + // Revoke privileges from test, we don't need them + $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'localhost';", $conn_root); + if ( !$q ) + { + return false; + } + if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' ) + { + // If not connecting to a server running on localhost, allow from any host + // this is safer than trying to detect the hostname of the webserver, but less secure + $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'%' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root); + if ( !$q ) + { + return false; + } + // Revoke privileges from test, we don't need them + $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'%';", $conn_root); + if ( !$q ) + { + return false; + } + } + } + } + $q = @mysql_query("USE $db_name;", $conn); + if ( !$q ) + { + // access denied to the database; try the whole root schenanegan again + if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) + { + $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); + if ( !$conn_root ) + { + // Couldn't connect as root; bail out + return false; + } + // create the database, if it doesn't exist + $q = @mysql_query("CREATE DATABASE IF NOT EXISTS $db_name;", $conn_root); + if ( !$q ) + { + // this really should never fail, so don't give any tolerance to it + return false; + } + // we're in with root rights; grant access to the database + $q = @mysql_query("GRANT ALL PRIVILEGES ON $db_name.* TO '{$db_user}'@'localhost';", $conn_root); + if ( !$q ) + { + return false; + } + if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' ) + { + $q = @mysql_query("GRANT ALL PRIVILEGES ON $db_name.* TO '{$db_user}'@'%';", $conn_root); + if ( !$q ) + { + return false; + } + } + } + else + { + return false; + } + // try again + $q = @mysql_query("USE $db_name;", $conn); + if ( !$q ) + { + // really failed this time; bail out + return false; + } + } + // connected and database exists + return true; +} + +function stg_drop_tables() +{ + $conn = stg_mysql_connect(true); + if ( !$conn ) + return false; + // Our list of tables included in Enano + $tables = Array( 'categories', 'comments', 'config', 'logs', 'page_text', 'session_keys', 'pages', 'users', 'users_extra', 'themes', 'buddies', 'banlist', 'files', 'privmsgs', 'sidebar', 'hits', 'search_index', 'groups', 'group_members', 'acl', 'search_cache', 'tags', 'page_groups', 'page_group_members' ); + + // Drop each table individually; if it fails, it probably means we're trying to drop a + // table that didn't exist in the Enano version we're deleting the database for. + foreach ( $tables as $table ) + { + // Remember that table_prefix is sanitized. + $table = "{$_POST['table_prefix']}$table"; + @mysql_query("DROP TABLE $table;", $conn); + } + return true; +} + +function stg_decrypt_admin_pass($act_get = false) +{ + static $decrypted_pass = false; + if ( $act_get ) + return $decrypted_pass; + + $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); + + if ( !empty($_POST['crypt_data']) ) + { + require('config.new.php'); + if ( !isset($cryptkey) ) + { + return false; + } + define('_INSTRESUME_AES_KEYBACKUP', $key); + $key = hexdecode($cryptkey); + + $decrypted_pass = $aes->decrypt($_POST['crypt_data'], $key, ENC_HEX); + + } + else + { + $decrypted_pass = $_POST['admin_pass']; + } + if ( empty($decrypted_pass) ) + return false; + return true; +} + +function stg_generate_aes_key($act_get = false) +{ + static $key = false; + if ( $act_get ) + return $key; + + $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); + $key = $aes->gen_readymade_key(); + return true; +} + +function stg_parse_schema($act_get = false) +{ + static $schema; + if ( $act_get ) + return $schema; + + $admin_pass = stg_decrypt_admin_pass(true); + $key = stg_generate_aes_key(true); + $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); + $key = $aes->hextostring($key); + $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX); + + $cacheonoff = is_writable(ENANO_ROOT.'/cache/') ? '1' : '0'; + + $schema = file_get_contents('schema.sql'); + $schema = str_replace('{{SITE_NAME}}', mysql_real_escape_string($_POST['sitename'] ), $schema); + $schema = str_replace('{{SITE_DESC}}', mysql_real_escape_string($_POST['sitedesc'] ), $schema); + $schema = str_replace('{{COPYRIGHT}}', mysql_real_escape_string($_POST['copyright'] ), $schema); + $schema = str_replace('{{ADMIN_USER}}', mysql_real_escape_string($_POST['admin_user'] ), $schema); + $schema = str_replace('{{ADMIN_PASS}}', mysql_real_escape_string($admin_pass ), $schema); + $schema = str_replace('{{ADMIN_EMAIL}}', mysql_real_escape_string($_POST['admin_email']), $schema); + $schema = str_replace('{{ENABLE_CACHE}}', mysql_real_escape_string($cacheonoff ), $schema); + $schema = str_replace('{{REAL_NAME}}', '', $schema); + $schema = str_replace('{{TABLE_PREFIX}}', $_POST['table_prefix'], $schema); + $schema = str_replace('{{VERSION}}', ENANO_VERSION, $schema); + $schema = str_replace('{{ADMIN_EMBED_PHP}}', $_POST['admin_embed_php'], $schema); + // Not anymore!! :-D + // $schema = str_replace('{{BETA_VERSION}}', ENANO_BETA_VERSION, $schema); + + if(isset($_POST['wiki_mode'])) + { + $schema = str_replace('{{WIKI_MODE}}', '1', $schema); + } + else + { + $schema = str_replace('{{WIKI_MODE}}', '0', $schema); + } + + // Build an array of queries + $schema = explode("\n", $schema); + + foreach ( $schema as $i => $sql ) + { + $query =& $schema[$i]; + $t = trim($query); + if ( empty($t) || preg_match('/^(\#|--)/i', $t) ) + { + unset($schema[$i]); + unset($query); + } + } + + $schema = array_values($schema); + $schema = implode("\n", $schema); + $schema = explode(";\n", $schema); + + foreach ( $schema as $i => $sql ) + { + $query =& $schema[$i]; + if ( substr($query, ( strlen($query) - 1 ), 1 ) != ';' ) + { + $query .= ';'; + } + } + + return true; +} + +function stg_install($_unused, $already_run) +{ + // This one's pretty easy. + $conn = stg_mysql_connect(true); + if ( !is_resource($conn) ) + return false; + $schema = stg_parse_schema(true); + if ( !is_array($schema) ) + return false; + + // If we're resuming installation, the encryption key was regenerated. + // This means we'll have to update the encrypted password in the database. + if ( $already_run ) + { + $admin_pass = stg_decrypt_admin_pass(true); + $key = stg_generate_aes_key(true); + $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); + $key = $aes->hextostring($key); + $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX); + $admin_user = mysql_real_escape_string($_POST['admin_user']); + + $q = @mysql_query("UPDATE {$_POST['table_prefix']}users SET password='$admin_pass' WHERE username='$admin_user';"); + if ( !$q ) + { + echo '

MySQL return: ' . mysql_error() . '

'; + return false; + } + + return true; + } + + // OK, do the loop, baby!!! + foreach($schema as $q) + { + $r = mysql_query($q, $conn); + if ( !$r ) + { + echo '

MySQL return: ' . mysql_error() . '

'; + return false; + } + } + + return true; +} + +function stg_write_config() +{ + $privkey = stg_generate_aes_key(true); + + switch($_POST['urlscheme']) + { + case "ugly": + default: + $cp = scriptPath.'/index.php?title='; + break; + case "short": + $cp = scriptPath.'/index.php/'; + break; + case "tiny": + $cp = scriptPath.'/'; + break; + } + + if ( $_POST['urlscheme'] == 'tiny' ) + { + $contents = '# Begin Enano rules +RewriteEngine on +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME} !-f +RewriteRule ^(.+) '.scriptPath.'/index.php?title=$1 [L,QSA] +RewriteRule \.(php|html|gif|jpg|png|css|js)$ - [L] +# End Enano rules +'; + if ( file_exists('./.htaccess') ) + $ht = fopen(ENANO_ROOT.'/.htaccess', 'a+'); + else + $ht = fopen(ENANO_ROOT.'/.htaccess.new', 'w'); + if ( !$ht ) + return false; + fwrite($ht, $contents); + fclose($ht); + } + + $config_file = ''; + + $cf_handle = fopen(ENANO_ROOT.'/config.new.php', 'w'); + if ( !$cf_handle ) + return false; + fwrite($cf_handle, $config_file); + + fclose($cf_handle); + + return true; +} + +function _stg_rename_config_revert() +{ + if ( file_exists('./config.php') ) + { + @rename('./config.php', './config.new.php'); + } + + $handle = @fopen('./config.php.new', 'w'); + if ( !$handle ) + return false; + $contents = ''; + fwrite($handle, $contents); + fclose($handle); + return true; +} + +function stg_rename_config() +{ + if ( !@rename('./config.new.php', './config.php') ) + { + echo '

Can\'t rename config.php

'; + _stg_rename_config_revert(); + return false; + } + + if ( $_POST['urlscheme'] == 'tiny' && !file_exists('./.htaccess') ) + { + if ( !@rename('./.htaccess.new', './.htaccess') ) + { + echo '

Can\'t rename .htaccess

'; + _stg_rename_config_revert(); + return false; + } + } + return true; +} + +function stg_start_api_success() +{ + return true; +} + +function stg_start_api_failure() +{ + return false; +} + +function stg_init_logs() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + + $q = $db->sql_query('INSERT INTO ' . table_prefix . 'logs(log_type,action,time_id,date_string,author,page_text,edit_summary) VALUES(\'security\', \'install_enano\', ' . time() . ', \'' . date('d M Y h:i a') . '\', \'' . mysql_real_escape_string($_POST['admin_user']) . '\', \'' . mysql_real_escape_string(ENANO_VERSION) . '\', \'' . mysql_real_escape_string($_SERVER['REMOTE_ADDR']) . '\');'); + if ( !$q ) + { + echo '

MySQL return: ' . mysql_error() . '

'; + return false; + } + + if ( !$session->get_permissions('clear_logs') ) + { + echo '

$session: denied clear_logs

'; + return false; + } + + PageUtils::flushlogs('Main_Page', 'Article'); + + return true; +} //die('Key size: ' . AES_BITS . '
Block size: ' . AES_BLOCKSIZE); @@ -390,7 +911,7 @@ run_test('return @ini_get(\'file_uploads\');', 'File upload support', 'It seems that your server does not support uploading files. Enano *requires* this functionality in order to work properly. Please ask your server administrator to set the "file_uploads" option in php.ini to "On".'); run_test('return is_apache();', 'Apache HTTP Server', 'Apparently your server is running a web server other than Apache. Enano will work nontheless, but there are some known bugs with non-Apache servers, and the "fancy" URLs will not work properly. The "Standard URLs" option will be set on the website configuration page, only change it if you are absolutely certain that your server is running Apache.', true); //run_test('return function_exists(\'finfo_file\');', 'Fileinfo PECL extension', 'The MIME magic PHP extension is used to determine the type of a file by looking for a certain "magic" string of characters inside it. This functionality is used by Enano to more effectively prevent malicious file uploads. The MIME magic option will be disabled by default.', true); - run_test('return is_writable(ENANO_ROOT.\'/config.php\');', 'Configuration file writable', 'It looks like the configuration file, config.php, is not writable. Enano needs to be able to write to this file in order to install.

If you are installing Enano on a SourceForge web site:
SourceForge mounts the web partitions read-only now, so you will need to use the project shell service to symlink config.php to a file in the /tmp/persistent directory.'); + run_test('return is_writable(ENANO_ROOT.\'/config.new.php\');', 'Configuration file writable', 'It looks like the configuration file, config.new.php, is not writable. Enano needs to be able to write to this file in order to install.

If you are installing Enano on a SourceForge web site:
SourceForge mounts the web partitions read-only now, so you will need to use the project shell service to symlink config.php to a file in the /tmp/persistent directory.'); run_test('return file_exists(\'/usr/bin/convert\');', 'ImageMagick support', 'Enano uses ImageMagick to scale images into thumbnails. Because ImageMagick was not found on your server, Enano will use the width= and height= attributes on the <img> tag to scale images. This can cause somewhat of a performance increase, but bandwidth usage will be higher, especially if you use high-resolution images on your site.

If you are sure that you have ImageMagick, you can set the location of the "convert" program using the administration panel after installation is complete.', true); run_test('return is_writable(ENANO_ROOT.\'/cache/\');', 'Cache directory writable', 'Apparently the cache/ directory is not writable. Enano will still work, but you will not be able to cache thumbnails, meaning the server will need to re-render them each time they are requested. In some cases, this can cause a significant slowdown.', true); run_test('return is_writable(ENANO_ROOT.\'/files/\');', 'File uploads directory writable', 'It seems that the directory where uploaded files are stored (' . ENANO_ROOT . '/files) cannot be written by the server. Enano will still function, but file uploads will not function, and will be disabled by default.', true); @@ -740,7 +1261,7 @@ exit; } unset($_POST['_cont']); - require('config.php'); + require('config.new.php'); $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); if ( isset($crypto_key) ) { @@ -749,7 +1270,7 @@ if(!isset($cryptkey) || ( isset($cryptkey) && strlen($cryptkey) != AES_BITS / 4) ) { $cryptkey = $aes->gen_readymade_key(); - $handle = @fopen(ENANO_ROOT.'/config.php', 'w'); + $handle = @fopen(ENANO_ROOT.'/config.new.php', 'w'); if(!$handle) { echo '

ERROR: Cannot open config.php for writing - exiting!

'; @@ -759,37 +1280,38 @@ fwrite($handle, ''); fclose($handle); } - ?> + // Sorry for the ugly hack, but this f***s up jEdit badly. + echo ' + '; + ?>
';