home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 April / PCWorld_2005-04_cd.bin / akce / web / phptriad / phptriad2-2-1.exe / htdocs / phpmyadmin / libraries / common.lib.php < prev    next >
PHP Script  |  2002-01-06  |  38KB  |  1,012 lines

  1. <?php
  2. /* $Id: common.lib.php,v 1.47 2001/12/29 17:25:16 loic1 Exp $ */
  3.  
  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.  
  12. if (!defined('PMA_COMMON_LIB_INCLUDED')){
  13.     define('PMA_COMMON_LIB_INCLUDED', 1);
  14.  
  15.     /**
  16.      * Order of sections for common.lib.php:
  17.      *
  18.      * in PHP3, functions and constants must be physically defined
  19.      * before they are referenced
  20.      *
  21.      * some functions need the constants of libraries/defines.lib.php
  22.      *
  23.      * the include of libraries/defines.lib.php must be after the connection
  24.      * to db to get the MySql version
  25.      *
  26.      * the PMA_sqlAddslashes() function must be before the connection to db
  27.      *
  28.      * the authentication libraries must be before the connection to db but
  29.      * after the PMA_isInto() function
  30.      *
  31.      * the PMA_mysqlDie() function must be before the connection to db but after
  32.      * mysql extension has been loaded
  33.      *
  34.      * ... so the required order is:
  35.      *
  36.      * - parsing of the configuration file
  37.      * - first load of the libraries/define.lib.php library (won't get the
  38.      *   MySQL release number)
  39.      * - load of mysql extension (if necessary)
  40.      * - definition of PMA_sqlAddslashes()
  41.      * - definition of PMA_mysqlDie()
  42.      * - definition of PMA_isInto()
  43.      * - loading of an authentication library
  44.      * - db connection
  45.      * - authentication work
  46.      * - second load of the libraries/define.lib.php library to get the MySQL
  47.      *   release number)
  48.      * - other functions, respecting dependencies 
  49.      */
  50.  
  51.  
  52.     /**
  53.      * Avoids undefined variables in PHP3
  54.      */
  55.     if (!isset($use_backquotes)) {
  56.         $use_backquotes   = 0;
  57.     }
  58.     if (!isset($pos)) {
  59.         $pos              = 0;
  60.     }
  61.  
  62.  
  63.     /**
  64.      * Parses the configuration file and gets some constants used to define
  65.      * versions of phpMyAdmin/php/mysql...
  66.      */
  67.     include('./config.inc.php');
  68.  
  69.     // For compatibility with old config.inc.php
  70.     if (!isset($cfgExecTimeLimit)) {
  71.         $cfgExecTimeLimit       = 300; // 5 minuts
  72.     }
  73.     if (!isset($cfgShowStats)) {
  74.         $cfgShowStats           = TRUE;
  75.     }
  76.     if (!isset($cfgShowTooltip)) {
  77.         $cfgShowTooltip         = TRUE;
  78.     }
  79.     if (!isset($cfgShowMysqlInfo)) {
  80.         $cfgShowMysqlInfo       = FALSE;
  81.     }
  82.     if (!isset($cfgShowMysqlVars)) {
  83.         $cfgShowMysqlVars       = FALSE;
  84.     }
  85.     if (!isset($cfgShowPhpInfo)) {
  86.         $cfgShowPhpInfo         = FALSE;
  87.     }
  88.     if (!isset($cfgShowAll)) {
  89.         $cfgShowAll             = FALSE;
  90.     }
  91.     if (!isset($cfgNavigationBarIconic)) {
  92.         $cfgNavigationBarIconic = TRUE;
  93.     }
  94.     if (!isset($cfgProtectBinary)) {
  95.         if (isset($cfgProtectBlob)) {
  96.             $cfgProtectBinary   = ($cfgProtectBlob ? 'blob' : FALSE);
  97.             unset($cfgProtectBlob);
  98.         } else {
  99.             $cfgProtectBinary   = 'blob';
  100.         }
  101.     }
  102.     if (!isset($cfgZipDump)) {
  103.         $cfgZipDump             = (isset($cfgGZipDump) ? $cfgGZipDump : TRUE);
  104.     }
  105.     if (!isset($cfgLeftBgColor)) {
  106.         $cfgLeftBgColor         = '#D0DCE0';
  107.     }
  108.     if (!isset($cfgLeftPointerColor)) {
  109.         $cfgLeftPointerColor  = '';
  110.     }
  111.     if (!isset($cfgRightBgColor)) {
  112.         $cfgRightBgColor        = '#F5F5F5';
  113.     }
  114.     if (!isset($cfgBrowsePointerColor)) {
  115.         $cfgBrowsePointerColor  = '';
  116.     }
  117.     if (!isset($cfgTextareaCols)) {
  118.         $cfgTextareaCols        = 40;
  119.     }
  120.     if (!isset($cfgTextareaRows)) {
  121.         $cfgTextareaRows        = 7;
  122.     }
  123.     if (!isset($cfgDefaultDisplay)) {
  124.         $cfgDefaultDisplay      = 'horizontal';
  125.     }
  126.     if (!isset($cfgRepeatCells)) {
  127.         $cfgRepeatCells         = 100;
  128.     }
  129.  
  130.     // Adds a trailing slash et the end of the phpMyAdmin uri if it does not
  131.     // exist
  132.     if ($cfgPmaAbsoluteUri != '' && substr($cfgPmaAbsoluteUri, -1) != '/') {
  133.         $cfgPmaAbsoluteUri .= '/';
  134.     }
  135.  
  136.     // Gets some constants
  137.     include('./libraries/defines.lib.php');
  138.  
  139.     // If zlib output compression is set in the php configuration file, no
  140.     // output buffering should be run
  141.     if (PMA_PHP_INT_VERSION < 40000
  142.         || (PMA_PHP_INT_VERSION >= 40005 && @ini_get('zlib.output_compression'))) {
  143.         $cfgOBGzip = FALSE;
  144.     }
  145.  
  146.  
  147.     /**
  148.      * Loads the mysql extensions if it is not loaded yet
  149.      * staybyte - 26. June 2001
  150.      */
  151.     if (((PMA_PHP_INT_VERSION >= 40000 && !@ini_get('safe_mode') && @ini_get('enable_dl'))
  152.         || (PMA_PHP_INT_VERSION > 30009 && !@get_cfg_var('safe_mode')))
  153.         && @function_exists('dl')) {
  154.         if (PMA_PHP_INT_VERSION < 40000) {
  155.             $extension = 'MySQL';
  156.         } else {
  157.             $extension = 'mysql';
  158.         }
  159.         if (PMA_IS_WINDOWS) {
  160.             $suffix = '.dll';
  161.         } else {
  162.             $suffix = '.so';
  163.         }
  164.         if (!@extension_loaded($extension)) {
  165.             @dl($extension.$suffix);
  166.         }
  167.         if (!@extension_loaded($extension)) {
  168.             echo $strCantLoadMySQL;
  169.             exit();
  170.         }
  171.     } // end load mysql extension
  172.  
  173.  
  174.     /**
  175.      * Add slashes before "'" and "\" characters so a value containing them can
  176.      * be used in a sql comparison.
  177.      *
  178.      * @param   string   the string to slash
  179.      * @param   boolean  whether the string will be used in a 'LIKE' clause
  180.      *                   (it then requires two more escaped sequences) or not
  181.      *
  182.      * @return  string   the slashed string
  183.      *
  184.      * @access  public
  185.      */
  186.     function PMA_sqlAddslashes($a_string = '', $is_like = FALSE)
  187.     {
  188.         if ($is_like) {
  189.             $a_string = str_replace('\\', '\\\\\\\\', $a_string);
  190.         } else {
  191.             $a_string = str_replace('\\', '\\\\', $a_string);
  192.         }
  193.         $a_string = str_replace('\'', '\\\'', $a_string);
  194.     
  195.         return $a_string;
  196.     } // end of the 'PMA_sqlAddslashes()' function
  197.  
  198.  
  199.     /**
  200.      * Displays a MySQL error message in the right frame.
  201.      *
  202.      * @param   string   the error mesage
  203.      * @param   string   the sql query that failed
  204.      * @param   boolean  whether to show a "modify" link or not
  205.      * @param   string   the "back" link url (full path is not required)
  206.      *
  207.      * @access  public
  208.      */
  209.     function PMA_mysqlDie($error_message = '', $the_query = '',
  210.                           $is_modify_link = TRUE, $back_url = '')
  211.     {
  212.         if (!$error_message) {
  213.             $error_message = mysql_error();
  214.         }
  215.         if (!$the_query && !empty($GLOBALS['sql_query'])) {
  216.             $the_query = $GLOBALS['sql_query'];
  217.         }
  218.  
  219.         echo '<b>'. $GLOBALS['strError'] . '</b>' . "\n";
  220.         // if the config password is wrong, or the MySQL server does not
  221.         // respond, do not show the query that would reveal the
  222.         // username/password
  223.         if (!empty($the_query) && !strstr($the_query, 'connect')) {
  224.             $query_base = htmlspecialchars($the_query);
  225.             $query_base = ereg_replace("((\015\012)|(\015)|(\012)){3,}", "\n\n", $query_base);
  226.             echo '<p>' . "\n";
  227.             echo '    ' . $GLOBALS['strSQLQuery'] . ' : ' . "\n";
  228.             if ($is_modify_link) {
  229.                 echo '    ['
  230.                      . '<a href="db_details.php?lang=' . $GLOBALS['lang'] . '&server=' . urlencode($GLOBALS['server']) . '&db=' . urlencode($GLOBALS['db']) . '&sql_query=' . urlencode($the_query) . '&show_query=y">' . $GLOBALS['strEdit'] . '</a>'
  231.                      . ']' . "\n";
  232.             } // end if
  233.             echo '<pre>' . "\n" . $query_base . "\n" . '</pre>' . "\n";
  234.             echo '</p>' . "\n";
  235.         } // end if
  236.         if (!empty($error_message)) {
  237.             $error_message = htmlspecialchars($error_message);
  238.             $error_message = ereg_replace("((\015\012)|(\015)|(\012)){3,}", "\n\n", $error_message);
  239.         }
  240.         echo '<p>' . "\n";
  241.         echo '    ' . $GLOBALS['strMySQLSaid'] . '<br />' . "\n";
  242.         echo '<pre>' . "\n" . $error_message . "\n" . '</pre>' . "\n";
  243.         echo '</p>' . "\n";
  244.         if (!empty($back_url)) {
  245.             echo '<a href="' . $back_url . '">' . $GLOBALS['strBack'] . '</a>';
  246.         }
  247.         echo "\n";
  248.  
  249.         include('./footer.inc.php');
  250.         exit();
  251.     } // end of the 'PMA_mysqlDie()' function
  252.  
  253.  
  254.     /**
  255.      * Defines whether a string exists inside an array or not
  256.      *
  257.      * @param   string   string to search for
  258.      * @param   mixed    array to search into
  259.      *
  260.      * @return  integer  the rank of the $toFind string in the array or '-1' if
  261.      *                   it hasn't been found
  262.      *
  263.      * @access  public
  264.      */
  265.     function PMA_isInto($toFind = '', &$in)
  266.     {
  267.         $max = count($in);
  268.         for ($i = 0; $i < $max && ($toFind != $in[$i]); $i++) {
  269.             // void();
  270.         }
  271.  
  272.         return ($i < $max) ? $i : -1;
  273.     }  // end of the 'PMA_isInto()' function
  274.  
  275.  
  276.     /**
  277.      * Use mysql_connect() or mysql_pconnect()?
  278.      */
  279.     $connect_func = ($cfgPersistentConnections) ? 'mysql_pconnect' : 'mysql_connect';
  280.     $dblist       = array();
  281.  
  282.  
  283.     /**
  284.      * Gets the valid servers list and parameters
  285.      */
  286.     reset($cfgServers);
  287.     while (list($key, $val) = each($cfgServers)) {
  288.         // Don't use servers with no hostname
  289.         if (empty($val['host'])) {
  290.             unset($cfgServers[$key]);
  291.         }
  292.     }
  293.  
  294.     if (empty($server) || !isset($cfgServers[$server]) || !is_array($cfgServers[$server])) {
  295.         $server = $cfgServerDefault;
  296.     }
  297.  
  298.  
  299.     /**
  300.      * If no server is selected, make sure that $cfgServer is empty (so that
  301.      * nothing will work), and skip server authentication.
  302.      * We do NOT exit here, but continue on without logging into any server.
  303.      * This way, the welcome page will still come up (with no server info) and
  304.      * present a choice of servers in the case that there are multiple servers
  305.      * and '$cfgServerDefault = 0' is set.
  306.      */
  307.     if ($server == 0) {
  308.         $cfgServer = array();
  309.     }
  310.  
  311.     /**
  312.      * Otherwise, set up $cfgServer and do the usual login stuff.
  313.      */
  314.     else if (isset($cfgServers[$server])) {
  315.         $cfgServer = $cfgServers[$server];
  316.  
  317.         // Check how the config says to connect to the server
  318.         $server_port   = (empty($cfgServer['port']))
  319.                        ? ''
  320.                        : ':' . $cfgServer['port'];
  321.         if (strtolower($cfgServer['connect_type']) == 'tcp') {
  322.             $cfgServer['socket'] = '';
  323.         }
  324.         $server_socket = (empty($cfgServer['socket']) || PMA_PHP_INT_VERSION < 30010)
  325.                        ? ''
  326.                        : ':' . $cfgServer['socket'];
  327.  
  328.         // Ensures compatibility with old config files
  329.         if (!isset($cfgServer['auth_type'])) {
  330.             $cfgServer['auth_type'] = (isset($cfgServer['adv_auth']) && $cfgServer['adv_auth'])
  331.                                     ? 'http'
  332.                                     : 'config';
  333.         }
  334.  
  335.         // Gets the authentication library that fits the cfgServer settings
  336.         // and run authentication
  337.         include('./libraries/auth/' . $cfgServer['auth_type'] . '.auth.lib.php');
  338.         if (!PMA_auth_check()) {
  339.             PMA_auth();
  340.         } else {
  341.             PMA_auth_set_user();
  342.         }
  343.  
  344.         // The user can work with only some databases
  345.         if (isset($cfgServer['only_db']) && $cfgServer['only_db'] != '') {
  346.             if (is_array($cfgServer['only_db'])) {
  347.                 $dblist   = $cfgServer['only_db'];
  348.             } else {
  349.                 $dblist[] = $cfgServer['only_db'];
  350.             }
  351.         } // end if
  352.  
  353.         if (PMA_PHP_INT_VERSION >= 40000) {
  354.             $bkp_track_err = @ini_set('track_errors', 1);
  355.         }
  356.  
  357.         // Try to connect MySQL with the standard user profile (will be used to
  358.         // get the privileges list for the current user but the true user link
  359.         // must be open after this one so it would be default one for all the
  360.         // scripts)
  361.         if ($cfgServer['stduser'] != '') {
  362.             $dbh           = @$connect_func(
  363.                                  $cfgServer['host'] . $server_port . $server_socket,
  364.                                  $cfgServer['stduser'],
  365.                                  $cfgServer['stdpass']
  366.                              );
  367.             if ($dbh == FALSE) {
  368.                 if (mysql_error()) {
  369.                     $conn_error = mysql_error();
  370.                 } else if (isset($php_errormsg)) {
  371.                     $conn_error = $php_errormsg;
  372.                 } else {
  373.                     $conn_error = 'Cannot connect: invalid settings.';
  374.                 }
  375.                 $local_query    = $connect_func . '('
  376.                                 . $cfgServer['host'] . $server_port . $server_socket . ', '
  377.                                 . $cfgServer['stduser'] . ', '
  378.                                 . $cfgServer['stdpass'] . ')';
  379.                 PMA_mysqlDie($conn_error, $local_query, FALSE);
  380.             } // end if
  381.         } // end if
  382.  
  383.         // Connects to the server (validates user's login)
  384.         $userlink      = @$connect_func(
  385.                              $cfgServer['host'] . $server_port . $server_socket,
  386.                              $cfgServer['user'],
  387.                              $cfgServer['password']
  388.                          );
  389.         if ($userlink == FALSE) {
  390.             PMA_auth_fails();
  391.         } // end if
  392.  
  393.         if (PMA_PHP_INT_VERSION >= 40000) {
  394.             @ini_set('track_errors', $bkp_track_err);
  395.         }
  396.  
  397.         // If stduser isn't defined, use the current user settings to get his
  398.         // rights
  399.         if ($cfgServer['stduser'] == '') {
  400.             $dbh = $userlink;
  401.         }
  402.  
  403.         // if 'only_db' is set for the current user, there is no need to check for
  404.         // available databases in the "mysql" db
  405.         $dblist_cnt = count($dblist);
  406.         if ($dblist_cnt) {
  407.             $true_dblist  = array();
  408.             $is_show_dbs  = TRUE;
  409.             for ($i = 0; $i < $dblist_cnt; $i++) {
  410.                 if ($is_show_dbs && ereg('(^|[^\])(_|%)', $dblist[$i])) {
  411.                     $local_query = 'SHOW DATABASES LIKE \'' . $dblist[$i] . '\'';
  412.                     $rs          = mysql_query($local_query, $dbh);
  413.                     // "SHOW DATABASES" statement is disabled
  414.                     if ($i == 0
  415.                         && (mysql_error() && mysql_errno() == 1045)) {
  416.                         $true_dblist[] = str_replace('\\_', '_', str_replace('\\%', '%', $dblist[$i]));
  417.                         $is_show_dbs   = FALSE;
  418.                     }
  419.                     // Debug
  420.                     // else if (mysql_error()) {
  421.                     //    PMA_mysqlDie('', $local_query, FALSE);
  422.                     // }
  423.                     while ($row = @mysql_fetch_row($rs)) {
  424.                         $true_dblist[] = $row[0];
  425.                     } // end while
  426.                     if ($rs) {
  427.                         mysql_free_result($rs);
  428.                     }
  429.                 } else {
  430.                     $true_dblist[]     = str_replace('\\_', '_', str_replace('\\%', '%', $dblist[$i]));
  431.                 } // end if... else...
  432.             } // end for
  433.             $dblist       = $true_dblist;
  434.             unset($true_dblist);
  435.         } // end if
  436.  
  437.         // 'only_db' is empty for the current user -> checks for available
  438.         // databases in the "mysql" db
  439.         else {
  440.             $auth_query = 'SELECT User, Select_priv '
  441.                         . 'FROM mysql.user '
  442.                         . 'WHERE User = \'' . PMA_sqlAddslashes($cfgServer['user']) . '\'';
  443.             $rs         = mysql_query($auth_query, $dbh); // Debug: or PMA_mysqlDie('', $auth_query, FALSE);
  444.         } // end if
  445.  
  446.         // Access to "mysql" db allowed -> gets the usable db list
  447.         if (!$dblist_cnt && @mysql_numrows($rs)) {
  448.             $row = mysql_fetch_array($rs);
  449.             mysql_free_result($rs);
  450.             // Correction uva 19991215
  451.             // Previous code assumed database "mysql" admin table "db" column
  452.             // "db" contains literal name of user database, and works if so.
  453.             // Mysql usage generally (and uva usage specifically) allows this
  454.             // column to contain regular expressions (we have all databases
  455.             // owned by a given student/faculty/staff beginning with user i.d.
  456.             // and governed by default by a single set of privileges with
  457.             // regular expression as key). This breaks previous code.
  458.             // This maintenance is to fix code to work correctly for regular
  459.             // expressions.
  460.             if ($row['Select_priv'] != 'Y') {
  461.  
  462.                 // 1. get allowed dbs from the "mysql.db" table
  463.                 // lem9: User can be blank (anonymous user)
  464.                 $local_query = 'SELECT DISTINCT Db FROM mysql.db WHERE Select_priv = \'Y\' AND (User = \'' . PMA_sqlAddslashes($cfgServer['user']) . '\' OR User = \'\')';
  465.                 $rs          = mysql_query($local_query, $dbh); // Debug: or PMA_mysqlDie('', $local_query, FALSE);
  466.                 if (@mysql_numrows($rs)) {
  467.                     // Will use as associative array of the following 2 code
  468.                     // lines:
  469.                     //   the 1st is the only line intact from before
  470.                     //     correction,
  471.                     //   the 2nd replaces $dblist[] = $row['Db'];
  472.                     $uva_mydbs = array();
  473.                     // Code following those 2 lines in correction continues
  474.                     // populating $dblist[], as previous code did. But it is
  475.                     // now populated with actual database names instead of
  476.                     // with regular expressions.
  477.                     while ($row = mysql_fetch_array($rs)) {
  478.                         // loic1: all databases cases - part 1
  479.                         if (empty($row['Db']) || $row['Db'] == '%') {
  480.                             $uva_mydbs['%'] = 1;
  481.                             break;
  482.                         }
  483.                         // loic1: avoid multiple entries for dbs
  484.                         if (!isset($uva_mydbs[$row['Db']])) {
  485.                             $uva_mydbs[$row['Db']] = 1;
  486.                         }
  487.                     } // end while
  488.                     mysql_free_result($rs);
  489.                     $uva_alldbs = mysql_list_dbs($dbh);
  490.                     // loic1: all databases cases - part 2
  491.                     if (isset($uva_mydbs['%'])) {
  492.                         while ($uva_row = mysql_fetch_array($uva_alldbs)) {
  493.                             $dblist[] = $uva_row[0];
  494.                         } // end while
  495.                     } // end if
  496.                     else {
  497.                         while ($uva_row = mysql_fetch_array($uva_alldbs)) {
  498.                             $uva_db = $uva_row[0];
  499.                             if (isset($uva_mydbs[$uva_db]) && $uva_mydbs[$uva_db] == 1) {
  500.                                 $dblist[]           = $uva_db;
  501.                                 $uva_mydbs[$uva_db] = 0;
  502.                             } else if (!isset($dblist[$uva_db])) {
  503.                                 reset($uva_mydbs);
  504.                                 while (list($uva_matchpattern, $uva_value) = each($uva_mydbs)) {
  505.                                     // loic1: fixed bad regexp
  506.                                     // TODO: db names may contain characters
  507.                                     //       that are regexp instructions
  508.                                     $re        = '(^|(\\\\\\\\)+|[^\])';
  509.                                     $uva_regex = ereg_replace($re . '%', '\\1.*', ereg_replace($re . '_', '\\1.{1}', $uva_matchpattern));
  510.                                     // Fixed db name matching
  511.                                     // 2000-08-28 -- Benjamin Gandon
  512.                                     if (ereg('^' . $uva_regex . '$', $uva_db)) {
  513.                                         $dblist[] = $uva_db;
  514.                                         break;
  515.                                     }
  516.                                 } // end while
  517.                             } // end if ... else if....
  518.                         } // end while
  519.                     } // end else
  520.                     mysql_free_result($uva_alldbs);
  521.                     unset($uva_mydbs);
  522.                 } // end if
  523.  
  524.                 // 2. get allowed dbs from the "mysql.tables_priv" table
  525.                 $local_query = 'SELECT DISTINCT Db FROM mysql.tables_priv WHERE Table_priv LIKE \'%Select%\' AND User = \'' . PMA_sqlAddslashes($cfgServer['user']) . '\'';
  526.                 $rs          = mysql_query($local_query, $dbh); // Debug: or PMA_mysqlDie('', $local_query, FALSE);
  527.                 if (@mysql_numrows($rs)) {
  528.                     while ($row = mysql_fetch_array($rs)) {
  529.                         if (PMA_isInto($row['Db'], $dblist) == -1) {
  530.                             $dblist[] = $row['Db'];
  531.                         }
  532.                     } // end while
  533.                     mysql_free_result($rs);
  534.                 } // end if
  535.             } // end if
  536.         } // end building available dbs from the "mysql" db
  537.  
  538.     } // end server connecting
  539.  
  540.     /**
  541.      * Missing server hostname
  542.      */
  543.     else {
  544.         echo $strHostEmpty;
  545.     }
  546.  
  547.  
  548.     /**
  549.      * Get the list and number of available databases.
  550.      *
  551.      * @param   string   the url to go back to in case of error
  552.      *
  553.      * @return  boolean  always true
  554.      *
  555.      * @global  array    the list of available databases
  556.      * @global  integer  the number of available databases
  557.      */
  558.     function PMA_availableDatabases($error_url = '')
  559.     {
  560.         global $dblist;
  561.         global $num_dbs;
  562.  
  563.         $num_dbs = count($dblist);
  564.  
  565.         // 1. A list of allowed databases has already been defined by the
  566.         //    authentification process -> gets the available databases list
  567.         if ($num_dbs) {
  568.             $true_dblist = array();
  569.             for ($i = 0; $i < $num_dbs; $i++) {
  570.                 $dblink  = @mysql_select_db($dblist[$i]);
  571.                 if ($dblink) {
  572.                     $true_dblist[] = $dblist[$i];
  573.                 } // end if
  574.             } // end for
  575.             $dblist      = array();
  576.             $dblist      = $true_dblist;
  577.             unset($true_dblist);
  578.             $num_dbs     = count($dblist);
  579.         } // end if
  580.  
  581.         // 2. Allowed database list is empty -> gets the list of all databases
  582.         //    on the server
  583.         else {
  584.             $dbs          = mysql_list_dbs() or PMA_mysqlDie('', 'mysql_list_dbs()', FALSE, $error_url);
  585.             $num_dbs      = @mysql_num_rows($dbs);
  586.             $real_num_dbs = 0;
  587.             for ($i = 0; $i < $num_dbs; $i++) {
  588.                 $db_name_tmp = mysql_dbname($dbs, $i);
  589.                 $dblink      = @mysql_select_db($db_name_tmp);
  590.                 if ($dblink) {
  591.                     $dblist[] = $db_name_tmp;
  592.                     $real_num_dbs++;
  593.                 }
  594.             } // end for
  595.             mysql_free_result($dbs);
  596.             $num_dbs = $real_num_dbs; 
  597.         } // end else
  598.  
  599.         return TRUE;
  600.     } // end of the 'PMA_availableDatabases()' function
  601.  
  602.  
  603.     /**
  604.      * Gets constants that defines the PHP, MySQL... releases.
  605.      * This include must be located physically before any code that needs to
  606.      * reference the constants, else PHP 3.0.16 won't be happy; and must be
  607.      * located after we are connected to db to get the MySql version.
  608.      */
  609.     include('./libraries/defines.lib.php');
  610.  
  611.  
  612.  
  613.     /* ----------------------- Set of misc functions ----------------------- */
  614.  
  615.     /**
  616.      * Determines the font sizes to use depending on the os and browser of the
  617.      * user.
  618.      *
  619.      * This function is based on an article from phpBuilder (see
  620.      * http://www.phpbuilder.net/columns/tim20000821.php).
  621.      *
  622.      * @return  boolean    always true
  623.      *
  624.      * @global  string     the standard font size
  625.      * @global  string     the font size for titles
  626.      * @global  string     the small font size
  627.      * @global  string     the smallest font size
  628.      *
  629.      * @access  public
  630.      *
  631.      * @version 1.1
  632.      */
  633.     function PMA_setFontSizes()
  634.     {
  635.         global $font_size, $font_bigger, $font_smaller, $font_smallest;
  636.  
  637.         // IE (<6)/Opera for win case: needs smaller fonts than anyone else
  638.         if (PMA_USR_OS == 'Win'
  639.             && ((PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 6) || PMA_USR_BROWSER_AGENT == 'OPERA')) {
  640.             $font_size     = 'x-small';
  641.             $font_bigger   = 'large';
  642.             $font_smaller  = '90%';
  643.             $font_smallest = '7pt';
  644.         }
  645.         // IE6 and other browsers for win case
  646.         else if (PMA_USR_OS == 'Win') {
  647.             $font_size     = 'small';
  648.             $font_bigger   = 'large';
  649.             $font_smaller  = (PMA_USR_BROWSER_AGENT == 'IE')
  650.                            ? '90%'
  651.                            : 'x-small';
  652.             $font_smallest = 'x-small';
  653.         }
  654.         // Some mac browsers need also smaller default fonts size (OmniWeb &
  655.         // Opera)...
  656.         else if (PMA_USR_OS == 'Mac'
  657.                  && (PMA_USR_BROWSER_AGENT == 'OMNIWEB' || PMA_USR_BROWSER_AGENT == 'OPERA')) {
  658.             $font_size     = 'x-small';
  659.             $font_bigger   = 'large';
  660.             $font_smaller  = '90%';
  661.             $font_smallest = '7pt';
  662.         }
  663.         // ... but most of them (except IE 5+ & NS 6+) need bigger fonts
  664.         else if (PMA_USR_OS == 'Mac'
  665.                  && ((PMA_USR_BROWSER_AGENT != 'IE' && PMA_USR_BROWSER_AGENT != 'MOZILLA')
  666.                      || PMA_USR_BROWSER_VER < 5)) {
  667.             $font_size     = 'medium';
  668.             $font_bigger   = 'x-large';
  669.             $font_smaller  = 'small';
  670.             $font_smallest = 'x-small';
  671.         }
  672.         // OS/2 browser
  673.         else if (PMA_USR_OS == 'OS/2'
  674.                  && PMA_USR_BROWSER_AGENT == 'OPERA') {
  675.             $font_size     = 'small';
  676.             $font_bigger   = 'medium';
  677.             $font_smaller  = 'x-small';
  678.             $font_smallest = 'x-small';
  679.         }
  680.         else {
  681.             $font_size     = 'small';
  682.             $font_bigger   = 'large';
  683.             $font_smaller  = 'x-small';
  684.             $font_smallest = 'x-small';
  685.         }
  686.  
  687.         return true;
  688.     } // end of the 'PMA_setFontSizes()' function
  689.  
  690.  
  691.     /**
  692.      * Adds backquotes on both sides of a database, table or field name.
  693.      * Since MySQL 3.23.6 this allows to use non-alphanumeric characters in
  694.      * these names.
  695.      *
  696.      * @param   string   the database, table or field name to "backquote"
  697.      * @param   boolean  a flag to bypass this function (used by dump functions)
  698.      *
  699.      * @return  string   the "backquoted" database, table or field name if the
  700.      *                   current MySQL release is >= 3.23.6, the original one
  701.      *                   else
  702.      *
  703.      * @access  public
  704.      */
  705.     function PMA_backquote($a_name, $do_it = TRUE)
  706.     {
  707.         if ($do_it
  708.             && PMA_MYSQL_INT_VERSION >= 32306
  709.             && !empty($a_name) && $a_name != '*') {
  710.             return '`' . $a_name . '`';
  711.         } else {
  712.             return $a_name;
  713.         }
  714.     } // end of the 'PMA_backquote()' function
  715.  
  716.  
  717.     /**
  718.      * Format a string so it can be passed to a javascript function.
  719.      * This function is used to displays a javascript confirmation box for
  720.      * "DROP/DELETE/ALTER" queries.
  721.      *
  722.      * @param   string   the string to format
  723.      * @param   boolean  whether to add backquotes to the string or not
  724.      *
  725.      * @return  string   the formated string
  726.      *
  727.      * @access  public
  728.      */
  729.     function PMA_jsFormat($a_string = '', $add_backquotes = TRUE)
  730.     {
  731.         if (is_string($a_string)) {
  732.             $a_string = str_replace('"', '"', $a_string);
  733.             $a_string = str_replace('\\', '\\\\', $a_string);
  734.             $a_string = str_replace('\'', '\\\'', $a_string);
  735.             $a_string = str_replace('#', '\\#', $a_string);
  736.             $a_string = str_replace("\012", '\\\\n', $a_string);
  737.             $a_string = str_replace("\015", '\\\\r', $a_string);
  738.         }
  739.  
  740.         return (($add_backquotes) ? PMA_backquote($a_string) : $a_string);
  741.     } // end of the 'PMA_jsFormat()' function
  742.  
  743.  
  744.     /**
  745.      * Defines the <CR><LF> value depending on the user OS.
  746.      *
  747.      * @return  string   the <CR><LF> value to use
  748.      *
  749.      * @access  public
  750.      */
  751.     function PMA_whichCrlf()
  752.     {
  753.         $the_crlf = "\n";
  754.  
  755.         // The 'PMA_USR_OS' constant is defined in "./libraries/defines.lib.php"
  756.         // Win case
  757.         if (PMA_USR_OS == 'Win') {
  758.             $the_crlf = "\r\n";
  759.         }
  760.         // Mac case
  761.         else if (PMA_USR_OS == 'Mac') {
  762.             $the_crlf = "\r";
  763.         }
  764.         // Others
  765.         else {
  766.             $the_crlf = "\n";
  767.         }
  768.  
  769.         return $the_crlf;
  770.     } // end of the 'PMA_whichCrlf()' function
  771.  
  772.  
  773.     /**
  774.      * Counts and displays the number of records in a table
  775.      *
  776.      * Last revision 13 July 2001: Patch for limiting dump size from
  777.      * vinay@sanisoft.com & girish@sanisoft.com
  778.      *
  779.      * @param   string   the current database name
  780.      * @param   string   the current table name
  781.      * @param   boolean  whether to retain or to displays the result
  782.      *
  783.      * @return  mixed    the number of records if retain is required, true else
  784.      *
  785.      * @access  public
  786.      */
  787.     function PMA_countRecords($db, $table, $ret = FALSE)
  788.     {
  789.         $result = mysql_query('SELECT COUNT(*) AS num FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table));
  790.         $num    = mysql_result($result, 0, 'num');
  791.         mysql_free_result($result);
  792.         if ($ret) {
  793.             return $num;
  794.         } else {
  795.             echo number_format($num, 0, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
  796.             return TRUE;
  797.         }
  798.     } // end of the 'PMA_countRecords()' function
  799.  
  800.  
  801.     /**
  802.      * Displays a message at the top of the "main" (right) frame
  803.      *
  804.      * @param   string  the message to display
  805.      *
  806.      * @access  public
  807.      */
  808.     function PMA_showMessage($message)
  809.     {
  810.         // Reloads the navigation frame via JavaScript if required
  811.         if (isset($GLOBALS['reload']) && $GLOBALS['reload']) {
  812.             echo "\n";
  813.             $reload_url = './left.php'
  814.                         . '?lang=' . $GLOBALS['lang']
  815.                         . '&server=' . $GLOBALS['server']
  816.                         . ((!empty($GLOBALS['db'])) ? '&db=' . urlencode($GLOBALS['db']) : '');
  817.             ?>
  818. <script type="text/javascript" language="javascript1.2">
  819. <!--
  820. window.parent.frames['nav'].location.replace('<?php echo $reload_url; ?>');
  821. //-->
  822. </script>
  823.             <?php
  824.         }
  825.         echo "\n";
  826.         ?>
  827. <div align="<?php echo $GLOBALS['cell_align_left']; ?>">
  828.     <table border="<?php echo $GLOBALS['cfgBorder']; ?>" cellpadding="5">
  829.     <tr>
  830.         <td bgcolor="<?php echo $GLOBALS['cfgThBgcolor']; ?>">
  831.             <b><?php echo stripslashes($message); ?></b><br />
  832.         </td>
  833.     </tr>
  834.         <?php
  835.         if ($GLOBALS['cfgShowSQL'] == TRUE && !empty($GLOBALS['sql_query'])) {
  836.             echo "\n";
  837.             ?>
  838.     <tr>
  839.         <td bgcolor="<?php echo $GLOBALS['cfgBgcolorOne']; ?>">
  840.             <?php
  841.             echo "\n";
  842.             // The nl2br function isn't used because its result isn't a valid
  843.             // xhtml1.0 statement before php4.0.5 ("<br>" and not "<br />")
  844.             $new_line   = '<br />' . "\n" . '            ';
  845.             $query_base = htmlspecialchars($GLOBALS['sql_query']);
  846.             $query_base = ereg_replace("((\015\012)|(\015)|(\012))+", $new_line, $query_base);
  847.             if (!isset($GLOBALS['show_query']) || $GLOBALS['show_query'] != 'y') {
  848.                 if (!isset($GLOBALS['goto'])) {
  849.                     $edit_target = (isset($GLOBALS['table'])) ? 'tbl_properties.php' : 'db_details.php';
  850.                 } else if ($GLOBALS['goto'] != 'main.php') {
  851.                     $edit_target = $GLOBALS['goto'];
  852.                 } else {
  853.                     $edit_target = '';
  854.                 }
  855.                 if ($edit_target == 'tbl_properties.php') {
  856.                     $edit_link = '<a href="tbl_properties.php?lang=' . $GLOBALS['lang'] . '&server=' . urlencode($GLOBALS['server']) . '&db=' . urlencode($GLOBALS['db']) . '&table=' . urlencode($GLOBALS['table']) . '&sql_query=' . urlencode($GLOBALS['sql_query']) . '&show_query=y#querybox">' . $GLOBALS['strEdit'] . '</a>';
  857.                 } else if ($edit_target != '') {
  858.                     $edit_link = '<a href="db_details.php?lang=' . $GLOBALS['lang'] . '&server=' . urlencode($GLOBALS['server']) . '&db=' . urlencode($GLOBALS['db']) . '&sql_query=' . urlencode($GLOBALS['sql_query']) . '&show_query=y#querybox">' . $GLOBALS['strEdit'] . '</a>';
  859.                 }
  860.             }
  861.             if (!empty($edit_target)) {
  862.                 echo '            ' . $GLOBALS['strSQLQuery'] . ' : [' . $edit_link . ']<br />' . "\n";
  863.             } else {
  864.                 echo '            ' . $GLOBALS['strSQLQuery'] . ' :<br />' . "\n";
  865.             }
  866.             echo '            ' . $query_base;
  867.             // If a 'LIMIT' clause has been programatically added to the query
  868.             // displays it
  869.             if (!empty($GLOBALS['sql_limit_to_append'])) {
  870.                 echo $GLOBALS['sql_limit_to_append'];
  871.             }
  872.             echo "\n";
  873.             ?>
  874.         </td>
  875.     </tr>
  876.            <?php
  877.         }
  878.         echo "\n";
  879.         ?>
  880.     </table>
  881. </div><br />
  882.         <?php
  883.     } // end of the 'PMA_showMessage()' function
  884.  
  885.  
  886.     /**
  887.      * Displays a link to the official MySQL documentation (short)
  888.      *
  889.      * @param   string  an anchor to move to
  890.      *
  891.      * @return  string  the html link
  892.      *
  893.      * @access  public
  894.      */
  895.     function PMA_showDocuShort($link)
  896.     {
  897.         if (!empty($GLOBALS['cfgManualBaseShort'])) {
  898.             return '[<a href="' . $GLOBALS['cfgManualBaseShort'] . '/' . $link .'" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
  899.         }
  900.     } // end of the 'PMA_showDocuShort()' function
  901.  
  902.  
  903.     /**
  904.      * Formats $value to byte view
  905.      *
  906.      * @param    double   the value to format
  907.      * @param    integer  the sensitiveness
  908.      * @param    integer  the number of decimals to retain
  909.      *
  910.      * @return   array    the formatted value and its unit
  911.      *
  912.      * @access  public
  913.      *
  914.      * @author   staybyte
  915.      * @version  1.1 - 07 July 2001
  916.      */
  917.     function PMA_formatByteDown($value, $limes = 6, $comma = 0)
  918.     {
  919.         $dh           = pow(10, $comma);
  920.         $li           = pow(10, $limes);
  921.         $return_value = $value;
  922.         $unit         = $GLOBALS['byteUnits'][0];
  923.  
  924.         if ($value >= $li*1000000) {
  925.             $value = round($value/(1073741824/$dh))/$dh;
  926.             $unit  = $GLOBALS['byteUnits'][3];
  927.         }
  928.         else if ($value >= $li*1000) {
  929.             $value = round($value/(1048576/$dh))/$dh;
  930.             $unit  = $GLOBALS['byteUnits'][2];
  931.         }
  932.         else if ($value >= $li) {
  933.             $value = round($value/(1024/$dh))/$dh;
  934.             $unit  = $GLOBALS['byteUnits'][1];
  935.         }
  936.         if ($unit != $GLOBALS['byteUnits'][0]) {
  937.             $return_value = number_format($value, $comma, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
  938.         } else {
  939.             $return_value = number_format($value, 0, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
  940.         }
  941.  
  942.         return array($return_value, $unit);
  943.     } // end of the 'PMA_formatByteDown' function
  944.  
  945.  
  946.     /**
  947.      * Ensures a database/table/field's name is not a reserved word (for MySQL
  948.      * releases < 3.23.6) 
  949.      *
  950.      * @param    string   the name to check
  951.      * @param    string   the url to go back in case of error
  952.      *
  953.      * @return   boolean  true if the name is valid (no return else)
  954.      *
  955.      * @access  public
  956.      *
  957.      * @author   Dell'Aiera Pol; Olivier Blin
  958.      */
  959.     function PMA_checkReservedWords($the_name, $error_url)
  960.     {
  961.         // The name contains caracters <> a-z, A-Z and "_" -> not a reserved
  962.         // word
  963.         if (!ereg('^[a-zA-Z_]+$', $the_name)) {
  964.             return true;
  965.         }
  966.         
  967.         // Else do the work
  968.         $filename = 'badwords.txt';
  969.         if (file_exists($filename)) {
  970.             // Builds the reserved words array
  971.             $fd        = fopen($filename, 'r');
  972.             $contents  = fread($fd, filesize($filename) - 1);
  973.             fclose ($fd);
  974.             $word_list = explode("\n", $contents);
  975.  
  976.             // Do the checking
  977.             $word_cnt  = count($word_list);
  978.             for ($i = 0; $i < $word_cnt; $i++) {
  979.                 if (strtolower($the_name) == $word_list[$i]) {
  980.                     PMA_mysqlDie(sprintf($GLOBALS['strInvalidName'], $the_name), '', FALSE, $error_url);
  981.                 } // end if
  982.             } // end for
  983.         } // end if
  984.     } // end of the 'PMA_checkReservedWords' function
  985.  
  986.  
  987.     /**
  988.      * Writes localised date
  989.      *
  990.      * @param   string   the current timestamp
  991.      *
  992.      * @return  string   the formatted date
  993.      *
  994.      * @access  public
  995.      */
  996.     function PMA_localisedDate($timestamp = -1)
  997.     {
  998.         global $datefmt, $month, $day_of_week;
  999.  
  1000.         if ($timestamp == -1) {
  1001.             $timestamp = time();
  1002.         }
  1003.  
  1004.         $date = ereg_replace('%[aA]', $day_of_week[(int)strftime('%w', $timestamp)], $datefmt);
  1005.         $date = ereg_replace('%[bB]', $month[(int)strftime('%m', $timestamp)-1], $date);
  1006.  
  1007.         return strftime($date, $timestamp);
  1008.     } // end of the 'PMA_localisedDate()' function
  1009.  
  1010. } // $__PMA_COMMON_LIB__
  1011. ?>
  1012.