Sorry, this installer requires PHP!
header('Content-Type: text/html; charset=' . (isset($txt['lang_character_set']) ? $txt['lang_character_set'] : 'ISO-8859-1')); echo ' ', $txt['smf_installer'], '
'; if (function_exists('doStep' . $_GET['step'])) call_user_func('doStep' . $_GET['step']); echo '
'; function initialize_inputs() { // Turn off magic quotes runtime and enable error reporting. @set_magic_quotes_runtime(0); error_reporting(E_ALL); // Fun. Low PHP version... if (!isset($_GET)) { $GLOBALS['_GET']['step'] = 0; return; } if (!isset($_GET['obgz'])) { ob_start(); if (@ini_get('session.save_handler') == 'user') @ini_set('session.save_handler', 'files'); if (function_exists('session_start')) @session_start(); } else { ob_start('ob_gzhandler'); if (@ini_get('session.save_handler') == 'user') @ini_set('session.save_handler', 'files'); session_start(); if (!headers_sent()) echo ' ', htmlspecialchars($_GET['pass_string']), ' ', htmlspecialchars($_GET['pass_string']), ' '; exit; } // Add slashes, as long as they aren't already being added. if (@get_magic_quotes_gpc() == 0) { foreach ($_POST as $k => $v) $_POST[$k] = addslashes($v); } // This is really quite simple; if ?delete is on the URL, delete the installer... if (isset($_GET['delete'])) { if (isset($_SESSION['installer_temp_ftp'])) { $ftp = new ftp_connection($_SESSION['installer_temp_ftp']['server'], $_SESSION['installer_temp_ftp']['port'], $_SESSION['installer_temp_ftp']['username'], $_SESSION['installer_temp_ftp']['password']); $ftp->chdir($_SESSION['installer_temp_ftp']['path']); $ftp->unlink('install.php'); $ftp->unlink('webinstall.php'); $ftp->unlink('install_1-1.sql'); $ftp->close(); unset($_SESSION['installer_temp_ftp']); } else { @unlink(__FILE__); @unlink(dirname(__FILE__) . '/webinstall.php'); @unlink(dirname(__FILE__) . '/install_1-1.sql'); } // Now just redirect to a blank.gif... header('Location: http://' . (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT']) . dirname($_SERVER['PHP_SELF']) . '/Themes/default/images/blank.gif'); exit; } // Force an integer step, defaulting to 0. $_GET['step'] = (int) @$_GET['step']; } // Load the list of language files, and the current language file. function load_lang_file() { global $txt; $GLOBALS['detected_languages'] = array(); // Make sure the languages directory actually exists. if (file_exists(dirname(__FILE__) . '/Themes/default/languages')) { // Find all the "Install" language files in the directory. $dir = dir(dirname(__FILE__) . '/Themes/default/languages'); while ($entry = $dir->read()) { if (substr($entry, 0, 8) == 'Install.' && substr($entry, -4) == '.php') $GLOBALS['detected_languages'][$entry] = ucfirst(substr($entry, 8, strlen($entry) - 12)); } $dir->close(); } // Didn't find any, show an error message! if (empty($GLOBALS['detected_languages'])) { // Let's not cache this message, eh? header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); header('Cache-Control: no-cache'); echo ' SMF Installer: Error!

A critical error has occurred.

This installer was unable to find the installer\'s language file or files. They should be found under:

', dirname($_SERVER['PHP_SELF']) != '/' ? dirname($_SERVER['PHP_SELF']) : '', '/Themes/default/languages

In some cases, FTP clients do not properly upload files with this many folders. Please double check to make sure you have uploaded all the files in the distribution.

If that doesn\'t help, please make sure this install.php file is in the same place as the Themes folder.

If you continue to get this error message, feel free to look to us for support.

'; die; } // Override the language file? if (isset($_GET['lang_file'])) $_SESSION['installer_temp_lang'] = $_GET['lang_file']; elseif (isset($GLOBALS['HTTP_GET_VARS']['lang_file'])) $_SESSION['installer_temp_lang'] = $GLOBALS['HTTP_GET_VARS']['lang_file']; // Make sure it exists, if it doesn't reset it. if (!isset($_SESSION['installer_temp_lang']) || !file_exists(dirname(__FILE__) . '/Themes/default/languages/' . $_SESSION['installer_temp_lang'])) { // Use the first one... list ($_SESSION['installer_temp_lang']) = array_keys($GLOBALS['detected_languages']); // If we have english and some other language, use the other language. We Americans hate english :P. if ($_SESSION['installer_temp_lang'] == 'Install.english.php' && count($GLOBALS['detected_languages']) > 1) list (, $_SESSION['installer_temp_lang']) = array_keys($GLOBALS['detected_languages']); } // And now include the actual language file itself. require_once(dirname(__FILE__) . '/Themes/default/languages/' . $_SESSION['installer_temp_lang']); } // Step zero: Finding out how and where to install. function doStep0() { global $txt; // Just so people using older versions of PHP aren't left in the cold. if (!isset($_SERVER['PHP_SELF'])) $_SERVER['PHP_SELF'] = isset($GLOBALS['HTTP_SERVER_VARS']['PHP_SELF']) ? $GLOBALS['HTTP_SERVER_VARS']['PHP_SELF'] : 'install.php'; // Show a language selection... if (count($GLOBALS['detected_languages']) > 1) { echo '
'; } // Check the PHP version. if ((!function_exists('version_compare') || version_compare($GLOBALS['required_php_version'], PHP_VERSION) > 0) && !isset($_GET['overphp'])) { echo '
', $txt['error_php_too_low'], '

', $txt['error_message_click'], ' ', $txt['error_message_bad_try_again'], '
'; return false; } // Is MySQL even compiled in? if (!function_exists('mysql_connect')) $error = 'error_mysql_missing'; // How about session support? Some crazy sysadmin remove it? elseif (!function_exists('session_start')) $error = 'error_session_missing'; // Make sure they uploaded all the files. elseif (!file_exists(dirname(__FILE__) . '/index.php') || !file_exists(dirname(__FILE__) . '/install_1-1.sql')) $error = 'error_missing_files'; // Very simple check on the session.save_path for Windows. // !!! Move this down later if they don't use database-driven sessions? elseif (session_save_path() == '/tmp' && substr(__FILE__, 1, 2) == ':\\') $error = 'error_session_save_path'; // Since each of the three messages would look the same, anyway... if (isset($error)) { echo '
', $txt[$error], '

', $txt['error_message_click'], ' ', $txt['error_message_try_again'], '
'; return false; } // Make sure all the files are properly writable (has its own messages...) if (!make_files_writable()) return false; // Mod_security blocks everything that smells funny. Let SMF handle security. if (!fixModSecurity() && !isset($_GET['overmodsecurity'])) { echo '
', $txt['error_mod_security'], '

', $txt['error_message_click'], ' ', $txt['error_message_bad_try_again'], '
'; return false; } // Set up the defaults. $db_server = @ini_get('mysql.default_host') or $db_server = 'localhost'; $db_user = isset($_POST['ftp_username']) ? $_POST['ftp_username'] : @ini_get('mysql.default_user'); $db_name = isset($_POST['ftp_username']) ? $_POST['ftp_username'] : @ini_get('mysql.default_user'); $db_passwd = @ini_get('mysql.default_password'); // This is just because it makes it easier for people on Lycos/Tripod UK :P. if (isset($_SERVER['SERVER_NAME']) && $_SERVER['SERVER_NAME'] == 'members.lycos.co.uk' && defined('LOGIN')) { $db_user = LOGIN; $db_name = LOGIN . '_uk_db'; } // Should we use a non standard port? $db_port = @ini_get('mysql.default_port'); if (!empty($db_port)) $db_server .= ':' . $db_port; // What host and port are we on? $host = empty($_SERVER['HTTP_HOST']) ? $_SERVER['SERVER_NAME'] . (empty($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == '80' ? '' : ':' . $_SERVER['SERVER_PORT']) : $_SERVER['HTTP_HOST']; // Now, to put what we've learned together... and add a path. $url = 'http://' . $host . substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/')); // Check if the database sessions will even work. $test_dbsession = @ini_get('session.auto_start') != 1 && @version_compare(PHP_VERSION, '4.2.0') != -1; echo '

', $txt['install_settings'], '

', $txt['install_settings_info'], '

'; if (strpos(strtolower(PHP_OS), 'win') === false || @version_compare(PHP_VERSION, '4.2.3') != -1) echo ' '; echo '
', $txt['install_settings_name_info'], '

', $txt['install_settings_url_info'], '
', $txt['install_settings_compress'], ':
', $txt['install_settings_compress_info'], '
', $txt['install_settings_dbsession'], ':
', $test_dbsession ? $txt['install_settings_dbsession_info1'] : $txt['install_settings_dbsession_info2'], '
', $txt['install_settings_utf8'], ':
', $txt['install_settings_utf8_info'], '
', $txt['install_settings_stats'], ':
', $txt['install_settings_stats_info'], '

', $txt['mysql_settings'], '

', $txt['mysql_settings_info'], '


', $txt['mysql_settings_server_info'], '

', $txt['mysql_settings_username_info'], '

', $txt['mysql_settings_password_info'], '

', $txt['mysql_settings_database_info'], '

', $txt['mysql_settings_prefix_info'], '
'; return true; } // Step one: Do the SQL thang. function doStep1() { global $txt, $db_connection; if (substr($_POST['boardurl'], -10) == '/index.php') $_POST['boardurl'] = substr($_POST['boardurl'], 0, -10); elseif (substr($_POST['boardurl'], -1) == '/') $_POST['boardurl'] = substr($_POST['boardurl'], 0, -1); if (substr($_POST['boardurl'], 0, 7) != 'http://' && substr($_POST['boardurl'], 0, 7) != 'file://' && substr($_POST['boardurl'], 0, 8) != 'https://') $_POST['boardurl'] = 'http://' . $_POST['boardurl']; // Take care of these variables... $vars = array( 'boardurl' => $_POST['boardurl'], 'boarddir' => addslashes(dirname(__FILE__)), 'sourcedir' => addslashes(dirname(__FILE__)) . '/Sources', 'db_name' => $_POST['db_name'], 'db_user' => $_POST['db_user'], 'db_passwd' => isset($_POST['db_passwd']) ? $_POST['db_passwd'] : '', 'db_server' => $_POST['db_server'], 'db_prefix' => preg_replace('~[^A-Za-z0-9_$]~', '', $_POST['db_prefix']), 'mbname' => $_POST['mbname'], 'language' => substr($_SESSION['installer_temp_lang'], 8, -4), // The cookiename is special; we want it to be the same if it ever needs to be reinstalled with the same info. 'cookiename' => 'SMFCookie' . abs(crc32($_POST['db_name'] . preg_replace('~[^A-Za-z0-9_$]~', '', $_POST['db_prefix'])) % 1000), ); // !!! if (is_numeric(substr($vars['db_prefix'], 0, 1))) if (!updateSettingsFile($vars) && substr(__FILE__, 1, 2) == ':\\') { echo '
', $txt['error_windows_chmod'], '

', $txt['error_message_click'], ' ', $txt['error_message_try_again'], '
'; return false; } // Make sure it works. require(dirname(__FILE__) . '/Settings.php'); // Attempt a connection. $db_connection = @mysql_connect($db_server, $db_user, $db_passwd); // No dice? Let's try adding the prefix they specified, just in case they misread the instructions ;). if (!$db_connection) { $mysql_error = mysql_error(); $db_connection = @mysql_connect($db_server, $_POST['db_prefix'] . $db_user, $db_passwd); if ($db_connection != false) { $db_user = $_POST['db_prefix'] . $db_user; updateSettingsFile(array('db_user' => $db_user)); } } // Still no connection? Big fat error message :P. if (!$db_connection) { echo '
', $txt['error_mysql_connect'], '
', $mysql_error, '
', $txt['error_message_click'], ' ', $txt['error_message_try_again'], '
'; return false; } // Do they meet the install requirements? // !!! Old client, new server? if (version_compare($GLOBALS['required_mysql_version'], preg_replace('~\-.+?$~', '', min(mysql_get_server_info(), mysql_get_client_info()))) > 0) { echo '
', $txt['error_mysql_too_low'], '

', $txt['error_message_click'], ' ', $txt['error_message_try_again'], '
'; return false; } // Let's try that database on for size... if ($db_name != '') mysql_query(" CREATE DATABASE IF NOT EXISTS `$db_name`", $db_connection); // Okay, let's try the prefix if it didn't work... if (!mysql_select_db($db_name, $db_connection) && $db_name != '') { mysql_query(" CREATE DATABASE IF NOT EXISTS `$_POST[db_prefix]$db_name`", $db_connection); if (mysql_select_db($_POST['db_prefix'] . $db_name, $db_connection)) { $db_name = $_POST['db_prefix'] . $db_name; updateSettingsFile(array('db_name' => $db_name)); } } // Okay, now let's try to connect... if (!mysql_select_db($db_name, $db_connection)) { echo '
', sprintf($txt['error_mysql_database'], $db_name), '

', $txt['error_message_click'], ' ', $txt['error_message_try_again'], '
'; return false; } // Before running any of the queries, let's make sure another version isn't already installed. $result = mysql_query(" SELECT value FROM {$db_prefix}settings WHERE variable = 'smfVersion' LIMIT 1"); if ($result !== false) { list ($database_version) = mysql_fetch_row($result); mysql_free_result($result); // Do they match? If so, this is just a refresh so charge on! if ($database_version != $GLOBALS['current_smf_version']) { echo '
', $txt['error_versions_do_not_match'], '

', $txt['error_message_click'], ' ', $txt['error_message_try_again'], '
'; return false; } } // UTF-8 requires a setting to override the language charset. if (isset($_POST['utf8'])) { if (version_compare('4.1.0', preg_replace('~\-.+?$~', '', mysql_get_server_info())) > 0) { echo '
', $txt['error_utf8_mysql_version'], '

', $txt['error_message_click'], ' ', $txt['error_message_try_again'], '
'; return false; } else { updateSettingsFile(array('db_character_set' => 'utf8')); mysql_query(" SET NAMES utf8"); } } $replaces = array( '{$db_prefix}' => $db_prefix, '{$boarddir}' => addslashes(dirname(__FILE__)), '{$boardurl}' => $_POST['boardurl'], '{$enableCompressedOutput}' => isset($_POST['compress']) ? '1' : '0', '{$databaseSession_enable}' => isset($_POST['dbsession']) ? '1' : '0', '{$smf_version}' => $GLOBALS['current_smf_version'], ); foreach ($txt as $key => $value) { if (substr($key, 0, 8) == 'default_') $replaces['{$' . $key . '}'] = addslashes($value); } $replaces['{$default_reserved_names}'] = strtr($replaces['{$default_reserved_names}'], array('\\\\n' => '\\n')); // If the UTF-8 setting was enabled, add it to the table definitions. if (isset($_POST['utf8'])) $replaces[') TYPE=MyISAM;'] = ') TYPE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;'; // Read in the SQL. Turn this on and that off... internationalize... etc. $sql_lines = explode("\n", strtr(implode(' ', file(dirname(__FILE__) . '/install_1-1.sql')), $replaces)); // Execute the SQL. $current_statement = ''; $failures = array(); $exists = array(); foreach ($sql_lines as $count => $line) { // No comments allowed! if (substr(trim($line), 0, 1) != '#') $current_statement .= "\n" . rtrim($line); // Is this the end of the query string? if (empty($current_statement) || (preg_match('~;[\s]*$~s', $line) == 0 && $count != count($sql_lines))) continue; // Does this table already exist? If so, don't insert more data into it! if (preg_match('~^\s*INSERT INTO ([^\s\n\r]+?)~', $current_statement, $match) != 0 && in_array($match[1], $exists)) { $current_statement = ''; continue; } if (mysql_query($current_statement) === false) { // Error 1050: Table already exists! if (mysql_errno($db_connection) === 1050 && preg_match('~^\s*CREATE TABLE ([^\s\n\r]+?)~', $current_statement, $match) == 1) $exists[] = $match[1]; else $failures[$count] = mysql_error(); } $current_statement = ''; } // Make sure UTF will be used globally. if (isset($_POST['utf8'])) mysql_query(" INSERT INTO {$db_prefix}settings (variable, value) VALUES ('global_character_set', 'UTF-8')"); // Maybe we can auto-detect better cookie settings? preg_match('~^http[s]?://([^\.]+?)([^/]*?)(/.*)?$~', $_POST['boardurl'], $matches); if (!empty($matches)) { // Default = both off. $localCookies = false; $globalCookies = false; // Okay... let's see. Using a subdomain other than www.? (not a perfect check.) if ($matches[2] != '' && (strpos(substr($matches[2], 1), '.') === false || in_array($matches[1], array('forum', 'board', 'community', 'forums', 'support', 'chat', 'help', 'talk', 'boards', 'www')))) $globalCookies = true; // If there's a / in the middle of the path, or it starts with ~... we want local. if (isset($matches[3]) && strlen($matches[3]) > 3 && (substr($matches[3], 0, 2) == '/~' || strpos(substr($matches[3], 1), '/') !== false)) $localCookies = true; $rows = array(); if ($globalCookies) $rows[] = "('globalCookies', '1')"; if ($localCookies) $rows[] = "('localCookies', '1')"; if (!empty($rows)) mysql_query(" INSERT INTO {$db_prefix}settings (variable, value) VALUES " . implode(', ', $rows)); } // Are we allowing stat collection? if (isset($_POST['stats']) && substr($_POST['boardurl'], 0, 16) != 'http://localhost') { // Attempt to register the site etc. $fp = @fsockopen("www.simplemachines.org", 80, $errno, $errstr); if ($fp) { $out = "GET /smf/stats/register_stats.php?site=" . base64_encode($_POST['boardurl']) . " HTTP/1.1\r\n"; $out .= "Host: www.simplemachines.org\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); $return_data = ''; while (!feof($fp)) $return_data .= fgets($fp, 128); fclose($fp); // Get the unique site ID. preg_match('~SITE-ID:\s(\w{10})~', $return_data, $ID); if (!empty($ID[1])) mysql_query(" INSERT INTO {$db_prefix}settings (variable, value) VALUES ('allow_sm_stats', '$ID[1]')"); } } // As of PHP 5.1, setting a timezone is required. if (!isset($modSettings['default_timezone']) && function_exists('date_default_timezone_set')) { $server_offset = mktime(0, 0, 0, 1, 1, 1970); $timezone_id = 'Etc/GMT' . ($server_offset > 0 ? '+' : '') . ($server_offset / 3600); if (date_default_timezone_set($timezone_id)) mysql_query(" REPLACE INTO {$db_prefix}settings (variable, value) VALUES ('default_timezone', '$timezone_id')"); } // Let's optimize those new tables. $tables = mysql_list_tables($db_name); $table_names = array(); while ($table = mysql_fetch_row($tables)) $table_names[] = $table[0]; mysql_free_result($tables); mysql_query(' OPTIMIZE TABLE `' . implode('`, `', $table_names) . '`') or $db_messed = true; if (!empty($db_messed)) $failures[-1] = mysql_error($db_connection); if (!empty($failures)) { echo '
', $txt['error_mysql_queries'], '
'; foreach ($failures as $line => $fail) echo ' ', $txt['error_mysql_queries_line'], $line + 1, ': ', nl2br(htmlspecialchars($fail)), '
'; echo '
', $txt['error_message_click'], ' ', $txt['error_message_try_again'], '
'; return false; } // Check for the ALTER privilege. if (mysql_query("ALTER TABLE {$db_prefix}boards ORDER BY ID_BOARD") === false) { echo '
', $txt['error_mysql_alter_priv'], '

', $txt['error_message_click'], ' ', $txt['error_message_try_again'], '
'; return false; } if (!empty($exists)) echo '

', $txt['user_refresh_install'], '

', $txt['user_refresh_install_desc'], '
'; return doStep2a(); } // Step two-A: Ask for the administrator login information. function doStep2a() { global $txt; if (!isset($_POST['username'])) $_POST['username'] = ''; if (!isset($_POST['email'])) $_POST['email'] = ''; echo '

', $txt['user_settings'], '

', $txt['user_settings_info'], '

', $txt['user_settings_username_info'], '
', $txt['user_settings_password_info'], '
', $txt['user_settings_again_info'], '
', $txt['user_settings_email_info'], '

', $txt['user_settings_database'], '

', $txt['user_settings_database_info'], '

'; return true; } // Step two: Create the administrator, and finish. function doStep2() { global $txt, $db_prefix, $db_connection, $HTTP_SESSION_VARS, $cookiename; global $func, $db_character_set, $mbname, $context, $scripturl, $boardurl; global $current_smf_version; // Load the SQL server login information. require_once(dirname(__FILE__) . '/Settings.php'); if (!isset($_POST['password3'])) return doStep2a(); $db_connection = @mysql_connect($db_server, $db_user, $_POST['password3']); if (!$db_connection) { echo '
', $txt['error_mysql_connect'], '
'; return doStep2a(); } if (!mysql_select_db($db_name, $db_connection)) { echo '
', sprintf($txt['error_mysql_database'], $db_name), '

'; return doStep2a(); } // Let them try again... if ($_POST['password1'] != $_POST['password2']) { echo '
', $txt['error_user_settings_again_match'], '

'; return doStep2a(); } if (!file_exists($sourcedir . '/Subs.php')) { echo '
', $txt['error_subs_missing'], '

'; return doStep2a(); } updateSettingsFile(array('webmaster_email' => $_POST['email'])); chdir(dirname(__FILE__)); define('SMF', 1); require_once($sourcedir . '/Subs.php'); require_once($sourcedir . '/Load.php'); require_once($sourcedir . '/Security.php'); require_once($sourcedir . '/Subs-Auth.php'); // Define the sha1 function, if it doesn't exist. if (!function_exists('sha1')) require_once($sourcedir . '/Subs-Compat.php'); if (isset($db_character_set)) mysql_query(" SET NAMES $db_character_set"); $result = mysql_query(" SELECT ID_MEMBER, passwordSalt FROM {$db_prefix}members WHERE memberName = '$_POST[username]' OR emailAddress = '$_POST[email]' LIMIT 1"); if (mysql_num_rows($result) != 0) { list ($id, $salt) = mysql_fetch_row($result); mysql_free_result($result); echo '
', $txt['error_user_settings_taken'], '

'; } elseif (preg_match('~[<>&"\'=\\\]~', $_POST['username']) != 0 || strlen($_POST['username']) > 25 || $_POST['username'] == '_' || $_POST['username'] == '|' || strpos($_POST['username'], '[code') !== false || strpos($_POST['username'], '[/code') !== false) { // Initialize some variables needed for the language file. $context = array( 'forum_name' => $mbname, ); $modSettings = array( 'lastActive' => '15', 'hotTopicPosts' => '15', 'hotTopicVeryPosts' => '25', 'smfVersion' => $current_smf_version, ); $scripturl = $boardurl . '/index.php'; require_once(dirname(__FILE__) . '/Themes/default/languages/' . strtr($_SESSION['installer_temp_lang'], array('Install' => 'index'))); echo '
', $txt[240], '

'; // Try the previous step again. return doStep2a(); } elseif (empty($_POST['email']) || preg_match('~^[0-9A-Za-z=_+\-/][0-9A-Za-z=_\'+\-/\.]*@[\w\-]+(\.[\w\-]+)*(\.[\w]{2,6})$~', stripslashes($_POST['email'])) === 0 || strlen(stripslashes($_POST['email'])) > 255) { // Artificially fill some of the globals needed for the language files. $context = array( 'forum_name' => $mbname, ); $modSettings = array( 'lastActive' => '15', 'hotTopicPosts' => '15', 'hotTopicVeryPosts' => '25', 'smfVersion' => $current_smf_version, ); $scripturl = $boardurl . '/index.php'; require_once(dirname(__FILE__) . '/Themes/default/languages/' . strtr($_SESSION['installer_temp_lang'], array('Install' => 'index'))); require_once(dirname(__FILE__) . '/Themes/default/languages/' . strtr($_SESSION['installer_temp_lang'], array('Install' => 'Login'))); echo '
', sprintf($txt[500], $_POST['username']), '

'; // One step back, this time fill out a proper email address. return doStep2a(); } elseif ($_POST['username'] != '') { $salt = substr(md5(mt_rand()), 0, 4); // Format the username properly. $_POST['username'] = preg_replace('~[\t\n\r\x0B\0\xA0]+~', ' ', $_POST['username']); $ip = isset($_SERVER['REMOTE_ADDR']) ? addslashes(substr(stripslashes($_SERVER['REMOTE_ADDR']), 0, 255)) : ''; $request = mysql_query(" INSERT INTO {$db_prefix}members (memberName, realName, passwd, emailAddress, ID_GROUP, posts, dateRegistered, hideEmail, passwordSalt, lngfile, personalText, avatar, memberIP, memberIP2, buddy_list, pm_ignore_list, messageLabels, websiteTitle, websiteUrl, location, ICQ, MSN, signature, usertitle, secretQuestion, additionalGroups) VALUES (SUBSTRING('$_POST[username]', 1, 25), SUBSTRING('$_POST[username]', 1, 25), '" . sha1(strtolower($_POST['username']) . $_POST['password1']) . "', '$_POST[email]', 1, '0', '" . time() . "', '0', '$salt', '', '', '', '$ip', '$ip', '', '', '', '', '', '', '', '', '', '', '', '')"); // Awww, crud! if ($request === false) { echo '
', $txt['error_user_settings_query'], '
', nl2br(htmlspecialchars(mysql_error($db_connection))), '
', $txt['error_message_click'], ' ', $txt['error_message_try_again'], '
'; return false; } $id = mysql_insert_id(); } // Automatically log them in ;). if (isset($id) && isset($salt)) setLoginCookie(3153600 * 60, $id, sha1(sha1(strtolower($_POST['username']) . $_POST['password1']) . $salt)); $result = mysql_query(" SELECT value FROM {$db_prefix}settings WHERE variable = 'databaseSession_enable'"); if (mysql_num_rows($result) != 0) list ($db_sessions) = mysql_fetch_row($result); mysql_free_result($result); if (empty($db_sessions)) { if (@version_compare(PHP_VERSION, '4.2.0') == -1) $HTTP_SESSION_VARS['php_412_bugfix'] = true; $_SESSION['admin_time'] = time(); } else { $_SERVER['HTTP_USER_AGENT'] = addslashes(substr($_SERVER['HTTP_USER_AGENT'], 0, 211)); mysql_query(" INSERT INTO {$db_prefix}sessions (session_id, last_update, data) VALUES ('" . session_id() . "', " . time() . ", 'USER_AGENT|s:" . strlen(stripslashes($_SERVER['HTTP_USER_AGENT'])) . ":\"$_SERVER[HTTP_USER_AGENT]\";admin_time|i:" . time() . ";')"); } updateStats('member'); updateStats('message'); updateStats('topic'); // This function is needed to do the updateStats('subject') call. $func['strtolower'] = $db_character_set === 'utf8' || $txt['lang_character_set'] === 'UTF-8' ? create_function('$string', ' return $string;') : 'strtolower'; $request = mysql_query(" SELECT ID_MSG FROM {$db_prefix}messages WHERE ID_MSG = 1 AND modifiedTime = 0 LIMIT 1"); if (mysql_num_rows($request) > 0) updateStats('subject', 1, addslashes(htmlspecialchars($txt['default_topic_subject']))); mysql_free_result($request); echo '

', $txt['congratulations'], '


', $txt['congratulations_help'], '

'; if (is_writable(dirname(__FILE__)) && substr(__FILE__, 1, 2) != ':\\') echo ' ', $txt['still_writable'], '

'; // Don't show the box if it's like 99% sure it won't work :P. if (isset($_SESSION['installer_temp_ftp']) || is_writable(dirname(__FILE__)) || is_writable(__FILE__)) echo '

'; echo ' ', sprintf($txt['go_to_your_forum'], $boardurl . '/index.php'), '

', $txt['good_luck'], '
'; return true; } // http://www.faqs.org/rfcs/rfc959.html class ftp_connection { var $connection = 'no_connection', $error = false, $last_message, $pasv = array(); // Create a new FTP connection... function ftp_connection($ftp_server, $ftp_port = 21, $ftp_user = 'anonymous', $ftp_pass = 'ftpclient@simplemachines.org') { if ($ftp_server !== null) $this->connect($ftp_server, $ftp_port, $ftp_user, $ftp_pass); } function connect($ftp_server, $ftp_port = 21, $ftp_user = 'anonymous', $ftp_pass = 'ftpclient@simplemachines.org') { if (substr($ftp_server, 0, 6) == 'ftp://') $ftp_server = substr($ftp_server, 6); elseif (substr($ftp_server, 0, 7) == 'ftps://') $ftp_server = 'ssl://' . substr($ftp_server, 7); if (substr($ftp_server, 0, 7) == 'http://') $ftp_server = substr($ftp_server, 7); $ftp_server = strtr($ftp_server, array('/' => '', ':' => '', '@' => '')); // Connect to the FTP server. $this->connection = @fsockopen($ftp_server, $ftp_port, $err, $err, 5); if (!$this->connection) { $this->error = 'bad_server'; return; } // Get the welcome message... if (!$this->check_response(220)) { $this->error = 'bad_response'; return; } // Send the username, it should ask for a password. fwrite($this->connection, 'USER ' . $ftp_user . "\r\n"); if (!$this->check_response(331)) { $this->error = 'bad_username'; return; } // Now send the password... and hope it goes okay. fwrite($this->connection, 'PASS ' . $ftp_pass . "\r\n"); if (!$this->check_response(230)) { $this->error = 'bad_password'; return; } } function chdir($ftp_path) { if (!is_resource($this->connection)) return false; // No slash on the end, please... if (substr($ftp_path, -1) == '/') $ftp_path = substr($ftp_path, 0, -1); fwrite($this->connection, 'CWD ' . $ftp_path . "\r\n"); if (!$this->check_response(250)) { $this->error = 'bad_path'; return false; } return true; } function chmod($ftp_file, $chmod) { if (!is_resource($this->connection)) return false; // Convert the chmod value from octal (0777) to text ("777"). fwrite($this->connection, 'SITE CHMOD ' . decoct($chmod) . ' ' . $ftp_file . "\r\n"); if (!$this->check_response(200)) { $this->error = 'bad_file'; return false; } return true; } function unlink($ftp_file) { // We are actually connected, right? if (!is_resource($this->connection)) return false; // Delete file X. fwrite($this->connection, 'DELE ' . $ftp_file . "\r\n"); if (!$this->check_response(250)) { fwrite($this->connection, 'RMD ' . $ftp_file . "\r\n"); // Still no love? if (!$this->check_response(250)) { $this->error = 'bad_file'; return false; } } return true; } function check_response($desired) { // Wait for a response that isn't continued with -, but don't wait too long. $time = time(); do $this->last_message = fgets($this->connection, 1024); while (substr($this->last_message, 3, 1) != ' ' && time() - $time < 5); // Was the desired response returned? return is_array($desired) ? in_array(substr($this->last_message, 0, 3), $desired) : substr($this->last_message, 0, 3) == $desired; } function passive() { // We can't create a passive data connection without a primary one first being there. if (!is_resource($this->connection)) return false; // Request a passive connection - this means, we'll talk to you, you don't talk to us. @fwrite($this->connection, "PASV\r\n"); $time = time(); do $response = fgets($this->connection, 1024); while (substr($response, 3, 1) != ' ' && time() - $time < 5); // If it's not 227, we weren't given an IP and port, which means it failed. if (substr($response, 0, 4) != '227 ') { $this->error = 'bad_response'; return false; } // Snatch the IP and port information, or die horribly trying... if (preg_match('~\((\d+),\s*(\d+),\s*(\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))\)~', $response, $match) == 0) { $this->error = 'bad_response'; return false; } // This is pretty simple - store it for later use ;). $this->pasv = array('ip' => $match[1] . '.' . $match[2] . '.' . $match[3] . '.' . $match[4], 'port' => $match[5] * 256 + $match[6]); return true; } function create_file($ftp_file) { // First, we have to be connected... very important. if (!is_resource($this->connection)) return false; // I'd like one passive mode, please! if (!$this->passive()) return false; // Seems logical enough, so far... fwrite($this->connection, 'STOR ' . $ftp_file . "\r\n"); // Okay, now we connect to the data port. If it doesn't work out, it's probably "file already exists", etc. $fp = @fsockopen($this->pasv['ip'], $this->pasv['port'], $err, $err, 5); if (!$fp || !$this->check_response(150)) { $this->error = 'bad_file'; @fclose($fp); return false; } // This may look strange, but we're just closing it to indicate a zero-byte upload. fclose($fp); if (!$this->check_response(226)) { $this->error = 'bad_response'; return false; } return true; } function list_dir($ftp_path = '', $search = false) { // Are we even connected...? if (!is_resource($this->connection)) return false; // Passive... non-agressive... if (!$this->passive()) return false; // Get the listing! fwrite($this->connection, 'LIST -1' . ($search ? 'R' : '') . ($ftp_path == '' ? '' : ' ' . $ftp_path) . "\r\n"); // Connect, assuming we've got a connection. $fp = @fsockopen($this->pasv['ip'], $this->pasv['port'], $err, $err, 5); if (!$fp || !$this->check_response(array(150, 125))) { $this->error = 'bad_response'; @fclose($fp); return false; } // Read in the file listing. $data = ''; while (!feof($fp)) $data .= fread($fp, 4096);; fclose($fp); // Everything go okay? if (!$this->check_response(226)) { $this->error = 'bad_response'; return false; } return $data; } function locate($file, $listing = null) { if ($listing === null) $listing = $this->list_dir('', true); $listing = explode("\n", $listing); @fwrite($this->connection, "PWD\r\n"); $time = time(); do $response = fgets($this->connection, 1024); while (substr($response, 3, 1) != ' ' && time() - $time < 5); // Check for 257! if (preg_match('~^257 "(.+?)" ~', $response, $match) != 0) $current_dir = strtr($match[1], array('""' => '"')); else $current_dir = ''; for ($i = 0, $n = count($listing); $i < $n; $i++) { if (trim($listing[$i]) == '' && isset($listing[$i + 1])) { $current_dir = substr(trim($listing[++$i]), 0, -1); $i++; } // Okay, this file's name is: $listing[$i] = $current_dir . '/' . trim(strlen($listing[$i]) > 30 ? strrchr($listing[$i], ' ') : $listing[$i]); if (substr($file, 0, 1) == '*' && substr($listing[$i], -(strlen($file) - 1)) == substr($file, 1)) return $listing[$i]; if (substr($file, -1) == '*' && substr($listing[$i], 0, strlen($file) - 1) == substr($file, 0, -1)) return $listing[$i]; if (basename($listing[$i]) == $file || $listing[$i] == $file) return $listing[$i]; } return false; } function create_dir($ftp_dir) { // We must be connected to the server to do something. if (!is_resource($this->connection)) return false; // Make this new beautiful directory! fwrite($this->connection, 'MKD ' . $ftp_dir . "\r\n"); if (!$this->check_response(257)) { $this->error = 'bad_file'; return false; } return true; } function detect_path($filesystem_path, $lookup_file = null) { $username = ''; if (isset($_SERVER['DOCUMENT_ROOT'])) { if (preg_match('~^/home[2]?/([^/]+?)/public_html~', $_SERVER['DOCUMENT_ROOT'], $match)) { $username = $match[1]; $path = strtr($_SERVER['DOCUMENT_ROOT'], array('/home/' . $match[1] . '/' => '', '/home2/' . $match[1] . '/' => '')); if (substr($path, -1) == '/') $path = substr($path, 0, -1); if (strlen(dirname($_SERVER['PHP_SELF'])) > 1) $path .= dirname($_SERVER['PHP_SELF']); } elseif (substr($filesystem_path, 0, 9) == '/var/www/') $path = substr($filesystem_path, 8); else $path = strtr(strtr($filesystem_path, array('\\' => '/')), array($_SERVER['DOCUMENT_ROOT'] => '')); } else $path = ''; if (is_resource($this->connection) && $this->list_dir($path) == '') { $data = $this->list_dir('', true); if ($lookup_file === null) $lookup_file = $_SERVER['PHP_SELF']; $found_path = dirname($this->locate('*' . basename(dirname($lookup_file)) . '/' . basename($lookup_file), $data)); if ($found_path == false) $found_path = dirname($this->locate(basename($lookup_file))); if ($found_path != false) $path = $found_path; } elseif (is_resource($this->connection)) $found_path = true; return array($username, $path, isset($found_path)); } function close() { // Goodbye! fwrite($this->connection, "QUIT\r\n"); fclose($this->connection); return true; } } function make_files_writable() { global $txt; $writable_files = array( 'attachments', 'avatars', 'Packages', 'Packages/installed.list', 'Smileys', 'Themes', 'agreement.txt', 'Settings.php', 'Settings_bak.php' ); $extra_files = array( 'Themes/classic/index.template.php', 'Themes/classic/style.css' ); foreach ($GLOBALS['detected_languages'] as $lang => $temp) $extra_files[] = 'Themes/default/languages/' . $lang; $failure = false; // With mod_security installed, we could attempt to fix it with .htaccess. if (function_exists('apache_get_modules') && in_array('mod_security', apache_get_modules())) $writable_files[] = file_exists(dirname(__FILE__) . '/.htaccess') ? '.htaccess' : '.'; // On linux, it's easy - just use is_writable! if (substr(__FILE__, 1, 2) != ':\\') { foreach ($writable_files as $file) { if (!is_writable(dirname(__FILE__) . '/' . $file)) { @chmod(dirname(__FILE__) . '/' . $file, 0755); // Well, 755 hopefully worked... if not, try 777. $failure |= !is_writable(dirname(__FILE__) . '/' . $file) && !@chmod(dirname(__FILE__) . '/' . $file, 0777); } } foreach ($extra_files as $file) @chmod(dirname(__FILE__) . (empty($file) ? '' : '/' . $file), 0777); } // Windows is trickier. Let's try opening for r+... else { foreach ($writable_files as $file) { // Folders can't be opened for write... but the index.php in them can ;). if (is_dir(dirname(__FILE__) . '/' . $file)) $file .= '/index.php'; // Funny enough, chmod actually does do something on windows - it removes the read only attribute. @chmod(dirname(__FILE__) . '/' . $file, 0777); $fp = @fopen(dirname(__FILE__) . '/' . $file, 'r+'); // Hmm, okay, try just for write in that case... if (!$fp) $fp = @fopen(dirname(__FILE__) . '/' . $file, 'w'); $failure |= !$fp; @fclose($fp); } foreach ($extra_files as $file) @chmod(dirname(__FILE__) . (empty($file) ? '' : '/' . $file), 0777); } if (!isset($_SERVER)) return !$failure; // It's not going to be possible to use FTP on windows to solve the problem... if ($failure && substr(__FILE__, 1, 2) == ':\\') { echo '
', $txt['error_windows_chmod'], '
', $txt['error_message_click'], ' ', $txt['error_message_try_again'], '
'; return false; } // We're going to have to use... FTP! elseif ($failure) { // Load any session data we might have... if (!isset($_POST['ftp_username']) && isset($_SESSION['installer_temp_ftp'])) { $_POST['ftp_server'] = $_SESSION['installer_temp_ftp']['server']; $_POST['ftp_port'] = $_SESSION['installer_temp_ftp']['port']; $_POST['ftp_username'] = $_SESSION['installer_temp_ftp']['username']; $_POST['ftp_password'] = $_SESSION['installer_temp_ftp']['password']; $_POST['ftp_path'] = $_SESSION['installer_temp_ftp']['path']; } if (isset($_POST['ftp_username'])) { $ftp = new ftp_connection($_POST['ftp_server'], $_POST['ftp_port'], $_POST['ftp_username'], $_POST['ftp_password']); if ($ftp->error === false) { // Try it without /home/abc just in case they messed up. if (!$ftp->chdir($_POST['ftp_path'])) { $ftp_error = $ftp->last_message; $ftp->chdir(preg_replace('~^/home[2]?/[^/]+?~', '', $_POST['ftp_path'])); } } } if (!isset($ftp) || $ftp->error !== false) { if (!isset($ftp)) $ftp = new ftp_connection(null); // Save the error so we can mess with listing... elseif ($ftp->error !== false && !isset($ftp_error)) $ftp_error = $ftp->last_message === null ? '' : $ftp->last_message; list ($username, $detect_path, $found_path) = $ftp->detect_path(dirname(__FILE__)); if ($found_path || !isset($_POST['ftp_path'])) $_POST['ftp_path'] = $detect_path; if (!isset($_POST['ftp_username'])) $_POST['ftp_username'] = $username; echo '

', $txt['ftp_setup'], '

', $txt['ftp_setup_info'], '

'; if (isset($ftp_error)) echo '
', $txt['error_ftp_no_connect'], '

', $ftp_error, '

'; echo '
', $txt['ftp_server_info'], '
', $txt['ftp_username_info'], '
', $txt['ftp_password_info'], '
', !empty($found_path) ? $txt['ftp_path_found_info'] : $txt['ftp_path_info'], '

', $txt['ftp_setup_why'], '

', $txt['ftp_setup_why_info'], '

', $txt['error_message_click'], ' ', $txt['ftp_setup_again'], '
'; return false; } else { $_SESSION['installer_temp_ftp'] = array( 'server' => $_POST['ftp_server'], 'port' => $_POST['ftp_port'], 'username' => $_POST['ftp_username'], 'password' => $_POST['ftp_password'], 'path' => $_POST['ftp_path'] ); foreach ($writable_files as $file) { if (!is_writable(dirname(__FILE__) . '/' . $file)) $ftp->chmod($file, 0755); if (!is_writable(dirname(__FILE__) . '/' . $file)) $ftp->chmod($file, 0777); } $ftp->close(); } } return true; } function updateSettingsFile($vars) { // Modify Settings.php. $settingsArray = file(dirname(__FILE__) . '/Settings.php'); // !!! Do we just want to read the file in clean, and split it this way always? if (count($settingsArray) == 1) $settingsArray = preg_split('~[\r\n]~', $settingsArray[0]); for ($i = 0, $n = count($settingsArray); $i < $n; $i++) { // Remove the redirect... if (trim($settingsArray[$i]) == 'if (file_exists(dirname(__FILE__) . \'/install.php\'))') { $settingsArray[$i] = ''; $settingsArray[$i++] = ''; $settingsArray[$i++] = ''; continue; } elseif (substr(trim($settingsArray[$i]), -16) == '/install.php\');' && substr(trim($settingsArray[$i]), 0, 26) == 'header(\'Location: http://\'') { $settingsArray[$i] = ''; continue; } if (trim($settingsArray[$i]) == '?' . '>') $settingsArray[$i] = ''; // Don't trim or bother with it if it's not a variable. if (substr($settingsArray[$i], 0, 1) != '$') continue; $settingsArray[$i] = rtrim($settingsArray[$i]) . "\n"; foreach ($vars as $var => $val) if (strncasecmp($settingsArray[$i], '$' . $var, 1 + strlen($var)) == 0) { $comment = strstr($settingsArray[$i], '#'); $settingsArray[$i] = '$' . $var . ' = \'' . $val . '\';' . ($comment != '' ? "\t\t" . $comment : "\n"); unset($vars[$var]); } } // Uh oh... the file wasn't empty... was it? if (!empty($vars)) { $settingsArray[$i++] = ''; foreach ($vars as $var => $val) $settingsArray[$i++] = '$' . $var . ' = \'' . $val . '\';' . "\n"; } // Blank out the file - done to fix a oddity with some servers. $fp = @fopen(dirname(__FILE__) . '/Settings.php', 'w'); if (!$fp) return false; fclose($fp); $fp = fopen(dirname(__FILE__) . '/Settings.php', 'r+'); // Gotta have one of these ;). if (trim($settingsArray[0]) != ''); fclose($fp); return true; } // Create an .htaccess file to prevent mod_security. SMF has filtering built-in. function fixModSecurity() { $htaccess_addition = ' # Turn off mod_security filtering. SMF is a big boy, it doesn\'t need its hands held. SecFilterEngine Off # The below probably isn\'t needed, but better safe than sorry. SecFilterScanPOST Off '; if (!function_exists('apache_get_modules') || !in_array('mod_security', apache_get_modules())) return true; elseif (file_exists(dirname(__FILE__) . '/.htaccess') && is_writable(dirname(__FILE__) . '/.htaccess')) { $current_htaccess = implode('', file(dirname(__FILE__) . '/.htaccess')); // Only change something if mod_security hasn't been addressed yet. if (strpos($current_htaccess, '') === false) { if ($ht_handle = fopen(dirname(__FILE__) . '/.htaccess', 'a')) { fwrite($ht_handle, $htaccess_addition); fclose($ht_handle); return true; } else return false; } else return true; } elseif (file_exists(dirname(__FILE__) . '/.htaccess')) return strpos(implode('', file(dirname(__FILE__) . '/.htaccess')), '') !== false; elseif (is_writable(dirname(__FILE__))) { if ($ht_handle = fopen(dirname(__FILE__) . '/.htaccess', 'w')) { fwrite($ht_handle, $htaccess_addition); fclose($ht_handle); return true; } else return false; } else return false; } ?>