home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 June / ENTER.ISO / files / xampp-win32-1.4.5-installer.exe / xampp / common.lib.php < prev    next >
Encoding:
PHP Script  |  2004-06-30  |  75.8 KB  |  2,024 lines

  1. <?php
  2. /* $Id: common.lib.php,v 2.10.2.6 2004/06/30 13:27:35 rabus Exp $ */
  3. // vim: expandtab sw=4 ts=4 sts=4:
  4.  
  5. /**
  6.  * Misc stuff and functions used by almost all the scripts.
  7.  * Among other things, it contains the advanced authentification work.
  8.  */
  9.  
  10. /**
  11.  * Order of sections for common.lib.php:
  12.  *
  13.  * some functions need the constants of libraries/defines.lib.php
  14.  * and defines_mysql.lib.php
  15.  *
  16.  * the PMA_setFontSizes() function must be before the call to the
  17.  * libraries/auth/cookie.auth.lib.php library
  18.  *
  19.  * the include of libraries/defines_mysql.lib.php must be after the connection
  20.  * to db to get the MySql version
  21.  *
  22.  * the PMA_sqlAddslashes() function must be before the connection to db
  23.  *
  24.  * the authentication libraries must be before the connection to db but
  25.  * after the PMA_isInto() function
  26.  *
  27.  * the PMA_mysqlDie() function must be before the connection to db but
  28.  * after mysql extension has been loaded
  29.  *
  30.  * the PMA_mysqlDie() function needs the PMA_format_sql() Function
  31.  *
  32.  * ... so the required order is:
  33.  *
  34.  * - parsing of the configuration file
  35.  * - load of the libraries/defines.lib.php library
  36.  * - load of mysql extension (if necessary)
  37.  * - definition of PMA_sqlAddslashes()
  38.  * - definition of PMA_format_sql()
  39.  * - definition of PMA_mysqlDie()
  40.  * - definition of PMA_isInto()
  41.  * - definition of PMA_setFontSizes()
  42.  * - loading of an authentication library
  43.  * - db connection
  44.  * - authentication work
  45.  * - load of the libraries/defines_mysql.lib.php library to get the MySQL
  46.  *   release number
  47.  * - other functions, respecting dependencies
  48.  */
  49.  
  50. /**
  51.  * Minimum inclusion? (i.e. for the stylesheet builder)
  52.  */
  53.  
  54. if (!isset($is_minimum_common)) {
  55.     $is_minimum_common = FALSE;
  56. }
  57.  
  58. /**
  59.  * Avoids undefined variables
  60.  */
  61. if (!isset($use_backquotes)) {
  62.     $use_backquotes   = 0;
  63. }
  64. if (!isset($pos)) {
  65.     $pos              = 0;
  66. }
  67.  
  68. /**
  69.  * 2004-06-30 rabus: Ensure, that $cfg variables are not set somwhere else
  70.  * before including the config file.
  71.  */
  72. unset($cfg);
  73.  
  74. /**
  75.  * Detects the config file we want to load
  76.  */
  77. if (file_exists('./config.inc.developer.php')) {
  78.     $cfgfile_to_load = './config.inc.developer.php';
  79. } else {
  80.     $cfgfile_to_load = './config.inc.php';
  81. }
  82.  
  83. /**
  84.  * Parses the configuration file and gets some constants used to define
  85.  * versions of phpMyAdmin/php/mysql...
  86.  */
  87. $old_error_reporting = error_reporting(0);
  88. include_once($cfgfile_to_load);
  89. // Include failed
  90. if (!isset($cfgServers) && !isset($cfg['Servers'])) {
  91.     // Creates fake settings
  92.     $cfg = array('DefaultLang'           => 'en-iso-8859-1',
  93.                     'AllowAnywhereRecoding' => FALSE);
  94.     // Loads the language file
  95.     require_once('./libraries/select_lang.lib.php');
  96.     // Sends the Content-Type header
  97.     header('Content-Type: text/html; charset=' . $charset);
  98.     // Displays the error message
  99.     ?>
  100. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  101. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  102. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $available_languages[$lang][2]; ?>" lang="<?php echo $available_languages[$lang][2]; ?>" dir="<?php echo $text_dir; ?>">
  103.  
  104. <head>
  105. <title>phpMyAdmin</title>
  106. <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $charset; ?>" />
  107.  
  108. <style type="text/css">
  109. <!--
  110. body  {font-family: sans-serif; font-size: small; color: #000000; background-color: #F5F5F5}
  111. h1    {font-family: sans-serif; font-size: large; font-weight: bold}
  112. //-->
  113. </style>
  114. </head>
  115.  
  116.  
  117. <body bgcolor="#ffffff">
  118. <h1>phpMyAdmin - <?php echo $strError; ?></h1>
  119. <p>
  120. <?php echo $strConfigFileError; ?><br /><br />
  121. <a href="config.inc.php" target="_blank">config.inc.php</a>
  122. </p>
  123. </body>
  124.  
  125. </html>
  126.     <?php
  127.     exit();
  128. }
  129. error_reporting($old_error_reporting);
  130. unset($old_error_reporting, $cfgfile_to_load);
  131.  
  132. /**
  133.  * Includes compatibility code for older config.inc.php revisions
  134.  * if necessary
  135.  */
  136. if (isset($cfg['FileRevision'])) {
  137.     // converting revision string into an array
  138.     //     e.g. "Revision: 2.0" becomes array(2, 0).
  139.     $cfg['FileRevision'] = str_replace('$' . 'Revision: ', '', $cfg['FileRevision']);
  140.     $cfg['FileRevision'] = str_replace(' $', '', $cfg['FileRevision']);
  141.     $cfg['FileRevision'] = explode('.', $cfg['FileRevision']);
  142. } else {
  143.     $cfg['FileRevision'] = array(1, 1);
  144. }
  145. if ($cfg['FileRevision'][0] < 2 || ($cfg['FileRevision'][0] == 2 && $cfg['FileRevision'][1] < 4)) {
  146.     require_once('./libraries/config_import.lib.php');
  147. }
  148.  
  149. /**
  150.  * Includes the language file if it hasn't been included yet
  151.  */
  152. require_once('./libraries/select_lang.lib.php');
  153.  
  154. if ($is_minimum_common == FALSE) {
  155.     /**
  156.      * Include MySQL wrappers.
  157.      */
  158.     require_once('./libraries/mysql_wrappers.lib.php');
  159. }
  160.  
  161. /**
  162.  * Gets constants that defines the PHP version number.
  163.  * This include must be located physically before any code that needs to
  164.  * reference the constants, else PHP 3.0.16 won't be happy.
  165.  */
  166. require_once('./libraries/defines.lib.php');
  167.  
  168. if ($is_minimum_common == FALSE) {
  169.     /**
  170.      * Define $is_upload
  171.      */
  172.  
  173.       $is_upload = TRUE;
  174.       if (strtolower(@ini_get('file_uploads')) == 'off'
  175.              || @ini_get('file_uploads') == 0) {
  176.           $is_upload = FALSE;
  177.       }
  178.  
  179.     /**
  180.      * Maximum upload size as limited by PHP
  181.      * Used with permission from Moodle (http://moodle.org) by Martin Dougiamas
  182.      *
  183.      * this section generates $max_upload_size in bytes
  184.      */
  185.  
  186.     function get_real_size($size=0) {
  187.     /// Converts numbers like 10M into bytes
  188.         if (!$size) {
  189.             return 0;
  190.         }
  191.         $scan['MB'] = 1048576;
  192.         $scan['Mb'] = 1048576;
  193.         $scan['M'] = 1048576;
  194.         $scan['m'] = 1048576;
  195.         $scan['KB'] = 1024;
  196.         $scan['Kb'] = 1024;
  197.         $scan['K'] = 1024;
  198.         $scan['k'] = 1024;
  199.  
  200.         while (list($key) = each($scan)) {
  201.             if ((strlen($size)>strlen($key))&&(substr($size, strlen($size) - strlen($key))==$key)) {
  202.                 $size = substr($size, 0, strlen($size) - strlen($key)) * $scan[$key];
  203.                 break;
  204.             }
  205.         }
  206.         return $size;
  207.     } // end function
  208.  
  209.  
  210.     if (!$filesize = ini_get('upload_max_filesize')) {
  211.         $filesize = "5M";
  212.     }
  213.     $max_upload_size = get_real_size($filesize);
  214.  
  215.     if ($postsize = ini_get('post_max_size')) {
  216.         $postsize = get_real_size($postsize);
  217.         if ($postsize < $max_upload_size) {
  218.             $max_upload_size = $postsize;
  219.         }
  220.     }
  221.     unset($filesize);
  222.     unset($postsize);
  223.  
  224.     /**
  225.      * other functions for maximum upload work
  226.      */
  227.  
  228.     /**
  229.      * Displays the maximum size for an upload
  230.      *
  231.      * @param   integer  the size
  232.      *
  233.      * @return  string   the message
  234.      *
  235.      * @access  public
  236.      */
  237.      function PMA_displayMaximumUploadSize($max_upload_size) {
  238.          list($max_size, $max_unit) = PMA_formatByteDown($max_upload_size);
  239.          return '(' . sprintf($GLOBALS['strMaximumSize'], $max_size, $max_unit) . ')';
  240.      }
  241.  
  242.     /**
  243.      * Generates a hidden field which should indicate to the browser
  244.      * the maximum size for upload
  245.      *
  246.      * @param   integer  the size
  247.      *
  248.      * @return  string   the INPUT field
  249.      *
  250.      * @access  public
  251.      */
  252.      function PMA_generateHiddenMaxFileSize($max_size){
  253.          return '<input type="hidden" name="MAX_FILE_SIZE" value="' .$max_size . '" />';
  254.      }
  255.  
  256.     /**
  257.      * Charset conversion.
  258.      */
  259.     require_once('./libraries/charset_conversion.lib.php');
  260. }
  261.  
  262. if ($is_minimum_common == FALSE) {
  263.     /**
  264.      * String handling
  265.      */
  266.     require_once('./libraries/string.lib.php');
  267. }
  268.  
  269. // If zlib output compression is set in the php configuration file, no
  270. // output buffering should be run
  271. if (@ini_get('zlib.output_compression')) {
  272.     $cfg['OBGzip'] = FALSE;
  273. }
  274.  
  275. // disable output-buffering (if set to 'auto') for IE6, else enable it.
  276. if (strtolower($cfg['OBGzip']) == 'auto') {
  277.     if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER >= 6 && PMA_USR_BROWSER_VER < 7) {
  278.         $cfg['OBGzip'] = FALSE;
  279.     } else {
  280.         $cfg['OBGzip'] = TRUE;
  281.     }
  282. }
  283.  
  284. if ($is_minimum_common == FALSE) {
  285.     /**
  286.      * Include URL/hidden inputs generating.
  287.      */
  288.     require_once('./libraries/url_generating.lib.php');
  289.  
  290.     /**
  291.      * Loads the mysql extensions if it is not loaded yet
  292.      */
  293.     if (!@function_exists('mysql_connect')) {
  294.         PMA_dl('mysql');
  295.     }
  296.  
  297.     // check whether mysql is available
  298.     if (!@function_exists('mysql_connect')) {
  299.         if (empty($is_header_sent)) {
  300.             require_once('./libraries/header_http.inc.php');
  301.         }
  302.         echo $strCantLoadMySQL . '<br />' . "\n"
  303.              . '<a href="./Documentation.html#faqmysql" target="documentation">' . $GLOBALS['strDocu'] . '</a>' . "\n";
  304.         exit();
  305.     }
  306.  
  307.     /**
  308.      * Now that we know that MySQL is loaded, we can determine the MySQL
  309.      * client API version
  310.      */
  311.     if (!defined('PMA_MYSQL_CLIENT_API')) {
  312.         if (function_exists('mysql_get_client_info')) {
  313.             $client_api = explode('.', mysql_get_client_info());
  314.             define('PMA_MYSQL_CLIENT_API', (int)sprintf('%d%02d%02d', $client_api[0], $client_api[1], intval($client_api[2])));
  315.             unset($client_api);
  316.         } else {
  317.             define('PMA_MYSQL_CLIENT_API', 32332); // always expect the worst...
  318.         }
  319.     }
  320.  
  321.  
  322.     /**
  323.      * Add slashes before "'" and "\" characters so a value containing them can
  324.      * be used in a sql comparison.
  325.      *
  326.      * @param   string   the string to slash
  327.      * @param   boolean  whether the string will be used in a 'LIKE' clause
  328.      *                   (it then requires two more escaped sequences) or not
  329.      * @param   boolean  whether to treat cr/lfs as escape-worthy entities
  330.      *                   (converts \n to \\n, \r to \\r)
  331.      *
  332.      * @return  string   the slashed string
  333.      *
  334.      * @access  public
  335.      */
  336.     function PMA_sqlAddslashes($a_string = '', $is_like = FALSE, $crlf = FALSE)
  337.     {
  338.         if ($is_like) {
  339.             $a_string = str_replace('\\', '\\\\\\\\', $a_string);
  340.         } else {
  341.             $a_string = str_replace('\\', '\\\\', $a_string);
  342.         }
  343.  
  344.         if ($crlf) {
  345.             $a_string = str_replace("\n", '\n', $a_string);
  346.             $a_string = str_replace("\r", '\r', $a_string);
  347.             $a_string = str_replace("\t", '\t', $a_string);
  348.         }
  349.  
  350.         $a_string = str_replace('\'', '\\\'', $a_string);
  351.  
  352.         return $a_string;
  353.     } // end of the 'PMA_sqlAddslashes()' function
  354.  
  355.  
  356.     /**
  357.      * Add slashes before "_" and "%" characters for using them in MySQL
  358.      * database, table and field names.
  359.      * Note: This function does not escape backslashes!
  360.      *
  361.      * @param   string   the string to escape
  362.      *
  363.      * @return  string   the escaped string
  364.      *
  365.      * @access  public
  366.      */
  367.     function PMA_escape_mysql_wildcards($name)
  368.     {
  369.         $name = str_replace('_', '\\_', $name);
  370.         $name = str_replace('%', '\\%', $name);
  371.  
  372.         return $name;
  373.     } // end of the 'PMA_escape_mysql_wildcards()' function
  374.  
  375.  
  376.     /**
  377.      * format sql strings
  378.      *
  379.      * @param   mixed    pre-parsed SQL structure
  380.      *
  381.      * @return  string   the formatted sql
  382.      *
  383.      * @global  array    the configuration array
  384.      * @global  boolean  whether the current statement is a multiple one or not
  385.      *
  386.      * @access  public
  387.      *
  388.      * @author  Robin Johnson <robbat2@users.sourceforge.net>
  389.      */
  390.     function PMA_formatSql($parsed_sql, $unparsed_sql = '')
  391.     {
  392.         global $cfg;
  393.  
  394.         // Check that we actually have a valid set of parsed data
  395.         // well, not quite
  396.         // first check for the SQL parser having hit an error
  397.         if (PMA_SQP_isError()) {
  398.             return $parsed_sql;
  399.         }
  400.         // then check for an array
  401.         if (!is_array($parsed_sql)) {
  402.             // We don't so just return the input directly
  403.             // This is intended to be used for when the SQL Parser is turned off
  404.             $formatted_sql = '<pre>' . "\n"
  405.                             . (($cfg['SQP']['fmtType'] == 'none' && $unparsed_sql != '') ? $unparsed_sql : $parsed_sql) . "\n"
  406.                             . '</pre>';
  407.             return $formatted_sql;
  408.         }
  409.  
  410.         $formatted_sql        = '';
  411.  
  412.         switch ($cfg['SQP']['fmtType']) {
  413.             case 'none':
  414.                 if ($unparsed_sql != '') {
  415.                     $formatted_sql = "<pre>\n" . PMA_SQP_formatNone(array('raw' => $unparsed_sql)) . "\n</pre>";
  416.                 } else {
  417.                     $formatted_sql = PMA_SQP_formatNone($parsed_sql);
  418.                 }
  419.                 break;
  420.             case 'html':
  421.                 $formatted_sql = PMA_SQP_formatHtml($parsed_sql,'color');
  422.                 break;
  423.             case 'text':
  424.                 //$formatted_sql = PMA_SQP_formatText($parsed_sql);
  425.                 $formatted_sql = PMA_SQP_formatHtml($parsed_sql,'text');
  426.                 break;
  427.             default:
  428.                 break;
  429.         } // end switch
  430.  
  431.         return $formatted_sql;
  432.     } // end of the "PMA_formatSql()" function
  433.  
  434.  
  435.     /**
  436.      * Displays a link to the official MySQL documentation
  437.      *
  438.      * @param   chapter of "HTML, one page per chapter" documentation
  439.      * @param   contains name of page/anchor that is being linked
  440.      *
  441.      * @return  string  the html link
  442.      *
  443.      * @access  public
  444.      */
  445.     function PMA_showMySQLDocu($chapter, $link)
  446.     {
  447.         if (!empty($GLOBALS['cfg']['MySQLManualBase'])) {
  448.             if (!empty($GLOBALS['cfg']['MySQLManualType'])) {
  449.                 switch ($GLOBALS['cfg']['MySQLManualType']) {
  450.                     case 'old':
  451.                         return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link[0] . '/' . $link[1] . '/' . $link . '.html" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
  452.                     case 'chapters':
  453.                         return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/manual_' . $chapter . '.html#' . $link . '" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
  454.                     case 'big':
  455.                         return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '#' . $link . '" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
  456.                     case 'none':
  457.                         return '';
  458.                     case 'searchable':
  459.                     default:
  460.                         return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link . '.html" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
  461.                 }
  462.             } else {
  463.                 // no Type defined, show the old one
  464.                 return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link[0] . '/' . $link[1] . '/' . $link . '.html" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
  465.             }
  466.         } else {
  467.             // no URL defined
  468.             if (!empty($GLOBALS['cfg']['ManualBaseShort'])) {
  469.                 // the old configuration
  470.                 return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link[0] . '/' . $link[1] . '/' . $link . '.html" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
  471.             } else {
  472.                 return '';
  473.             }
  474.         }
  475.     } // end of the 'PMA_showDocu()' function
  476.  
  477.     /**
  478.      * Displays a MySQL error message in the right frame.
  479.      *
  480.      * @param   string   the error mesage
  481.      * @param   string   the sql query that failed
  482.      * @param   boolean  whether to show a "modify" link or not
  483.      * @param   string   the "back" link url (full path is not required)
  484.      * @param   boolean  EXIT the page?
  485.      *
  486.      * @global  array    the configuration array
  487.      *
  488.      * @access  public
  489.      */
  490.     function PMA_mysqlDie($error_message = '', $the_query = '',
  491.                             $is_modify_link = TRUE, $back_url = '',
  492.                             $exit = TRUE)
  493.     {
  494.         global $cfg, $table, $db, $sql_query;
  495.  
  496.         require_once('./header.inc.php');
  497.  
  498.         if (!$error_message) {
  499.             $error_message = PMA_mysql_error();
  500.         }
  501.         if (!$the_query && !empty($GLOBALS['sql_query'])) {
  502.             $the_query = $GLOBALS['sql_query'];
  503.         }
  504.  
  505.         // --- Added to solve bug #641765
  506.         // Robbat2 - 12 January 2003, 9:46PM
  507.         // Revised, Robbat2 - 13 Janurary 2003, 2:59PM
  508.         if (!function_exists('PMA_SQP_isError') || PMA_SQP_isError()) {
  509.             $formatted_sql = htmlspecialchars($the_query);
  510.         } else {
  511.             $formatted_sql = PMA_formatSql(PMA_SQP_parse($the_query), $the_query);
  512.         }
  513.         // ---
  514.  
  515.         echo '<p><b>'. $GLOBALS['strError'] . '</b></p>' . "\n";
  516.         // if the config password is wrong, or the MySQL server does not
  517.         // respond, do not show the query that would reveal the
  518.         // username/password
  519.         if (!empty($the_query) && !strstr($the_query, 'connect')) {
  520.             // --- Added to solve bug #641765
  521.             // Robbat2 - 12 January 2003, 9:46PM
  522.             // Revised, Robbat2 - 13 Janurary 2003, 2:59PM
  523.             if (function_exists('PMA_SQP_isError') && PMA_SQP_isError()) {
  524.                 echo PMA_SQP_getErrorString();
  525.             }
  526.             // ---
  527.             echo '<p>' . "\n";
  528.             echo '    ' . $GLOBALS['strSQLQuery'] . ' : ' . "\n";
  529.             if ($is_modify_link && isset($db)) {
  530.                 echo '    ['
  531.                         . '<a href="db_details.php?' . PMA_generate_common_url($GLOBALS['db']) . '&sql_query=' . urlencode($the_query) . '&show_query=1">' . $GLOBALS['strEdit'] . '</a>'
  532.                         . ']' . "\n";
  533.             } // end if
  534.             echo '</p>' . "\n"
  535.                     . '<p>' . "\n"
  536.                     . '    ' . $formatted_sql . "\n"
  537.                     . '</p>' . "\n";
  538.         } // end if
  539.         if (!empty($error_message)) {
  540.             $error_message = htmlspecialchars($error_message);
  541.             $error_message = preg_replace("@((\015\012)|(\015)|(\012)){3,}@", "\n\n", $error_message);
  542.         }
  543.         echo '<p>' . "\n"
  544.                 . '    ' . $GLOBALS['strMySQLSaid'] . '<br />' . "\n"
  545.                 . '</p>' . "\n";
  546.  
  547.         // The error message will be displayed within a CODE segment.
  548.         // To preserve original formatting, but allow wordwrapping, we do a couple of replacements
  549.  
  550.         // Replace all non-single blanks with their HTML-counterpart
  551.         $error_message = str_replace('  ', '  ', $error_message);
  552.         // Replace TAB-characters with their HTML-counterpart
  553.         $error_message = str_replace("\t", '    ', $error_message);
  554.         // Replace linebreaks
  555.         $error_message = nl2br($error_message);
  556.  
  557.         echo '<code>' . "\n"
  558.                 . $error_message . "\n"
  559.                 . '</code><br /><br />' . "\n";
  560.  
  561.         echo PMA_showMySQLDocu('Error-returns', 'Error-returns');
  562.  
  563.         if (!empty($back_url) && $exit) {
  564.             echo ' · [<a href="' . (strstr($back_url, '?') ? $back_url . '&no_history=true' : $back_url . '?no_history=true') . '">' . $GLOBALS['strBack'] . '</a>]';
  565.         }
  566.         echo "\n";
  567.  
  568.         if ($exit) {
  569.             require_once('./footer.inc.php');
  570.         }
  571.     } // end of the 'PMA_mysqlDie()' function
  572.  
  573.  
  574.     /**
  575.      * Defines whether a string exists inside an array or not
  576.      *
  577.      * @param   string   string to search for
  578.      * @param   mixed    array to search into
  579.      *
  580.      * @return  integer  the rank of the $toFind string in the array or '-1' if
  581.      *                   it hasn't been found
  582.      *
  583.      * @access  public
  584.      */
  585.     function PMA_isInto($toFind = '', &$in)
  586.     {
  587.         $max = count($in);
  588.         for ($i = 0; $i < $max && ($toFind != $in[$i]); $i++) {
  589.             // void();
  590.         }
  591.  
  592.         return ($i < $max) ? $i : -1;
  593.     }  // end of the 'PMA_isInto()' function
  594. }
  595.  
  596. /**
  597.  * Get the complete list of Databases a user can access
  598.  *
  599.  * @param   boolean   whether to include check on failed 'only_db' operations
  600.  * @param   ressource database handle (superuser)
  601.  * @param   integer   amount of databases inside the 'only_db' container
  602.  * @param   ressource possible ressource from a failed previous query
  603.  * @param   ressource database handle (user)
  604.  * @param   array     configuration
  605.  * @param   array     previous list of databases
  606.  *
  607.  * @return  array     all databases a user has access to
  608.  *
  609.  * @access  private
  610.  */
  611. function PMA_safe_db_list($only_db_check, $dbh, $dblist_cnt, $rs, $userlink, $cfg, $dblist) {
  612.  
  613.     if ($only_db_check == FALSE) {
  614.         // ... first checks whether the "safe_show_database" is on or not
  615.         //     (if MYSQL supports this)
  616.         $is_safe_show_dbs = FALSE;
  617.         if (PMA_MYSQL_INT_VERSION >= 40002) {
  618.             $is_safe_show_dbs = 'ON';
  619.         }
  620.         else {
  621.             $local_query      = 'SHOW VARIABLES LIKE \'safe\\_show\\_database\'';
  622.             $rs               = PMA_mysql_query($local_query, $dbh); // Debug: or PMA_mysqlDie('', $local_query, FALSE);
  623.             $is_safe_show_dbs = ($rs) ? @PMA_mysql_result($rs, 0, 'Value') : FALSE;
  624.             mysql_free_result($rs);
  625.         }
  626.  
  627.         // ... and if on, try to get the available dbs list
  628.         if ($is_safe_show_dbs && strtoupper($is_safe_show_dbs) != 'OFF') {
  629.             $uva_alldbs   = mysql_list_dbs($userlink);
  630.             while ($uva_row = PMA_mysql_fetch_array($uva_alldbs)) {
  631.                   $dblist[] = $uva_row[0];
  632.             } // end while
  633.             $dblist_cnt   = count($dblist);
  634.             unset($uva_alldbs);
  635.         } // end if ($is_safe_show_dbs)
  636.  
  637.         // ... else checks for available databases in the "mysql" db
  638.         if (!$dblist_cnt) {
  639.             $auth_query   = 'SELECT User, Select_priv '
  640.                           . 'FROM mysql.user '
  641.                           . 'WHERE User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\'';
  642.             $rs           = PMA_mysql_query($auth_query, $dbh); // Debug: or PMA_mysqlDie('', $auth_query, FALSE);
  643.         } // end
  644.     }
  645.  
  646.     // Access to "mysql" db allowed and dblist still empty -> gets the
  647.     // usable db list
  648.     if (!$dblist_cnt
  649.         && ($rs && @mysql_numrows($rs))) {
  650.         $row = PMA_mysql_fetch_array($rs);
  651.         mysql_free_result($rs);
  652.         // Correction uva 19991215
  653.         // Previous code assumed database "mysql" admin table "db" column
  654.         // "db" contains literal name of user database, and works if so.
  655.         // Mysql usage generally (and uva usage specifically) allows this
  656.         // column to contain regular expressions (we have all databases
  657.         // owned by a given student/faculty/staff beginning with user i.d.
  658.         // and governed by default by a single set of privileges with
  659.         // regular expression as key). This breaks previous code.
  660.         // This maintenance is to fix code to work correctly for regular
  661.         // expressions.
  662.         if ($row['Select_priv'] != 'Y') {
  663.  
  664.             // 1. get allowed dbs from the "mysql.db" table
  665.             // lem9: User can be blank (anonymous user)
  666.             $local_query = 'SELECT DISTINCT Db FROM mysql.db WHERE Select_priv = \'Y\' AND (User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\' OR User = \'\')';
  667.             $rs          = PMA_mysql_query($local_query, $dbh); // Debug: or PMA_mysqlDie('', $local_query, FALSE);
  668.             if ($rs && @mysql_numrows($rs)) {
  669.                 // Will use as associative array of the following 2 code
  670.                 // lines:
  671.                 //   the 1st is the only line intact from before
  672.                 //     correction,
  673.                 //   the 2nd replaces $dblist[] = $row['Db'];
  674.                 $uva_mydbs = array();
  675.                 // Code following those 2 lines in correction continues
  676.                 // populating $dblist[], as previous code did. But it is
  677.                 // now populated with actual database names instead of
  678.                 // with regular expressions.
  679.                 while ($row = PMA_mysql_fetch_array($rs)) {
  680.                     // loic1: all databases cases - part 1
  681.                     if (empty($row['Db']) || $row['Db'] == '%') {
  682.                         $uva_mydbs['%'] = 1;
  683.                         break;
  684.                     }
  685.                     // loic1: avoid multiple entries for dbs
  686.                     if (!isset($uva_mydbs[$row['Db']])) {
  687.                         $uva_mydbs[$row['Db']] = 1;
  688.                     }
  689.                 } // end while
  690.                 mysql_free_result($rs);
  691.                 $uva_alldbs = mysql_list_dbs($dbh);
  692.                 // loic1: all databases cases - part 2
  693.                 if (isset($uva_mydbs['%'])) {
  694.                     while ($uva_row = PMA_mysql_fetch_array($uva_alldbs)) {
  695.                         $dblist[] = $uva_row[0];
  696.                     } // end while
  697.                 } // end if
  698.                 else {
  699.                     while ($uva_row = PMA_mysql_fetch_array($uva_alldbs)) {
  700.                         $uva_db = $uva_row[0];
  701.                         if (isset($uva_mydbs[$uva_db]) && $uva_mydbs[$uva_db] == 1) {
  702.                             $dblist[]           = $uva_db;
  703.                             $uva_mydbs[$uva_db] = 0;
  704.                         } else if (!isset($dblist[$uva_db])) {
  705.                             foreach($uva_mydbs AS $uva_matchpattern => $uva_value) {
  706.                                 // loic1: fixed bad regexp
  707.                                 // TODO: db names may contain characters
  708.                                 //       that are regexp instructions
  709.                                 $re        = '(^|(\\\\\\\\)+|[^\])';
  710.                                 $uva_regex = ereg_replace($re . '%', '\\1.*', ereg_replace($re . '_', '\\1.{1}', $uva_matchpattern));
  711.                                 // Fixed db name matching
  712.                                 // 2000-08-28 -- Benjamin Gandon
  713.                                 if (ereg('^' . $uva_regex . '$', $uva_db)) {
  714.                                     $dblist[] = $uva_db;
  715.                                     break;
  716.                                 }
  717.                             } // end while
  718.                         } // end if ... else if....
  719.                     } // end while
  720.                 } // end else
  721.                 mysql_free_result($uva_alldbs);
  722.                 unset($uva_mydbs);
  723.             } // end if
  724.  
  725.             // 2. get allowed dbs from the "mysql.tables_priv" table
  726.             $local_query = 'SELECT DISTINCT Db FROM mysql.tables_priv WHERE Table_priv LIKE \'%Select%\' AND User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\'';
  727.             $rs          = PMA_mysql_query($local_query, $dbh); // Debug: or PMA_mysqlDie('', $local_query, FALSE);
  728.             if ($rs && @mysql_numrows($rs)) {
  729.                 while ($row = PMA_mysql_fetch_array($rs)) {
  730.                     if (PMA_isInto($row['Db'], $dblist) == -1) {
  731.                         $dblist[] = $row['Db'];
  732.                     }
  733.                 } // end while
  734.                 mysql_free_result($rs);
  735.             } // end if
  736.         } // end if
  737.     } // end building available dbs from the "mysql" db
  738.  
  739.     return $dblist;
  740. }
  741.  
  742. /**
  743.  * Determines the font sizes to use depending on the os and browser of the
  744.  * user.
  745.  *
  746.  * This function is based on an article from phpBuilder (see
  747.  * http://www.phpbuilder.net/columns/tim20000821.php).
  748.  *
  749.  * @return  boolean    always true
  750.  *
  751.  * @global  string     the standard font size
  752.  * @global  string     the font size for titles
  753.  * @global  string     the small font size
  754.  * @global  string     the smallest font size
  755.  *
  756.  * @access  public
  757.  *
  758.  * @version 1.1
  759.  */
  760. function PMA_setFontSizes()
  761. {
  762.     global $font_size, $font_biggest, $font_bigger, $font_smaller, $font_smallest;
  763.  
  764.     // IE (<6)/Opera (<7) for win case: needs smaller fonts than anyone else
  765.     if (PMA_USR_OS == 'Win'
  766.         && ((PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 6)
  767.         || (PMA_USR_BROWSER_AGENT == 'OPERA' && PMA_USR_BROWSER_VER < 7))) {
  768.         $font_size     = 'x-small';
  769.         $font_biggest  = 'large';
  770.         $font_bigger   = 'medium';
  771.         $font_smaller  = '90%';
  772.         $font_smallest = '7pt';
  773.     }
  774.     // IE6 and other browsers for win case
  775.     else if (PMA_USR_OS == 'Win') {
  776.         $font_size     = 'small';
  777.         $font_biggest  = 'large';
  778.         $font_bigger   = 'medium';
  779.         $font_smaller  = (PMA_USR_BROWSER_AGENT == 'IE')
  780.                         ? '90%'
  781.                         : 'x-small';
  782.         $font_smallest = 'x-small';
  783.     }
  784.     // Some mac browsers need also smaller default fonts size (OmniWeb &
  785.     // Opera)...
  786.     // and a beta version of Safari did also, but not the final 1.0 version
  787.     // so I remove   || PMA_USR_BROWSER_AGENT == 'SAFARI'
  788.     // but we got a report that Safari 1.0 build 85.5 needs it!
  789.  
  790.     else if (PMA_USR_OS == 'Mac'
  791.                 && (PMA_USR_BROWSER_AGENT == 'OMNIWEB' || PMA_USR_BROWSER_AGENT == 'OPERA' || PMA_USR_BROWSER_AGENT == 'SAFARI')) {
  792.         $font_size     = 'x-small';
  793.         $font_biggest  = 'large';
  794.         $font_bigger   = 'medium';
  795.         $font_smaller  = '90%';
  796.         $font_smallest = '7pt';
  797.     }
  798.     // ... but most of them (except IE 5+ & NS 6+) need bigger fonts
  799.     else if ((PMA_USR_OS == 'Mac'
  800.                 && ((PMA_USR_BROWSER_AGENT != 'IE' && PMA_USR_BROWSER_AGENT != 'MOZILLA')
  801.                     || PMA_USR_BROWSER_VER < 5))
  802.             || PMA_USR_BROWSER_AGENT == 'KONQUEROR') {
  803.         $font_size     = 'medium';
  804.         $font_biggest  = 'x-large';
  805.         $font_bigger   = 'large';
  806.         $font_smaller  = 'small';
  807.         $font_smallest = 'x-small';
  808.     }
  809.     // OS/2 browser
  810.     else if (PMA_USR_OS == 'OS/2'
  811.                 && PMA_USR_BROWSER_AGENT == 'OPERA') {
  812.         $font_size     = 'small';
  813.         $font_biggest  = 'medium';
  814.         $font_bigger   = 'medium';
  815.         $font_smaller  = 'x-small';
  816.         $font_smallest = 'x-small';
  817.     }
  818.     else {
  819.         $font_size     = 'small';
  820.         $font_biggest  = 'large';
  821.         $font_bigger   = 'medium';
  822.         $font_smaller  = 'x-small';
  823.         $font_smallest = 'x-small';
  824.     }
  825.  
  826.     return TRUE;
  827. } // end of the 'PMA_setFontSizes()' function
  828.  
  829.  
  830. if ($is_minimum_common == FALSE) {
  831.     /**
  832.      * $cfg['PmaAbsoluteUri'] is a required directive else cookies won't be
  833.      * set properly and, depending on browsers, inserting or updating a
  834.      * record might fail
  835.      */
  836.     $display_pmaAbsoluteUri_warning = 0;
  837.  
  838.     // Olivier: Setup a default value to let the people and lazy syadmins
  839.     //          work anyway, but display a big warning on the main.php
  840.     //          page.
  841.     if (empty($cfg['PmaAbsoluteUri'])) {
  842.         if (!empty($_SERVER)) {
  843.             $SERVER_ARRAY = '_SERVER';
  844.         } else {
  845.             $SERVER_ARRAY = 'GLOBALS';
  846.         } // end if
  847.         if (isset(${$SERVER_ARRAY}['HTTP_HOST'])) {
  848.             $HTTP_HOST = ${$SERVER_ARRAY}['HTTP_HOST'];
  849.         }
  850.         if (isset(${$SERVER_ARRAY}['HTTPS'])) {
  851.             $HTTPS = ${$SERVER_ARRAY}['HTTPS'];
  852.         }
  853.         if (isset(${$SERVER_ARRAY}['SERVER_PORT'])) {
  854.             $SERVER_PORT = ${$SERVER_ARRAY}['SERVER_PORT'];
  855.         }
  856.         if (isset(${$SERVER_ARRAY}['REQUEST_URI'])) {
  857.             $REQUEST_URI = ${$SERVER_ARRAY}['REQUEST_URI'];
  858.         }
  859.         if (isset(${$SERVER_ARRAY}['PATH_INFO'])) {
  860.             $PATH_INFO = ${$SERVER_ARRAY}['PATH_INFO'];
  861.         }
  862.         if (isset(${$SERVER_ARRAY}['HTTP_SCHEME'])) {
  863.             $HTTP_SCHEME = ${$SERVER_ARRAY}['HTTP_SCHEME'];
  864.         }
  865.         if (!empty($HTTP_SCHEME)) {
  866.             $cfg['PmaAbsoluteUri']      = $HTTP_SCHEME . '://';
  867.         } else {
  868.             $cfg['PmaAbsoluteUri']      = ((!empty($HTTPS) && strtolower($HTTPS) != 'off') ? 'https' : 'http') . '://';
  869.         }
  870.         $port_in_HTTP_HOST              = (strpos($HTTP_HOST, ':') > 0);
  871.         $cfg['PmaAbsoluteUri']          .= $HTTP_HOST;
  872.  
  873.         // if $cfg['PmaAbsoluteUri'] is empty and port == 80 or port == 443, do not add ":80" or ":443"
  874.         // to the generated URL -> prevents a double password query in case of http authentication.
  875.  
  876.         if (!(!$port_in_HTTP_HOST && !empty($SERVER_PORT) && ($SERVER_PORT == 80 || $SERVER_PORT == 443))) {
  877.             $cfg['PmaAbsoluteUri']      .= ((!empty($SERVER_PORT) && !$port_in_HTTP_HOST) ? ':' . $SERVER_PORT : '');
  878.         }
  879.  
  880.         // rabus: if php is in CGI mode, $PHP_SELF often contains the path to the CGI executable.
  881.         //   This is why we try to get the path from $REQUEST_URI or $PATH_INFO first.
  882.         if (isset($REQUEST_URI)) {
  883.             $cfg['PmaAbsoluteUri']      .= substr($REQUEST_URI, 0, strrpos($REQUEST_URI, '/') + 1);
  884.         } else if (isset($PATH_INFO)) {
  885.             $cfg['PmaAbsoluteUri']      .= substr($PATH_INFO, 0, strrpos($PATH_INFO, '/') + 1);
  886.         } else {
  887.             $cfg['PmaAbsoluteUri']      .= substr($PHP_SELF, 0, strrpos($PHP_SELF, '/') + 1);
  888.         }
  889.  
  890.         // We display the warning by default, but not if it is disabled thru
  891.         // via the $cfg['PmaAbsoluteUri_DisableWarning'] variable.
  892.         // This is intended for sysadmins that actually want the default
  893.         // behaviour of auto-detection due to their setup.
  894.         // See the mailing list message:
  895.         // http://sourceforge.net/mailarchive/forum.php?thread_id=859093&forum_id=2141
  896.         if ($cfg['PmaAbsoluteUri_DisableWarning'] == FALSE) {
  897.             $display_pmaAbsoluteUri_warning = 1;
  898.         }
  899.     } else {
  900.         // The URI is specified, however users do often specify this
  901.         // wrongly, so we try to fix this.
  902.  
  903.         // Adds a trailing slash et the end of the phpMyAdmin uri if it
  904.         // does not exist.
  905.         if (substr($cfg['PmaAbsoluteUri'], -1) != '/') {
  906.             $cfg['PmaAbsoluteUri'] .= '/';
  907.         }
  908.  
  909.         // If URI doesn't start with http:// or https://, we will add
  910.         // this.
  911.         if (substr($cfg['PmaAbsoluteUri'], 0, 7) != 'http://' && substr($cfg['PmaAbsoluteUri'], 0, 8) != 'https://') {
  912.             if (!empty($_SERVER)) {
  913.                 $SERVER_ARRAY = '_SERVER';
  914.             } else {
  915.                 $SERVER_ARRAY = 'GLOBALS';
  916.             } // end if
  917.             if (isset(${$SERVER_ARRAY}['HTTPS'])) {
  918.                 $HTTPS = ${$SERVER_ARRAY}['HTTPS'];
  919.             }
  920.  
  921.             $cfg['PmaAbsoluteUri']          = ((!empty($HTTPS) && strtolower($HTTPS) != 'off') ? 'https' : 'http') . ':'
  922.                                             . (substr($cfg['PmaAbsoluteUri'], 0, 2) == '//' ? '' : '//')
  923.                                             . $cfg['PmaAbsoluteUri'];
  924.         }
  925.     }
  926.  
  927.  
  928.     /**
  929.      * Use mysql_connect() or mysql_pconnect()?
  930.      */
  931.     $connect_func = ($cfg['PersistentConnections']) ? 'mysql_pconnect' : 'mysql_connect';
  932.     $dblist       = array();
  933.  
  934.  
  935.     /**
  936.      * Gets the valid servers list and parameters
  937.      */
  938.     foreach($cfg['Servers'] AS $key => $val) {
  939.         // Don't use servers with no hostname
  940.         if ( ($val['connect_type'] == 'tcp') && empty($val['host'])) {
  941.             unset($cfg['Servers'][$key]);
  942.         }
  943.  
  944.         // Final solution to bug #582890
  945.         // If we are using a socket connection
  946.         // and there is nothing in the verbose server name
  947.         // or the host field, then generate a name for the server
  948.         // in the form of "Server 2", localized of course!
  949.         if ( ($val['connect_type'] == 'socket') && empty($val['host']) && empty($val['verbose']) ) {
  950.             $cfg['Servers'][$key]['verbose'] = sprintf($GLOBALS['strServer'], $key);
  951.             $val['verbose']                  = sprintf($GLOBALS['strServer'],$key);
  952.         }
  953.     }
  954.  
  955.     if (empty($server) || !isset($cfg['Servers'][$server]) || !is_array($cfg['Servers'][$server])) {
  956.         $server = $cfg['ServerDefault'];
  957.     }
  958.  
  959.  
  960.     /**
  961.      * If no server is selected, make sure that $cfg['Server'] is empty (so
  962.      * that nothing will work), and skip server authentication.
  963.      * We do NOT exit here, but continue on without logging into any server.
  964.      * This way, the welcome page will still come up (with no server info) and
  965.      * present a choice of servers in the case that there are multiple servers
  966.      * and '$cfg['ServerDefault'] = 0' is set.
  967.      */
  968.     if ($server == 0) {
  969.         $cfg['Server'] = array();
  970.     }
  971.  
  972.     /**
  973.      * Otherwise, set up $cfg['Server'] and do the usual login stuff.
  974.      */
  975.     else if (isset($cfg['Servers'][$server])) {
  976.         $cfg['Server'] = $cfg['Servers'][$server];
  977.  
  978.         // Check how the config says to connect to the server
  979.         $server_port   = (empty($cfg['Server']['port']))
  980.                        ? ''
  981.                        : ':' . $cfg['Server']['port'];
  982.         if (strtolower($cfg['Server']['connect_type']) == 'tcp') {
  983.             $cfg['Server']['socket'] = '';
  984.         }
  985.         $server_socket = (empty($cfg['Server']['socket']))
  986.                        ? ''
  987.                        : ':' . $cfg['Server']['socket'];
  988.         if (PMA_MYSQL_CLIENT_API >= 32349) {
  989.             $client_flags = $cfg['Server']['compress'] && defined('MYSQL_CLIENT_COMPRESS') ? MYSQL_CLIENT_COMPRESS : 0;
  990.         }
  991.  
  992.         // Gets the authentication library that fits the $cfg['Server'] settings
  993.         // and run authentication
  994.  
  995.         // (for a quick check of path disclosure in auth/cookies:)
  996.         $coming_from_common = TRUE;
  997.  
  998.         require_once('./libraries/auth/' . $cfg['Server']['auth_type'] . '.auth.lib.php');
  999.         if (!PMA_auth_check()) {
  1000.             PMA_auth();
  1001.         } else {
  1002.             PMA_auth_set_user();
  1003.         }
  1004.  
  1005.         // Check IP-based Allow/Deny rules as soon as possible to reject the
  1006.         // user
  1007.         // Based on mod_access in Apache:
  1008.         // http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/aaa/mod_access.c?rev=1.37&content-type=text/vnd.viewcvs-markup
  1009.         // Look at: "static int check_dir_access(request_rec *r)"
  1010.         // Robbat2 - May 10, 2002
  1011.         if (isset($cfg['Server']['AllowDeny']) && isset($cfg['Server']['AllowDeny']['order'])) {
  1012.             require_once('./libraries/ip_allow_deny.lib.php');
  1013.  
  1014.             $allowDeny_forbidden         = FALSE; // default
  1015.             if ($cfg['Server']['AllowDeny']['order'] == 'allow,deny') {
  1016.                 $allowDeny_forbidden     = TRUE;
  1017.                 if (PMA_allowDeny('allow')) {
  1018.                     $allowDeny_forbidden = FALSE;
  1019.                 }
  1020.                 if (PMA_allowDeny('deny')) {
  1021.                     $allowDeny_forbidden = TRUE;
  1022.                 }
  1023.             } else if ($cfg['Server']['AllowDeny']['order'] == 'deny,allow') {
  1024.                 if (PMA_allowDeny('deny')) {
  1025.                     $allowDeny_forbidden = TRUE;
  1026.                 }
  1027.                 if (PMA_allowDeny('allow')) {
  1028.                     $allowDeny_forbidden = FALSE;
  1029.                 }
  1030.             } else if ($cfg['Server']['AllowDeny']['order'] == 'explicit') {
  1031.                 if (PMA_allowDeny('allow')
  1032.                     && !PMA_allowDeny('deny')) {
  1033.                     $allowDeny_forbidden = FALSE;
  1034.                 } else {
  1035.                     $allowDeny_forbidden = TRUE;
  1036.                 }
  1037.             } // end if... else if... else if
  1038.  
  1039.             // Ejects the user if banished
  1040.             if ($allowDeny_forbidden) {
  1041.                PMA_auth_fails();
  1042.             }
  1043.             unset($allowDeny_forbidden); //Clean up after you!
  1044.         } // end if
  1045.  
  1046.         // The user can work with only some databases
  1047.         if (isset($cfg['Server']['only_db']) && $cfg['Server']['only_db'] != '') {
  1048.             if (is_array($cfg['Server']['only_db'])) {
  1049.                 $dblist   = $cfg['Server']['only_db'];
  1050.             } else {
  1051.                 $dblist[] = $cfg['Server']['only_db'];
  1052.             }
  1053.         } // end if
  1054.  
  1055.         $bkp_track_err = @ini_set('track_errors', 1);
  1056.  
  1057.         // Try to connect MySQL with the control user profile (will be used to
  1058.         // get the privileges list for the current user but the true user link
  1059.         // must be open after this one so it would be default one for all the
  1060.         // scripts)
  1061.         if ($cfg['Server']['controluser'] != '') {
  1062.             if (empty($client_flags)) {
  1063.                 $dbh            = @$connect_func(
  1064.                                       $cfg['Server']['host'] . $server_port . $server_socket,
  1065.                                       $cfg['Server']['controluser'],
  1066.                                       $cfg['Server']['controlpass']
  1067.                                   );
  1068.             } else {
  1069.                 $dbh            = @$connect_func(
  1070.                                       $cfg['Server']['host'] . $server_port . $server_socket,
  1071.                                       $cfg['Server']['controluser'],
  1072.                                       $cfg['Server']['controlpass'],
  1073.                                       FALSE,
  1074.                                       $client_flags
  1075.                                   );
  1076.             }
  1077.             if ($dbh == FALSE) {
  1078.                 if (PMA_mysql_error()) {
  1079.                     $conn_error = PMA_mysql_error();
  1080.                 } else if (isset($php_errormsg)) {
  1081.                     $conn_error = $php_errormsg;
  1082.                 } else {
  1083.                     $conn_error = 'Cannot connect: invalid settings.';
  1084.                 }
  1085.                 $local_query    = $connect_func . '('
  1086.                                 . $cfg['Server']['host'] . $server_port . $server_socket . ', '
  1087.                                 . $cfg['Server']['controluser'] . ', '
  1088.                                 . $cfg['Server']['controlpass']
  1089.                                 . (empty($client_flags) ? '' : ', FALSE, ' . $client_flags)
  1090.                                 . ')';
  1091.                 require_once('./header.inc.php');
  1092.                 //PMA_mysqlDie($conn_error, $local_query, FALSE);
  1093.                 PMA_mysqlDie($conn_error, '', FALSE);
  1094.             } // end if
  1095.         } // end if
  1096.  
  1097.         // Pass #1 of DB-Config to read in master level DB-Config will go here
  1098.         // Robbat2 - May 11, 2002
  1099.  
  1100.         // Connects to the server (validates user's login)
  1101.         if (empty($client_flags)) {
  1102.             $userlink           = @$connect_func(
  1103.                                       $cfg['Server']['host'] . $server_port . $server_socket,
  1104.                                       $cfg['Server']['user'],
  1105.                                       $cfg['Server']['password']
  1106.                                   );
  1107.         } else {
  1108.             $userlink           = @$connect_func(
  1109.                                       $cfg['Server']['host'] . $server_port . $server_socket,
  1110.                                       $cfg['Server']['user'],
  1111.                                       $cfg['Server']['password'],
  1112.                                       FALSE,
  1113.                                       $client_flags
  1114.                                   );
  1115.         }
  1116.         if ($userlink == FALSE) {
  1117.             PMA_auth_fails();
  1118.         } // end if
  1119.  
  1120.         // Pass #2 of DB-Config to read in user level DB-Config will go here
  1121.         // Robbat2 - May 11, 2002
  1122.  
  1123.         @ini_set('track_errors', $bkp_track_err);
  1124.  
  1125.         // If controluser isn't defined, use the current user settings to get
  1126.         // his rights
  1127.         if ($cfg['Server']['controluser'] == '') {
  1128.             $dbh = $userlink;
  1129.         }
  1130.  
  1131.         // Gets the mysql release number
  1132.         require_once('./libraries/defines_mysql.lib.php');
  1133.  
  1134.         /**
  1135.          * SQL Parser code
  1136.          */
  1137.         require_once('./libraries/sqlparser.lib.php');
  1138.  
  1139.         /**
  1140.          * SQL Validator interface code
  1141.          */
  1142.         require_once('./libraries/sqlvalidator.lib.php');
  1143.  
  1144.         // if 'only_db' is set for the current user, there is no need to check for
  1145.         // available databases in the "mysql" db
  1146.         $dblist_cnt = count($dblist);
  1147.         if ($dblist_cnt) {
  1148.             $true_dblist  = array();
  1149.             $is_show_dbs  = TRUE;
  1150.  
  1151.             $dblist_asterisk_bool = FALSE;
  1152.             for ($i = 0; $i < $dblist_cnt; $i++) {
  1153.  
  1154.                 // The current position
  1155.                 if ($dblist[$i] == '*' && $dblist_asterisk_bool == FALSE) {
  1156.                     $dblist_asterisk_bool = TRUE;
  1157.                     $dblist_full = PMA_safe_db_list(FALSE, $dbh, FALSE, $rs, $userlink, $cfg, $dblist);
  1158.                     foreach($dblist_full AS $dbl_key => $dbl_val) {
  1159.                         if (!in_array($dbl_val, $dblist)) {
  1160.                             $true_dblist[] = $dbl_val;
  1161.                         }
  1162.                     }
  1163.  
  1164.                     continue;
  1165.                 } elseif ($dblist[$i] == '*') {
  1166.                     // We don't want more than one asterisk inside our 'only_db'.
  1167.                     continue;
  1168.                 }
  1169.                 if ($is_show_dbs && ereg('(^|[^\])(_|%)', $dblist[$i])) {
  1170.                     $local_query = 'SHOW DATABASES LIKE \'' . $dblist[$i] . '\'';
  1171.                     $rs          = PMA_mysql_query($local_query, $dbh);
  1172.                     // "SHOW DATABASES" statement is disabled
  1173.                     if ($i == 0
  1174.                         && (PMA_mysql_error() && mysql_errno() == 1045)) {
  1175.                         $true_dblist[] = str_replace('\\_', '_', str_replace('\\%', '%', $dblist[$i]));
  1176.                         $is_show_dbs   = FALSE;
  1177.                     }
  1178.                     // Debug
  1179.                     // else if (PMA_mysql_error()) {
  1180.                     //    PMA_mysqlDie('', $local_query, FALSE);
  1181.                     // }
  1182.                     while ($row = @PMA_mysql_fetch_row($rs)) {
  1183.                         $true_dblist[] = $row[0];
  1184.                     } // end while
  1185.                     if ($rs) {
  1186.                         mysql_free_result($rs);
  1187.                     }
  1188.                 } else {
  1189.                     $true_dblist[]     = str_replace('\\_', '_', str_replace('\\%', '%', $dblist[$i]));
  1190.                 } // end if... else...
  1191.             } // end for
  1192.             $dblist       = $true_dblist;
  1193.             unset($true_dblist);
  1194.             $only_db_check = TRUE;
  1195.         } // end if
  1196.  
  1197.         // 'only_db' is empty for the current user...
  1198.         else {
  1199.             $only_db_check = FALSE;
  1200.         } // end if (!$dblist_cnt)
  1201.  
  1202.         if (isset($dblist_full) && !count($dblist_full)) {
  1203.             $dblist = PMA_safe_db_list($only_db_check, $dbh, $dblist_cnt, $rs, $userlink, $cfg, $dblist);
  1204.         }
  1205.  
  1206.     } // end server connecting
  1207.     /**
  1208.      * Missing server hostname
  1209.      */
  1210.     else {
  1211.         echo $strHostEmpty;
  1212.     }
  1213.  
  1214.  
  1215.     /**
  1216.      * Get the list and number of available databases.
  1217.      *
  1218.      * @param   string   the url to go back to in case of error
  1219.      *
  1220.      * @return  boolean  always true
  1221.      *
  1222.      * @global  array    the list of available databases
  1223.      * @global  integer  the number of available databases
  1224.      * @global  array    current configuration
  1225.      */
  1226.     function PMA_availableDatabases($error_url = '')
  1227.     {
  1228.         global $dblist;
  1229.         global $num_dbs;
  1230.         global $cfg;
  1231.  
  1232.         $num_dbs = count($dblist);
  1233.  
  1234.         // 1. A list of allowed databases has already been defined by the
  1235.         //    authentification process -> gets the available databases list
  1236.         if ($num_dbs) {
  1237.             $true_dblist = array();
  1238.             for ($i = 0; $i < $num_dbs; $i++) {
  1239.                 $dblink  = @PMA_mysql_select_db($dblist[$i]);
  1240.                 if ($dblink) {
  1241.                     $true_dblist[] = $dblist[$i];
  1242.                 } // end if
  1243.             } // end for
  1244.             $dblist      = array();
  1245.             $dblist      = $true_dblist;
  1246.             unset($true_dblist);
  1247.             $num_dbs     = count($dblist);
  1248.         } // end if
  1249.         // 2. Allowed database list is empty -> gets the list of all databases
  1250.         //    on the server
  1251.         else if (!isset($cfg['Server']['only_db']) || $cfg['Server']['only_db'] == '') {
  1252.             $dbs          = mysql_list_dbs() or PMA_mysqlDie('', 'SHOW DATABASES;', FALSE, $error_url);
  1253.             $num_dbs      = ($dbs) ? @mysql_num_rows($dbs) : 0;
  1254.             $real_num_dbs = 0;
  1255.             for ($i = 0; $i < $num_dbs; $i++) {
  1256.                 $db_name_tmp = PMA_mysql_dbname($dbs, $i);
  1257.                 $dblink      = @PMA_mysql_select_db($db_name_tmp);
  1258.                 if ($dblink) {
  1259.                     $dblist[] = $db_name_tmp;
  1260.                     $real_num_dbs++;
  1261.                 }
  1262.             } // end for
  1263.             mysql_free_result($dbs);
  1264.             $num_dbs = $real_num_dbs;
  1265.         } // end else
  1266.  
  1267.         return TRUE;
  1268.     } // end of the 'PMA_availableDatabases()' function
  1269.  
  1270.  
  1271.  
  1272.     /* ----------------------- Set of misc functions ----------------------- */
  1273.  
  1274.  
  1275.     /**
  1276.      * Adds backquotes on both sides of a database, table or field name.
  1277.      * Since MySQL 3.23.6 this allows to use non-alphanumeric characters in
  1278.      * these names.
  1279.      *
  1280.      * @param   mixed    the database, table or field name to "backquote" or
  1281.      *                   array of it
  1282.      * @param   boolean  a flag to bypass this function (used by dump
  1283.      *                   functions)
  1284.      *
  1285.      * @return  mixed    the "backquoted" database, table or field name if the
  1286.      *                   current MySQL release is >= 3.23.6, the original one
  1287.      *                   else
  1288.      *
  1289.      * @access  public
  1290.      */
  1291.     function PMA_backquote($a_name, $do_it = TRUE)
  1292.     {
  1293.         if ($do_it
  1294.             && !empty($a_name) && $a_name != '*') {
  1295.  
  1296.             if (is_array($a_name)) {
  1297.                  $result = array();
  1298.                  foreach($a_name AS $key => $val) {
  1299.                      $result[$key] = '`' . $val . '`';
  1300.                  }
  1301.                  return $result;
  1302.             } else {
  1303.                 return '`' . $a_name . '`';
  1304.             }
  1305.         } else {
  1306.             return $a_name;
  1307.         }
  1308.     } // end of the 'PMA_backquote()' function
  1309.  
  1310.  
  1311.     /**
  1312.      * Format a string so it can be passed to a javascript function.
  1313.      * This function is used to displays a javascript confirmation box for
  1314.      * "DROP/DELETE/ALTER" queries.
  1315.      *
  1316.      * @param   string   the string to format
  1317.      * @param   boolean  whether to add backquotes to the string or not
  1318.      *
  1319.      * @return  string   the formated string
  1320.      *
  1321.      * @access  public
  1322.      */
  1323.     function PMA_jsFormat($a_string = '', $add_backquotes = TRUE)
  1324.     {
  1325.         if (is_string($a_string)) {
  1326.             $a_string = htmlspecialchars($a_string);
  1327.             $a_string = str_replace('\\', '\\\\', $a_string);
  1328.             $a_string = str_replace('\'', '\\\'', $a_string);
  1329.             $a_string = str_replace('#', '\\#', $a_string);
  1330.             $a_string = str_replace("\012", '\\\\n', $a_string);
  1331.             $a_string = str_replace("\015", '\\\\r', $a_string);
  1332.         }
  1333.  
  1334.         return (($add_backquotes) ? PMA_backquote($a_string) : $a_string);
  1335.     } // end of the 'PMA_jsFormat()' function
  1336.  
  1337.  
  1338.     /**
  1339.      * Defines the <CR><LF> value depending on the user OS.
  1340.      *
  1341.      * @return  string   the <CR><LF> value to use
  1342.      *
  1343.      * @access  public
  1344.      */
  1345.     function PMA_whichCrlf()
  1346.     {
  1347.         $the_crlf = "\n";
  1348.  
  1349.         // The 'PMA_USR_OS' constant is defined in "./libraries/defines.lib.php"
  1350.         // Win case
  1351.         if (PMA_USR_OS == 'Win') {
  1352.             $the_crlf = "\r\n";
  1353.         }
  1354.         // Mac case
  1355.         else if (PMA_USR_OS == 'Mac') {
  1356.             $the_crlf = "\r";
  1357.         }
  1358.         // Others
  1359.         else {
  1360.             $the_crlf = "\n";
  1361.         }
  1362.  
  1363.         return $the_crlf;
  1364.     } // end of the 'PMA_whichCrlf()' function
  1365.  
  1366.  
  1367.     /**
  1368.      * Counts and displays the number of records in a table
  1369.      *
  1370.      * Last revision 13 July 2001: Patch for limiting dump size from
  1371.      * vinay@sanisoft.com & girish@sanisoft.com
  1372.      *
  1373.      * @param   string   the current database name
  1374.      * @param   string   the current table name
  1375.      * @param   boolean  whether to retain or to displays the result
  1376.      *
  1377.      * @return  mixed    the number of records if retain is required, true else
  1378.      *
  1379.      * @access  public
  1380.      */
  1381.     function PMA_countRecords($db, $table, $ret = FALSE)
  1382.     {
  1383.         global $err_url, $cfg;
  1384.         $local_query  = 'SHOW TABLE STATUS FROM ' . PMA_backquote($db) . ' LIKE \'' . PMA_sqlAddslashes($table, TRUE) . '\'';
  1385.         $result       = PMA_mysql_query($local_query) or PMA_mysqlDie('', $local_query, '', $err_url);
  1386.         $showtable    = PMA_mysql_fetch_array($result);
  1387.         $num     = (isset($showtable['Rows']) ? $showtable['Rows'] : 0);
  1388.         if ($num < $cfg['MaxExactCount']) {
  1389.             unset($num);
  1390.         }
  1391.         mysql_free_result($result);
  1392.  
  1393.         if (!isset($num)) {
  1394.             $result = PMA_mysql_query('SELECT COUNT(*) AS num FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table)) or PMA_mysqlDie('', $local_query, '', $err_url);
  1395.             $num    = ($result) ? PMA_mysql_result($result, 0, 'num') : 0;
  1396.             mysql_free_result($result);
  1397.         }
  1398.         if ($ret) {
  1399.             return $num;
  1400.         } else {
  1401.             echo number_format($num, 0, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
  1402.             return TRUE;
  1403.         }
  1404.     } // end of the 'PMA_countRecords()' function
  1405.  
  1406.  
  1407.     /**
  1408.      * Displays a message at the top of the "main" (right) frame
  1409.      *
  1410.      * @param   string  the message to display
  1411.      *
  1412.      * @global  array   the configuration array
  1413.      *
  1414.      * @access  public
  1415.      */
  1416.     function PMA_showMessage($message)
  1417.     {
  1418.         global $cfg;
  1419.  
  1420.         require_once('./header.inc.php');
  1421.  
  1422.         // Reloads the navigation frame via JavaScript if required
  1423.         if (isset($GLOBALS['reload']) && $GLOBALS['reload']) {
  1424.             echo "\n";
  1425.             $reload_url = './left.php?' . PMA_generate_common_url((isset($GLOBALS['db']) ? $GLOBALS['db'] : ''), '', '&')
  1426.             ?>
  1427. <script type="text/javascript" language="javascript1.2">
  1428. <!--
  1429. if (typeof(window.parent) != 'undefined'
  1430.     && typeof(window.parent.frames['nav']) != 'undefined') {
  1431.     window.parent.frames['nav'].location.replace('<?php echo $reload_url; ?>&hash=' + <?php echo (($cfg['QueryFrame'] && $cfg['QueryFrameJS']) ? 'window.parent.frames[\'queryframe\'].document.hashform.hash.value' : "'" . md5($cfg['PmaAbsoluteUri']) . "'"); ?>);
  1432. }
  1433. //-->
  1434. </script>
  1435.             <?php
  1436.             unset($GLOBALS['reload']);
  1437.         }
  1438.  
  1439.         // Corrects the tooltip text via JS if required
  1440.         else if (!empty($GLOBALS['table']) && $cfg['ShowTooltip']) {
  1441.             $result = @PMA_mysql_query('SHOW TABLE STATUS FROM ' . PMA_backquote($GLOBALS['db']) . ' LIKE \'' . PMA_sqlAddslashes($GLOBALS['table'], TRUE) . '\'');
  1442.             if ($result) {
  1443.                 $tbl_status = PMA_mysql_fetch_array($result, MYSQL_ASSOC);
  1444.                 $tooltip    = (empty($tbl_status['Comment']))
  1445.                             ? ''
  1446.                             : $tbl_status['Comment'] . ' ';
  1447.                 $tooltip .= '(' . $tbl_status['Rows'] . ' ' . $GLOBALS['strRows'] . ')';
  1448.                 mysql_free_result($result);
  1449.                 $md5_tbl = md5($GLOBALS['table']);
  1450.                 echo "\n";
  1451.                 ?>
  1452. <script type="text/javascript" language="javascript1.2">
  1453. <!--
  1454. if (typeof(document.getElementById) != 'undefined'
  1455.     && typeof(window.parent.frames['nav']) != 'undefined'
  1456.     && typeof(window.parent.frames['nav'].document) != 'undefined' && typeof(window.parent.frames['nav'].document) != 'unknown'
  1457.     && (window.parent.frames['nav'].document.getElementById('<?php echo 'tbl_' . $md5_tbl; ?>'))
  1458.     && typeof(window.parent.frames['nav'].document.getElementById('<?php echo 'tbl_' . $md5_tbl; ?>')) != 'undefined'
  1459.     && typeof(window.parent.frames['nav'].document.getElementById('<?php echo 'tbl_' . $md5_tbl; ?>').title) == 'string') {
  1460.     window.parent.frames['nav'].document.getElementById('<?php echo 'tbl_' . $md5_tbl; ?>').title = '<?php echo PMA_jsFormat($tooltip, FALSE); ?>';
  1461. }
  1462. //-->
  1463. </script>
  1464.                 <?php
  1465.             } // end if
  1466.         } // end if... else if
  1467.  
  1468.         // Checks if the table needs to be repaired after a TRUNCATE query.
  1469.         if (isset($GLOBALS['table']) && isset($GLOBALS['sql_query'])
  1470.             && $GLOBALS['sql_query'] == 'TRUNCATE TABLE ' . PMA_backquote($GLOBALS['table'])) {
  1471.             if (!isset($tbl_status)) {
  1472.                 $result = @PMA_mysql_query('SHOW TABLE STATUS FROM ' . PMA_backquote($GLOBALS['db']) . ' LIKE \'' . PMA_sqlAddslashes($GLOBALS['table'], TRUE) . '\'');
  1473.                 if ($result) {
  1474.                     $tbl_status = PMA_mysql_fetch_array($result, MYSQL_ASSOC);
  1475.                     mysql_free_result($result);
  1476.                 }
  1477.             }
  1478.             if (isset($tbl_status) && (int) $tbl_status['Index_length'] > 1024) {
  1479.                 @PMA_mysql_query('REPAIR TABLE ' . PMA_backquote($GLOBALS['table']));
  1480.             }
  1481.         }
  1482.         unset($tbl_status);
  1483.  
  1484.         echo "\n";
  1485.         ?>
  1486. <div align="<?php echo $GLOBALS['cell_align_left']; ?>">
  1487.     <table border="<?php echo $cfg['Border']; ?>" cellpadding="5">
  1488.     <tr>
  1489.         <td bgcolor="<?php echo $cfg['ThBgcolor']; ?>">
  1490.             <b><?php echo $message; ?></b><br />
  1491.         </td>
  1492.     </tr>
  1493.         <?php
  1494.         if ($cfg['ShowSQL'] == TRUE && (!empty($GLOBALS['sql_query']) || !empty($GLOBALS['display_query']))) {
  1495.             $local_query = !empty($GLOBALS['display_query']) ? $GLOBALS['display_query'] : (($cfg['SQP']['fmtType'] == 'none' && $GLOBALS['unparsed_sql'] != '') ? $GLOBALS['unparsed_sql'] : $GLOBALS['sql_query']);
  1496.             // Basic url query part
  1497.             $url_qpart = '?' . PMA_generate_common_url(isset($GLOBALS['db']) ? $GLOBALS['db'] : '', isset($GLOBALS['table']) ? $GLOBALS['table'] : '');
  1498.             echo "\n";
  1499.             ?>
  1500.     <tr>
  1501.         <td bgcolor="<?php echo $cfg['BgcolorOne']; ?>">
  1502.             <?php
  1503.             echo "\n";
  1504.             // Html format the query to be displayed
  1505.             // The nl2br function isn't used because its result isn't a valid
  1506.             // xhtml1.0 statement before php4.0.5 ("<br>" and not "<br />")
  1507.             // If we want to show some sql code it is easiest to create it here
  1508.              /* SQL-Parser-Analyzer */
  1509.             $sqlnr = 1;
  1510.             if (!empty($GLOBALS['show_as_php'])) {
  1511.                 $new_line = '\'<br />' . "\n" . '        . \' ';
  1512.             }
  1513.             if (isset($new_line)) {
  1514.                  /* SQL-Parser-Analyzer */
  1515.                 $query_base = PMA_sqlAddslashes(htmlspecialchars($local_query));
  1516.                  /* SQL-Parser-Analyzer */
  1517.                 $query_base = preg_replace("@((\015\012)|(\015)|(\012))+@", $new_line, $query_base);
  1518.             } else {
  1519.                 $query_base = $local_query;
  1520.             }
  1521.             if (!empty($GLOBALS['show_as_php'])) {
  1522.                 $query_base = '$sql  = \'' . $query_base;
  1523.             } else if (!empty($GLOBALS['validatequery'])) {
  1524.                 $query_base = PMA_validateSQL($query_base);
  1525.             } else {
  1526.                 $parsed_sql = PMA_SQP_parse($query_base);
  1527.                 $query_base = PMA_formatSql($parsed_sql, $query_base);
  1528.             }
  1529.  
  1530.             // Prepares links that may be displayed to edit/explain the query
  1531.             // (don't go to default pages, we must go to the page
  1532.             // where the query box is available)
  1533.             // (also, I don't see why we should check the goto variable)
  1534.  
  1535.             //if (!isset($GLOBALS['goto'])) {
  1536.                 //$edit_target = (isset($GLOBALS['table'])) ? $cfg['DefaultTabTable'] : $cfg['DefaultTabDatabase'];
  1537.             $edit_target = isset($GLOBALS['db']) ? (isset($GLOBALS['table']) ? 'tbl_properties.php' : 'db_details.php') : '';
  1538.             //} else if ($GLOBALS['goto'] != 'main.php') {
  1539.             //    $edit_target = $GLOBALS['goto'];
  1540.             //} else {
  1541.             //    $edit_target = '';
  1542.             //}
  1543.  
  1544.             if (isset($cfg['SQLQuery']['Edit'])
  1545.                 && ($cfg['SQLQuery']['Edit'] == TRUE )
  1546.                 && (!empty($edit_target))) {
  1547.  
  1548.                 $onclick = '';
  1549.                 if ($cfg['QueryFrameJS'] && $cfg['QueryFrame']) {
  1550.                     $onclick = 'onclick="focus_querywindow(\'' . urlencode($local_query) . '\'); return false;"';
  1551.                 }
  1552.  
  1553.                 $edit_link = ' [<a href="'
  1554.                            . $edit_target
  1555.                            . $url_qpart
  1556.                            . '&sql_query=' . urlencode($local_query) . '&show_query=1#querybox" ' . $onclick . '>' . $GLOBALS['strEdit'] . '</a>]';
  1557.             } else {
  1558.                 $edit_link = '';
  1559.             }
  1560.  
  1561.             // Want to have the query explained (Mike Beck 2002-05-22)
  1562.             // but only explain a SELECT (that has not been explained)
  1563.             /* SQL-Parser-Analyzer */
  1564.             if (isset($cfg['SQLQuery']['Explain'])
  1565.                 && $cfg['SQLQuery']['Explain'] == TRUE) {
  1566.  
  1567.                 // Detect if we are validating as well
  1568.                 // To preserve the validate uRL data
  1569.                 if (!empty($GLOBALS['validatequery'])) {
  1570.                     $explain_link_validate = '&validatequery=1';
  1571.                 } else {
  1572.                     $explain_link_validate = '';
  1573.                 }
  1574.  
  1575.                 $explain_link = ' [<a href="sql.php'
  1576.                               . $url_qpart
  1577.                               . $explain_link_validate
  1578.                               . '&sql_query=';
  1579.  
  1580.                 if (preg_match('@^SELECT[[:space:]]+@i', $local_query)) {
  1581.                     $explain_link .= urlencode('EXPLAIN ' . $local_query) . '">' . $GLOBALS['strExplain'];
  1582.                 } else if (preg_match('@^EXPLAIN[[:space:]]+SELECT[[:space:]]+@i', $local_query)) {
  1583.                     $explain_link .= urlencode(substr($local_query, 8)) . '">' . $GLOBALS['strNoExplain'];
  1584.                 } else {
  1585.                     $explain_link = '';
  1586.                 }
  1587.                 if(!empty($explain_link)) {
  1588.                     $explain_link .= '</a>]';
  1589.                 }
  1590.             } else {
  1591.                 $explain_link = '';
  1592.             } //show explain
  1593.  
  1594.             // Also we would like to get the SQL formed in some nice
  1595.             // php-code (Mike Beck 2002-05-22)
  1596.             if (isset($cfg['SQLQuery']['ShowAsPHP'])
  1597.                 && $cfg['SQLQuery']['ShowAsPHP'] == TRUE) {
  1598.                 $php_link = ' [<a href="sql.php'
  1599.                           . $url_qpart
  1600.                           . '&show_query=1'
  1601.                           . '&sql_query=' . urlencode($local_query)
  1602.                           . '&show_as_php=';
  1603.  
  1604.                 if (!empty($GLOBALS['show_as_php'])) {
  1605.                     $php_link .= '0">' . $GLOBALS['strNoPhp'];
  1606.                 } else {
  1607.                     $php_link .= '1">' . $GLOBALS['strPhp'];
  1608.                 }
  1609.                 $php_link .= '</a>]';
  1610.  
  1611.                 if (isset($GLOBALS['show_as_php']) && $GLOBALS['show_as_php'] == '1') {
  1612.                     $php_link .= ' [<a href="sql.php'
  1613.                               . $url_qpart
  1614.                               . '&show_query=1'
  1615.                               . '&sql_query=' . urlencode($local_query)
  1616.                               . '">' . $GLOBALS['strRunQuery'] . '</a>]';
  1617.                 }
  1618.  
  1619.             } else {
  1620.                 $php_link = '';
  1621.             } //show as php
  1622.  
  1623.             if (isset($cfg['SQLValidator']['use'])
  1624.                 && $cfg['SQLValidator']['use'] == TRUE
  1625.                 && isset($cfg['SQLQuery']['Validate'])
  1626.                 && $cfg['SQLQuery']['Validate'] == TRUE) {
  1627.                 $validate_link = ' [<a href="sql.php'
  1628.                                . $url_qpart
  1629.                                . '&show_query=1'
  1630.                                . '&sql_query=' . urlencode($local_query)
  1631.                                . '&validatequery=';
  1632.                 if (!empty($GLOBALS['validatequery'])) {
  1633.                     $validate_link .= '0">' .  $GLOBALS['strNoValidateSQL'] ;
  1634.                 } else {
  1635.                     $validate_link .= '1">'. $GLOBALS['strValidateSQL'] ;
  1636.                 }
  1637.                 $validate_link .= '</a>]';
  1638.             } else {
  1639.                 $validate_link = '';
  1640.             } //validator
  1641.  
  1642.             // Displays the message
  1643.             echo '            ' . $GLOBALS['strSQLQuery'] . ' :';
  1644.             if (!empty($edit_target)) {
  1645.                 echo $edit_link . $explain_link . $php_link . $validate_link;
  1646.             }
  1647.             echo '<br />' . "\n";
  1648.             echo '            ' . $query_base;
  1649.             // If a 'LIMIT' clause has been programatically added to the query
  1650.             // displays it
  1651.             if (!empty($GLOBALS['sql_limit_to_append'])) {
  1652.                 if (!empty($GLOBALS['show_as_php'])) {
  1653.                     echo $GLOBALS['sql_limit_to_append'];
  1654.                 } else if (!empty($GLOBALS['validatequery'])) {
  1655.                     // skip the extra bit here
  1656.                 } else {
  1657.                     echo ' ' . PMA_formatSql(PMA_SQP_parse($GLOBALS['sql_limit_to_append'], $GLOBALS['sql_limit_to_append']));
  1658.                 }
  1659.             }
  1660.  
  1661.             unset($local_query);
  1662.             //Clean up the end of the PHP
  1663.             if (!empty($GLOBALS['show_as_php'])) {
  1664.                 echo '\';';
  1665.             }
  1666.             echo "\n";
  1667.             ?>
  1668.         </td>
  1669.     </tr>
  1670.            <?php
  1671.         }
  1672.         echo "\n";
  1673.         ?>
  1674.     </table>
  1675. </div><br />
  1676.         <?php
  1677.     } // end of the 'PMA_showMessage()' function
  1678.  
  1679.  
  1680.     /**
  1681.      * Formats $value to byte view
  1682.      *
  1683.      * @param    double   the value to format
  1684.      * @param    integer  the sensitiveness
  1685.      * @param    integer  the number of decimals to retain
  1686.      *
  1687.      * @return   array    the formatted value and its unit
  1688.      *
  1689.      * @access  public
  1690.      *
  1691.      * @author   staybyte
  1692.      * @version  1.2 - 18 July 2002
  1693.      */
  1694.     function PMA_formatByteDown($value, $limes = 6, $comma = 0)
  1695.     {
  1696.         $dh           = pow(10, $comma);
  1697.         $li           = pow(10, $limes);
  1698.         $return_value = $value;
  1699.         $unit         = $GLOBALS['byteUnits'][0];
  1700.  
  1701.         for ( $d = 6, $ex = 15; $d >= 1; $d--, $ex-=3 ) {
  1702.             if (isset($GLOBALS['byteUnits'][$d]) && $value >= $li * pow(10, $ex)) {
  1703.                 $value = round($value / ( pow(1024, $d) / $dh) ) /$dh;
  1704.                 $unit = $GLOBALS['byteUnits'][$d];
  1705.                 break 1;
  1706.             } // end if
  1707.         } // end for
  1708.  
  1709.         if ($unit != $GLOBALS['byteUnits'][0]) {
  1710.             $return_value = number_format($value, $comma, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
  1711.         } else {
  1712.             $return_value = number_format($value, 0, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
  1713.         }
  1714.  
  1715.         return array($return_value, $unit);
  1716.     } // end of the 'PMA_formatByteDown' function
  1717.  
  1718.  
  1719.     /**
  1720.      * Extracts ENUM / SET options from a type definition string
  1721.      *
  1722.      * @param   string   The column type definition
  1723.      *
  1724.      * @return  array    The options or
  1725.      *          boolean  FALSE in case of an error.
  1726.      *
  1727.      * @author  rabus
  1728.      */
  1729.     function PMA_getEnumSetOptions($type_def) {
  1730.         $open = strpos($type_def, '(');
  1731.         $close = strrpos($type_def, ')');
  1732.         if (!$open || !$close) {
  1733.             return FALSE;
  1734.         }
  1735.         $options = substr($type_def, $open + 2, $close - $open - 3);
  1736.         $options = explode('\',\'', $options);
  1737.         return $options;
  1738.     } // end of the 'PMA_getEnumSetOptions' function
  1739.  
  1740.     /**
  1741.      * Writes localised date
  1742.      *
  1743.      * @param   string   the current timestamp
  1744.      *
  1745.      * @return  string   the formatted date
  1746.      *
  1747.      * @access  public
  1748.      */
  1749.     function PMA_localisedDate($timestamp = -1, $format = '')
  1750.     {
  1751.         global $datefmt, $month, $day_of_week;
  1752.  
  1753.         if ($format == '') {
  1754.             $format = $datefmt;
  1755.         }
  1756.  
  1757.         if ($timestamp == -1) {
  1758.             $timestamp = time();
  1759.         }
  1760.  
  1761.         $date = preg_replace('@%[aA]@', $day_of_week[(int)strftime('%w', $timestamp)], $format);
  1762.         $date = preg_replace('@%[bB]@', $month[(int)strftime('%m', $timestamp)-1], $date);
  1763.  
  1764.         return strftime($date, $timestamp);
  1765.     } // end of the 'PMA_localisedDate()' function
  1766.  
  1767.  
  1768.     /**
  1769.      * Prints out a tab for tabbed navigation.
  1770.      * If the variables $link and $args ar left empty, an inactive tab is created
  1771.      *
  1772.      * @param   string  the text to be displayed as link
  1773.      * @param   string  main link file, e.g. "test.php"
  1774.      * @param   string  link arguments
  1775.      * @param   string  link attributes
  1776.      * @param   string  include '?' even though no attributes are set. Can be set empty, should be '?'.
  1777.      * @param   boolean force display TAB as active
  1778.      *
  1779.      * @return  string  two table cells, the first beeing a separator, the second the tab itself
  1780.      *
  1781.      * @access  public
  1782.      */
  1783.     function PMA_printTab($text, $link, $args = '', $attr = '', $sep = '?', $active = false) {
  1784.         global $PHP_SELF, $cfg;
  1785.         global $db_details_links_count_tabs;
  1786.  
  1787.         if (((!isset($GLOBALS['active_page']) && basename($PHP_SELF) == $link) ||
  1788.                 $active ||
  1789.                 (isset($GLOBALS['active_page']) && $GLOBALS['active_page'] == $link)
  1790.             ) && ($text != $GLOBALS['strEmpty'] && $text != $GLOBALS['strDrop'])) {
  1791.             $bgcolor = 'silver';
  1792.         } else {
  1793.             $bgcolor = '#DFDFDF';
  1794.         }
  1795.  
  1796.         $db_details_links_count_tabs++;
  1797.         if (!empty($attr)) {
  1798.             if ($cfg['LightTabs']) {
  1799.                 $attr = ' ' . $attr;
  1800.             } else {
  1801.                 $attr = ' style="display:block" ' . $attr;
  1802.             }
  1803.         } else {
  1804.             if ($cfg['LightTabs']) {
  1805.                 $attr = ' ';
  1806.             } else {
  1807.                 $attr = ' style="display:block" ';
  1808.             }
  1809.         }
  1810.  
  1811.         if ($cfg['LightTabs']) {
  1812.             $out = '';
  1813.             if (strlen($link) > 0) {
  1814.                 $out .= '<nobr><a href="' . $link . $sep . $args . '"' . $attr . '>'
  1815.                      .  '<b>' . $text . '</b></a></nobr>';
  1816.             } else {
  1817.                 $out .= '<nobr><b>' . $text . '</b></nobr>';
  1818.             }
  1819.             $out = '[ ' . $out . ' ]   ';
  1820.         } else {
  1821.             $out     = "\n" . '        '
  1822.                      . '<td bgcolor="' . $bgcolor . '" align="center" width="64" nowrap="nowrap" class="tab">'
  1823.                      . "\n" . '            ';
  1824.             if (strlen($link) > 0) {
  1825.                 $out .= '<nobr><a href="' . $link . $sep . $args . '"' . $attr . '>'
  1826.                      .  '<b>' . $text . '</b></a></nobr>';
  1827.             } else {
  1828.                 $out .= '<nobr><b>' . $text . '</b></nobr>';
  1829.             }
  1830.             $out     .= "\n" . '        '
  1831.                      .  '</td>'
  1832.                      .  "\n" . '        '
  1833.                      .  '<td width="8"> </td>';
  1834.         }
  1835.  
  1836.         return $out;
  1837.     } // end of the 'PMA_printTab()' function
  1838.  
  1839.  
  1840.     /**
  1841.      * Displays a link, or a button if the link's URL is too large, to
  1842.      * accommodate some browsers' limitations
  1843.      *
  1844.      * @param  string  the URL
  1845.      * @param  string  the link message
  1846.      * @param  string  js confirmation
  1847.      *
  1848.      * @return string  the results to be echoed or saved in an array
  1849.      */
  1850.     function PMA_linkOrButton($url, $message, $js_conf)
  1851.     {
  1852.         if (strlen($url) <= 2047) {
  1853.             $onclick_url        = (empty($js_conf) ? '' : ' onclick="return confirmLink(this, \'' . $js_conf . '\')"');
  1854.             $link_or_button     = '        <a href="' . $url . '"' . $onclick_url . '>' . "\n"
  1855.                                 . '           ' . $message . '</a>' . "\n";
  1856.         }
  1857.         else {
  1858.             $edit_url_parts     = parse_url($url);
  1859.             $query_parts        = explode('&', $edit_url_parts['query']);
  1860.             $link_or_button     = '        <form action="'
  1861.                                 . $edit_url_parts['path']
  1862.                                 . '" method="post">' . "\n";
  1863.             foreach($query_parts AS $query_pair) {
  1864.                 list($eachvar, $eachval) = explode('=', $query_pair);
  1865.                 $link_or_button .= '            <input type="hidden" name="' . str_replace('amp;', '', $eachvar) . '" value="' . htmlspecialchars(urldecode($eachval)) . '" />' . "\n";
  1866.             } // end while
  1867.  
  1868.             if (stristr($message, '<img')) {
  1869.                 $link_or_button     .= '            <input type="image" src="' . preg_replace('@^.*src="(.*)".*$@si', '\1', $message) . '" value="'
  1870.                                     . htmlspecialchars(preg_replace('@^.*alt="(.*)".*$@si', '\1', $message)) . '" />' . "\n" . '</form>' . "\n";
  1871.             } else {
  1872.                 $link_or_button     .= '            <input type="submit" value="'
  1873.                                     . htmlspecialchars($message) . '" />' . "\n" . '</form>' . "\n";
  1874.             }
  1875.         } // end if... else...
  1876.  
  1877.         return $link_or_button;
  1878.     } // end of the 'PMA_linkOrButton()' function
  1879.  
  1880.  
  1881.     /**
  1882.      * Returns a given timespan value in a readable format.
  1883.      *
  1884.      * @param  int     the timespan
  1885.      *
  1886.      * @return string  the formatted value
  1887.      */
  1888.     function PMA_timespanFormat($seconds)
  1889.     {
  1890.         $return_string = '';
  1891.         $days = floor($seconds / 86400);
  1892.         if ($days > 0) {
  1893.             $seconds -= $days * 86400;
  1894.         }
  1895.         $hours = floor($seconds / 3600);
  1896.         if ($days > 0 || $hours > 0) {
  1897.             $seconds -= $hours * 3600;
  1898.         }
  1899.         $minutes = floor($seconds / 60);
  1900.         if ($days > 0 || $hours > 0 || $minutes > 0) {
  1901.             $seconds -= $minutes * 60;
  1902.         }
  1903.         return sprintf($GLOBALS['timespanfmt'], (string)$days, (string)$hours, (string)$minutes, (string)$seconds);
  1904.     }
  1905.  
  1906.     /**
  1907.      * Takes a string and outputs each character on a line for itself. Used mainly for horizontalflipped display mode.
  1908.      * Takes care of special html-characters.
  1909.      * Fulfills todo-item http://sourceforge.net/tracker/index.php?func=detail&aid=544361&group_id=23067&atid=377411
  1910.      *
  1911.      * @param   string   The string
  1912.      * @param   string   The Separator (defaults to "<br />\n")
  1913.      *
  1914.      * @access  public
  1915.      * @author  Garvin Hicking <me@supergarv.de>
  1916.      * @return  string      The flipped string
  1917.      */
  1918.     function PMA_flipstring($string, $Separator = "<br />\n") {
  1919.         $format_string = '';
  1920.         $charbuff = false;
  1921.  
  1922.         for ($i = 0; $i <= strlen($string); $i++) {
  1923.             $char = $string{$i};
  1924.             $append = false;
  1925.  
  1926.             if ($char == '&') {
  1927.                 $format_string .= $charbuff;
  1928.                 $charbuff = $char;
  1929.                 $append = true;
  1930.             } elseif (!empty($charbuff)) {
  1931.                 $charbuff .= $char;
  1932.             } elseif ($char == ';' && !empty($charbuff)) {
  1933.                 $format_string .= $charbuff;
  1934.                 $charbuff = false;
  1935.                 $append = true;
  1936.             } else {
  1937.                 $format_string .= $char;
  1938.                 $append = true;
  1939.             }
  1940.  
  1941.             if ($append && ($i != strlen($string))) {
  1942.                 $format_string .= $Separator;
  1943.             }
  1944.         }
  1945.  
  1946.         return $format_string;
  1947.     }
  1948.  
  1949.  
  1950.     /**
  1951.      * Function added to avoid path disclosures.
  1952.      * Called by each script that needs parameters, it displays
  1953.      * an error message and, by defaults, stops the execution.
  1954.      *
  1955.      * @param   array   The names of the parameters needed by the calling
  1956.      *                  script.
  1957.      * @param   boolean Stop the execution?
  1958.      *                  (Set this manually to FALSE in the calling script
  1959.      *                   until you know all needed parameters to check).
  1960.      *
  1961.      * @access  public
  1962.      * @author  Marc Delisle (lem9@users.sourceforge.net)
  1963.      */
  1964.     function PMA_checkParameters($params, $die = TRUE) {
  1965.         global $PHP_SELF;
  1966.  
  1967.         $reported_script_name = basename($PHP_SELF);
  1968.         $found_error = FALSE;
  1969.         $error_message = '';
  1970.  
  1971.         foreach($params AS $param) {
  1972.             if (!isset($GLOBALS[$param])) {
  1973.                 $error_message .= $reported_script_name . ': Missing ' . $param . '<br />';
  1974.                 $found_error = TRUE;
  1975.             }
  1976.         }
  1977.         if ($found_error) {
  1978.             require_once('./libraries/header_meta_style.inc.php');
  1979.             echo '</head><body><p>' . $error_message . '</p></body></html>';
  1980.             if ($die) {
  1981.                 exit();
  1982.             }
  1983.         }
  1984.     } // end function
  1985.  
  1986.  
  1987.     // Kanji encoding convert feature appended by Y.Kawada (2002/2/20)
  1988.     if (@function_exists('mb_convert_encoding')
  1989.         && strpos(' ' . $lang, 'ja-')
  1990.         && file_exists('./libraries/kanji-encoding.lib.php')) {
  1991.         require_once('./libraries/kanji-encoding.lib.php');
  1992.         define('PMA_MULTIBYTE_ENCODING', 1);
  1993.     } // end if
  1994.  
  1995.     /**
  1996.      * Function to check valid extension of file. It accepts entered
  1997.      * extensions and bz2 and gz if supported.
  1998.      *
  1999.      * @param   string  File name to be tested.
  2000.      * @param   string  Extension that is valid.
  2001.      *
  2002.      * @access  public
  2003.      * @author  Michal Cihar (nijel@users.sourceforge.net)
  2004.      */
  2005.     function PMA_checkFileExtensions($file, $extension) {
  2006.         if (substr($file, -1 * strlen($extension)) == $extension) {
  2007.             return TRUE;
  2008.         }
  2009.         if ($GLOBALS['cfg']['GZipDump'] && @function_exists('gzopen')) {
  2010.             if (substr($file, -3 - strlen($extension)) == $extension . '.gz') {
  2011.                 return TRUE;
  2012.             }
  2013.         }
  2014.         if ($GLOBALS['cfg']['BZipDump'] && @function_exists('bzdecompress')) {
  2015.             if (substr($file, -4 - strlen($extension)) == $extension . '.bz2') {
  2016.                 return TRUE;
  2017.             }
  2018.         }
  2019.         return FALSE;
  2020.     } // end function
  2021.  
  2022. } // end if: minimal common.lib needed?
  2023. ?>
  2024.