Beispiel #1
0
function AdminAccount()
{
    global $txt, $db_type, $db_connection, $incontext, $db_prefix, $db_passwd, $sourcedir;
    $incontext['sub_template'] = 'admin_account';
    $incontext['page_title'] = $txt['user_settings'];
    $incontext['continue'] = 1;
    // Skipping?
    if (!empty($_POST['skip'])) {
        return true;
    }
    // Need this to check whether we need the database password.
    require dirname(__FILE__) . '/Settings.php';
    load_database();
    if (!isset($_POST['username'])) {
        $_POST['username'] = '';
    }
    if (!isset($_POST['email'])) {
        $_POST['email'] = '';
    }
    $incontext['username'] = htmlspecialchars(stripslashes($_POST['username']));
    $incontext['email'] = htmlspecialchars(stripslashes($_POST['email']));
    $incontext['require_db_confirm'] = empty($db_type) || $db_type != 'sqlite';
    // Only allow skipping if we think they already have an account setup.
    $request = smf_db_query('
		SELECT id_member
		FROM {db_prefix}members
		WHERE id_group = {int:admin_group} OR FIND_IN_SET({int:admin_group}, additional_groups) != 0
		LIMIT 1', array('db_error_skip' => true, 'admin_group' => 1));
    if (mysql_num_rows($request) != 0) {
        $incontext['skip'] = 1;
    }
    mysql_free_result($request);
    // Trying to create an account?
    if (isset($_POST['password1']) && !empty($_POST['contbutt'])) {
        // Wrong password?
        if ($incontext['require_db_confirm'] && $_POST['password3'] != $db_passwd) {
            $incontext['error'] = $txt['error_db_connect'];
            return false;
        }
        // Not matching passwords?
        if ($_POST['password1'] != $_POST['password2']) {
            $incontext['error'] = $txt['error_user_settings_again_match'];
            return false;
        }
        // No password?
        if (strlen($_POST['password1']) < 4) {
            $incontext['error'] = $txt['error_user_settings_no_password'];
            return false;
        }
        if (!file_exists($sourcedir . '/lib/Subs.php')) {
            $incontext['error'] = $txt['error_subs_missing'];
            return false;
        }
        // Update the main contact email?
        if (!empty($_POST['email']) && (empty($webmaster_email) || $webmaster_email == '*****@*****.**')) {
            updateSettingsFile(array('webmaster_email' => $_POST['email']));
        }
        // Work out whether we're going to have dodgy characters and remove them.
        $invalid_characters = preg_match('~[<>&"\'=\\\\]~', $_POST['username']) != 0;
        $_POST['username'] = preg_replace('~[<>&"\'=\\\\]~', '', $_POST['username']);
        $result = smf_db_query('
			SELECT id_member, password_salt
			FROM {db_prefix}members
			WHERE member_name = {string:username} OR email_address = {string:email}
			LIMIT 1', array('username' => stripslashes($_POST['username']), 'email' => stripslashes($_POST['email']), 'db_error_skip' => true));
        if (mysql_num_rows($result) != 0) {
            list($incontext['member_id'], $incontext['member_salt']) = mysql_fetch_row($result);
            mysql_free_result($result);
            $incontext['account_existed'] = $txt['error_user_settings_taken'];
        } elseif ($_POST['username'] == '' || strlen($_POST['username']) > 25) {
            // Try the previous step again.
            $incontext['error'] = $_POST['username'] == '' ? $txt['error_username_left_empty'] : $txt['error_username_too_long'];
            return false;
        } elseif ($invalid_characters || $_POST['username'] == '_' || $_POST['username'] == '|' || strpos($_POST['username'], '[code') !== false || strpos($_POST['username'], '[/code') !== false) {
            // Try the previous step again.
            $incontext['error'] = $txt['error_invalid_characters_username'];
            return false;
        } 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) {
            // One step back, this time fill out a proper email address.
            $incontext['error'] = sprintf($txt['error_valid_email_needed'], $_POST['username']);
            return false;
        } elseif ($_POST['username'] != '') {
            $incontext['member_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']) ? substr($_SERVER['REMOTE_ADDR'], 0, 255) : '';
            $request = smf_db_insert('insert', $db_prefix . 'members', array('member_name' => 'string-25', 'real_name' => 'string-25', 'passwd' => 'string', 'email_address' => 'string', 'id_group' => 'int', 'posts' => 'int', 'date_registered' => 'int', 'hide_email' => 'int', 'password_salt' => 'string', 'lngfile' => 'string', 'personal_text' => 'string', 'avatar' => 'string', 'member_ip' => 'string', 'member_ip2' => 'string', 'buddy_list' => 'string', 'pm_ignore_list' => 'string', 'message_labels' => 'string', 'location' => 'string', 'signature' => 'string', 'usertitle' => 'string', 'secret_question' => 'string', 'additional_groups' => 'string', 'ignore_boards' => 'string', 'openid_uri' => 'string'), array(stripslashes($_POST['username']), stripslashes($_POST['username']), sha1(strtolower(stripslashes($_POST['username'])) . stripslashes($_POST['password1'])), stripslashes($_POST['email']), 1, 0, time(), 0, $incontext['member_salt'], '', '', '', $ip, $ip, '', '', '', '', '', '', '', '', '', ''), array('id_member'));
            // Awww, crud!
            if ($request === false) {
                $incontext['error'] = $txt['error_user_settings_query'] . '<br />
				<div style="margin: 2ex;">' . nl2br(htmlspecialchars(mysql_error($db_connection))) . '</div>';
                return false;
            }
            $incontext['member_id'] = smf_db_insert_id("{$db_prefix}members", 'id_member');
        }
        // If we're here we're good.
        return true;
    }
    return false;
}
function smf_db_error($db_string, $connection = null)
{
    global $txt, $context, $sourcedir, $webmaster_email, $modSettings;
    global $forum_version, $db_connection, $db_last_error, $db_persist;
    global $db_server, $db_user, $db_passwd, $db_name, $db_show_debug, $ssi_db_user, $ssi_db_passwd;
    global $smcFunc;
    // Get the file and line numbers.
    list($file, $line) = smf_db_error_backtrace('', '', 'return', __FILE__, __LINE__);
    // Decide which connection to use
    $connection = $connection == null ? $db_connection : $connection;
    // This is the error message...
    $query_error = mysql_error($connection);
    $query_errno = mysql_errno($connection);
    // Error numbers:
    //    1016: Can't open file '....MYI'
    //    1030: Got error ??? from table handler.
    //    1034: Incorrect key file for table.
    //    1035: Old key file for table.
    //    1205: Lock wait timeout exceeded.
    //    1213: Deadlock found.
    //    2006: Server has gone away.
    //    2013: Lost connection to server during query.
    // Log the error.
    if ($query_errno != 1213 && $query_errno != 1205 && function_exists('log_error')) {
        log_error($txt['database_error'] . ': ' . $query_error . (!empty($modSettings['enableErrorQueryLogging']) ? "\n\n{$db_string}" : ''), 'database', $file, $line);
    }
    // Database error auto fixing ;).
    if (function_exists('cache_get_data') && (!isset($modSettings['autoFixDatabase']) || $modSettings['autoFixDatabase'] == '1')) {
        // Force caching on, just for the error checking.
        $old_cache = @$modSettings['cache_enable'];
        $modSettings['cache_enable'] = '1';
        if (($temp = cache_get_data('db_last_error', 600)) !== null) {
            $db_last_error = max(@$db_last_error, $temp);
        }
        if (@$db_last_error < time() - 3600 * 24 * 3) {
            // We know there's a problem... but what?  Try to auto detect.
            if ($query_errno == 1030 && strpos($query_error, ' 127 ') !== false) {
                preg_match_all('~(?:[\\n\\r]|^)[^\']+?(?:FROM|JOIN|UPDATE|TABLE) ((?:[^\\n\\r(]+?(?:, )?)*)~s', $db_string, $matches);
                $fix_tables = array();
                foreach ($matches[1] as $tables) {
                    $tables = array_unique(explode(',', $tables));
                    foreach ($tables as $table) {
                        // Now, it's still theoretically possible this could be an injection.  So backtick it!
                        if (trim($table) != '') {
                            $fix_tables[] = '`' . strtr(trim($table), array('`' => '')) . '`';
                        }
                    }
                }
                $fix_tables = array_unique($fix_tables);
            } elseif ($query_errno == 1016) {
                if (preg_match('~\'([^\\.\']+)~', $query_error, $match) != 0) {
                    $fix_tables = array('`' . $match[1] . '`');
                }
            } elseif ($query_errno == 1034 || $query_errno == 1035) {
                preg_match('~\'([^\']+?)\'~', $query_error, $match);
                $fix_tables = array('`' . $match[1] . '`');
            }
        }
        // Check for errors like 145... only fix it once every three days, and send an email. (can't use empty because it might not be set yet...)
        if (!empty($fix_tables)) {
            // Subs-Admin.php for updateSettingsFile(), Subs-Post.php for sendmail().
            require_once $sourcedir . '/Subs-Admin.php';
            require_once $sourcedir . '/Subs-Post.php';
            // Make a note of the REPAIR...
            cache_put_data('db_last_error', time(), 600);
            if (($temp = cache_get_data('db_last_error', 600)) === null) {
                updateSettingsFile(array('db_last_error' => time()));
            }
            // Attempt to find and repair the broken table.
            foreach ($fix_tables as $table) {
                $smcFunc['db_query']('', "\r\n\t\t\t\t\tREPAIR TABLE {$table}", false, false);
            }
            // And send off an email!
            sendmail($webmaster_email, $txt['database_error'], $txt['tried_to_repair']);
            $modSettings['cache_enable'] = $old_cache;
            // Try the query again...?
            $ret = $smcFunc['db_query']('', $db_string, false, false);
            if ($ret !== false) {
                return $ret;
            }
        } else {
            $modSettings['cache_enable'] = $old_cache;
        }
        // Check for the "lost connection" or "deadlock found" errors - and try it just one more time.
        if (in_array($query_errno, array(1205, 1213, 2006, 2013))) {
            if (in_array($query_errno, array(2006, 2013)) && $db_connection == $connection) {
                // Are we in SSI mode?  If so try that username and password first
                if (SMF == 'SSI' && !empty($ssi_db_user) && !empty($ssi_db_passwd)) {
                    if (empty($db_persist)) {
                        $db_connection = @mysql_connect($db_server, $ssi_db_user, $ssi_db_passwd);
                    } else {
                        $db_connection = @mysql_pconnect($db_server, $ssi_db_user, $ssi_db_passwd);
                    }
                }
                // Fall back to the regular username and password if need be
                if (!$db_connection) {
                    if (empty($db_persist)) {
                        $db_connection = @mysql_connect($db_server, $db_user, $db_passwd);
                    } else {
                        $db_connection = @mysql_pconnect($db_server, $db_user, $db_passwd);
                    }
                }
                if (!$db_connection || !@mysql_select_db($db_name, $db_connection)) {
                    $db_connection = false;
                }
            }
            if ($db_connection) {
                // Try a deadlock more than once more.
                for ($n = 0; $n < 4; $n++) {
                    $ret = $smcFunc['db_query']('', $db_string, false, false);
                    $new_errno = mysql_errno($db_connection);
                    if ($ret !== false || in_array($new_errno, array(1205, 1213))) {
                        break;
                    }
                }
                // If it failed again, shucks to be you... we're not trying it over and over.
                if ($ret !== false) {
                    return $ret;
                }
            }
        } elseif ($query_errno == 1030 && (strpos($query_error, ' -1 ') !== false || strpos($query_error, ' 28 ') !== false || strpos($query_error, ' 12 ') !== false)) {
            if (!isset($txt)) {
                $query_error .= ' - check database storage space.';
            } else {
                if (!isset($txt['mysql_error_space'])) {
                    loadLanguage('Errors');
                }
                $query_error .= !isset($txt['mysql_error_space']) ? ' - check database storage space.' : $txt['mysql_error_space'];
            }
        }
    }
    // Nothing's defined yet... just die with it.
    if (empty($context) || empty($txt)) {
        die($query_error);
    }
    // Show an error message, if possible.
    $context['error_title'] = $txt['database_error'];
    if (allowedTo('admin_forum')) {
        $context['error_message'] = nl2br($query_error) . '<br />' . $txt['file'] . ': ' . $file . '<br />' . $txt['line'] . ': ' . $line;
    } else {
        $context['error_message'] = $txt['try_again'];
    }
    // A database error is often the sign of a database in need of upgrade.  Check forum versions, and if not identical suggest an upgrade... (not for Demo/CVS versions!)
    if (allowedTo('admin_forum') && !empty($forum_version) && $forum_version != 'SMF ' . @$modSettings['smfVersion'] && strpos($forum_version, 'Demo') === false && strpos($forum_version, 'CVS') === false) {
        $context['error_message'] .= '<br /><br />' . sprintf($txt['database_error_versions'], $forum_version, $modSettings['smfVersion']);
    }
    if (allowedTo('admin_forum') && isset($db_show_debug) && $db_show_debug === true) {
        $context['error_message'] .= '<br /><br />' . nl2br($db_string);
    }
    // It's already been logged... don't log it again.
    fatal_error($context['error_message'], false);
}
Beispiel #3
0
function ConvertUtf8()
{
    global $scripturl, $context, $txt, $language, $db_character_set;
    global $modSettings, $user_info, $sourcedir, $smcFunc, $db_prefix;
    // Show me your badge!
    isAllowedTo('admin_forum');
    // The character sets used in SMF's language files with their db equivalent.
    $charsets = array('big5' => 'big5', 'gbk' => 'gbk', 'ISO-8859-1' => 'latin1', 'ISO-8859-2' => 'latin2', 'ISO-8859-9' => 'latin5', 'ISO-8859-15' => 'latin9', 'tis-620' => 'tis620', 'UTF-8' => 'utf8', 'windows-1251' => 'cp1251', 'windows-1253' => 'utf8', 'windows-1255' => 'utf8', 'windows-1256' => 'cp1256');
    // Get a list of character sets supported by your MySQL server.
    $request = $smcFunc['db_query']('', '
		SHOW CHARACTER SET', array());
    $db_charsets = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $db_charsets[] = $row['Charset'];
    }
    $smcFunc['db_free_result']($request);
    // Character sets supported by both MySQL and SMF's language files.
    $charsets = array_intersect($charsets, $db_charsets);
    // This is for the first screen telling backups is good.
    if (!isset($_POST['proceed'])) {
        // Character set conversions are only supported as of MySQL 4.1.2.
        if (version_compare('4.1.2', preg_replace('~\\-.+?$~', '', $smcFunc['db_server_info']())) > 0) {
            fatal_lang_error('utf8_db_version_too_low');
        }
        // Use the messages.body column as indicator for the database charset.
        $request = $smcFunc['db_query']('', '
			SHOW FULL COLUMNS
			FROM {db_prefix}messages
			LIKE {string:body_like}', array('body_like' => 'body'));
        $column_info = $smcFunc['db_fetch_assoc']($request);
        $smcFunc['db_free_result']($request);
        // A collation looks like latin1_swedish. We only need the character set.
        list($context['database_charset']) = explode('_', $column_info['Collation']);
        $context['database_charset'] = in_array($context['database_charset'], $charsets) ? array_search($context['database_charset'], $charsets) : $context['database_charset'];
        // No need to convert to UTF-8 if it already is.
        if ($db_character_set === 'utf8' && !empty($modSettings['global_character_set']) && $modSettings['global_character_set'] === 'UTF-8') {
            fatal_lang_error('utf8_already_utf8');
        }
        // Cannot do conversion if using a fulltext index
        if (!empty($modSettings['search_index']) && $modSettings['search_index'] == 'fulltext') {
            fatal_lang_error('utf8_cannot_convert_fulltext');
        }
        // Grab the character set from the default language file.
        loadLanguage('index', $language, true);
        $context['charset_detected'] = $txt['lang_character_set'];
        $context['charset_about_detected'] = sprintf($txt['utf8_detected_charset'], $language, $context['charset_detected']);
        // Go back to your own language.
        loadLanguage('index', $user_info['language'], true);
        // Show a warning if the character set seems not to be supported.
        if (!isset($charsets[strtr(strtolower($context['charset_detected']), array('utf' => 'UTF', 'iso' => 'ISO'))])) {
            $context['charset_warning'] = sprintf($txt['utf8_charset_not_supported'], $txt['lang_character_set']);
            // Default to ISO-8859-1.
            $context['charset_detected'] = 'ISO-8859-1';
        }
        $context['charset_list'] = array_keys($charsets);
        $context['page_title'] = $txt['utf8_title'];
        $context['sub_template'] = 'convert_utf8';
        return;
    }
    // After this point we're starting the conversion. But first: session check.
    checkSession();
    // Translation table for the character sets not native for MySQL.
    $translation_tables = array('windows-1255' => array('0x81' => '\'\'', '0x8A' => '\'\'', '0x8C' => '\'\'', '0x8D' => '\'\'', '0x8E' => '\'\'', '0x8F' => '\'\'', '0x90' => '\'\'', '0x9A' => '\'\'', '0x9C' => '\'\'', '0x9D' => '\'\'', '0x9E' => '\'\'', '0x9F' => '\'\'', '0xCA' => '\'\'', '0xD9' => '\'\'', '0xDA' => '\'\'', '0xDB' => '\'\'', '0xDC' => '\'\'', '0xDD' => '\'\'', '0xDE' => '\'\'', '0xDF' => '\'\'', '0xFB' => '\'\'', '0xFC' => '\'\'', '0xFF' => '\'\'', '0xC2' => '0xFF', '0x80' => '0xFC', '0xE2' => '0xFB', '0xA0' => '0xC2A0', '0xA1' => '0xC2A1', '0xA2' => '0xC2A2', '0xA3' => '0xC2A3', '0xA5' => '0xC2A5', '0xA6' => '0xC2A6', '0xA7' => '0xC2A7', '0xA8' => '0xC2A8', '0xA9' => '0xC2A9', '0xAB' => '0xC2AB', '0xAC' => '0xC2AC', '0xAD' => '0xC2AD', '0xAE' => '0xC2AE', '0xAF' => '0xC2AF', '0xB0' => '0xC2B0', '0xB1' => '0xC2B1', '0xB2' => '0xC2B2', '0xB3' => '0xC2B3', '0xB4' => '0xC2B4', '0xB5' => '0xC2B5', '0xB6' => '0xC2B6', '0xB7' => '0xC2B7', '0xB8' => '0xC2B8', '0xB9' => '0xC2B9', '0xBB' => '0xC2BB', '0xBC' => '0xC2BC', '0xBD' => '0xC2BD', '0xBE' => '0xC2BE', '0xBF' => '0xC2BF', '0xD7' => '0xD7B3', '0xD1' => '0xD781', '0xD4' => '0xD7B0', '0xD5' => '0xD7B1', '0xD6' => '0xD7B2', '0xE0' => '0xD790', '0xEA' => '0xD79A', '0xEC' => '0xD79C', '0xED' => '0xD79D', '0xEE' => '0xD79E', '0xEF' => '0xD79F', '0xF0' => '0xD7A0', '0xF1' => '0xD7A1', '0xF2' => '0xD7A2', '0xF3' => '0xD7A3', '0xF5' => '0xD7A5', '0xF6' => '0xD7A6', '0xF7' => '0xD7A7', '0xF8' => '0xD7A8', '0xF9' => '0xD7A9', '0x82' => '0xE2809A', '0x84' => '0xE2809E', '0x85' => '0xE280A6', '0x86' => '0xE280A0', '0x87' => '0xE280A1', '0x89' => '0xE280B0', '0x8B' => '0xE280B9', '0x93' => '0xE2809C', '0x94' => '0xE2809D', '0x95' => '0xE280A2', '0x97' => '0xE28094', '0x99' => '0xE284A2', '0xC0' => '0xD6B0', '0xC1' => '0xD6B1', '0xC3' => '0xD6B3', '0xC4' => '0xD6B4', '0xC5' => '0xD6B5', '0xC6' => '0xD6B6', '0xC7' => '0xD6B7', '0xC8' => '0xD6B8', '0xC9' => '0xD6B9', '0xCB' => '0xD6BB', '0xCC' => '0xD6BC', '0xCD' => '0xD6BD', '0xCE' => '0xD6BE', '0xCF' => '0xD6BF', '0xD0' => '0xD780', '0xD2' => '0xD782', '0xE3' => '0xD793', '0xE4' => '0xD794', '0xE5' => '0xD795', '0xE7' => '0xD797', '0xE9' => '0xD799', '0xFD' => '0xE2808E', '0xFE' => '0xE2808F', '0x92' => '0xE28099', '0x83' => '0xC692', '0xD3' => '0xD783', '0x88' => '0xCB86', '0x98' => '0xCB9C', '0x91' => '0xE28098', '0x96' => '0xE28093', '0xBA' => '0xC3B7', '0x9B' => '0xE280BA', '0xAA' => '0xC397', '0xA4' => '0xE282AA', '0xE1' => '0xD791', '0xE6' => '0xD796', '0xE8' => '0xD798', '0xEB' => '0xD79B', '0xF4' => '0xD7A4', '0xFA' => '0xD7AA', '0xFF' => '0xD6B2', '0xFC' => '0xE282AC', '0xFB' => '0xD792'), 'windows-1253' => array('0x81' => '\'\'', '0x88' => '\'\'', '0x8A' => '\'\'', '0x8C' => '\'\'', '0x8D' => '\'\'', '0x8E' => '\'\'', '0x8F' => '\'\'', '0x90' => '\'\'', '0x98' => '\'\'', '0x9A' => '\'\'', '0x9C' => '\'\'', '0x9D' => '\'\'', '0x9E' => '\'\'', '0x9F' => '\'\'', '0xAA' => '\'\'', '0xD2' => '\'\'', '0xFF' => '\'\'', '0xCE' => '0xCE9E', '0xB8' => '0xCE88', '0xBA' => '0xCE8A', '0xBC' => '0xCE8C', '0xBE' => '0xCE8E', '0xBF' => '0xCE8F', '0xC0' => '0xCE90', '0xC8' => '0xCE98', '0xCA' => '0xCE9A', '0xCC' => '0xCE9C', '0xCD' => '0xCE9D', '0xCF' => '0xCE9F', '0xDA' => '0xCEAA', '0xE8' => '0xCEB8', '0xEA' => '0xCEBA', '0xEC' => '0xCEBC', '0xEE' => '0xCEBE', '0xEF' => '0xCEBF', '0xC2' => '0xFF', '0xBD' => '0xC2BD', '0xED' => '0xCEBD', '0xB2' => '0xC2B2', '0xA0' => '0xC2A0', '0xA3' => '0xC2A3', '0xA4' => '0xC2A4', '0xA5' => '0xC2A5', '0xA6' => '0xC2A6', '0xA7' => '0xC2A7', '0xA8' => '0xC2A8', '0xA9' => '0xC2A9', '0xAB' => '0xC2AB', '0xAC' => '0xC2AC', '0xAD' => '0xC2AD', '0xAE' => '0xC2AE', '0xB0' => '0xC2B0', '0xB1' => '0xC2B1', '0xB3' => '0xC2B3', '0xB5' => '0xC2B5', '0xB6' => '0xC2B6', '0xB7' => '0xC2B7', '0xBB' => '0xC2BB', '0xE2' => '0xCEB2', '0x80' => '0xD2', '0x82' => '0xE2809A', '0x84' => '0xE2809E', '0x85' => '0xE280A6', '0x86' => '0xE280A0', '0xA1' => '0xCE85', '0xA2' => '0xCE86', '0x87' => '0xE280A1', '0x89' => '0xE280B0', '0xB9' => '0xCE89', '0x8B' => '0xE280B9', '0x91' => '0xE28098', '0x99' => '0xE284A2', '0x92' => '0xE28099', '0x93' => '0xE2809C', '0x94' => '0xE2809D', '0x95' => '0xE280A2', '0x96' => '0xE28093', '0x97' => '0xE28094', '0x9B' => '0xE280BA', '0xAF' => '0xE28095', '0xB4' => '0xCE84', '0xC1' => '0xCE91', '0xC3' => '0xCE93', '0xC4' => '0xCE94', '0xC5' => '0xCE95', '0xC6' => '0xCE96', '0x83' => '0xC692', '0xC7' => '0xCE97', '0xC9' => '0xCE99', '0xCB' => '0xCE9B', '0xD0' => '0xCEA0', '0xD1' => '0xCEA1', '0xD3' => '0xCEA3', '0xD4' => '0xCEA4', '0xD5' => '0xCEA5', '0xD6' => '0xCEA6', '0xD7' => '0xCEA7', '0xD8' => '0xCEA8', '0xD9' => '0xCEA9', '0xDB' => '0xCEAB', '0xDC' => '0xCEAC', '0xDD' => '0xCEAD', '0xDE' => '0xCEAE', '0xDF' => '0xCEAF', '0xE0' => '0xCEB0', '0xE1' => '0xCEB1', '0xE3' => '0xCEB3', '0xE4' => '0xCEB4', '0xE5' => '0xCEB5', '0xE6' => '0xCEB6', '0xE7' => '0xCEB7', '0xE9' => '0xCEB9', '0xEB' => '0xCEBB', '0xF0' => '0xCF80', '0xF1' => '0xCF81', '0xF2' => '0xCF82', '0xF3' => '0xCF83', '0xF4' => '0xCF84', '0xF5' => '0xCF85', '0xF6' => '0xCF86', '0xF7' => '0xCF87', '0xF8' => '0xCF88', '0xF9' => '0xCF89', '0xFA' => '0xCF8A', '0xFB' => '0xCF8B', '0xFC' => '0xCF8C', '0xFD' => '0xCF8D', '0xFE' => '0xCF8E', '0xFF' => '0xCE92', '0xD2' => '0xE282AC'));
    // Make some preparations.
    if (isset($translation_tables[$_POST['src_charset']])) {
        $replace = '%field%';
        foreach ($translation_tables[$_POST['src_charset']] as $from => $to) {
            $replace = 'REPLACE(' . $replace . ', ' . $from . ', ' . $to . ')';
        }
    }
    // Grab a list of tables.
    if (preg_match('~^`(.+?)`\\.(.+?)$~', $db_prefix, $match) === 1) {
        $queryTables = $smcFunc['db_query']('', '
			SHOW TABLE STATUS
			FROM `' . strtr($match[1], array('`' => '')) . '`
			LIKE {string:table_name}', array('table_name' => str_replace('_', '\\_', $match[2]) . '%'));
    } else {
        $queryTables = $smcFunc['db_query']('', '
			SHOW TABLE STATUS
			LIKE {string:table_name}', array('table_name' => str_replace('_', '\\_', $db_prefix) . '%'));
    }
    while ($table_info = $smcFunc['db_fetch_assoc']($queryTables)) {
        // Just to make sure it doesn't time out.
        if (function_exists('apache_reset_timeout')) {
            @apache_reset_timeout();
        }
        $table_charsets = array();
        // Loop through each column.
        $queryColumns = $smcFunc['db_query']('', '
			SHOW FULL COLUMNS
			FROM ' . $table_info['Name'], array());
        while ($column_info = $smcFunc['db_fetch_assoc']($queryColumns)) {
            // Only text'ish columns have a character set and need converting.
            if (strpos($column_info['Type'], 'text') !== false || strpos($column_info['Type'], 'char') !== false) {
                $collation = empty($column_info['Collation']) || $column_info['Collation'] === 'NULL' ? $table_info['Collation'] : $column_info['Collation'];
                if (!empty($collation) && $collation !== 'NULL') {
                    list($charset) = explode('_', $collation);
                    if (!isset($table_charsets[$charset])) {
                        $table_charsets[$charset] = array();
                    }
                    $table_charsets[$charset][] = $column_info;
                }
            }
        }
        $smcFunc['db_free_result']($queryColumns);
        // Only change the column if the data doesn't match the current charset.
        if (count($table_charsets) === 1 && key($table_charsets) !== $charsets[$_POST['src_charset']] || count($table_charsets) > 1) {
            $updates_blob = '';
            $updates_text = '';
            foreach ($table_charsets as $charset => $columns) {
                if ($charset !== $charsets[$_POST['src_charset']]) {
                    foreach ($columns as $column) {
                        $updates_blob .= '
							CHANGE COLUMN ' . $column['Field'] . ' ' . $column['Field'] . ' ' . strtr($column['Type'], array('text' => 'blob', 'char' => 'binary')) . ($column['Null'] === 'YES' ? ' NULL' : ' NOT NULL') . (strpos($column['Type'], 'char') === false ? '' : ' default \'' . $column['Default'] . '\'') . ',';
                        $updates_text .= '
							CHANGE COLUMN ' . $column['Field'] . ' ' . $column['Field'] . ' ' . $column['Type'] . ' CHARACTER SET ' . $charsets[$_POST['src_charset']] . ($column['Null'] === 'YES' ? '' : ' NOT NULL') . (strpos($column['Type'], 'char') === false ? '' : ' default \'' . $column['Default'] . '\'') . ',';
                    }
                }
            }
            // Change the columns to binary form.
            $smcFunc['db_query']('', '
				ALTER TABLE {raw:table_name}{raw:updates_blob}', array('table_name' => $table_info['Name'], 'updates_blob' => substr($updates_blob, 0, -1)));
            // Convert the character set if MySQL has no native support for it.
            if (isset($translation_tables[$_POST['src_charset']])) {
                $update = '';
                foreach ($table_charsets as $charset => $columns) {
                    foreach ($columns as $column) {
                        $update .= '
							' . $column['Field'] . ' = ' . strtr($replace, array('%field%' => $column['Field'])) . ',';
                    }
                }
                $smcFunc['db_query']('', '
					UPDATE {raw:table_name}
					SET {raw:updates}', array('table_name' => $table_info['Name'], 'updates' => substr($update, 0, -1)));
            }
            // Change the columns back, but with the proper character set.
            $smcFunc['db_query']('', '
				ALTER TABLE {raw:table_name}{raw:updates_text}', array('table_name' => $table_info['Name'], 'updates_text' => substr($updates_text, 0, -1)));
        }
        // Now do the actual conversion (if still needed).
        if ($charsets[$_POST['src_charset']] !== 'utf8') {
            $smcFunc['db_query']('', '
				ALTER TABLE {raw:table_name}
				CONVERT TO CHARACTER SET utf8', array('table_name' => $table_info['Name']));
        }
    }
    $smcFunc['db_free_result']($queryTables);
    // Let the settings know we have a new character set.
    updateSettings(array('global_character_set' => 'UTF-8', 'previousCharacterSet' => empty($translation_tables[$_POST['src_charset']]) ? $charsets[$_POST['src_charset']] : $translation_tables[$_POST['src_charset']]));
    // Store it in Settings.php too because it's needed before db connection.
    require_once $sourcedir . '/Subs-Admin.php';
    updateSettingsFile(array('db_character_set' => '\'utf8\''));
    // The conversion might have messed up some serialized strings. Fix them!
    require_once $sourcedir . '/Subs-Charset.php';
    fix_serialized_columns();
    redirectexit('action=admin;area=maintain;done=convertutf8');
}
Beispiel #4
0
/**
 * Ask for the administrator login information.
 */
function action_adminAccount()
{
    global $txt, $db_type, $db_connection, $databases, $incontext, $db_prefix, $db_passwd;
    $incontext['sub_template'] = 'admin_account';
    $incontext['page_title'] = $txt['user_settings'];
    $incontext['continue'] = 1;
    // Need this to check whether we need the database password.
    require dirname(__FILE__) . '/Settings.php';
    if (!defined('ELK')) {
        define('ELK', 1);
    }
    definePaths();
    // These files may be or may not be already included, better safe than sorry for now
    require_once SOURCEDIR . '/Subs.php';
    require_once SUBSDIR . '/Util.class.php';
    $db = load_database();
    if (!isset($_POST['username'])) {
        $_POST['username'] = '';
    }
    if (!isset($_POST['email'])) {
        $_POST['email'] = '';
    }
    $incontext['username'] = htmlspecialchars(stripslashes($_POST['username']), ENT_COMPAT, 'UTF-8');
    $incontext['email'] = htmlspecialchars(stripslashes($_POST['email']), ENT_COMPAT, 'UTF-8');
    $incontext['require_db_confirm'] = empty($db_type) || !empty($databases[$db_type]['require_db_confirm']);
    // Only allow create an admin account if they don't have one already.
    $request = $db->query('', '
		SELECT id_member
		FROM {db_prefix}members
		WHERE id_group = {int:admin_group} OR FIND_IN_SET({int:admin_group}, additional_groups) != 0
		LIMIT 1', array('db_error_skip' => true, 'admin_group' => 1));
    // Skip the step if an admin already exists
    if ($db->num_rows($request) != 0) {
        return true;
    }
    $db->free_result($request);
    // Trying to create an account?
    if (isset($_POST['password1']) && !empty($_POST['contbutt'])) {
        // Wrong password?
        if ($incontext['require_db_confirm'] && $_POST['password3'] != $db_passwd) {
            $incontext['error'] = $txt['error_db_connect'];
            return false;
        }
        // Not matching passwords?
        if ($_POST['password1'] != $_POST['password2']) {
            $incontext['error'] = $txt['error_user_settings_again_match'];
            return false;
        }
        // No password?
        if (strlen($_POST['password1']) < 4) {
            $incontext['error'] = $txt['error_user_settings_no_password'];
            return false;
        }
        if (!file_exists(SOURCEDIR . '/Subs.php')) {
            $incontext['error'] = $txt['error_subs_missing'];
            return false;
        }
        // Update the main contact email?
        if (!empty($_POST['email']) && (empty($webmaster_email) || $webmaster_email == '*****@*****.**')) {
            updateSettingsFile(array('webmaster_email' => $_POST['email']));
        }
        // Work out whether we're going to have dodgy characters and remove them.
        $invalid_characters = preg_match('~[<>&"\'=\\\\]~', $_POST['username']) != 0;
        $_POST['username'] = preg_replace('~[<>&"\'=\\\\]~', '', $_POST['username']);
        $result = $db->query('', '
			SELECT id_member, password_salt
			FROM {db_prefix}members
			WHERE member_name = {string:username} OR email_address = {string:email}
			LIMIT 1', array('username' => stripslashes($_POST['username']), 'email' => stripslashes($_POST['email']), 'db_error_skip' => true));
        if ($db->num_rows($result) != 0) {
            list($incontext['member_id'], $incontext['member_salt']) = $db->fetch_row($result);
            $db->free_result($result);
            $incontext['account_existed'] = $txt['error_user_settings_taken'];
        } elseif ($_POST['username'] == '' || strlen($_POST['username']) > 25) {
            // Try the previous step again.
            $incontext['error'] = $_POST['username'] == '' ? $txt['error_username_left_empty'] : $txt['error_username_too_long'];
            return false;
        } elseif ($invalid_characters || $_POST['username'] == '_' || $_POST['username'] == '|' || strpos($_POST['username'], '[code') !== false || strpos($_POST['username'], '[/code') !== false) {
            // Try the previous step again.
            $incontext['error'] = $txt['error_invalid_characters_username'];
            return false;
        } elseif (empty($_POST['email']) || !filter_var(stripslashes($_POST['email']), FILTER_VALIDATE_EMAIL) || strlen(stripslashes($_POST['email'])) > 255) {
            // One step back, this time fill out a proper email address.
            $incontext['error'] = sprintf($txt['error_valid_email_needed'], $_POST['username']);
            return false;
        } elseif ($_POST['username'] != '') {
            require_once SUBSDIR . '/Auth.subs.php';
            $incontext['member_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']) ? substr($_SERVER['REMOTE_ADDR'], 0, 255) : '';
            // Get a security hash for this combination
            $password = stripslashes($_POST['password1']);
            $incontext['passwd'] = validateLoginPassword($password, '', $_POST['username'], true);
            $request = $db->insert('', $db_prefix . 'members', array('member_name' => 'string-25', 'real_name' => 'string-25', 'passwd' => 'string', 'email_address' => 'string', 'id_group' => 'int', 'posts' => 'int', 'date_registered' => 'int', 'hide_email' => 'int', 'password_salt' => 'string', 'lngfile' => 'string', 'personal_text' => 'string', 'avatar' => 'string', 'member_ip' => 'string', 'member_ip2' => 'string', 'buddy_list' => 'string', 'pm_ignore_list' => 'string', 'message_labels' => 'string', 'website_title' => 'string', 'website_url' => 'string', 'location' => 'string', 'signature' => 'string', 'usertitle' => 'string', 'secret_question' => 'string', 'additional_groups' => 'string', 'ignore_boards' => 'string', 'openid_uri' => 'string'), array(stripslashes($_POST['username']), stripslashes($_POST['username']), $incontext['passwd'], stripslashes($_POST['email']), 1, 0, time(), 0, $incontext['member_salt'], '', '', '', $ip, $ip, '', '', '', '', '', '', '', '', '', '', '', ''), array('id_member'));
            // Awww, crud!
            if ($request === false) {
                $incontext['error'] = $txt['error_user_settings_query'] . '<br />
				<div style="margin: 2ex;">' . nl2br(htmlspecialchars($db->last_error($db_connection), ENT_COMPAT, 'UTF-8')) . '</div>';
                return false;
            }
            $incontext['member_id'] = $db->insert_id("{$db_prefix}members", 'id_member');
        }
        // If we're here we're good.
        return true;
    }
    return false;
}
function saveSettings(&$config_vars)
{
    global $boarddir, $sc, $cookiename, $modSettings, $user_settings;
    global $sourcedir, $context, $cachedir;
    // Fix the darn stupid cookiename! (more may not be allowed, but these for sure!)
    if (isset($_POST['cookiename'])) {
        $_POST['cookiename'] = preg_replace('~[,;\\s\\.$]+~' . ($context['utf8'] ? 'u' : ''), '', $_POST['cookiename']);
    }
    // Fix the forum's URL if necessary.
    if (isset($_POST['boardurl'])) {
        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'];
        }
    }
    // Any passwords?
    $config_passwords = array('db_passwd', 'ssi_db_passwd');
    // All the strings to write.
    $config_strs = array('mtitle', 'mmessage', 'language', 'mbname', 'boardurl', 'cookiename', 'webmaster_email', 'db_name', 'db_user', 'db_server', 'db_prefix', 'ssi_db_user', 'boarddir', 'sourcedir', 'cachedir');
    // All the numeric variables.
    $config_ints = array();
    // All the checkboxes.
    $config_bools = array('db_persist', 'db_error_send', 'maintenance');
    // Now sort everything into a big array, and figure out arrays and etc.
    $new_settings = array();
    foreach ($config_passwords as $config_var) {
        if (isset($_POST[$config_var][1]) && $_POST[$config_var][0] == $_POST[$config_var][1]) {
            $new_settings[$config_var] = '\'' . addcslashes($_POST[$config_var][0], '\'\\') . '\'';
        }
    }
    foreach ($config_strs as $config_var) {
        if (isset($_POST[$config_var])) {
            $new_settings[$config_var] = '\'' . addcslashes($_POST[$config_var], '\'\\') . '\'';
        }
    }
    foreach ($config_ints as $config_var) {
        if (isset($_POST[$config_var])) {
            $new_settings[$config_var] = (int) $_POST[$config_var];
        }
    }
    foreach ($config_bools as $key) {
        if (!empty($_POST[$key])) {
            $new_settings[$key] = '1';
        } else {
            $new_settings[$key] = '0';
        }
    }
    // Save the relevant settings in the Settings.php file.
    require_once $sourcedir . '/Subs-Admin.php';
    updateSettingsFile($new_settings);
    // Now loopt through the remaining (database-based) settings.
    $new_settings = array();
    foreach ($config_vars as $config_var) {
        // We just saved the file-based settings, so skip their definitions.
        if (!is_array($config_var) || $config_var[2] == 'file') {
            continue;
        }
        // Rewrite the definition a bit.
        $new_settings[] = array($config_var[3], $config_var[0]);
    }
    // Save the new database-based settings, if any.
    if (!empty($new_settings)) {
        saveDBSettings($new_settings);
    }
}
Beispiel #6
0
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 '
				<div class="error_message">
					<div style="color: red;">', $txt['error_mysql_connect'], '</div>
				</div>';
        return doStep2a();
    }
    if (!mysql_select_db($db_name, $db_connection)) {
        echo '
				<div class="error_message">
					<div style="color: red;">', sprintf($txt['error_mysql_database'], $db_name), '</div>
				</div>
				<br />';
        return doStep2a();
    }
    // Let them try again...
    if ($_POST['password1'] != $_POST['password2']) {
        echo '
				<div class="error_message">
					<div style="color: red;">', $txt['error_user_settings_again_match'], '</div>
				</div>
				<br />';
        return doStep2a();
    }
    if (!file_exists($sourcedir . '/Subs.php')) {
        echo '
				<div class="error_message">
					<div style="color: red;">', $txt['error_subs_missing'], '</div>
				</div>
				<br />';
        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("\n\t\t\tSET NAMES {$db_character_set}");
    }
    $result = mysql_query("\n\t\tSELECT ID_MEMBER, passwordSalt\n\t\tFROM {$db_prefix}members\n\t\tWHERE memberName = '{$_POST['username']}' OR emailAddress = '{$_POST['email']}'\n\t\tLIMIT 1");
    if (mysql_num_rows($result) != 0) {
        list($id, $salt) = mysql_fetch_row($result);
        mysql_free_result($result);
        echo '
				<div class="error_message">
					<div style="color: red;">', $txt['error_user_settings_taken'], '</div>
				</div>
				<br />';
    } 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 '
				<div class="error_message">
					<div style="color: red;">', $txt[240], '</div>
				</div>
				<br />';
        // 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 '
				<div class="error_message">
					<div style="color: red;">', sprintf($txt[500], $_POST['username']), '</div>
				</div>
				<br />';
        // 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("\n\t\t\tINSERT INTO {$db_prefix}members\n\t\t\t\t(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)\n\t\t\tVALUES (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 '
				<div class="error_message">
					<div style="color: red;">', $txt['error_user_settings_query'], '</div>

					<div style="margin: 2ex;">', nl2br(htmlspecialchars(mysql_error($db_connection))), '</div>

					<a href="', $_SERVER['PHP_SELF'], '?step=2">', $txt['error_message_click'], '</a> ', $txt['error_message_try_again'], '
				</div>';
            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("\n\t\tSELECT value\n\t\tFROM {$db_prefix}settings\n\t\tWHERE 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("\n\t\t\tINSERT INTO {$db_prefix}sessions\n\t\t\t\t(session_id, last_update, data)\n\t\t\tVALUES ('" . session_id() . "', " . time() . ",\n\t\t\t\t'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("\n\t\tSELECT ID_MSG\n\t\tFROM {$db_prefix}messages\n\t\tWHERE ID_MSG = 1\n\t\t\tAND modifiedTime = 0\n\t\tLIMIT 1");
    if (mysql_num_rows($request) > 0) {
        updateStats('subject', 1, addslashes(htmlspecialchars($txt['default_topic_subject'])));
    }
    mysql_free_result($request);
    echo '
				<div class="panel">
					<h2>', $txt['congratulations'], '</h2>
					<br />
					', $txt['congratulations_help'], '<br />
					<br />';
    if (is_writable(dirname(__FILE__)) && substr(__FILE__, 1, 2) != ':\\') {
        echo '
					<i>', $txt['still_writable'], '</i><br />
					<br />';
    }
    // 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 '
					<div style="margin: 1ex; font-weight: bold;">
						<label for="delete_self"><input type="checkbox" id="delete_self" onclick="doTheDelete();" /> ', $txt['delete_installer'], !isset($_SESSION['installer_temp_ftp']) ? ' ' . $txt['delete_installer_maybe'] : '', '</label>
					</div>
					<script language="JavaScript" type="text/javascript"><!-- // --><![CDATA[
						function doTheDelete()
						{
							var theCheck = document.getElementById ? document.getElementById("delete_self") : document.all.delete_self;
							var tempImage = new Image();

							tempImage.src = "', $_SERVER['PHP_SELF'], '?delete=1&ts=" + (new Date().getTime());
							tempImage.width = 0;
							theCheck.disabled = true;
						}
					// ]]></script>
					<br />';
    }
    echo '
					', sprintf($txt['go_to_your_forum'], $boardurl . '/index.php'), '<br />
					<br />
					', $txt['good_luck'], '
				</div>';
    return true;
}
Beispiel #7
0
                    <div style="margin: 2.5ex; font-family: monospace;"><b>', $mysql_error, '</b></div>

                    <a href="', $_SERVER['PHP_SELF'], '?step=0&amp;overphp=true">', $install_lang['error_message_click'], '</a> ', $install_lang['error_message_try_again'], '
                </div>';
        return false;
    }
    // Let's try that database on for size...
    if ($database != '') {
        mysql_query("\r\n            CREATE DATABASE IF NOT EXISTS `{$database}`", $db_connection);
    }
    // Okay, let's try the prefix if it didn't work...
    if (!mysql_select_db($database, $db_connection) && $database != '') {
        mysql_query("\r\n            CREATE DATABASE IF NOT EXISTS `{$TABLE_PREFIX}{$database}`", $db_connection);
        if (mysql_select_db($TABLE_PREFIX . $database, $db_connection)) {
            $db_name = $TABLE_PREFIX . $db_name;
            updateSettingsFile(array('database' => $database));
        }
    }
    // Okay, now let's try to connect...
    if (!mysql_select_db($database, $db_connection)) {
        echo '
                <div class="error_message">
                    <div style="color: red;">', sprintf($install_lang['error_mysql_database'], $database), '</div>
                    <br />
                    <a href="', $_SERVER['PHP_SELF'], '?step=0&amp;overphp=true">', $install_lang['error_message_click'], '</a> ', $install_lang['error_message_try_again'], '
                </div>';
        return false;
    }
    $replaces = array('{$db_prefix}' => $TABLE_PREFIX);
    foreach ($install_lang as $key => $value) {
        if (substr($key, 0, 8) == 'default_') {
Beispiel #8
0
function show_db_error($loadavg = false)
{
    global $sourcedir, $mbname, $maintenance, $mtitle, $mmessage, $modSettings;
    global $db_connection, $webmaster_email, $db_last_error, $db_error_send, $smcFunc;
    // Don't cache this page!
    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');
    // Send the right error codes.
    header('HTTP/1.1 503 Service Temporarily Unavailable');
    header('Status: 503 Service Temporarily Unavailable');
    header('Retry-After: 3600');
    if ($loadavg == false) {
        // For our purposes, we're gonna want this on if at all possible.
        $modSettings['cache_enable'] = '1';
        if (($temp = cache_get_data('db_last_error', 600)) !== null) {
            $db_last_error = max($db_last_error, $temp);
        }
        if ($db_last_error < time() - 3600 * 24 * 3 && empty($maintenance) && !empty($db_error_send)) {
            require_once $sourcedir . '/Subs-Admin.php';
            // Avoid writing to the Settings.php file if at all possible; use shared memory instead.
            cache_put_data('db_last_error', time(), 600);
            if (($temp = cache_get_data('db_last_error', 600)) === null) {
                updateSettingsFile(array('db_last_error' => time()));
            }
            // Language files aren't loaded yet :(.
            $db_error = @$smcFunc['db_error']($db_connection);
            @mail($webmaster_email, $mbname . ': SMF Database Error!', 'There has been a problem with the database!' . ($db_error == '' ? '' : "\n" . $smcFunc['db_title'] . ' reported:' . "\n" . $db_error) . "\n\n" . 'This is a notice email to let you know that SMF could not connect to the database, contact your host if this continues.');
        }
    }
    if (!empty($maintenance)) {
        echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta name="robots" content="noindex" />
		<title>', $mtitle, '</title>
	</head>
	<body>
		<h3>', $mtitle, '</h3>
		', $mmessage, '
	</body>
</html>';
    } elseif ($loadavg) {
        echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta name="robots" content="noindex" />
		<title>Temporarily Unavailable</title>
	</head>
	<body>
		<h3>Temporarily Unavailable</h3>
		Due to high stress on the server the forum is temporarily unavailable.  Please try again later.
	</body>
</html>';
    } else {
        echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta name="robots" content="noindex" />
		<title>Connection Problems</title>
	</head>
	<body>
		<h3>Connection Problems</h3>
		Sorry, SMF was unable to connect to the database.  This may be caused by the server being busy.  Please try again later.
	</body>
</html>';
    }
    die;
}
Beispiel #9
0
function ModifyCoreSettings2()
{
    global $boarddir, $sc, $cookiename, $modSettings, $user_settings, $sourcedir;
    global $context;
    // Strip the slashes off of the post vars.
    foreach ($_POST as $key => $val) {
        $_POST[$key] = stripslashes__recursive($val);
    }
    // Fix the darn stupid cookiename! (more may not be allowed, but these for sure!)
    if (isset($_POST['cookiename'])) {
        $_POST['cookiename'] = preg_replace('~[,;\\s\\.$]+~' . ($context['utf8'] ? 'u' : ''), '', $_POST['cookiename']);
    }
    // Fix the forum's URL if necessary.
    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'];
    }
    // Any passwords?
    $config_passwords = array('db_passwd');
    // All the strings to write.
    $config_strs = array('mtitle', 'mmessage', 'language', 'mbname', 'boardurl', 'cookiename', 'webmaster_email', 'db_name', 'db_user', 'db_server', 'db_prefix', 'boarddir', 'sourcedir');
    // All the numeric variables.
    $config_ints = array();
    // All the checkboxes.
    $config_bools = array('db_persist', 'db_error_send', 'maintenance');
    // Now sort everything into a big array, and figure out arrays and etc.
    $config_vars = array();
    foreach ($config_passwords as $config_var) {
        if (isset($_POST[$config_var][1]) && $_POST[$config_var][0] == $_POST[$config_var][1]) {
            $config_vars[$config_var] = '\'' . addcslashes($_POST[$config_var][0], "'\\") . '\'';
        }
    }
    foreach ($config_strs as $config_var) {
        if (isset($_POST[$config_var])) {
            $config_vars[$config_var] = '\'' . addcslashes($_POST[$config_var], "'\\") . '\'';
        }
    }
    foreach ($config_ints as $config_var) {
        if (isset($_POST[$config_var])) {
            $config_vars[$config_var] = (int) $_POST[$config_var];
        }
    }
    foreach ($config_bools as $key) {
        if (!empty($_POST[$key])) {
            $config_vars[$key] = '1';
        } else {
            $config_vars[$key] = '0';
        }
    }
    require_once $sourcedir . '/Admin.php';
    updateSettingsFile($config_vars);
    // If the cookie name was changed, reset the cookie.
    if (isset($config_vars['cookiename']) && $cookiename != $_POST['cookiename']) {
        include_once $sourcedir . '/Subs-Auth.php';
        $cookiename = $_POST['cookiename'];
        setLoginCookie(60 * $modSettings['cookieTime'], $user_settings['ID_MEMBER'], sha1($user_settings['passwd'] . $user_settings['passwordSalt']));
        redirectexit('action=serversettings;sa=core;sesc=' . $sc, $context['server']['needs_login_fix']);
    }
    redirectexit('action=serversettings;sa=core;sesc=' . $sc);
}
Beispiel #10
0
/**
 * Edit a particular set of language entries.
 */
function ModifyLanguage()
{
    global $settings, $context, $smcFunc, $txt, $modSettings, $boarddir, $sourcedir, $language;
    loadLanguage('ManageSettings');
    // Select the languages tab.
    $context['menu_data_' . $context['admin_menu_id']]['current_subsection'] = 'edit';
    $context['page_title'] = $txt['edit_languages'];
    $context['sub_template'] = 'modify_language_entries';
    $context['lang_id'] = $_GET['lid'];
    list($theme_id, $file_id) = empty($_REQUEST['tfid']) || strpos($_REQUEST['tfid'], '+') === false ? array(1, '') : explode('+', $_REQUEST['tfid']);
    // Clean the ID - just in case.
    preg_match('~([A-Za-z0-9_-]+)~', $context['lang_id'], $matches);
    $context['lang_id'] = $matches[1];
    // Get all the theme data.
    $request = $smcFunc['db_query']('', '
		SELECT id_theme, variable, value
		FROM {db_prefix}themes
		WHERE id_theme != {int:default_theme}
			AND id_member = {int:no_member}
			AND variable IN ({string:name}, {string:theme_dir})', array('default_theme' => 1, 'no_member' => 0, 'name' => 'name', 'theme_dir' => 'theme_dir'));
    $themes = array(1 => array('name' => $txt['dvc_default'], 'theme_dir' => $settings['default_theme_dir']));
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $themes[$row['id_theme']][$row['variable']] = $row['value'];
    }
    $smcFunc['db_free_result']($request);
    // This will be where we look
    $lang_dirs = array();
    // Check we have themes with a path and a name - just in case - and add the path.
    foreach ($themes as $id => $data) {
        if (count($data) != 2) {
            unset($themes[$id]);
        } elseif (is_dir($data['theme_dir'] . '/languages')) {
            $lang_dirs[$id] = $data['theme_dir'] . '/languages';
        }
        // How about image directories?
        if (is_dir($data['theme_dir'] . '/images/' . $context['lang_id'])) {
            $images_dirs[$id] = $data['theme_dir'] . '/images/' . $context['lang_id'];
        }
    }
    $current_file = $file_id ? $lang_dirs[$theme_id] . '/' . $file_id . '.' . $context['lang_id'] . '.php' : '';
    // Now for every theme get all the files and stick them in context!
    $context['possible_files'] = array();
    foreach ($lang_dirs as $theme => $theme_dir) {
        // Open it up.
        $dir = dir($theme_dir);
        while ($entry = $dir->read()) {
            // We're only after the files for this language.
            if (preg_match('~^([A-Za-z]+)\\.' . $context['lang_id'] . '\\.php$~', $entry, $matches) == 0) {
                continue;
            }
            if (!isset($context['possible_files'][$theme])) {
                $context['possible_files'][$theme] = array('id' => $theme, 'name' => $themes[$theme]['name'], 'files' => array());
            }
            $context['possible_files'][$theme]['files'][] = array('id' => $matches[1], 'name' => isset($txt['lang_file_desc_' . $matches[1]]) ? $txt['lang_file_desc_' . $matches[1]] : $matches[1], 'selected' => $theme_id == $theme && $file_id == $matches[1]);
        }
        $dir->close();
        usort($context['possible_files'][$theme]['files'], create_function('$val1, $val2', 'return strcmp($val1[\'name\'], $val2[\'name\']);'));
    }
    // We no longer wish to speak this language.
    if (!empty($_POST['delete_main']) && $context['lang_id'] != 'english') {
        checkSession();
        validateToken('admin-mlang');
        // @todo Todo: FTP Controls?
        require_once $sourcedir . '/Subs-Package.php';
        // First, Make a backup?
        if (!empty($modSettings['package_make_backups']) && (!isset($_SESSION['last_backup_for']) || $_SESSION['last_backup_for'] != $context['lang_id'] . '$$$')) {
            $_SESSION['last_backup_for'] = $context['lang_id'] . '$$$';
            package_create_backup('backup_lang_' . $context['lang_id']);
        }
        // Second, loop through the array to remove the files.
        foreach ($lang_dirs as $curPath) {
            foreach ($context['possible_files'][1]['files'] as $lang) {
                if (file_exists($curPath . '/' . $lang['id'] . '.' . $context['lang_id'] . '.php')) {
                    unlink($curPath . '/' . $lang['id'] . '.' . $context['lang_id'] . '.php');
                }
            }
            // Check for the email template.
            if (file_exists($curPath . '/EmailTemplates.' . $context['lang_id'] . '.php')) {
                unlink($curPath . '/EmailTemplates.' . $context['lang_id'] . '.php');
            }
        }
        // Third, the agreement file.
        if (file_exists($boarddir . '/agreement.' . $context['lang_id'] . '.txt')) {
            unlink($boarddir . '/agreement.' . $context['lang_id'] . '.txt');
        }
        // Fourth, a related images folder?
        foreach ($images_dirs as $curPath) {
            if (is_dir($curPath)) {
                deltree($curPath);
            }
        }
        // Members can no longer use this language.
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}members
			SET lngfile = {string:empty_string}
			WHERE lngfile = {string:current_language}', array('empty_string' => '', 'current_language' => $context['lang_id']));
        // Fifth, update getLanguages() cache.
        if (!empty($modSettings['cache_enable'])) {
            cache_put_data('known_languages', null, !empty($modSettings['cache_enable']) && $modSettings['cache_enable'] < 1 ? 86400 : 3600);
            cache_put_data('known_languages_all', null, !empty($modSettings['cache_enable']) && $modSettings['cache_enable'] < 1 ? 86400 : 3600);
        }
        // Sixth, if we deleted the default language, set us back to english?
        if ($context['lang_id'] == $language) {
            require_once $sourcedir . '/Subs-Admin.php';
            $language = 'english';
            updateSettingsFile(array('language' => '\'' . $language . '\''));
        }
        // Seventh, get out of here.
        redirectexit('action=admin;area=languages;sa=edit;' . $context['session_var'] . '=' . $context['session_id']);
    }
    // Saving primary settings?
    $madeSave = false;
    if (!empty($_POST['save_main']) && !$current_file) {
        checkSession();
        validateToken('admin-mlang');
        // Read in the current file.
        $current_data = implode('', file($settings['default_theme_dir'] . '/languages/index.' . $context['lang_id'] . '.php'));
        // These are the replacements. old => new
        $replace_array = array('~\\$txt\\[\'lang_character_set\'\\]\\s=\\s(\'|")[^\\r\\n]+~' => '$txt[\'lang_character_set\'] = \'' . addslashes($_POST['character_set']) . '\';', '~\\$txt\\[\'lang_locale\'\\]\\s=\\s(\'|")[^\\r\\n]+~' => '$txt[\'lang_locale\'] = \'' . addslashes($_POST['locale']) . '\';', '~\\$txt\\[\'lang_dictionary\'\\]\\s=\\s(\'|")[^\\r\\n]+~' => '$txt[\'lang_dictionary\'] = \'' . addslashes($_POST['dictionary']) . '\';', '~\\$txt\\[\'lang_spelling\'\\]\\s=\\s(\'|")[^\\r\\n]+~' => '$txt[\'lang_spelling\'] = \'' . addslashes($_POST['spelling']) . '\';', '~\\$txt\\[\'lang_rtl\'\\]\\s=\\s[A-Za-z0-9]+;~' => '$txt[\'lang_rtl\'] = ' . (!empty($_POST['rtl']) ? 'true' : 'false') . ';');
        $current_data = preg_replace(array_keys($replace_array), array_values($replace_array), $current_data);
        $fp = fopen($settings['default_theme_dir'] . '/languages/index.' . $context['lang_id'] . '.php', 'w+');
        fwrite($fp, $current_data);
        fclose($fp);
        $madeSave = true;
    }
    // Quickly load index language entries.
    $old_txt = $txt;
    require $settings['default_theme_dir'] . '/languages/index.' . $context['lang_id'] . '.php';
    $context['lang_file_not_writable_message'] = is_writable($settings['default_theme_dir'] . '/languages/index.' . $context['lang_id'] . '.php') ? '' : sprintf($txt['lang_file_not_writable'], $settings['default_theme_dir'] . '/languages/index.' . $context['lang_id'] . '.php');
    // Setup the primary settings context.
    $context['primary_settings'] = array('name' => $smcFunc['ucwords'](strtr($context['lang_id'], array('_' => ' ', '-utf8' => ''))), 'character_set' => $txt['lang_character_set'], 'locale' => $txt['lang_locale'], 'dictionary' => $txt['lang_dictionary'], 'spelling' => $txt['lang_spelling'], 'rtl' => $txt['lang_rtl']);
    // Restore normal service.
    $txt = $old_txt;
    // Are we saving?
    $save_strings = array();
    if (isset($_POST['save_entries']) && !empty($_POST['entry'])) {
        checkSession();
        validateToken('admin-mlang');
        // Clean each entry!
        foreach ($_POST['entry'] as $k => $v) {
            // Only try to save if it's changed!
            if ($_POST['entry'][$k] != $_POST['comp'][$k]) {
                $save_strings[$k] = cleanLangString($v, false);
            }
        }
    }
    // If we are editing a file work away at that.
    if ($current_file) {
        $context['entries_not_writable_message'] = is_writable($current_file) ? '' : sprintf($txt['lang_entries_not_writable'], $current_file);
        $entries = array();
        // We can't just require it I'm afraid - otherwise we pass in all kinds of variables!
        $multiline_cache = '';
        foreach (file($current_file) as $line) {
            // Got a new entry?
            if ($line[0] == '$' && !empty($multiline_cache)) {
                preg_match('~\\$(helptxt|txt|editortxt)\\[\'(.+)\'\\]\\s?=\\s?(.+);~ms', strtr($multiline_cache, array("\r" => '')), $matches);
                if (!empty($matches[3])) {
                    $entries[$matches[2]] = array('type' => $matches[1], 'full' => $matches[0], 'entry' => $matches[3]);
                    $multiline_cache = '';
                }
            }
            $multiline_cache .= $line;
        }
        // Last entry to add?
        if ($multiline_cache) {
            preg_match('~\\$(helptxt|txt|editortxt)\\[\'(.+)\'\\]\\s?=\\s?(.+);~ms', strtr($multiline_cache, array("\r" => '')), $matches);
            if (!empty($matches[3])) {
                $entries[$matches[2]] = array('type' => $matches[1], 'full' => $matches[0], 'entry' => $matches[3]);
            }
        }
        // These are the entries we can definitely save.
        $final_saves = array();
        $context['file_entries'] = array();
        foreach ($entries as $entryKey => $entryValue) {
            // Ignore some things we set separately.
            $ignore_files = array('lang_character_set', 'lang_locale', 'lang_dictionary', 'lang_spelling', 'lang_rtl');
            if (in_array($entryKey, $ignore_files)) {
                continue;
            }
            // These are arrays that need breaking out.
            $arrays = array('days', 'days_short', 'months', 'months_titles', 'months_short', 'happy_birthday_author', 'karlbenson1_author', 'nite0859_author', 'zwaldowski_author', 'geezmo_author', 'karlbenson2_author');
            if (in_array($entryKey, $arrays)) {
                // Get off the first bits.
                $entryValue['entry'] = substr($entryValue['entry'], strpos($entryValue['entry'], '(') + 1, strrpos($entryValue['entry'], ')') - strpos($entryValue['entry'], '('));
                $entryValue['entry'] = explode(',', strtr($entryValue['entry'], array(' ' => '')));
                // Now create an entry for each item.
                $cur_index = 0;
                $save_cache = array('enabled' => false, 'entries' => array());
                foreach ($entryValue['entry'] as $id => $subValue) {
                    // Is this a new index?
                    if (preg_match('~^(\\d+)~', $subValue, $matches)) {
                        $cur_index = $matches[1];
                        $subValue = substr($subValue, strpos($subValue, '\''));
                    }
                    // Clean up some bits.
                    $subValue = strtr($subValue, array('"' => '', '\'' => '', ')' => ''));
                    // Can we save?
                    if (isset($save_strings[$entryKey . '-+- ' . $cur_index])) {
                        $save_cache['entries'][$cur_index] = strtr($save_strings[$entryKey . '-+- ' . $cur_index], array('\'' => ''));
                        $save_cache['enabled'] = true;
                    } else {
                        $save_cache['entries'][$cur_index] = $subValue;
                    }
                    $context['file_entries'][] = array('key' => $entryKey . '-+- ' . $cur_index, 'value' => $subValue, 'rows' => 1);
                    $cur_index++;
                }
                // Do we need to save?
                if ($save_cache['enabled']) {
                    // Format the string, checking the indexes first.
                    $items = array();
                    $cur_index = 0;
                    foreach ($save_cache['entries'] as $k2 => $v2) {
                        // Manually show the custom index.
                        if ($k2 != $cur_index) {
                            $items[] = $k2 . ' => \'' . $v2 . '\'';
                            $cur_index = $k2;
                        } else {
                            $items[] = '\'' . $v2 . '\'';
                        }
                        $cur_index++;
                    }
                    // Now create the string!
                    $final_saves[$entryKey] = array('find' => $entryValue['full'], 'replace' => '$' . $entryValue['type'] . '[\'' . $entryKey . '\'] = array(' . implode(', ', $items) . ');');
                }
            } else {
                // Saving?
                if (isset($save_strings[$entryKey]) && $save_strings[$entryKey] != $entryValue['entry']) {
                    // @todo Fix this properly.
                    if ($save_strings[$entryKey] == '') {
                        $save_strings[$entryKey] = '\'\'';
                    }
                    // Set the new value.
                    $entryValue['entry'] = $save_strings[$entryKey];
                    // And we know what to save now!
                    $final_saves[$entryKey] = array('find' => $entryValue['full'], 'replace' => '$' . $entryValue['type'] . '[\'' . $entryKey . '\'] = ' . $save_strings[$entryKey] . ';');
                }
                $editing_string = cleanLangString($entryValue['entry'], true);
                $context['file_entries'][] = array('key' => $entryKey, 'value' => $editing_string, 'rows' => (int) (strlen($editing_string) / 38) + substr_count($editing_string, "\n") + 1);
            }
        }
        // Any saves to make?
        if (!empty($final_saves)) {
            checkSession();
            $file_contents = implode('', file($current_file));
            foreach ($final_saves as $save) {
                $file_contents = strtr($file_contents, array($save['find'] => $save['replace']));
            }
            // Save the actual changes.
            $fp = fopen($current_file, 'w+');
            fwrite($fp, strtr($file_contents, array("\r" => '')));
            fclose($fp);
            $madeSave = true;
        }
        // Another restore.
        $txt = $old_txt;
    }
    // If we saved, redirect.
    if ($madeSave) {
        redirectexit('action=admin;area=languages;sa=editlang;lid=' . $context['lang_id']);
    }
    createToken('admin-mlang');
}