<?php

/*
+--------------------------------------------------------------------------
|   Invision Power Board v1.1
|   ========================================
|   by Matthew Mecham
|   (c) 2001,2002 Invision Power Services
|   http://www.ibforums.com
|   ========================================
|   Web: http://www.ibforums.com
|   Email: phpboards@ibforums.com
|   Licence Info: phpib-licence@ibforums.com
+---------------------------------------------------------------------------
|
|   > mySQL Admin Stuff
|   > Module written by Matt Mecham
|   > Date started: 21st October 2002
|
|	> Module Version Number: 1.0.0
|   > Music listen to when coding this: Martin Grech - Open Heart Zoo
|   > Talk about useless information!
+--------------------------------------------------------------------------
*/


// Ensure we've not accessed this script directly:

@set_time_limit(1200);

$idx = new ad_mysql();


class ad_mysql {

	var $base_url;
	var $mysql_version   = "";
	var $true_version    = "";
	var $str_gzip_header = "\x1f\x8b\x08\x00\x00\x00\x00\x00";

	function ad_mysql() {
		global $IN, $INFO, $DB, $SKIN, $ADMIN, $std, $MEMBER, $GROUP, $HTTP_POST_VARS, $HTTP_GET_VARS;
		
		//---------------------------------------
		// Kill globals - globals bad, Homer good.
		//---------------------------------------
		
		$tmp_in = array_merge( $_GET, $_POST, $_COOKIE );
		
		foreach ( $tmp_in as $k => $v )
		{
			unset($$k);
		}
		
		// Make sure we're a root admin, or else!
		
		if ($MEMBER['mgroup'] != $INFO['admin_group'])
		{
			$ADMIN->error("对不起，此功能只有管理员团队用户才能操作使用！");
		}
		
		//---------------------------------------
		// Get the mySQL version.
		// Adapted from phpMyAdmin
		//---------------------------------------
		
		$DB->query("SELECT VERSION() AS version");
		
		if ( ! $row = $DB->fetch_row() )
		{
			$DB->query("SHOW VARIABLES LIKE 'version'");
			$row = $DB->fetch_row();
		}
		
		$this->true_version = $row['version'];
		
		$no_array = explode( '.', preg_replace( "/^(.+?)[-_]?/", "\\1", $row['version']) );
		
		$one   = (!isset($no_array) || !isset($no_array[0])) ? 3  : $no_array[0];
		$two   = (!isset($no_array[1]))                      ? 21 : $no_array[1];
		$three = (!isset($no_array[2]))                      ? 0  : $no_array[2];
		
   		$this->mysql_version = (int)sprintf('%d%02d%02d', $one, $two, intval($three));
   		
		switch($IN['code'])
		{
		
			case 'dotool':
				$this->run_tool();
				break;
				
			case 'runtime':
				$this->view_sql("SHOW STATUS");
				break;
				
			case 'system':
				$this->view_sql("SHOW VARIABLES");
				break;
				
			case 'processes':
				$this->view_sql("SHOW PROCESSLIST");
				break;
				
			case 'runsql':
				$q = $HTTP_POST_VARS['query'] == "" ? $HTTP_GET_VARS['query'] : $HTTP_POST_VARS['query'];
				$this->view_sql(trim(urldecode(stripslashes($q))));
				break;
			
			case 'backup':
				$this->show_backup_form();
				break;
				
			case 'safebackup':
				$this->sbup_splash();
				break;
				
			case 'dosafebackup':
				$this->do_safe_backup();
				break;
				
			case 'export_tbl':
				$this->do_safe_backup(trim(urldecode(stripslashes($HTTP_GET_VARS['tbl']))));
				break;

//------------------------------------------------------------------
// 添加数据备份恢复插件 - 详情请访问: http://www.ibfchina.com - 开始
//------------------------------------------------------------------
			#数据备份
			case 'command_backup_form':
				$this->command_backup_form();
				break;

			case 'do_command_backup':
				$this->do_command_backup();
				break;

			#数据恢复
			case 'command_restore_form':
				$this->command_restore_form();
				break;
			
			case 'do_command_restore':
				$this->do_command_restore();
				break;

			#数据管理
			case 'manage_backups':
				$this->manage_form();
				break;

			case  'do_manage':
				$this->do_manage();
				break;
			
			case 'ad_del':
				$this->ad_del();
				break;

//------------------------------------------------------------------
// 添加数据备份恢复插件 - 详情请访问: http://www.ibfchina.com - 结束
//------------------------------------------------------------------
			
			//-------------------------
			default:
				$this->list_index();
				break;
		}
		
	}
	
	//-----------------------------------------------
	// Back up baby, back up
	//-----------------------------------------------

//------------------------------------------------------------------
// 添加数据备份恢复插件 - 详情请访问: http://www.ibfchina.com - 开始
//------------------------------------------------------------------
	#建立数据备份页面
	function command_backup_form()
	{
		global $ADMIN,$SKIN;
        $ADMIN->page_detail="<b>论坛数据备份：</b>系统将自动发送一个备份论坛数据的命令给服务器，这样系统就能为你快速的备份大容量的数据库而不会因为网络速度或PHP运行时间问题而产生错误。(注意：如果你的服务器安全模式打开的话可能无法使用此功能)";
        $ADMIN->page_title="论坛数据备份";
        $ADMIN->html .= $SKIN->start_form( array( 1 => array( 'act'  , 'mysql' ),
                                                  2 => array( 'code' , 'do_command_backup'),
                                                                                  )      );

        $ADMIN->html .= $SKIN->start_table("论坛数据备份");
        $ADMIN->html .= $SKIN->add_td_row(array("注意：如果你使用的是 UNIX/Linux 服务器，那么必须在备份数据前修改目录 archive_out 的属性(CHMOD 777)。"));
        $ADMIN->html .= $SKIN->end_form('开始备份');
        $ADMIN->html .=$SKIN->end_table();
        $ADMIN->output();
	}

	#开始执行数据备份
	function do_command_backup()
	{
        global $ADMIN,$SKIN,$INFO;

        #检查服务器操作系统
        $OS=@php_uname();
        
		if(preg_match("|win|i",$OS))
        {
			$windows=1;
			$unix=0;
			$slash="\\";
        }
        else
        {
			$windows=0;
			$unix=1;
			$slash="/";
        }

        #文件和路径设置
        $file_name="db_".date('Y_m_d')."_".time().".sql";
        $path=getcwd().$slash."archive_out".$slash.$file_name;

        #mysql_bin 目录，适用windows系统...
        if($windows)
        {
			$getdir=mysql_query("SHOW VARIABLES like 'basedir'");
			$getdir=mysql_fetch_array($getdir);
			$mysql_bin=$getdir[1].$slash."bin".$slash;
        }
        else
        {
			$mysql_bin="";
        }

        #生成系统命令...
        if($INFO['sql_pass']=="")
        {
			$pass="";
        }
        else
        {
			$pass="-p".$INFO['sql_pass'];
        }
        $systemstring=sprintf("%smysqldump --add-locks -qela  --add-drop-table -h%s -u%s %s %s > %s",$mysql_bin,$INFO['sql_host'],$INFO['sql_user'],$pass,$INFO['sql_database'],$path);

		#发送系统命令...
        $result=`$systemstring`;
        if($result=="")
        {
			$result=true;
        }
        if(filesize($path)<4)
        {
			$result=false;
        }

        //mysql操作，适用UNIX/Linux系统...;
        if(!$result):
			$getdir=mysql_query("SHOW VARIABLES like 'basedir'");
			$getdir=mysql_fetch_array($getdir);
			$mysql_bin=$getdir[1].$slash."bin".$slash;
        if($INFO['sql_pass']=="")
        {
			$pass="";
        }
        else
        {
			$pass="-p".$INFO['sql_pass'];
        }
        $systemstring=sprintf("%smysqldump --add-locks -qela  --add-drop-table -h%s -u%s %s %s > %s",$mysql_bin,$INFO['sql_host'],$INFO['sql_user'],$pass,$INFO['sql_database'],$path);
        $result=`$systemstring`;
        if($result=="")
        {
			$result=true;
        }
		if(filesize($path)<4)
        {
			$result=false;
        }
        endif;

        //设置目录或文件属性...
        @chmod($path,0777);

        #显示结果...
        $ADMIN->page_title="数据备份结果";
        $ADMIN->page_detail="";
        if($result)
        {
			$ADMIN->html .=$SKIN->start_table("数据已经完成备份！");
			$ADMIN->html .=$SKIN->add_td_row(array("数据备份文件已经成功建立<br>你现在可以[<a href='archive_out/{$file_name}' target='_blank'>按此下载</a>] SQL 文件。"));
			$ADMIN->html .=$SKIN->end_table();
        }
        else
        {
			$ADMIN->html .=$SKIN->start_table("数据备份错误");
			$ADMIN->html .=$SKIN->add_td_row(array("对不起，无法建立数据备份文件，如果你在目录 archive_out 中找到空的备份文件，请立即删除！"));
			$ADMIN->html .=$SKIN->end_table();
        }
			$ADMIN->output();
        }

	//论坛数据恢复页面
	function command_restore_form()
        {
        global $SKIN,$ADMIN;
        $ADMIN->page_title  = "论坛数据恢复";
        $ADMIN->page_detail = "本功能可以让你从数据文件 *.sql 来快速恢复你的大容量论坛数据库。你不必为论坛数据尺寸大小而担心。";
        $ADMIN->html .= $SKIN->start_form( array( 1 => array( 'act'  , 'mysql' ),
                                                  2 => array( 'code' , 'do_command_restore'),
                                                                                  )      );
        $ADMIN->html .=$SKIN->start_table("论坛数据恢复");
        $ADMIN->html .=$SKIN->add_td_row(array("选择论坛数据文件：<br> (注意：系统将只显示目录 archive_out 和/或 archive_in 中的所有 *.sql 文件"));
        $ADMIN->html .="<tr><td id='tdrow2'>";
        $ADMIN->html .="<select name='file'>";

		//获取文件
        $DIR=getcwd();

        $os=@php_uname();
        if(preg_match("|win|i",$os))
        {
			$b="\\";
        }
        else
        {
			$b="/";
        }
        $out=opendir($DIR.$b."archive_out");
        while($file=readdir($out))
        {
			if(preg_match("|(.*?).sql|",$file))
			{
				$ADMIN->html .="<option value='".$DIR.$b."archive_out".$b.$file."'>{$file}</option>";
			}
        }
        closedir($out);
        $in=opendir($DIR.$b."archive_in");
        while($file=readdir($in))
        {
			if(preg_match("|(.*?).sql|",$file))
			{
				$ADMIN->html .="<option value='".$DIR.$b."archive_in".$b.$file."'>{$file}</option>";
			}
        }
        closedir($in);
        $ADMIN->html.="</select>";
        $ADMIN->html .="</td></tr>";
        $ADMIN->html .= $SKIN->end_form('Restore');
        $ADMIN->html .= $SKIN->end_table();
        $ADMIN->output();
        }

	//恢复选择的数据文件...
	function do_command_restore()
        {
        global $SKIN,$ADMIN,$HTTP_POST_VARS,$INFO,$DB;

		#检查服务器操作系统
        $OS=@php_uname();
        if(preg_match("|win|i",$OS))
        {
			$windows=1;
			$unix=0;
			$slash="\\";
        }
        else
        {
			$windows=0;
			$unix=1;
			$slash="/";
        }
        if($windows)
        {
			$getdir=mysql_query("SHOW VARIABLES like 'basedir'");
			$getdir=mysql_fetch_array($getdir);
			$mysql_bin=$getdir[1].$slash."bin".$slash;
        }
        else
        {
			$mysql_bin="";
        }
        $DB->query("INSERT  INTO ibf_sessions VALUES(1,'','','','','','','','','','')");

        //建立和执行命令
        if($INFO['sql_pass']=="")
        {
			$pass="";
        }
        else
        {
			$pass="-p".$INFO['sql_pass'];
        }
        $systemstring=sprintf("%smysql -h%s -u%s %s %s < %s",$mysql_bin,$INFO['sql_host'],$INFO['sql_user'],$pass,$INFO['sql_database'],$HTTP_POST_VARS['file']);
        $send=`$systemstring`;
        $check=$DB->query("SELECT id FROM ibf_sessions WHERE member_name='' LIMIT 0,1");
        $check=mysql_fetch_array($check);
        if($check[0]!=1)
        {
			$result=true;
        }
        if($check[0]==1):
        $getdir=mysql_query("SHOW VARIABLES like 'basedir'");
        $getdir=mysql_fetch_array($getdir);
        $mysql_bin=$getdir[1].$slash."bin".$slash;

		//建立和执行命令
        $systemstring=sprintf("%smysql -h%s -u%s %s %s < %s",$mysql_bin,$INFO['sql_host'],$INFO['sql_user'],$pass,$INFO['sql_database'],$HTTP_POST_VARS['file']);
        $send=`$systemstring`;

		//再次检查
        $check=$DB->query("SELECT id FROM ibf_sessions WHERE member_name='' LIMIT 0,1");
        $check=mysql_fetch_array($check);
        if($check[0]!=1)
        {
			$result=true;
        }
        else
        {
			$result=false;
        }
        endif;
        $DB->query("DELETE FROM  ibf_sessions WHERE id=1");
        $ADMIN->page_title  = "数据恢复结果";
        $ADMIN->page_detail ="";
        if($result)
        {
			$ADMIN->html .=$SKIN->start_table("数据恢复成功！");
			$ADMIN->html .=$SKIN->add_td_row(array("你的数据已经恢复成功"));
        }
        else
        {
			$ADMIN->html .=$SKIN->start_table("数据恢复错误");
			$ADMIN->html .=$SKIN->add_td_row(array("数据恢复发生错误，无法恢复数据..."));
        }
        $ADMIN->html .=$SKIN->end_table();
        $ADMIN->output();
        }

	function manage_form()
	{
        global $SKIN,$ADMIN;
        $ADMIN->page_title="数据文件管理";
        $ADMIN->page_detail="你可以删除不需要的数据备份文件";
        $ADMIN->html .= $SKIN->start_form( array( 1 => array( 'act'  , 'mysql' ),
                                                  2 => array( 'code' , 'do_manage'),
                                                                                  )      );
        $ADMIN->html .=$SKIN->start_table("数据文件管理");
        $ADMIN->html .=$SKIN->add_td_row(array("请选择需要删除的数据文件"));
        $ADMIN->html .="<tr><td id='tdrow2'>";
        $ADMIN->html .="<select name='files[]' size='8' multiple>";

        //读取文件
        $DIR=getcwd();
        $os=@php_uname();
        if(preg_match("|win|i",$os))
        {
			$b="\\";
        }
			else
        {
        $b="/";
        }
        $out=opendir($DIR.$b."archive_out");
        while($file=readdir($out))
        {
			if(preg_match("|(.*?).sql|",$file))
			{
				$ADMIN->html .="<option value='".$DIR.$b."archive_out".$b.$file."'>{$file}</option>";
			}
        }
        closedir($out);
        $in=opendir($DIR.$b."archive_in");
        while($file=readdir($in))
        {
			if(preg_match("|(.*?).sql|",$file))
			{
				$ADMIN->html .="<option value='".$DIR.$b."archive_in".$b.$file."'>{$file}</option>";
			}
        }
        closedir($in);
        $ADMIN->html.="</select>";
        $ADMIN->html .="</td></tr>";
        $ADMIN->html .= $SKIN->end_form('删除数据文件');
        $ADMIN->html .= $SKIN->end_table();
        $ADMIN->html .= $SKIN->start_form( array( 1 => array( 'act'  , 'mysql' ),
                                                  2 => array( 'code' , 'ad_del'),
                                                                                  )      );
        $ADMIN->html .=$SKIN->start_table("根据选择的条件删除数据文件...");
        $ADMIN->html.=$SKIN->add_td_row(array("<b>删除多少小时前的数据文件</b>","<input type='text' name='hour'>"));
        $ADMIN->html.=$SKIN->add_td_row(array("<b>删除多少天前的数据文件</b>","<input type='text' name='day'>"));
        $ADMIN->html.=$SKIN->add_td_row(array("<b>删除多少月前的数据文件</b>","<input type='text' name='mou'>"));
        $ADMIN->html .= $SKIN->end_form('删除');
        $ADMIN->html .= $SKIN->end_table();
        $ADMIN->output();
        }

	function do_manage()
	{
        global $ADMIN,$SKIN,$HTTP_POST_VARS;
        $count=0;
        $all=count($HTTP_POST_VARS['files']);
        foreach($HTTP_POST_VARS['files'] as $to_del)
        {
			$count+=@unlink($to_del);
        }
        $ADMIN->page_title="数据文件管理结果";
        $ADMIN->page_detail="数据文件删除结果";
        $ADMIN->html.=$SKIN->start_table("显示结果");
        $ADMIN->html .=$SKIN->add_td_row(array("总数 $all 文件中 $count 文件被删除"));
        $ADMIN->output();
        }

	function ad_del()
	{
        global $ADMIN,$SKIN,$HTTP_POST_VARS;
        $current=time();
        if($HTTP_POST_VARS['hour']!="")
        {
			$del=$HTTP_POST_VARS['hour'] * 3600;
			$deltime=$current - $del;
        }
        elseif($HTTP_POST_VARS['day']!="")
        {
			$del=$HTTP_POST_VARS['day'] * 86400;
			$deltime=$current - $del;
        }
        elseif($HTTP_POST_VARS['mou']!="")
        {
			$del=$HTTP_POST_VARS['mou'] * 2592000;
			$deltime=$current - $del;
        }
        else
        {
			$ADMIN->page_title="显示结果";
			$ADMIN->page_detail="数据文件删除结果";
			$ADMIN->html.=$SKIN->start_table("显示结果");
			$ADMIN->html .=$SKIN->add_td_row(array("没有删除文件"));
			$ADMIN->output();
			exit();
        }
         $count=0;

		 //获取文件
        $DIR=getcwd();
        $os=@php_uname();
        if(preg_match("|win|i",$os))
        {
			$b="\\";
        }
        else
        {
			$b="/";
        }
        $out=opendir($DIR.$b."archive_out");
        while($file=readdir($out))
        {
			if(preg_match("|(.*?).sql|",$file)):
				$date=str_replace(".sql","",$file);
				$date=explode("_",$file);
				$date=$date[4];
			if($date < $deltime)
			{
				$count=@unlink($DIR.$b."archive_out".$b.$file);
			}
			endif;
        }
        closedir($out);
        $out=opendir($DIR.$b."archive_in");
        while($file=readdir($out))
        {
			if(preg_match("|(.*?).sql|",$file)):
				$date=str_replace(".sql","",$file);
				$date=explode("_",$file);
				$date=$date[4];
			if($date < $deltime)
			{
				$count=@unlink($DIR.$b."archive_in".$b.$file);
			}
			endif;
        }
        closedir($out);
        $ADMIN->page_title="显示结果";
        $ADMIN->page_detail="数据文件删除结果";
        $ADMIN->html.=$SKIN->start_table("显示结果");
        $ADMIN->html .=$SKIN->add_td_row(array("{$count} 文件已经删除"));
        $ADMIN->output();
        }
//------------------------------------------------------------------
// 添加数据备份恢复插件 - 详情请访问: http://www.ibfchina.com - 结束
//------------------------------------------------------------------
	
	function do_safe_backup($tbl_name="")
	{
		global $IN, $INFO, $DB, $SKIN, $ADMIN, $std, $MEMBER, $GROUP;
		
		if ($tbl_name == "")
		{
			// Auto all tables
			$skip        = intval($IN['skip']);
			$create_tbl  = intval($IN['create_tbl']);
			$enable_gzip = intval($IN['enable_gzip']);
			$filename    = 'ibf_dbbackup';
		}
		else
		{
			// Man. click export
			
			$skip        = 0;
			$create_tbl  = 0;
			$enable_gzip = 1;
			$filename    = $tbl_name;
		}
		
		$output = "";
		
		@header("Pragma: no-cache");
		
		$do_gzip = 0;
		
		if( $enable_gzip )
		{
			$phpver = phpversion();

			if($phpver >= "4.0")
			{
				if(extension_loaded("zlib"))
				{
					$do_gzip = 1;
				}
			}
		}
		
		if( $do_gzip != 0 )
		{
			@ob_start();
			@ob_implicit_flush(0);
			header("Content-Type: text/x-delimtext; name=\"$filename.sql.gz\"");
			header("Content-disposition: attachment; filename=$filename.sql.gz");
		}
		else
		{
			header("Content-Type: text/x-delimtext; name=\"$filename.sql\"");
			header("Content-disposition: attachment; filename=$filename.sql");
		}
		
		//-----------------------------
		// Get tables to work on
		//-----------------------------
		
		if ($tbl_name == "")
		{
			$tmp_tbl = $DB->get_table_names();
				
			foreach($tmp_tbl as $tbl)
			{
				// Ensure that we're only peeking at IBF tables
				
				if ( preg_match( "/^".$INFO['sql_tbl_prefix']."/", $tbl ) )
				{
					// We've started our headers, so print as we go to stop
					// poss memory problems
					
					$this->get_table_sql($tbl, $create_tbl, $skip);
				}
			}
		}
		else
		{
			$this->get_table_sql($tbl_name, $create_tbl, $skip);
		}
		
		//-----------------------------
		// GZIP?
		//-----------------------------
		
		if($do_gzip)
		{
			$size     = ob_get_length();
			$crc      = crc32(ob_get_contents());
			$contents = gzcompress(ob_get_contents());
			ob_end_clean();
			echo $this->str_gzip_header
				.substr($contents, 0, strlen($contents) - 4)
				.$this->gzip_four_chars($crc)
				.$this->gzip_four_chars($size);
		}
		
		exit();
		
	}
	
	//-----------------------------------------------
	// Internal handler to return content from table
	//-----------------------------------------------
	
	function get_table_sql($tbl, $create_tbl, $skip=0)
	{
		global $IN, $INFO, $DB, $SKIN, $ADMIN, $std, $MEMBER, $GROUP;
		
		if ($create_tbl)
		{
			// Generate table structure
			
			if ( $IN['addticks'] )
			{
				$DB->query("SHOW CREATE TABLE `".$INFO['sql_database'].".".$tbl."`");
			}
			else
			{
				$DB->query("SHOW CREATE TABLE ".$INFO['sql_database'].".".$tbl);
			}
			
			$ctable = $DB->fetch_row();
			
			echo $this->sql_strip_ticks($ctable['Create Table']).";\n";
		}
		
		// Are we skipping? Woohoo, where's me rope?!
		
		if ($skip == 1)
		{
			if ($tbl == $INFO['sql_tbl_prefix'].'admin_sessions'
				OR $tbl == $INFO['sql_tbl_prefix'].'sessions'
				OR $tbl == $INFO['sql_tbl_prefix'].'reg_anti_spam'
				OR $tbl == $INFO['sql_tbl_prefix'].'search_results'
			   )
			{
				return $ret;
			}
		}
		
		// Get the data
		
		$DB->query("SELECT * FROM $tbl");
		
		// Check to make sure rows are in this
		// table, if not return.
		
		$row_count = $DB->get_num_rows();
		
		if ($row_count < 1)
		{
			return TRUE;
		}
		
		//---------------------------
		// Get col names
		//---------------------------
		
		$f_list = "";
	
		$fields = $DB->get_result_fields();
		
		$cnt = count($fields);
		
		for( $i = 0; $i < $cnt; $i++ )
		{
			$f_list .= $fields[$i]->name . ", ";
		}
		
		$f_list = preg_replace( "/, $/", "", $f_list );
		
		while ( $row = $DB->fetch_row() )
		{
			//---------------------------
			// Get col data
			//---------------------------
			
			$d_list = "";
			
			for( $i = 0; $i < $cnt; $i++ )
			{
				if ( ! isset($row[ $fields[$i]->name ]) )
				{
					$d_list .= "NULL,";
				}
				elseif ( $row[ $fields[$i]->name ] != '' )
				{
					$d_list .= "'".$this->sql_add_slashes($row[ $fields[$i]->name ]). "',";
				}
				else
				{
					$d_list .= "'',";
				}
			}
			
			$d_list = preg_replace( "/,$/", "", $d_list );
			
			echo "INSERT INTO $tbl ($f_list) VALUES($d_list);\n";
		}
		
		return TRUE;
		
	}
	
	//-----------------------------------------------
	// sql_strip_ticks from field names
	//-----------------------------------------------
	
	function sql_strip_ticks($data)
	{
		return str_replace( "`", "", $data );
	}
	
	//-----------------------------------------------
	// Add slashes to single quotes to stop sql breaks
	//-----------------------------------------------
	
	function sql_add_slashes($data)
	{
		$data = str_replace('\\', '\\\\', $data);
        $data = str_replace('\'', '\\\'', $data);
        $data = str_replace("\r", '\r'  , $data);
        $data = str_replace("\n", '\n'  , $data);
        
        return $data;
	}
	
	//-----------------------------------------------
	// Almost there!
	//-----------------------------------------------
	
	function sbup_splash()
	{
		global $IN, $INFO, $DB, $SKIN, $ADMIN, $std, $MEMBER, $GROUP;
		
		$ADMIN->page_detail = "你可以使用此功能备份你的论坛数据。";

		$ADMIN->page_title  = "mySQL ".$this->true_version." 数据备份";
		
		// Check for mySQL version..
		// Might change at some point..
		
		if ( $this->mysql_version < 32321 )
		{
			$ADMIN->error("对不起，你的 mySQL 数据库版本低于 3.23.21，数据库不支持备份功能，请先升级你的数据库系统。");
		}
		
		$SKIN->td_header[] = array( "&nbsp;" , "100%" );

		$ADMIN->html .= $SKIN->start_table( "Simple Back Up" );
		
		$ADMIN->html .= $SKIN->add_td_row( array( 
													"<b>备份论坛 mySQL 数据：</b><br><br>一旦你点击了下面的链接，请耐心等待直到你的浏览器弹出备份成功对话框。备份数据所需的时间取决于你论坛数据的大小。<br><br>
													<b><a href='{$ADMIN->base_url}&act=mysql&code=dosafebackup&create_tbl={$IN['create_tbl']}&addticks={$IN['addticks']}&skip={$IN['skip']}&enable_gzip={$IN['enable_gzip']}'>按此开始进行论坛数据备份</a></b>"
									     )      );
									     
												 
		$ADMIN->html .= $SKIN->end_table();
		
		
		$ADMIN->output();
		
	
	}
	
	
	function show_backup_form()
	{
		global $IN, $INFO, $DB, $SKIN, $ADMIN, $std, $MEMBER, $GROUP;
		
		$ADMIN->page_detail = "此功能允许你对论坛数据进行备份。<br><br><b>普通论坛数据备份</b>
							  <br>此功能将自动生成一个数据备份文件让你选择保存。（需要 PHP 打开安全模式参数）建议小型数据选用此功能进行数据备份。<!--<br><br>
							  <b>高级论坛数据备份</b>
							  <br>此功能允许你生成一个经过压缩的数据备份文件，并且可以直接保存到磁盘中。<br>注意：需要 PHP 打开安全模式参数才能使用此功能。-->";

		$ADMIN->page_title  = "mySQL ".$this->true_version." 数据备份";
		
		// Check for mySQL version..
		// Might change at some point..
		
		if ( $this->mysql_version < 32321 )
		{
			$ADMIN->error("对不起，你的 mySQL 数据库版本低于 3.23.21，数据库不支持备份功能，请先升级你的数据库系统。");
		}
		
		$SKIN->td_header[] = array( "&nbsp;" , "60%" );
		$SKIN->td_header[] = array( "&nbsp;" , "40%" );
			
		$ADMIN->html .= $SKIN->start_form( array( 1 => array( 'act'  , 'mysql' ),
											  	  2 => array( 'code' , 'safebackup'),
									 	 )      );
		
		$ADMIN->html .= $SKIN->start_table( "普通论坛数据备份" );
		
		$ADMIN->html .= $SKIN->add_td_row( array( 
													"<b>是否添加 'CREATE TABLE' 语句？</b><br>是否在数据表名称添加返回符号？<br>(如果你在备份时发现数据库错误信息，请选择此项) <input type='checkbox' name='addticks' value=1>",
													$SKIN->form_yes_no( 'create_tbl', 1),
									     )      );
									     
		$ADMIN->html .= $SKIN->add_td_row( array( 
													"<b>是否省略无意义的数据？</b><br>将不保存下列数据：ibf_sessions, ibf_admin_sessions, ibf_search_results, ibf_reg_anti_spam.",
													$SKIN->form_yes_no( 'skip', 1),
									     )      );
									     
		$ADMIN->html .= $SKIN->add_td_row( array( 
													"<b>是否使用 GZIP 功能？</b><br>将自动生成一个经过压缩的数据备份文件。",
													$SKIN->form_yes_no( 'enable_gzip', 1),
									     )      );
												 
		$ADMIN->html .= $SKIN->end_form("开始备份论坛数据");
		$ADMIN->html .= $SKIN->end_table();
		
		
		$ADMIN->output();
		
	
	}
	
	
	
	//-------------------------
	// Run mySQL queries
	//-------------------------
	
	
	function view_sql($sql)
	{
		global $IN, $INFO, $DB, $SKIN, $ADMIN, $std, $MEMBER, $GROUP;
		
		$limit = 50;
		$start = intval($IN['st']) == "" ? 0 : intval($IN['st']);
		$pages = "";
		
		$ADMIN->page_detail = "此功能允许你管理你的 mySQL 数据库.$extra";
		$ADMIN->page_title  = "mySQL ".$this->true_version." 数据库管理工具";
		
		$map = array( 'processes' => "数据用户信息",
					  'runtime'   => "数据运行信息",
					  'system'    => "数据系统信息",
					);
					
		if ($map[ $IN['code'] ] != "")
		{
			$tbl_title = $map[ $IN['code'] ];
			$man_query = 0;
		}
		else
		{
			$tbl_title = "SQL 查询语句";
			$man_query = 1;
		}
		
		//------------------------------------------------
		
		if ($man_query == 1)
		{
			$SKIN->td_header[] = array( "&nbsp;" , "100%" );
			
			$ADMIN->html .= $SKIN->start_form( array( 1 => array( 'act'  , 'mysql' ),
											      2 => array( 'code' , 'runsql'),
										 )      );
			
			$ADMIN->html .= $SKIN->start_table( "运行 SQL 语句" );
			
			$ADMIN->html .= $SKIN->add_td_row( array( "<center>".$SKIN->form_textarea("query", $sql )."</center>" ) );
													 
			$ADMIN->html .= $SKIN->end_form("运行新 SQL 语句");
			$ADMIN->html .= $SKIN->end_table();
			
			
			// Check for drop, create and flush
			
			if ( preg_match( "/^DROP|CREATE|FLUSH/i", trim($sql) ) )
			{
				$ADMIN->error = "对不起，为了安全起见，这些权限不允许。";
			}
		}
		
		//------------------------------------------------
		
		$DB->return_die = 1;
		
		$DB->query($sql);
		
		// Check for errors..
		
		if ( $DB->error != "")
		{
			$SKIN->td_header[] = array( "&nbsp;" , "100%" );
			
			$ADMIN->html .= $SKIN->start_table( "SQL 语句错误" );
			
			$ADMIN->html .= $SKIN->add_td_row( array($DB->error) );
		
			$ADMIN->html .= $SKIN->end_table();
			
			$ADMIN->output(); // End output and script
			
		}
		
		if ( preg_match( "/^INSERT|UPDATE|DELETE|ALTER/i", trim($sql) ) )
		{
			// We can't show any info, and if we're here, there isn't
			// an error, so we're good to go.
			
			$SKIN->td_header[] = array( "&nbsp;" , "100%" );
			
			$ADMIN->html .= $SKIN->start_table( "运行 SQL 语句完成" );
			
			$ADMIN->html .= $SKIN->add_td_row( array("语句：$sql<br>执行成功") );
		
			$ADMIN->html .= $SKIN->end_table();
			
			$ADMIN->output(); // End output and script
			
		}
		else if ( preg_match( "/^SELECT/i", $sql ) )
		{
			// Sort out the pages and stuff
			// auto limit if need be
			
			if ( ! preg_match( "/LIMIT[ 0-9,]+$/i", $sql ) )
			{
				$rows_returned = $DB->get_num_rows();
			
				if ($rows_returned > $limit)
				{
					// Get tbl name
			
					//$tbl_name = preg_replace( "/(".$INFO['sql_tbl_prefix']."\S+?)([\s\.,]|$)/i", "\\1", $sql );
			
					// Set up pages.
					
					$links = $std->build_pagelinks( array( 'TOTAL_POSS'  => $rows_returned,
														   'PER_PAGE'    => $limit,
														   'CUR_ST_VAL'  => $start,
														   'L_SINGLE'    => " ",
														   'L_MULTI'     => "页：",
														   'BASE_URL'    => $ADMIN->base_url."&act=mysql&code=runsql&query=".urlencode($sql),
														 )
												  );
												  
					$sql .= " LIMIT $start, $limit";
				
					// Re-run with limit
					
					$DB->query($sql, 1); /// bypass table swapping
				}
			}
			
		}
		
		$fields = $DB->get_result_fields();
		
		$cnt = count($fields);
		
		// Print the headers - we don't what or how many so...
		
		for( $i = 0; $i < $cnt; $i++ )
		{
			$SKIN->td_header[] = array( $fields[$i]->name , "*" );
		}
		
		$ADMIN->html .= $SKIN->start_table( "结果：".$tbl_title );
		
		if ($links != "")
		{
			$pages = $SKIN->add_td_basic( $links, 'left', 'tdrow2' );
		
			$ADMIN->html .= $pages;
		}
		
		while( $r = $DB->fetch_row() )
		{
		
			// Grab the rows - we don't what or how many so...
			
			$rows = array();
			
			for( $i = 0; $i < $cnt; $i++ )
			{
				if ($man_query == 1)
				{
					// Limit output
					if ( strlen($r[ $fields[$i]->name ]) > 200 )
					{
						$r[ $fields[$i]->name ] = substr($r[ $fields[$i]->name ], 0, 200) .'...';
					}
				}
				
				$rows[] = wordwrap( htmlspecialchars(nl2br($r[ $fields[$i]->name ])) , 50, "<br>", 1 );
			}
			
			$ADMIN->html .= $SKIN->add_td_row( $rows );
		
		}
		
		$ADMIN->html .= $SKIN->end_table();
		
		//+-------------------------------
		
		$ADMIN->output();
		
		
	}
	
	//-------------------------------------------------------------
	// I'm A TOOL!
	//-------------------------------------------------------------
	
	function run_tool()
	{
		global $IN, $INFO, $DB, $SKIN, $ADMIN, $std, $MEMBER, $GROUP;
		
		$ADMIN->page_detail = "此功能允许你管理你的 mySQL 数据库.$extra";
		$ADMIN->page_title  = "mySQL ".$this->true_version." 数据库管理工具";
		
		//-------------------------------------------------------------
		// have we got some there tables me laddo?
		//-------------------------------------------------------------
		
		$tables = array();
 		
 		foreach ($IN as $key => $value)
 		{
 			if ( preg_match( "/^tbl_(\S+)$/", $key, $match ) )
 			{
 				if ($IN[$match[0]])
 				{
 					$tables[] = $match[1];
 				}
 			}
 		}
 		
 		if ( count($tables) < 1 )
 		{
 			$ADMIN->error("你必须选择需要执行此功能的数据表格。");
 		}
 		
 		//-------------------------------------------------------------
		// What tool is one running?
		// optimize analyze check repair
		//-------------------------------------------------------------
		
		if (strtoupper($IN['tool']) == 'DROP' || strtoupper($IN['tool']) == 'CREATE' || strtoupper($IN['tool']) == 'FLUSH')
		{
			$ADMIN->error("对不起，你不能执行此操作！");
		}
		
		foreach($tables as $table)
		{
			$DB->query(strtoupper($IN['tool'])." TABLE $table");
			
			$fields = $DB->get_result_fields();
			
			$data = $DB->fetch_row();
			
			$cnt = count($fields);
			
			// Print the headers - we don't what or how many so...
			
			for( $i = 0; $i < $cnt; $i++ )
			{
				$SKIN->td_header[] = array( $fields[$i]->name , "*" );
			}
			
			$ADMIN->html .= $SKIN->start_table( "结果：".$IN['tool']." ".$table );
			
			// Grab the rows - we don't what or how many so...
			
			$rows = array();
			
			for( $i = 0; $i < $cnt; $i++ )
			{
				$rows[] = $data[ $fields[$i]->name ];
			}
			
			$ADMIN->html .= $SKIN->add_td_row( $rows );
			
			$ADMIN->html .= $SKIN->end_table();
		}
		
		//+-------------------------------
		
		$ADMIN->output();
		
		
	}
	
	
	//-------------------------------------------------------------
	// SHOW ALL TABLES AND STUFF!
	// 5 hours ago this seemed like a damned good idea.
	// Now it's late and I want to replace all of this code with
	// header("Location: http://yoursite/phpmyadmin");
	//-------------------------------------------------------------
	
	function list_index()
	{
		global $IN, $INFO, $DB, $SKIN, $ADMIN, $std, $MEMBER, $GROUP;
		
		$form_array = array();
		
		if ( $this->mysql_version < 32322 )
		{
			$extra = "<br><b>注意：你的 mySQL 数据库版本对某些功能进行了限制。</b>";
		}
	
		$ADMIN->page_detail = "此功能允许你管理你的 mySQL 数据库.$extra";
		$ADMIN->page_title  = "mySQL ".$this->true_version." 数据库管理工具";
		
		//+-------------------------------
		// Show advanced stuff for mySQL > 3.23.03
		//+-------------------------------
		
		$idx_size = 0;
		$tbl_size = 0;
		
		
		$ADMIN->html .= "
				     <script language='Javascript'>
                     <!--
                     function CheckAll(cb) {
                         var fmobj = document.theForm;
                         for (var i=0;i<fmobj.elements.length;i++) {
                             var e = fmobj.elements[i];
                             if ((e.name != 'allbox') && (e.type=='checkbox') && (!e.disabled)) {
                                 e.checked = fmobj.allbox.checked;
                             }
                         }
                     }
                     function CheckCheckAll(cb) {	
                         var fmobj = document.theForm;
                         var TotalBoxes = 0;
                         var TotalOn = 0;
                         for (var i=0;i<fmobj.elements.length;i++) {
                             var e = fmobj.elements[i];
                             if ((e.name != 'allbox') && (e.type=='checkbox')) {
                                 TotalBoxes++;
                                 if (e.checked) {
                                     TotalOn++;
                                 }
                             }
                         }
                         if (TotalBoxes==TotalOn) {fmobj.allbox.checked=true;}
                         else {fmobj.allbox.checked=false;}
                     }
                     //-->
                     </script>
                     ";
						  
		$ADMIN->html .= $SKIN->start_form( array( 1 => array( 'act'  , 'mysql' ),
											      2 => array( 'code' , 'dotool'),
										 ) , "theForm"     );
		
		if ( $this->mysql_version >= 32303 )
		{
		
			$SKIN->td_header[] = array( "数据表"      , "20%" );
			$SKIN->td_header[] = array( "数据纪录"       , "10%" );
			$SKIN->td_header[] = array( "数据尺寸"   , "20%" );
			$SKIN->td_header[] = array( "索引尺寸" , "20%" );
			$SKIN->td_header[] = array( "导出"     , "10%" );
			$SKIN->td_header[] = array( '<input name="allbox" type="checkbox" value="全部选中" onClick="CheckAll();">'     , "10%" );
			
			$ADMIN->html .= $SKIN->start_table( "华酷论坛数据表" );
			
			$DB->query("SHOW TABLE STATUS FROM `".$INFO['sql_database']."`");
			
			while ( $r = $DB->fetch_row() )
			{
				// Check to ensure it's a table for this install...
				
				if ( ! preg_match( "/^".$INFO['sql_tbl_prefix']."/", $r['Name'] ) )
				{
					continue;
				}
				
				$idx_size += $r['Index_length'];
				$tbl_size += $r['Data_length'];
				
				$iBit = ($r['Index_length'] > 0) ? 1 : 0;
				$tBit = ($r['Data_length'] > 0)  ? 1 : 0;
				
				$idx = $this->gen_size( $r['Index_length'], 3, $iBit );
				$tbl = $this->gen_size( $r['Data_length'] , 3, $tBit );
				
				$ADMIN->html .= $SKIN->add_td_row( array( "<b><span style='font-size:12px'><a href='{$SKIN->base_url}&act=mysql&code=runsql&query=".urlencode("SELECT * FROM {$r['Name']}")."'>{$r['Name']}</a></span></b>",
														  "<center>{$r['Rows']}</center>",
														  "<div align='right'><span style='color:blue;font-size:12px'>{$tbl[0]} {$tbl[1]}</span></div>",
														  "<div align='right'>{$idx[0]} {$idx[1]}</div>",
														  "<center><a href='{$SKIN->base_url}&act=mysql&code=export_tbl&tbl={$r['Name']}'>导出</a></center></b>",
														  "<center><input name=\"tbl_{$r['Name']}\" value=1 type='checkbox' onClick=\"CheckCheckAll();\"></center>",
												 )      );
			}
			
			$total = $idx_size + $tbl_size;
			
			$iBit = ($idx_size > 0) ? 1 : 0;
			$tBit = ($tbl_size > 0)  ? 1 : 0;
			$oBit = ($total    > 0)  ? 1 : 0;
			
			$idx = $this->gen_size( $idx_size , 3, $iBit );
			$tbl = $this->gen_size( $tbl_size , 3, $tBit );
			$tot = $this->gen_size( $total    , 3, $oBit );
			
			$ADMIN->html .= $SKIN->add_td_row( array ("&nbsp;",
													  "<div align='right'>共：(<b>{$tot[0]} {$tot[1]}</b>)</div>",
													  "<div align='right'><b>{$tbl[0]} {$tbl[1]}</b></div>",
													  "<div align='right'><b>{$idx[0]} {$idx[1]}</b></div>",
													  "&nbsp;",
											 )       );
											 
		}
		else
		{
			// display a basic information table
			
			$SKIN->td_header[] = array( "数据表"      , "60%" );
			$SKIN->td_header[] = array( "数据记录"       , "30%" );
			$SKIN->td_header[] = array( '<input name="allbox" type="checkbox" value="全部选中" onClick="CheckAll();">'     , "10%" );
			
			$ADMIN->html .= $SKIN->start_table( "华酷论坛数据表" );
			
			$tables = $DB->get_table_names();
			
			foreach($tables as $tbl)
			{
				// Ensure that we're only peeking at IBF tables
				
				if ( ! preg_match( "/^".$INFO['sql_tbl_prefix']."/", $tbl ) )
				{
					continue;
				}
				
				$DB->query("SELECT COUNT(*) AS Rows FROM $tbl");
				
				$cnt = $DB->fetch_row();
				
				$ADMIN->html .= $SKIN->add_td_row( array( "<b><span style='font-size:12px'>$tbl</span></b>",
														  "<center>{$cnt['Rows']}</center>",
														  "<center><input name='tbl_$tbl' type='checkbox' onClick=\"CheckCheckAll(this);\"></center>",
												 )      );
												 
			}
			
		}
		
		//----------------------------
		// Add in the bottom stuff
		//----------------------------
											 
		if ( $this->mysql_version < 32322 )
		{
			$ADMIN->html .= $SKIN->add_td_basic( "<select id='button' name='tool'>
													<option value='optimize'>优化选择的数据表</option>
												  </select>
												 <input type='submit' value='执行' id='button'></form>", "center", "tdrow2" );
		}
		else
		{
										 
			$ADMIN->html .= $SKIN->add_td_basic( "<select id='button' name='tool'>
													<option value='optimize'>优化选择的数据表</option>
													<option value='repair'>修复选择的数据表</option>
													<option value='check'>检查选择的数据表</option>
													<option value='analyze'>分析选择的数据表</option>
												  </select>
												 <input type='submit' value='执行' id='button'></form>", "center", "tdrow2" );
		}
			
		$ADMIN->html .= $SKIN->end_table();
		
		
		//----------------------------
		
		$ADMIN->html .= $SKIN->start_form( array( 1 => array( 'act'  , 'mysql' ),
											      2 => array( 'code' , 'runsql'),
										 )      );
		
		$SKIN->td_header[] = array( "数据表"      , "30%" );
		$SKIN->td_header[] = array( "数据记录"       , "70%" );
		
		$ADMIN->html .= $SKIN->start_table( "运行 SQL 语句" );
		
		$ADMIN->html .= $SKIN->add_td_row( array( "<b>SQL 查询语句</b><br>高级用户使用",
												  $SKIN->form_textarea("query", "" ),
												 )      );
												 
		$ADMIN->html .= $SKIN->end_form("运行 SQL 语句");
		$ADMIN->html .= $SKIN->end_table();
		
		
		//+-------------------------------
		
		$ADMIN->output();
	
	}
	
	//-------------------------------------------------------------
	// Convert chars into byte sizes
	// (Based on a similar function in phpmyadmin)
	// "Based on?" my ass!
	// Ok, so I pretty much cut n' pasted it - but it's late and I
	// have to get this done.
	// I did make it pretty though - does that count?
	// Oh CMON! A zillion lines of new code and you can't get over
	// a few lines "borrowed" from another script?
	//-------------------------------------------------------------
	
	function gen_size($val, $li, $sepa )
	{
		$sep     = pow(10, $sepa);
		$li      = pow(10, $li);
		$retval  = $val;
		$unit    = 'Bytes';
	
		if ($val >= $li * 1000000)
		{
			$val = round( $val / (1073741824/$sep) ) / $sep;
			$unit  = 'GB';
		}
		else if ($val >= $li*1000)
		{
			$val = round( $val / (1048576/$sep) ) / $sep;
			$unit  = 'MB';
		}
		else if ($val >= $li)
		{
			$val = round( $val / (1024/$sep) ) / $sep;
			$unit  = 'KB';
		}
		if ($unit != 'Bytes')
		{
			$retval = number_format($val, $sepa, '.', ',');
		}
		else
		{
			$retval = number_format($val, 0, '.', ',');
		}
		
		return array($retval, $unit);
    }
    
    function gzip_four_chars($val)
	{
		for ($i = 0; $i < 4; $i ++)
		{
			$return .= chr($val % 256);
			$val     = floor($val / 256);
		}
		return $return;
	} 
	
	
	
}


?>