' . fread($config_fd, filesize('./config.inc.php'))); fclose($config_fd); // Eval failed if ($result === FALSE || !isset($cfg['Servers'])) { // Creates fake settings $cfg = array('DefaultLang' => 'en-iso-8859-1', 'AllowAnywhereRecoding' => FALSE); // Loads the language file require_once('./libraries/select_lang.lib.php'); // Displays the error message // (do not use & for parameters sent by header) header( 'Location: error.php' . '?lang=' . urlencode( $available_languages[$lang][2] ) . '&char=' . urlencode( $charset ) . '&dir=' . urlencode( $text_dir ) . '&type=' . urlencode( $strError ) . '&error=' . urlencode( strtr( $strConfigFileError, array( '
' => '[br]' ) ) . '[br][br]' . '[a@./config.inc.php@_blank]config.inc.php[/a]' ) . '&' . SID ); exit(); } error_reporting($old_error_reporting); unset($old_error_reporting); } /** * Includes the language file if it hasn't been included yet */ require_once('./libraries/select_lang.lib.php'); /** * Servers array fixups. */ // Do we have some server? if (!isset($cfg['Servers']) || count($cfg['Servers']) == 0) { // No server => create one with defaults $cfg['Servers'] = array(1 => $default_server); } else { // We have server(s) => apply default config $new_servers = array(); foreach($cfg['Servers'] as $key => $val) { if (!is_int($key) || $key < 1) { // Show error header( 'Location: error.php' . '?lang=' . urlencode( $available_languages[$lang][2] ) . '&char=' . urlencode( $charset ) . '&dir=' . urlencode( $text_dir ) . '&type=' . urlencode( $strError ) . '&error=' . urlencode( // FIXME: We could translate this message, however it's translations freeze right now: sprintf( 'Invalid server index: "%s"', $key)) . '&' . SID ); } $new_servers[$key] = array_merge($default_server, $val); } $cfg['Servers'] = $new_servers; unset($new_servers); } // Cleanup unset($default_server); /** * We really need this one! */ if (!function_exists('preg_replace')) { header( 'Location: error.php' . '?lang=' . urlencode( $available_languages[$lang][2] ) . '&char=' . urlencode( $charset ) . '&dir=' . urlencode( $text_dir ) . '&type=' . urlencode( $strError ) . '&error=' . urlencode( strtr( sprintf( $strCantLoad, 'pcre' ), array('
' => '[br]') ) ) . '&' . SID ); exit(); } /** * Gets constants that defines the PHP version number. * This include must be located physically before any code that needs to * reference the constants, else PHP 3.0.16 won't be happy. */ require_once('./libraries/defines.lib.php'); /* Input sanitizing */ require_once('./libraries/sanitizing.lib.php'); // XSS if (isset($convcharset)) { $convcharset = PMA_sanitize($convcharset); } if ($is_minimum_common == FALSE) { /** * Define $is_upload */ $is_upload = TRUE; if (strtolower(@ini_get('file_uploads')) == 'off' || @ini_get('file_uploads') == 0) { $is_upload = FALSE; } /** * Maximum upload size as limited by PHP * Used with permission from Moodle (http://moodle.org) by Martin Dougiamas * * this section generates $max_upload_size in bytes */ function get_real_size($size=0) { /// Converts numbers like 10M into bytes if (!$size) { return 0; } $scan['MB'] = 1048576; $scan['Mb'] = 1048576; $scan['M'] = 1048576; $scan['m'] = 1048576; $scan['KB'] = 1024; $scan['Kb'] = 1024; $scan['K'] = 1024; $scan['k'] = 1024; while (list($key) = each($scan)) { if ((strlen($size)>strlen($key))&&(substr($size, strlen($size) - strlen($key))==$key)) { $size = substr($size, 0, strlen($size) - strlen($key)) * $scan[$key]; break; } } return $size; } // end function if (!$filesize = ini_get('upload_max_filesize')) { $filesize = "5M"; } $max_upload_size = get_real_size($filesize); if ($postsize = ini_get('post_max_size')) { $postsize = get_real_size($postsize); if ($postsize < $max_upload_size) { $max_upload_size = $postsize; } } unset($filesize); unset($postsize); /** * other functions for maximum upload work */ /** * Displays the maximum size for an upload * * @param integer the size * * @return string the message * * @access public */ function PMA_displayMaximumUploadSize($max_upload_size) { list($max_size, $max_unit) = PMA_formatByteDown($max_upload_size); return '(' . sprintf($GLOBALS['strMaximumSize'], $max_size, $max_unit) . ')'; } /** * Generates a hidden field which should indicate to the browser * the maximum size for upload * * @param integer the size * * @return string the INPUT field * * @access public */ function PMA_generateHiddenMaxFileSize($max_size){ return ''; } /** * Charset conversion. */ require_once('./libraries/charset_conversion.lib.php'); /** * String handling */ require_once('./libraries/string.lib.php'); } /** * Removes insecure parts in a path; used before include() or * require() when a part of the path comes from an insecure source * like a cookie or form. * * @param string The path to check * * @return string The secured path * * @access public * @author Marc Delisle (lem9@users.sourceforge.net) */ function PMA_securePath($path) { // change .. to . $path = preg_replace('@\.\.*@','.',$path); return $path; } // end function // If zlib output compression is set in the php configuration file, no // output buffering should be run if (@ini_get('zlib.output_compression')) { $cfg['OBGzip'] = FALSE; } // disable output-buffering (if set to 'auto') for IE6, else enable it. if (strtolower($cfg['OBGzip']) == 'auto') { if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER >= 6 && PMA_USR_BROWSER_VER < 7) { $cfg['OBGzip'] = FALSE; } else { $cfg['OBGzip'] = TRUE; } } /* Theme Manager * 2004-05-20 Michael Keck (mail_at_michaelkeck_dot_de) * This little script checks if there're themes available * and if the directory $ThemePath/$theme/img/ exists * If not, it will use default images */ // Allow different theme per server $theme_cookie_name = 'pma_theme'; if ($GLOBALS['cfg']['ThemePerServer'] && isset($server)) { $theme_cookie_name .= '-' . $server; } //echo $theme_cookie_name; // Theme Manager if (!$cfg['ThemeManager'] || !isset($_COOKIE[$theme_cookie_name]) || empty($_COOKIE[$theme_cookie_name])){ $GLOBALS['theme'] = $cfg['ThemeDefault']; $ThemeDefaultOk = FALSE; if ($cfg['ThemePath']!='' && $cfg['ThemePath'] != FALSE) { $tmp_theme_mainpath = $cfg['ThemePath']; $tmp_theme_fullpath = $cfg['ThemePath'] . '/' .$cfg['ThemeDefault']; if (@is_dir($tmp_theme_mainpath)) { if (isset($cfg['ThemeDefault']) && @is_dir($tmp_theme_fullpath)) { $ThemeDefaultOk = TRUE; } } } if ($ThemeDefaultOk == TRUE){ $GLOBALS['theme'] = $cfg['ThemeDefault']; } else { $GLOBALS['theme'] = 'original'; } } else { // if we just changed theme, we must take the new one so that // index.php takes the correct one for height computing if (isset($_POST['set_theme'])) { $GLOBALS['theme'] = PMA_securePath($_POST['set_theme']); } else { $GLOBALS['theme'] = PMA_securePath($_COOKIE[$theme_cookie_name]); } } // check for theme requires/name unset($theme_name, $theme_generation, $theme_version); @include($cfg['ThemePath'] . '/' . $GLOBALS['theme'] . '/info.inc.php'); // did it set correctly? if (!isset($theme_name, $theme_generation, $theme_version)) { $GLOBALS['theme'] = 'original'; // invalid theme } elseif ($theme_generation != PMA_THEME_GENERATION) { $GLOBALS['theme'] = 'original'; // different generation } elseif ($theme_version < PMA_THEME_VERSION) { $GLOBALS['theme'] = 'original'; // too old version } $pmaThemeImage = $cfg['ThemePath'] . '/' . $GLOBALS['theme'] . '/img/'; $tmp_layout_file = $cfg['ThemePath'] . '/' . $GLOBALS['theme'] . '/layout.inc.php'; if (@file_exists($tmp_layout_file)) { include($tmp_layout_file); } if (!is_dir($pmaThemeImage)) { $pmaThemeImage = $cfg['ThemePath'] . '/original/img/'; } // end theme manager /** * collation_connection */ // (could be improved by executing it after the MySQL connection only if // PMA_MYSQL_INT_VERSION >= 40100 ) if (isset($_COOKIE) && !empty($_COOKIE['pma_collation_connection']) && empty($_POST['collation_connection'])) { $collation_connection = $_COOKIE['pma_collation_connection']; } if ($is_minimum_common == FALSE) { /** * Include URL/hidden inputs generating. */ require_once('./libraries/url_generating.lib.php'); /** * Add slashes before "'" and "\" characters so a value containing them can * be used in a sql comparison. * * @param string the string to slash * @param boolean whether the string will be used in a 'LIKE' clause * (it then requires two more escaped sequences) or not * @param boolean whether to treat cr/lfs as escape-worthy entities * (converts \n to \\n, \r to \\r) * * @param boolean whether this function is used as part of the * "Create PHP code" dialog * * @return string the slashed string * * @access public */ function PMA_sqlAddslashes($a_string = '', $is_like = FALSE, $crlf = FALSE, $php_code = FALSE) { if ($is_like) { $a_string = str_replace('\\', '\\\\\\\\', $a_string); } else { $a_string = str_replace('\\', '\\\\', $a_string); } if ($crlf) { $a_string = str_replace("\n", '\n', $a_string); $a_string = str_replace("\r", '\r', $a_string); $a_string = str_replace("\t", '\t', $a_string); } if ($php_code) { $a_string = str_replace('\'', '\\\'', $a_string); } else { $a_string = str_replace('\'', '\'\'', $a_string); } return $a_string; } // end of the 'PMA_sqlAddslashes()' function /** * Add slashes before "_" and "%" characters for using them in MySQL * database, table and field names. * Note: This function does not escape backslashes! * * @param string the string to escape * * @return string the escaped string * * @access public */ function PMA_escape_mysql_wildcards($name) { $name = str_replace('_', '\\_', $name); $name = str_replace('%', '\\%', $name); return $name; } // end of the 'PMA_escape_mysql_wildcards()' function /** * removes slashes before "_" and "%" characters * Note: This function does not unescape backslashes! * * @param string $name the string to escape * @return string the escaped string * @access public */ function PMA_unescape_mysql_wildcards( $name ) { $name = str_replace('\\_', '_', $name); $name = str_replace('\\%', '%', $name); return $name; } // end of the 'PMA_unescape_mysql_wildcards()' function /** * format sql strings * * @param mixed pre-parsed SQL structure * * @return string the formatted sql * * @global array the configuration array * @global boolean whether the current statement is a multiple one or not * * @access public * * @author Robin Johnson */ function PMA_formatSql($parsed_sql, $unparsed_sql = '') { global $cfg; // Check that we actually have a valid set of parsed data // well, not quite // first check for the SQL parser having hit an error if (PMA_SQP_isError()) { return $parsed_sql; } // then check for an array if (!is_array($parsed_sql)) { // We don't so just return the input directly // This is intended to be used for when the SQL Parser is turned off $formatted_sql = '
' . "\n"
                            . (($cfg['SQP']['fmtType'] == 'none' && $unparsed_sql != '') ? $unparsed_sql : $parsed_sql) . "\n"
                            . '
'; return $formatted_sql; } $formatted_sql = ''; switch ($cfg['SQP']['fmtType']) { case 'none': if ($unparsed_sql != '') { $formatted_sql = "
\n" . PMA_SQP_formatNone(array('raw' => $unparsed_sql)) . "\n
"; } else { $formatted_sql = PMA_SQP_formatNone($parsed_sql); } break; case 'html': $formatted_sql = PMA_SQP_formatHtml($parsed_sql,'color'); break; case 'text': //$formatted_sql = PMA_SQP_formatText($parsed_sql); $formatted_sql = PMA_SQP_formatHtml($parsed_sql,'text'); break; default: break; } // end switch return $formatted_sql; } // end of the "PMA_formatSql()" function /** * Displays a link to the official MySQL documentation * * @param string chapter of "HTML, one page per chapter" documentation * @param string contains name of page/anchor that is being linked * @param bool whether to use big icon (like in left frame) * * @return string the html link * * @access public */ function PMA_showMySQLDocu($chapter, $link, $big_icon = FALSE) { global $cfg; if ($cfg['MySQLManualType'] == 'none' || empty($cfg['MySQLManualBase'])) return ''; // Fixup for newly used names: $chapter = str_replace('_', '-', strtolower($chapter)); $link = str_replace('_', '-', strtolower($link)); switch ($cfg['MySQLManualType']) { case 'chapters': if (empty($chapter)) $chapter = 'index'; $url = $cfg['MySQLManualBase'] . '/' . $chapter . '.html#' . $link; break; case 'big': $url = $cfg['MySQLManualBase'] . '#' . $link; break; case 'searchable': if (empty($link)) $link = 'index'; $url = $cfg['MySQLManualBase'] . '/' . $link . '.html'; break; case 'viewable': default: if (empty($link)) $link = 'index'; $mysql = '4.1'; if (PMA_MYSQL_INT_VERSION > 50100) { $mysql = '5.1'; } elseif (PMA_MYSQL_INT_VERSION > 50000) { $mysql = '5.0'; } $url = $cfg['MySQLManualBase'] . '/' . $mysql . '/en/' . $link . '.html'; break; } if ($big_icon) { return '' . $GLOBALS['strDocu'] . ''; } elseif ($GLOBALS['cfg']['ReplaceHelpImg']) { return '' . $GLOBALS['strDocu'] . ''; }else{ return '[' . $GLOBALS['strDocu'] . ']'; } } // end of the 'PMA_showMySQLDocu()' function /** * Displays a hint icon, on mouse over show the hint * * @param string the error message * * @access public */ function PMA_showHint($hint_message) { //return '' . $hint_message . ''; return 'Tip'; } /** * Displays a MySQL error message in the right frame. * * @param string the error message * @param string the sql query that failed * @param boolean whether to show a "modify" link or not * @param string the "back" link url (full path is not required) * @param boolean EXIT the page? * * @global array the configuration array * * @access public */ function PMA_mysqlDie($error_message = '', $the_query = '', $is_modify_link = TRUE, $back_url = '', $exit = TRUE) { global $cfg, $table, $db, $sql_query; require_once('./header.inc.php'); if (!$error_message) { $error_message = PMA_DBI_getError(); } if (!$the_query && !empty($GLOBALS['sql_query'])) { $the_query = $GLOBALS['sql_query']; } // --- Added to solve bug #641765 // Robbat2 - 12 January 2003, 9:46PM // Revised, Robbat2 - 13 January 2003, 2:59PM if (!function_exists('PMA_SQP_isError') || PMA_SQP_isError()) { $formatted_sql = htmlspecialchars($the_query); } elseif (empty($the_query) || trim($the_query) == '') { $formatted_sql = ''; } else { $formatted_sql = PMA_formatSql(PMA_SQP_parse($the_query), $the_query); } // --- echo "\n" . '' . "\n"; echo '

' . $GLOBALS['strError'] . '

' . "\n"; // if the config password is wrong, or the MySQL server does not // respond, do not show the query that would reveal the // username/password if (!empty($the_query) && !strstr($the_query, 'connect')) { // --- Added to solve bug #641765 // Robbat2 - 12 January 2003, 9:46PM // Revised, Robbat2 - 13 January 2003, 2:59PM if (function_exists('PMA_SQP_isError') && PMA_SQP_isError()) { echo PMA_SQP_getErrorString() . "\n"; echo '
' . "\n"; } // --- // modified to show me the help on sql errors (Michael Keck) echo '

' . $GLOBALS['strSQLQuery'] . ':' . "\n"; if (strstr(strtolower($formatted_sql),'select')) { // please show me help to the error on select echo PMA_showMySQLDocu('SQL-Syntax', 'SELECT'); } if ($is_modify_link && isset($db)) { if (isset($table)) { $doedit_goto = ''; } else { $doedit_goto = ''; } if ($GLOBALS['cfg']['PropertiesIconic']) { echo $doedit_goto . '' . $GLOBALS['strEdit'] .'' . ''; } else { echo ' [' . $doedit_goto . $GLOBALS['strEdit'] . '' . ']' . "\n"; } } // end if echo '

' . "\n" .'

' . "\n" .' ' . $formatted_sql . "\n" .'

' . "\n"; } // end if $tmp_mysql_error = ''; // for saving the original $error_message if (!empty($error_message)) { $tmp_mysql_error = strtolower($error_message); // save the original $error_message $error_message = htmlspecialchars($error_message); $error_message = preg_replace("@((\015\012)|(\015)|(\012)){3,}@", "\n\n", $error_message); } // modified to show me the help on error-returns (Michael Keck) echo '

' . "\n" . ' ' . $GLOBALS['strMySQLSaid'] . '' . PMA_showMySQLDocu('Error-returns', 'Error-returns') . "\n" . '

' . "\n"; // The error message will be displayed within a CODE segment. // To preserve original formatting, but allow wordwrapping, we do a couple of replacements // Replace all non-single blanks with their HTML-counterpart $error_message = str_replace(' ', '  ', $error_message); // Replace TAB-characters with their HTML-counterpart $error_message = str_replace("\t", '    ', $error_message); // Replace linebreaks $error_message = nl2br($error_message); echo '' . "\n" . $error_message . "\n" . '
' . "\n"; // feature request #1036254: // Add a link by MySQL-Error #1062 - Duplicate entry // 2004-10-20 by mkkeck // 2005-01-17 modified by mkkeck bugfix if (substr($error_message, 1, 4) == '1062') { // get the duplicate entry // get table name preg_match( '°ALTER\sTABLE\s\`([^\`]+)\`°iu', $the_query, $error_table = array() ); $error_table = $error_table[1]; // get fields preg_match( '°\(([^\)]+)\)°i', $the_query, $error_fields = array() ); $error_fields = explode( ',', $error_fields[1] ); // duplicate value preg_match( '°\'([^\']+)\'°i', $tmp_mysql_error, $duplicate_value = array() ); $duplicate_value = $duplicate_value[1]; $sql = ' SELECT * FROM ' . PMA_backquote( $error_table ) . ' WHERE CONCAT_WS( "-", ' . implode( ', ', $error_fields ) . ' ) = "' . PMA_sqlAddslashes( $duplicate_value ) . '" ORDER BY ' . implode( ', ', $error_fields ); unset( $error_table, $error_fields, $duplicate_value ); echo '
' ."\n" .' ' . "\n" .' ' . PMA_generate_common_hidden_inputs($db, $table) . "\n" .' ' . "\n" .'
' . "\n"; unset( $sql ); } // end of show duplicate entry echo '
'; echo '
'; if (!empty($back_url) && $exit) { $goto_back_url=''; echo '[ ' . $goto_back_url . $GLOBALS['strBack'] . ' ]'; } echo '
' . "\n\n"; if ($exit) { require_once('./footer.inc.php'); } } // end of the 'PMA_mysqlDie()' function /** * Defines whether a string exists inside an array or not * * @param string string to search for * @param mixed array to search into * * @return integer the rank of the $toFind string in the array or '-1' if * it hasn't been found * * @access public */ function PMA_isInto($toFind = '', &$in) { $max = count($in); for ($i = 0; $i < $max && ($toFind != $in[$i]); $i++) { // void(); } return ($i < $max) ? $i : -1; } // end of the 'PMA_isInto()' function /** * Returns a string formatted with CONVERT ... USING * if MySQL supports it * * @param string the string itself * @param string the mode: quoted or unquoted (this one by default) * * @return the formatted string * * @access private */ function PMA_convert_using($string, $mode='unquoted') { if ($mode == 'quoted') { $possible_quote = "'"; } else { $possible_quote = ""; } if (PMA_MYSQL_INT_VERSION >= 40100) { list($conn_charset) = explode('_', $GLOBALS['collation_connection']); $converted_string = "CONVERT(" . $possible_quote . $string . $possible_quote . " USING " . $conn_charset . ")"; } else { $converted_string = $possible_quote . $string . $possible_quote; } return $converted_string; } // end function } /** * returns array with dbs grouped with extended infos * * @uses $GLOBALS['dblist'] from PMA_availableDatabases() * @uses $GLOBALS['num_dbs'] from PMA_availableDatabases() * @uses $GLOBALS['cfgRelation']['commwork'] * @uses $GLOBALS['cfg']['ShowTooltip'] * @uses $GLOBALS['cfg']['LeftFrameDBTree'] * @uses $GLOBALS['cfg']['LeftFrameDBSeparator'] * @uses $GLOBALS['cfg']['ShowTooltipAliasDB'] * @uses PMA_availableDatabases() * @uses PMA_getTableCount() * @uses PMA_getComments() * @uses PMA_availableDatabases() * @uses is_array() * @uses implode() * @uses strstr() * @uses explode() * @return array db list */ function PMA_getDbList() { if ( empty( $GLOBALS['dblist'] ) ) { PMA_availableDatabases(); } $dblist = $GLOBALS['dblist']; $dbgroups = array(); $parts = array(); foreach ( $dblist as $key => $db ) { // garvin: Get comments from PMA comments table $db_tooltip = ''; if ( $GLOBALS['cfg']['ShowTooltip'] && $GLOBALS['cfgRelation']['commwork'] ) { $_db_tooltip = PMA_getComments( $db ); if ( is_array( $_db_tooltip ) ) { $db_tooltip = implode( ' ', $_db_tooltip ); } } if ( $GLOBALS['cfg']['LeftFrameDBTree'] && $GLOBALS['cfg']['LeftFrameDBSeparator'] && strstr( $db, $GLOBALS['cfg']['LeftFrameDBSeparator'] ) ) { $pos = strrpos($db, $GLOBALS['cfg']['LeftFrameDBSeparator']); $group = substr($db, 0, $pos); $disp_name_cut = substr($db, $pos); } else { $group = $db; $disp_name_cut = $db; } $disp_name = $db; if ( $db_tooltip && $GLOBALS['cfg']['ShowTooltipAliasDB'] ) { $disp_name = $db_tooltip; $disp_name_cut = $db_tooltip; $db_tooltip = $db; } $dbgroups[$group][$db] = array( 'name' => $db, 'disp_name_cut' => $disp_name_cut, 'disp_name' => $disp_name, 'comment' => $db_tooltip, 'num_tables' => PMA_getTableCount( $db ), ); } // end foreach ( $dblist as $db ) return $dbgroups; } /** * returns html code for select form element with dbs * * @return string html code select */ function PMA_getHtmlSelectDb( $selected = '' ) { $dblist = PMA_getDbList(); // TODO: IE can not handle different text directions in select boxes // so, as mostly names will be in english, we set the whole selectbox to LTR // and EN $return = ''; return $return; } /** * returns count of tables in given db * * @param string $db database to count tables for * @return integer count of tables in $db */ function PMA_getTableCount( $db ) { $tables = PMA_DBI_try_query( 'SHOW TABLES FROM ' . PMA_backquote( $db ) . ';', NULL, PMA_DBI_QUERY_STORE); if ( $tables ) { $num_tables = PMA_DBI_num_rows( $tables ); PMA_DBI_free_result( $tables ); } else { $num_tables = 0; } return $num_tables; } /** * Get the complete list of Databases a user can access * * @param boolean whether to include check on failed 'only_db' operations * @param resource database handle (superuser) * @param integer amount of databases inside the 'only_db' container * @param resource possible resource from a failed previous query * @param resource database handle (user) * @param array configuration * @param array previous list of databases * * @return array all databases a user has access to * * @access private */ function PMA_safe_db_list($only_db_check, $dbh, $dblist_cnt, $rs, $userlink, $cfg, $dblist) { if ($only_db_check == FALSE) { // try to get the available dbs list // use userlink by default $dblist = PMA_DBI_get_dblist(); $dblist_cnt = count($dblist); // did not work so check for available databases in the "mysql" db; // I don't think we can fall here now... if (!$dblist_cnt) { $auth_query = 'SELECT User, Select_priv ' . 'FROM mysql.user ' . 'WHERE User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\''; $rs = PMA_DBI_try_query($auth_query, $dbh); } // end } // Access to "mysql" db allowed and dblist still empty -> gets the // usable db list if (!$dblist_cnt && ($rs && @PMA_DBI_num_rows($rs))) { $row = PMA_DBI_fetch_assoc($rs); PMA_DBI_free_result($rs); // Correction uva 19991215 // Previous code assumed database "mysql" admin table "db" column // "db" contains literal name of user database, and works if so. // Mysql usage generally (and uva usage specifically) allows this // column to contain regular expressions (we have all databases // owned by a given student/faculty/staff beginning with user i.d. // and governed by default by a single set of privileges with // regular expression as key). This breaks previous code. // This maintenance is to fix code to work correctly for regular // expressions. if ($row['Select_priv'] != 'Y') { // 1. get allowed dbs from the "mysql.db" table // lem9: User can be blank (anonymous user) $local_query = 'SELECT DISTINCT Db FROM mysql.db WHERE Select_priv = \'Y\' AND (User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\' OR User = \'\')'; $rs = PMA_DBI_try_query($local_query, $dbh); if ($rs && @PMA_DBI_num_rows($rs)) { // Will use as associative array of the following 2 code // lines: // the 1st is the only line intact from before // correction, // the 2nd replaces $dblist[] = $row['Db']; $uva_mydbs = array(); // Code following those 2 lines in correction continues // populating $dblist[], as previous code did. But it is // now populated with actual database names instead of // with regular expressions. while ($row = PMA_DBI_fetch_assoc($rs)) { // loic1: all databases cases - part 1 if (empty($row['Db']) || $row['Db'] == '%') { $uva_mydbs['%'] = 1; break; } // loic1: avoid multiple entries for dbs if (!isset($uva_mydbs[$row['Db']])) { $uva_mydbs[$row['Db']] = 1; } } // end while PMA_DBI_free_result($rs); $uva_alldbs = PMA_DBI_query('SHOW DATABASES;', $GLOBALS['dbh']); // loic1: all databases cases - part 2 if (isset($uva_mydbs['%'])) { while ($uva_row = PMA_DBI_fetch_row($uva_alldbs)) { $dblist[] = $uva_row[0]; } // end while } // end if else { while ($uva_row = PMA_DBI_fetch_row($uva_alldbs)) { $uva_db = $uva_row[0]; if (isset($uva_mydbs[$uva_db]) && $uva_mydbs[$uva_db] == 1) { $dblist[] = $uva_db; $uva_mydbs[$uva_db] = 0; } else if (!isset($dblist[$uva_db])) { foreach ($uva_mydbs AS $uva_matchpattern => $uva_value) { // loic1: fixed bad regexp // TODO: db names may contain characters // that are regexp instructions $re = '(^|(\\\\\\\\)+|[^\])'; $uva_regex = ereg_replace($re . '%', '\\1.*', ereg_replace($re . '_', '\\1.{1}', $uva_matchpattern)); // Fixed db name matching // 2000-08-28 -- Benjamin Gandon if (ereg('^' . $uva_regex . '$', $uva_db)) { $dblist[] = $uva_db; break; } } // end while } // end if ... else if.... } // end while } // end else PMA_DBI_free_result($uva_alldbs); unset($uva_mydbs); } // end if // 2. get allowed dbs from the "mysql.tables_priv" table $local_query = 'SELECT DISTINCT Db FROM mysql.tables_priv WHERE Table_priv LIKE \'%Select%\' AND User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\''; $rs = PMA_DBI_try_query($local_query, $dbh); if ($rs && @PMA_DBI_num_rows($rs)) { while ($row = PMA_DBI_fetch_assoc($rs)) { if (PMA_isInto($row['Db'], $dblist) == -1) { $dblist[] = $row['Db']; } } // end while PMA_DBI_free_result($rs); } // end if } // end if } // end building available dbs from the "mysql" db return $dblist; } /** * Determines the font sizes to use depending on the os and browser of the * user. * * This function is based on an article from phpBuilder (see * http://www.phpbuilder.net/columns/tim20000821.php). * * @return boolean always true * * @global string the standard font size * @global string the font size for titles * @global string the small font size * @global string the smallest font size * * @access public * * @version 1.1 */ function PMA_setFontSizes() { global $font_size, $font_biggest, $font_bigger, $font_smaller, $font_smallest; // IE (<7)/Opera (<7) for win case: needs smaller fonts than anyone else if (PMA_USR_OS == 'Win' && ((PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 7) || (PMA_USR_BROWSER_AGENT == 'OPERA' && PMA_USR_BROWSER_VER < 7))) { $font_size = 'x-small'; $font_biggest = 'large'; $font_bigger = 'medium'; $font_smaller = '90%'; $font_smallest = '7pt'; } // IE6 and other browsers for win case else if (PMA_USR_OS == 'Win') { $font_size = 'small'; $font_biggest = 'large'; $font_bigger = 'medium'; $font_smaller = (PMA_USR_BROWSER_AGENT == 'IE') ? '90%' : 'x-small'; $font_smallest = 'x-small'; } // Some mac browsers need also smaller default fonts size (OmniWeb & // Opera)... // and a beta version of Safari did also, but not the final 1.0 version // so I remove || PMA_USR_BROWSER_AGENT == 'SAFARI' // but we got a report that Safari 1.0 build 85.5 needs it! else if (PMA_USR_OS == 'Mac' && (PMA_USR_BROWSER_AGENT == 'OMNIWEB' || PMA_USR_BROWSER_AGENT == 'OPERA' || PMA_USR_BROWSER_AGENT == 'SAFARI')) { $font_size = 'x-small'; $font_biggest = 'large'; $font_bigger = 'medium'; $font_smaller = '90%'; $font_smallest = '7pt'; } // ... but most of them (except IE 5+ & NS 6+) need bigger fonts else if ((PMA_USR_OS == 'Mac' && ((PMA_USR_BROWSER_AGENT != 'IE' && PMA_USR_BROWSER_AGENT != 'MOZILLA') || PMA_USR_BROWSER_VER < 5)) || PMA_USR_BROWSER_AGENT == 'KONQUEROR' || PMA_USR_BROWSER_AGENT == 'MOZILLA') { $font_size = 'medium'; $font_biggest = 'x-large'; $font_bigger = 'large'; $font_smaller = 'small'; $font_smallest = 'x-small'; } // OS/2 browser else if (PMA_USR_OS == 'OS/2' && PMA_USR_BROWSER_AGENT == 'OPERA') { $font_size = 'small'; $font_biggest = 'medium'; $font_bigger = 'medium'; $font_smaller = 'x-small'; $font_smallest = 'x-small'; } else { $font_size = 'small'; $font_biggest = 'large'; $font_bigger = 'medium'; $font_smaller = 'x-small'; $font_smallest = 'x-small'; } return TRUE; } // end of the 'PMA_setFontSizes()' function if ($is_minimum_common == FALSE) { /** * $cfg['PmaAbsoluteUri'] is a required directive else cookies won't be * set properly and, depending on browsers, inserting or updating a * record might fail */ // Setup a default value to let the people and lazy syadmins work anyway, // they'll get an error if the autodetect code doesn't work if (empty($cfg['PmaAbsoluteUri'])) { $url = array(); // At first we try to parse REQUEST_URI, it might contain full URI if (!empty($_SERVER['REQUEST_URI'])) { $url = parse_url($_SERVER['REQUEST_URI']); } // If we don't have scheme, we didn't have full URL so we need to dig deeper if (empty($url['scheme'])) { // Scheme if (!empty($_SERVER['HTTP_SCHEME'])) { $url['scheme'] = $_SERVER['HTTP_SCHEME']; } else { $url['scheme'] = (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') ? 'https' : 'http'; } // Host and port if (!empty($_SERVER['HTTP_HOST'])) { if (strpos($_SERVER['HTTP_HOST'], ':') > 0) { list($url['host'], $url['port']) = explode(':', $_SERVER['HTTP_HOST']); } else { $url['host'] = $_SERVER['HTTP_HOST']; } } else if (!empty($_SERVER['SERVER_NAME'])) { $url['host'] = $_SERVER['SERVER_NAME']; } else { // Displays the error message header( 'Location: error.php' . '?lang=' . urlencode( $available_languages[$lang][2] ) . '&char=' . urlencode( $charset ) . '&dir=' . urlencode( $text_dir ) . '&type=' . urlencode( $strError ) . '&error=' . urlencode( strtr( $strPmaUriError, array( '' => '[tt]', '' => '[/tt]' ) ) ) . '&' . SID ); exit(); } // If we didn't set port yet... if (empty($url['port']) && !empty($_SERVER['SERVER_PORT'])) { $url['port'] = $_SERVER['SERVER_PORT']; } // And finally the path could be already set from REQUEST_URI if (empty($url['path'])) { if (!empty($_SERVER['PATH_INFO'])) { $path = parse_url($_SERVER['PATH_INFO']); } else { // PHP_SELF in CGI often points to cgi executable, so use it as last choice $path = parse_url($_SERVER['PHP_SELF']); } $url['path'] = $path['path']; unset($path); } } // Make url from parts we have $cfg['PmaAbsoluteUri'] = $url['scheme'] . '://'; // Was there user information? if (!empty($url['user'])) { $cfg['PmaAbsoluteUri'] .= $url['user']; if (!empty($url['pass'])) { $cfg['PmaAbsoluteUri'] .= ':' . $url['pass']; } $cfg['PmaAbsoluteUri'] .= '@'; } // Add hostname $cfg['PmaAbsoluteUri'] .= $url['host']; // Add port, if it not the default one if (!empty($url['port']) && (($url['scheme'] == 'http' && $url['port'] != 80) || ($url['scheme'] == 'https' && $url['port'] != 443))) { $cfg['PmaAbsoluteUri'] .= ':' . $url['port']; } // And finally path, without script name, the 'a' is there not to // strip our directory, when path is only /pmadir/ without filename $path = dirname($url['path'] . 'a'); // To work correctly within transformations overview: if (defined('PMA_PATH_TO_BASEDIR') && PMA_PATH_TO_BASEDIR == '../../') { $path = dirname(dirname($path)); } $cfg['PmaAbsoluteUri'] .= $path . '/'; unset($url); // We used to display a warning if PmaAbsoluteUri wasn't set, but now // the autodetect code works well enough that we don't display the // warning at all. The user can still set PmaAbsoluteUri manually. // See https://sourceforge.net/tracker/index.php?func=detail&aid=1257134&group_id=23067&atid=377411 } else { // The URI is specified, however users do often specify this // wrongly, so we try to fix this. // Adds a trailing slash et the end of the phpMyAdmin uri if it // does not exist. if (substr($cfg['PmaAbsoluteUri'], -1) != '/') { $cfg['PmaAbsoluteUri'] .= '/'; } // If URI doesn't start with http:// or https://, we will add // this. if (substr($cfg['PmaAbsoluteUri'], 0, 7) != 'http://' && substr($cfg['PmaAbsoluteUri'], 0, 8) != 'https://') { $cfg['PmaAbsoluteUri'] = ((!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') ? 'https' : 'http') . ':' . (substr($cfg['PmaAbsoluteUri'], 0, 2) == '//' ? '' : '//') . $cfg['PmaAbsoluteUri']; } } // some variables used mostly for cookies: $pma_uri_parts = parse_url($cfg['PmaAbsoluteUri']); $cookie_path = substr($pma_uri_parts['path'], 0, strrpos($pma_uri_parts['path'], '/')) . '/'; $is_https = (isset($pma_uri_parts['scheme']) && $pma_uri_parts['scheme'] == 'https') ? 1 : 0; // if ($cfg['ForceSLL'] && !$is_https) { header( 'Location: ' . preg_replace( '/^http/', 'https', $cfg['PmaAbsoluteUri'] ) . ( isset( $_SERVER['REQUEST_URI'] ) ? preg_replace( '@' . $pma_uri_parts['path'] . '@', '', $_SERVER['REQUEST_URI'] ) : '' ) . '&' . SID ); exit; } $dblist = array(); /** * Gets the valid servers list and parameters */ foreach ($cfg['Servers'] AS $key => $val) { // Don't use servers with no hostname if ( isset($val['connect_type']) && ($val['connect_type'] == 'tcp') && empty($val['host'])) { unset($cfg['Servers'][$key]); } // Final solution to bug #582890 // If we are using a socket connection // and there is nothing in the verbose server name // or the host field, then generate a name for the server // in the form of "Server 2", localized of course! if ( isset($val['connect_type']) && $val['connect_type'] == 'socket' && empty($val['host']) && empty($val['verbose']) ) { $cfg['Servers'][$key]['verbose'] = $GLOBALS['strServer'] . $key; $val['verbose'] = $GLOBALS['strServer'] . $key; } } if (empty($server) || !isset($cfg['Servers'][$server]) || !is_array($cfg['Servers'][$server])) { $server = $cfg['ServerDefault']; } /** * If no server is selected, make sure that $cfg['Server'] is empty (so * that nothing will work), and skip server authentication. * We do NOT exit here, but continue on without logging into any server. * This way, the welcome page will still come up (with no server info) and * present a choice of servers in the case that there are multiple servers * and '$cfg['ServerDefault'] = 0' is set. */ if ($server == 0) { $cfg['Server'] = array(); } /** * Otherwise, set up $cfg['Server'] and do the usual login stuff. */ else if (isset($cfg['Servers'][$server])) { $cfg['Server'] = $cfg['Servers'][$server]; /** * Loads the proper database interface for this server */ require_once('./libraries/database_interface.lib.php'); // Gets the authentication library that fits the $cfg['Server'] settings // and run authentication // (for a quick check of path disclosure in auth/cookies:) $coming_from_common = TRUE; if (!file_exists('./libraries/auth/' . $cfg['Server']['auth_type'] . '.auth.lib.php')) { header( 'Location: error.php' . '?lang=' . urlencode( $available_languages[$lang][2] ) . '&char=' . urlencode( $charset ) . '&dir=' . urlencode( $text_dir ) . '&type=' . urlencode( $strError ) . '&error=' . urlencode( $strInvalidAuthMethod . ' ' . $cfg['Server']['auth_type'] ) . '&' . SID ); exit(); } require_once('./libraries/auth/' . $cfg['Server']['auth_type'] . '.auth.lib.php'); if (!PMA_auth_check()) { PMA_auth(); } else { PMA_auth_set_user(); } // Check IP-based Allow/Deny rules as soon as possible to reject the // user // Based on mod_access in Apache: // http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/aaa/mod_access.c?rev=1.37&content-type=text/vnd.viewcvs-markup // Look at: "static int check_dir_access(request_rec *r)" // Robbat2 - May 10, 2002 if (isset($cfg['Server']['AllowDeny']) && isset($cfg['Server']['AllowDeny']['order'])) { require_once('./libraries/ip_allow_deny.lib.php'); $allowDeny_forbidden = FALSE; // default if ($cfg['Server']['AllowDeny']['order'] == 'allow,deny') { $allowDeny_forbidden = TRUE; if (PMA_allowDeny('allow')) { $allowDeny_forbidden = FALSE; } if (PMA_allowDeny('deny')) { $allowDeny_forbidden = TRUE; } } else if ($cfg['Server']['AllowDeny']['order'] == 'deny,allow') { if (PMA_allowDeny('deny')) { $allowDeny_forbidden = TRUE; } if (PMA_allowDeny('allow')) { $allowDeny_forbidden = FALSE; } } else if ($cfg['Server']['AllowDeny']['order'] == 'explicit') { if (PMA_allowDeny('allow') && !PMA_allowDeny('deny')) { $allowDeny_forbidden = FALSE; } else { $allowDeny_forbidden = TRUE; } } // end if... else if... else if // Ejects the user if banished if ($allowDeny_forbidden) { PMA_auth_fails(); } unset($allowDeny_forbidden); //Clean up after you! } // end if // is root allowed? if (!$cfg['Server']['AllowRoot'] && $cfg['Server']['user'] == 'root') { $allowDeny_forbidden = TRUE; PMA_auth_fails(); unset($allowDeny_forbidden); //Clean up after you! } // The user can work with only some databases if (isset($cfg['Server']['only_db']) && $cfg['Server']['only_db'] != '') { if (is_array($cfg['Server']['only_db'])) { $dblist = $cfg['Server']['only_db']; } else { $dblist[] = $cfg['Server']['only_db']; } } // end if $bkp_track_err = @ini_set('track_errors', 1); // Try to connect MySQL with the control user profile (will be used to // get the privileges list for the current user but the true user link // must be open after this one so it would be default one for all the // scripts) if ($cfg['Server']['controluser'] != '') { $dbh = PMA_DBI_connect($cfg['Server']['controluser'], $cfg['Server']['controlpass'], TRUE); } else { $dbh = PMA_DBI_connect($cfg['Server']['user'], $cfg['Server']['password'], TRUE); } // end if ... else // Pass #1 of DB-Config to read in master level DB-Config will go here // Robbat2 - May 11, 2002 // Connects to the server (validates user's login) $userlink = PMA_DBI_connect($cfg['Server']['user'], $cfg['Server']['password'], FALSE); // Pass #2 of DB-Config to read in user level DB-Config will go here // Robbat2 - May 11, 2002 @ini_set('track_errors', $bkp_track_err); unset($bkp_track_err); /** * SQL Parser code */ require_once('./libraries/sqlparser.lib.php'); /** * SQL Validator interface code */ require_once('./libraries/sqlvalidator.lib.php'); // if 'only_db' is set for the current user, there is no need to check for // available databases in the "mysql" db $dblist_cnt = count($dblist); if ($dblist_cnt) { $true_dblist = array(); $is_show_dbs = TRUE; $dblist_asterisk_bool = FALSE; for ($i = 0; $i < $dblist_cnt; $i++) { // The current position if ($dblist[$i] == '*' && $dblist_asterisk_bool == FALSE) { $dblist_asterisk_bool = TRUE; $dblist_full = PMA_safe_db_list(FALSE, $dbh, FALSE, $rs, $userlink, $cfg, $dblist); foreach ($dblist_full AS $dbl_key => $dbl_val) { if (!in_array($dbl_val, $dblist)) { $true_dblist[] = $dbl_val; } } continue; } elseif ($dblist[$i] == '*') { // We don't want more than one asterisk inside our 'only_db'. continue; } if ($is_show_dbs && ereg('(^|[^\])(_|%)', $dblist[$i])) { $local_query = 'SHOW DATABASES LIKE \'' . $dblist[$i] . '\''; // here, a PMA_DBI_query() could fail silently // if SHOW DATABASES is disabled $rs = PMA_DBI_try_query($local_query, $dbh); if ($i == 0 && (substr(PMA_DBI_getError($dbh), 1, 4) == 1045)) { // "SHOW DATABASES" statement is disabled $true_dblist[] = str_replace('\\_', '_', str_replace('\\%', '%', $dblist[$i])); $is_show_dbs = FALSE; } // Debug // else if (PMA_DBI_getError($dbh)) { // PMA_mysqlDie(PMA_DBI_getError($dbh), $local_query, FALSE); // } while ($row = @PMA_DBI_fetch_row($rs)) { $true_dblist[] = $row[0]; } // end while if ($rs) { PMA_DBI_free_result($rs); } } else { $true_dblist[] = str_replace('\\_', '_', str_replace('\\%', '%', $dblist[$i])); } // end if... else... } // end for $dblist = $true_dblist; unset($true_dblist); $only_db_check = TRUE; } // end if // 'only_db' is empty for the current user... else { $only_db_check = FALSE; } // end if (!$dblist_cnt) if (isset($dblist_full) && !count($dblist_full)) { $dblist = PMA_safe_db_list($only_db_check, $dbh, $dblist_cnt, $rs, $userlink, $cfg, $dblist); } } // end server connecting /** * Missing server hostname */ else { echo $strHostEmpty; } /** * Send HTTP header, taking IIS limits into account * ( 600 seems ok) * * @param string the header to send * * @return boolean always true */ function PMA_sendHeaderLocation($uri) { if (PMA_IS_IIS && strlen($uri) > 600) { echo '- - -' . "\n"; echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; echo ' ' . "\n"; } else { header( 'Location: ' . $uri . '&' . SID ); } } /** * Get the list and number of available databases. * * @param string the url to go back to in case of error * * @return boolean always true * * @global array the list of available databases * @global integer the number of available databases * @global array current configuration */ function PMA_availableDatabases($error_url = '') { global $dblist; global $num_dbs; global $cfg; // 1. A list of allowed databases has already been defined by the // authentification process -> gets the available databases list if ( count( $dblist ) ) { foreach ( $dblist as $key => $db ) { if ( ! @PMA_DBI_select_db( $db ) ) { unset( $dblist[$key] ); } // end if } // end for } // end if // 2. Allowed database list is empty -> gets the list of all databases // on the server elseif ( empty( $cfg['Server']['only_db'] ) ) { $dblist = PMA_DBI_get_dblist(); // needed? or PMA_mysqlDie('', 'SHOW DATABASES;', FALSE, $error_url); } // end else $num_dbs = count( $dblist ); // natural order for db list; but do not sort if user asked // for a specific order with the 'only_db' mechanism if ( ! is_array( $GLOBALS['cfg']['Server']['only_db'] ) && $GLOBALS['cfg']['NaturalOrder'] ) { natsort( $dblist ); } return TRUE; } // end of the 'PMA_availableDatabases()' function /** * returns array with tables of given db with extended infomation and grouped * * @uses $GLOBALS['cfg']['LeftFrameTableSeparator'] * @uses $GLOBALS['cfg']['LeftFrameTableLevel'] * @uses $GLOBALS['cfg']['ShowTooltipAliasTB'] * @uses $GLOBALS['cfg']['NaturalOrder'] * @uses PMA_DBI_fetch_result() * @uses PMA_backquote() * @uses count() * @uses array_merge * @uses uksort() * @uses strstr() * @uses explode() * @param string $db name of db * return array (rekursive) grouped table list */ function PMA_getTableList( $db ) { $sep = $GLOBALS['cfg']['LeftFrameTableSeparator']; $tables = PMA_DBI_get_tables_full($db); if ( count( $tables ) < 1 ) { return $tables; } if ( $GLOBALS['cfg']['NaturalOrder'] ) { uksort( $tables, 'strcmp' ); } $default = array( 'Name' => '', 'Rows' => 0, 'Comment' => '', 'disp_name' => '', ); $table_groups = array(); foreach ( $tables as $table_name => $table ) { // check for correct row count if ( NULL === $table['Rows'] ) { $table['Rows'] = PMA_countRecords( $db, $table['Name'], $return = true, $force_exact = true ); } // in $group we save the reference to the place in $table_groups // where to store the table info if ( $GLOBALS['cfg']['LeftFrameDBTree'] && $sep && strstr( $table_name, $sep ) ) { $parts = explode( $sep, $table_name ); $group =& $table_groups; $i = 0; $group_name_full = ''; while ( $i < count( $parts ) - 1 && $i < $GLOBALS['cfg']['LeftFrameTableLevel'] ) { $group_name = $parts[$i] . $sep; $group_name_full .= $group_name; if ( ! isset( $group[$group_name] ) ) { $group[$group_name] = array(); $group[$group_name]['is' . $sep . 'group'] = true; $group[$group_name]['tab' . $sep . 'count'] = 1; $group[$group_name]['tab' . $sep . 'group'] = $group_name_full; } elseif ( ! isset( $group[$group_name]['is' . $sep . 'group'] ) ) { $table = $group[$group_name]; $group[$group_name] = array(); $group[$group_name][$group_name] = $table; unset( $table ); $group[$group_name]['is' . $sep . 'group'] = true; $group[$group_name]['tab' . $sep . 'count'] = 1; $group[$group_name]['tab' . $sep . 'group'] = $group_name_full; } else { $group[$group_name]['tab_count']++; } $group =& $group[$group_name]; $i++; } } else { if ( ! isset( $table_groups[$table_name] ) ) { $table_groups[$table_name] = array(); } $group =& $table_groups; } if ( $GLOBALS['cfg']['ShowTooltipAliasTB'] && $GLOBALS['cfg']['ShowTooltipAliasTB'] !== 'nested' ) { // switch tooltip and name $table['Comment'] = $table['Name']; $table['disp_name'] = $table['Comment']; } else { $table['disp_name'] = $table['Name']; } $group[$table_name] = array_merge( $default, $table ); } return $table_groups; } /* ----------------------- Set of misc functions ----------------------- */ /** * Adds backquotes on both sides of a database, table or field name. * Since MySQL 3.23.6 this allows to use non-alphanumeric characters in * these names. * * @param mixed the database, table or field name to "backquote" or * array of it * @param boolean a flag to bypass this function (used by dump * functions) * * @return mixed the "backquoted" database, table or field name if the * current MySQL release is >= 3.23.6, the original one * else * * @access public */ function PMA_backquote($a_name, $do_it = TRUE) { // '0' is also empty for php :-( if ($do_it && (!empty($a_name) || $a_name == '0') && $a_name != '*') { if (is_array($a_name)) { $result = array(); foreach ($a_name AS $key => $val) { $result[$key] = '`' . $val . '`'; } return $result; } else { return '`' . $a_name . '`'; } } else { return $a_name; } } // end of the 'PMA_backquote()' function /** * Format a string so it can be passed to a javascript function. * This function is used to displays a javascript confirmation box for * "DROP/DELETE/ALTER" queries. * * @param string the string to format * @param boolean whether to add backquotes to the string or not * * @return string the formated string * * @access public */ function PMA_jsFormat($a_string = '', $add_backquotes = TRUE) { if (is_string($a_string)) { $a_string = htmlspecialchars($a_string); $a_string = str_replace('\\', '\\\\', $a_string); $a_string = str_replace('\'', '\\\'', $a_string); $a_string = str_replace('#', '\\#', $a_string); $a_string = str_replace("\012", '\\\\n', $a_string); $a_string = str_replace("\015", '\\\\r', $a_string); } return (($add_backquotes) ? PMA_backquote($a_string) : $a_string); } // end of the 'PMA_jsFormat()' function /** * Defines the value depending on the user OS. * * @return string the value to use * * @access public */ function PMA_whichCrlf() { $the_crlf = "\n"; // The 'PMA_USR_OS' constant is defined in "./libraries/defines.lib.php" // Win case if (PMA_USR_OS == 'Win') { $the_crlf = "\r\n"; } // Mac case else if (PMA_USR_OS == 'Mac') { $the_crlf = "\r"; } // Others else { $the_crlf = "\n"; } return $the_crlf; } // end of the 'PMA_whichCrlf()' function /** * Counts and displays the number of records in a table * * Last revision 13 July 2001: Patch for limiting dump size from * vinay@sanisoft.com & girish@sanisoft.com * * @param string the current database name * @param string the current table name * @param boolean whether to retain or to displays the result * @param boolean whether to force an exact count * * @return mixed the number of records if retain is required, true else * * @access public */ function PMA_countRecords($db, $table, $ret = FALSE, $force_exact = FALSE) { global $err_url, $cfg; if (!$force_exact) { $result = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_backquote($db) . ' LIKE \'' . PMA_sqlAddslashes($table, TRUE) . '\';'); $showtable = PMA_DBI_fetch_assoc($result); $num = (isset($showtable['Rows']) ? $showtable['Rows'] : 0); if ($num < $cfg['MaxExactCount']) { unset($num); } PMA_DBI_free_result($result); } if (!isset($num)) { $result = PMA_DBI_query('SELECT COUNT(*) AS num FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table)); list($num) = ($result) ? PMA_DBI_fetch_row($result) : array(0); PMA_DBI_free_result($result); } if ($ret) { return $num; } else { echo number_format($num, 0, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']); return TRUE; } } // end of the 'PMA_countRecords()' function /** * Reloads navigation if needed. * * @global mixed configuration * @global bool whether to reload * * @access public */ function PMA_reloadNavigation() { global $cfg; // Reloads the navigation frame via JavaScript if required if (isset($GLOBALS['reload']) && $GLOBALS['reload']) { echo "\n"; $reload_url = './left.php?' . PMA_generate_common_url((isset($GLOBALS['db']) ? $GLOBALS['db'] : ''), '', '&'); ?> 1024) { PMA_DBI_try_query('REPAIR TABLE ' . PMA_backquote($GLOBALS['table'])); } } unset($tbl_status); ?>

'; } if ( $cfg['ShowSQL'] == TRUE && ( !empty($GLOBALS['sql_query']) || !empty($GLOBALS['display_query']) ) ) { $local_query = !empty($GLOBALS['display_query']) ? $GLOBALS['display_query'] : (($cfg['SQP']['fmtType'] == 'none' && isset($GLOBALS['unparsed_sql']) && $GLOBALS['unparsed_sql'] != '') ? $GLOBALS['unparsed_sql'] : $GLOBALS['sql_query']); // Basic url query part $url_qpart = '?' . PMA_generate_common_url(isset($GLOBALS['db']) ? $GLOBALS['db'] : '', isset($GLOBALS['table']) ? $GLOBALS['table'] : ''); // Html format the query to be displayed // The nl2br function isn't used because its result isn't a valid // xhtml1.0 statement before php4.0.5 ("
" and not "
") // If we want to show some sql code it is easiest to create it here /* SQL-Parser-Analyzer */ if (!empty($GLOBALS['show_as_php'])) { $new_line = '\'
' . "\n" . '        . \' '; } if (isset($new_line)) { /* SQL-Parser-Analyzer */ $query_base = PMA_sqlAddslashes(htmlspecialchars($local_query), FALSE, FALSE, TRUE); /* SQL-Parser-Analyzer */ $query_base = preg_replace("@((\015\012)|(\015)|(\012))+@", $new_line, $query_base); } else { $query_base = $local_query; } // Parse SQL if needed if (isset($GLOBALS['parsed_sql']) && $query_base == $GLOBALS['parsed_sql']['raw']) { $parsed_sql = $GLOBALS['parsed_sql']; } else { $parsed_sql = PMA_SQP_parse($query_base); } // Analyze it $analyzed_display_query = PMA_SQP_analyze($parsed_sql); // Here we append the LIMIT added for navigation, to // enable its display. Adding it higher in the code // to $local_query would create a problem when // using the Refresh or Edit links. // Only append it on SELECTs. // FIXME: what would be the best to do when someone // hits Refresh: use the current LIMITs ? if (isset($analyzed_display_query[0]['queryflags']['select_from']) && isset($GLOBALS['sql_limit_to_append'])) { $query_base = $analyzed_display_query[0]['section_before_limit'] . "\n" . $GLOBALS['sql_limit_to_append'] . $analyzed_display_query[0]['section_after_limit']; // Need to reparse query $parsed_sql = PMA_SQP_parse($query_base); } if (!empty($GLOBALS['show_as_php'])) { $query_base = '$sql = \'' . $query_base; } else if (!empty($GLOBALS['validatequery'])) { $query_base = PMA_validateSQL($query_base); } else { $query_base = PMA_formatSql($parsed_sql, $query_base); } // Prepares links that may be displayed to edit/explain the query // (don't go to default pages, we must go to the page // where the query box is available) // (also, I don't see why we should check the goto variable) //if (!isset($GLOBALS['goto'])) { //$edit_target = (isset($GLOBALS['table'])) ? $cfg['DefaultTabTable'] : $cfg['DefaultTabDatabase']; $edit_target = isset($GLOBALS['db']) ? (isset($GLOBALS['table']) ? 'tbl_properties.php' : 'db_details.php') : 'server_sql.php'; //} else if ($GLOBALS['goto'] != 'main.php') { // $edit_target = $GLOBALS['goto']; //} else { // $edit_target = ''; //} if (isset($cfg['SQLQuery']['Edit']) && ($cfg['SQLQuery']['Edit'] == TRUE ) && (!empty($edit_target))) { $onclick = ''; if ($cfg['QueryFrameJS'] && $cfg['QueryFrame']) { $onclick = 'window.parent.focus_querywindow(\'' . urlencode($local_query) . '\'); return false;'; } $edit_link = $edit_target . $url_qpart . '&sql_query=' . urlencode($local_query) . '&show_query=1#querybox"'; $edit_link = ' [' . PMA_linkOrButton( $edit_link, $GLOBALS['strEdit'], array( 'onclick' => $onclick ) ) . ']'; } else { $edit_link = ''; } // Want to have the query explained (Mike Beck 2002-05-22) // but only explain a SELECT (that has not been explained) /* SQL-Parser-Analyzer */ if (isset($cfg['SQLQuery']['Explain']) && $cfg['SQLQuery']['Explain'] == TRUE) { // Detect if we are validating as well // To preserve the validate uRL data if (!empty($GLOBALS['validatequery'])) { $explain_link_validate = '&validatequery=1'; } else { $explain_link_validate = ''; } $explain_link = 'import.php' . $url_qpart . $explain_link_validate . '&sql_query='; if (preg_match('@^SELECT[[:space:]]+@i', $local_query)) { $explain_link .= urlencode('EXPLAIN ' . $local_query); $message = $GLOBALS['strExplain']; } else if (preg_match('@^EXPLAIN[[:space:]]+SELECT[[:space:]]+@i', $local_query)) { $explain_link .= urlencode(substr($local_query, 8)); $message = $GLOBALS['strNoExplain']; } else { $explain_link = ''; } if (!empty($explain_link)) { $explain_link = ' [' . PMA_linkOrButton( $explain_link, $message ) . ']'; } } else { $explain_link = ''; } //show explain // Also we would like to get the SQL formed in some nice // php-code (Mike Beck 2002-05-22) if (isset($cfg['SQLQuery']['ShowAsPHP']) && $cfg['SQLQuery']['ShowAsPHP'] == TRUE) { $php_link = 'import.php' . $url_qpart . '&show_query=1' . '&sql_query=' . urlencode($local_query) . '&show_as_php='; if (!empty($GLOBALS['show_as_php'])) { $php_link .= '0'; $message = $GLOBALS['strNoPhp']; } else { $php_link .= '1'; $message = $GLOBALS['strPhp']; } $php_link = ' [' . PMA_linkOrButton( $php_link, $message ) . ']'; if (isset($GLOBALS['show_as_php']) && $GLOBALS['show_as_php'] == '1') { $runquery_link = 'import.php' . $url_qpart . '&show_query=1' . '&sql_query=' . urlencode($local_query); $php_link .= ' [' . PMA_linkOrButton( $runquery_link, $GLOBALS['strRunQuery'] ) . ']'; } } else { $php_link = ''; } //show as php // Refresh query if (isset($cfg['SQLQuery']['Refresh']) && $cfg['SQLQuery']['Refresh'] && preg_match('@^(SELECT|SHOW)[[:space:]]+@i', $local_query)) { $refresh_link = 'import.php' . $url_qpart . '&show_query=1' . '&sql_query=' . urlencode($local_query); $refresh_link = ' [' . PMA_linkOrButton( $refresh_link, $GLOBALS['strRefresh'] ) . ']'; } else { $refresh_link = ''; } //show as php if (isset($cfg['SQLValidator']['use']) && $cfg['SQLValidator']['use'] == TRUE && isset($cfg['SQLQuery']['Validate']) && $cfg['SQLQuery']['Validate'] == TRUE) { $validate_link = 'import.php' . $url_qpart . '&show_query=1' . '&sql_query=' . urlencode($local_query) . '&validatequery='; if (!empty($GLOBALS['validatequery'])) { $validate_link .= '0'; $validate_message = $GLOBALS['strNoValidateSQL'] ; } else { $validate_link .= '1'; $validate_message = $GLOBALS['strValidateSQL'] ; } $validate_link = ' [' . PMA_linkOrButton( $validate_link, $validate_message ) . ']'; } else { $validate_link = ''; } //validator unset($local_query); // Displays the message echo '
' . "\n"; echo ' ' . $GLOBALS['strSQLQuery'] . ':'; echo ' ' . $query_base; //Clean up the end of the PHP if (!empty($GLOBALS['show_as_php'])) { echo '\';'; } echo '
' . "\n"; if ( ! empty( $edit_target ) ) { echo '
'; echo $edit_link . $explain_link . $php_link . $refresh_link . $validate_link; echo '
'; } } ?>

= 1; $d--, $ex-=3 ) { if (isset($GLOBALS['byteUnits'][$d]) && $value >= $li * pow(10, $ex)) { $value = round($value / ( pow(1024, $d) / $dh) ) /$dh; $unit = $GLOBALS['byteUnits'][$d]; break 1; } // end if } // end for if ($unit != $GLOBALS['byteUnits'][0]) { $return_value = number_format($value, $comma, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']); } else { $return_value = number_format($value, 0, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']); } return array($return_value, $unit); } // end of the 'PMA_formatByteDown' function /** * Formats $value to the given length and appends SI prefixes * $comma is not substracted from the length * with a $length of 0 no truncation occurs, number is only formated * to the current locale * * echo PMA_formatNumber( 123456789, 6 ); // 123,457 k * echo PMA_formatNumber( -123456789, 4, 2 ); // -123.46 M * echo PMA_formatNumber( -0.003, 6 ); // -3 m * echo PMA_formatNumber( 0.003, 3, 3 ); // 0.003 * echo PMA_formatNumber( 0.00003, 3, 2 ); // 0.03 m * echo PMA_formatNumber( 0, 6 ); // 0 * * @param double $value the value to format * @param integer $length the max length * @param integer $comma the number of decimals to retain * @param boolean $only_down do not reformat numbers below 1 * * @return string the formatted value and its unit * * @access public * * @author staybyte, sebastian mendel * @version 1.1.0 - 2005-10-27 */ function PMA_formatNumber( $value, $length = 3, $comma = 0, $only_down = false ) { if ( $length === 0 ) { return number_format( $value, $comma, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator'] ); } // this units needs no translation, ISO $units = array( -8 => 'y', -7 => 'z', -6 => 'a', -5 => 'f', -4 => 'p', -3 => 'n', -2 => 'µ', -1 => 'm', 0 => ' ', 1 => 'k', 2 => 'M', 3 => 'G', 4 => 'T', 5 => 'P', 6 => 'E', 7 => 'Z', 8 => 'Y' ); // we need at least 3 digits to be displayed if ( 3 > $length + $comma ) { $length = 3 - $comma; } // check for negativ value to retain sign if ( $value < 0 ) { $sign = '-'; $value = abs( $value ); } else { $sign = ''; } $dh = pow(10, $comma); $li = pow(10, $length); $unit = $units[0]; if ( $value >= 1 ) { for ( $d = 8; $d >= 0; $d-- ) { if (isset($units[$d]) && $value >= $li * pow(1000, $d-1)) { $value = round($value / ( pow(1000, $d) / $dh) ) /$dh; $unit = $units[$d]; break 1; } // end if } // end for } elseif ( ! $only_down && (float) $value !== 0.0 ) { for ( $d = -8; $d <= 8; $d++ ) { if (isset($units[$d]) && $value <= $li * pow(1000, $d-1)) { $value = round($value / ( pow(1000, $d) / $dh) ) /$dh; $unit = $units[$d]; break 1; } // end if } // end for } // end if ( $value >= 1 ) elseif ( ! $only_down && (float) $value !== 0.0 ) $value = number_format( $value, $comma, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator'] ); return $sign . $value . ' ' . $unit; } // end of the 'PMA_formatNumber' function /** * Extracts ENUM / SET options from a type definition string * * @param string The column type definition * * @return array The options or * boolean FALSE in case of an error. * * @author rabus */ function PMA_getEnumSetOptions($type_def) { $open = strpos($type_def, '('); $close = strrpos($type_def, ')'); if (!$open || !$close) { return FALSE; } $options = substr($type_def, $open + 2, $close - $open - 3); $options = explode('\',\'', $options); return $options; } // end of the 'PMA_getEnumSetOptions' function /** * Writes localised date * * @param string the current timestamp * * @return string the formatted date * * @access public */ function PMA_localisedDate($timestamp = -1, $format = '') { global $datefmt, $month, $day_of_week; if ($format == '') { $format = $datefmt; } if ($timestamp == -1) { $timestamp = time(); } $date = preg_replace('@%[aA]@', $day_of_week[(int)strftime('%w', $timestamp)], $format); $date = preg_replace('@%[bB]@', $month[(int)strftime('%m', $timestamp)-1], $date); return strftime($date, $timestamp); } // end of the 'PMA_localisedDate()' function /** * returns a tab for tabbed navigation. * If the variables $link and $args ar left empty, an inactive tab is created * * @uses array_merge() * basename() * $GLOBALS['strEmpty'] * $GLOBALS['strDrop'] * $GLOBALS['active_page'] * $GLOBALS['PHP_SELF'] * htmlentities() * PMA_generate_common_url() * $GLOBALS['url_query'] * urlencode() * $GLOBALS['cfg']['MainPageIconic'] * $GLOBALS['pmaThemeImage'] * sprintf() * trigger_error() * E_USER_NOTICE * @param array $tab array with all options * @return string html code for one tab, a link if valid otherwise a span * @access public */ function PMA_getTab( $tab ) { // default values $defaults = array( 'text' => '', 'class' => '', 'active' => false, 'link' => '', 'sep' => '?', 'attr' => '', 'args' => '', ); $tab = array_merge( $defaults, $tab ); // determine aditional style-class if ( empty( $tab['class'] ) ) { if ( $tab['text'] == $GLOBALS['strEmpty'] || $tab['text'] == $GLOBALS['strDrop'] ) { $tab['class'] = 'caution'; } elseif ( isset( $tab['active'] ) && $tab['active'] || isset( $GLOBALS['active_page'] ) && $GLOBALS['active_page'] == $tab['link'] || basename( $GLOBALS['PHP_SELF'] ) == $tab['link'] ) { $tab['class'] = 'active'; } } // build the link if ( ! empty( $tab['link'] ) ) { $tab['link'] = htmlentities( $tab['link'] ); $tab['link'] = $tab['link'] . $tab['sep'] .( empty( $GLOBALS['url_query'] ) ? PMA_generate_common_url() : $GLOBALS['url_query'] ); if ( ! empty( $tab['args'] ) ) { foreach( $tab['args'] as $param => $value ) { $tab['link'] .= '&' . urlencode( $param ) . '=' . urlencode( $value ); } } } // display icon, even if iconic is disabled but the link-text is missing if ( ( $GLOBALS['cfg']['MainPageIconic'] || empty( $tab['text'] ) ) && isset( $tab['icon'] ) ) { $image = '%2$s%2$s'; $tab['text'] = sprintf( $image, htmlentities( $tab['icon'] ), $tab['text'] ); } // check to not display an empty link-text elseif ( empty( $tab['text'] ) ) { $tab['text'] = '?'; trigger_error( __FILE__ . '(' . __LINE__ . '): ' . 'empty linktext in function ' . __FUNCTION__ . '()', E_USER_NOTICE ); } if ( ! empty( $tab['link'] ) ) { $out = '' . $tab['text'] . ''; } else { $out = '' . $tab['text'] . ''; } return $out; } // end of the 'PMA_printTab()' function /** * returns html-code for a tab navigation * * @uses PMA_getTab() * @uses htmlentities() * @param array $tabs one element per tab * @param string $tag_id id used for the html-tag * @return string html-code for tab-navigation */ function PMA_getTabs( $tabs, $tag_id = 'topmenu' ) { $tab_navigation = '
' . "\n" .'
    ' . "\n"; foreach ( $tabs as $tab ) { $tab_navigation .= '
  • ' . PMA_getTab( $tab ) . '
  • ' . "\n"; } $tab_navigation .= '
' . "\n" .'
' .'
' . "\n"; return $tab_navigation; } /** * Displays a link, or a button if the link's URL is too large, to * accommodate some browsers' limitations * * @param string the URL * @param string the link message * @param mixed $tag_params string: js confirmation * array: additional tag params (f.e. style="") * @param boolean $new_form we set this to FALSE when we are already in * a form, to avoid generating nested forms * * @return string the results to be echoed or saved in an array */ function PMA_linkOrButton($url, $message, $tag_params = array(), $new_form = TRUE, $strip_img = FALSE, $target = '') { if ( ! is_array( $tag_params ) ) { $tmp = $tag_params; $tag_params = array(); if ( ! empty( $tmp ) ) { $tag_params['onclick'] = 'return confirmLink(this, \'' . $tmp . '\')'; } unset( $tmp ); } if ( ! empty( $target ) ) { $tag_params['target'] = htmlentities( $target ); } $tag_params_strings = array(); foreach( $tag_params as $par_name => $par_value ) { // htmlentities() only on non javascript $par_value = substr( $par_name,0 ,2 ) == 'on' ? $par_value : htmlentities( $par_value ); $tag_params_strings[] = $par_name . '="' . $par_value . '"'; } // previously the limit was set to 2047, it seems 1000 is better if (strlen($url) <= 1000) { $ret = '' . "\n" . ' ' . $message . '' . "\n"; } else { // no spaces (linebreaks) at all // or after the hidden fields // IE will display them all // add class=link to submit button if ( empty( $tag_params['class'] ) ) { $tag_params['class'] = 'link'; } $url = str_replace('&', '&', $url); $url_parts = parse_url($url); $query_parts = explode('&', $url_parts['query']); if ($new_form) { $ret = '