-<?php\r
-/**\r
- * Scripts to create/restore a backup of the Nucleus database\r
- *\r
- * Based on code in phpBB (http://phpBB.sourceforge.net)\r
- */\r
-\r
- \r
-/**\r
- * This function creates an sql dump of the database and sends it to\r
- * the user as a file (can be gzipped if they want)\r
- *\r
- * @requires \r
- * no output may have preceded (new headers are sent)\r
- * @param gzip \r
- * 1 = compress backup file, 0 = no compression (default)\r
- */\r
-function do_backup($gzip = 0) {\r
- global $manager;\r
-\r
- // tables of which backup is needed\r
- $tables = array(\r
- sql_table('actionlog'),\r
- sql_table('ban'),\r
- sql_table('blog'),\r
- sql_table('comment'),\r
- sql_table('config'),\r
- sql_table('item'),\r
- sql_table('karma'),\r
- sql_table('member'),\r
- sql_table('skin'),\r
- sql_table('skin_desc'),\r
- sql_table('team'),\r
- sql_table('template'),\r
- sql_table('template_desc'),\r
- sql_table('plugin'),\r
- sql_table('plugin_event'),\r
- sql_table('plugin_option'),\r
- sql_table('plugin_option_desc'),\r
- sql_table('category')\r
- );\r
-\r
- // add tables that plugins want to backup to the list\r
- // catch all output generated by plugins\r
- ob_start();\r
- $res = sql_query('SELECT pfile FROM '.sql_table('plugin'));\r
- while ($plugName = mysql_fetch_object($res)) {\r
- $plug =& $manager->getPlugin($plugName->pfile);\r
- if ($plug) $tables = array_merge($tables, $plug->getTableList());\r
- }\r
- ob_end_clean();\r
- \r
- // remove duplicates\r
- $tables = array_unique($tables);\r
- \r
- // make sure browsers don't cache the backup\r
- header("Pragma: no-cache");\r
- \r
- // don't allow gzip compression when extension is not loaded\r
- if (($gzip != 0) && !extension_loaded("zlib"))\r
- $gzip = 0;\r
- \r
- \r
-\r
- if ($gzip) {\r
- // use an output buffer\r
- @ob_start();\r
- @ob_implicit_flush(0);\r
- \r
- // set filename\r
- $filename = 'nucleus_db_backup_'.strftime("%Y%m%d", time()).".sql.gz";\r
- } else {\r
- $filename = 'nucleus_db_backup_'.strftime("%Y%m%d", time()).".sql";\r
- }\r
- \r
- \r
- // send headers that tell the browser a file is coming\r
- header("Content-Type: text/x-delimtext; name=\"$filename\"");\r
- header("Content-disposition: attachment; filename=$filename");\r
- \r
- // dump header\r
- echo "#\n";\r
- echo "# This is a backup file generated by Nucleus \n";\r
- echo "# http://www.nucleuscms.org/\n";\r
- echo "#\n";\r
- echo "# backup-date: " . gmdate("d-m-Y H:i:s", time()) . " GMT\n";\r
- global $nucleus;\r
- echo "# nucleus version: " . $nucleus['version'] . "\n"; \r
- echo "#\n";\r
- echo "# WARNING: Only try to restore on servers running the exact same version of Nucleus\n";\r
- echo "#\n";\r
- \r
- // dump all tables\r
- reset($tables);\r
- array_walk($tables, '_backup_dump_table');\r
- \r
- if($gzip)\r
- {\r
- $Size = ob_get_length();\r
- $Crc = crc32(ob_get_contents());\r
- $contents = gzcompress(ob_get_contents());\r
- ob_end_clean();\r
- echo "\x1f\x8b\x08\x00\x00\x00\x00\x00".substr($contents, 0, strlen($contents) - 4).gzip_PrintFourChars($Crc).gzip_PrintFourChars($Size);\r
- }\r
- \r
- exit;\r
-\r
-}\r
-\r
-\r
-/**\r
- * Creates a dump for a single table\r
- * ($tablename and $key are filled in by array_walk)\r
- */\r
-function _backup_dump_table($tablename, $key) {\r
-\r
- echo "#\n";\r
- echo "# TABLE: " . $tablename . "\n";\r
- echo "#\n";\r
- \r
- // dump table structure\r
- _backup_dump_structure($tablename);\r
-\r
- // dump table contents\r
- _backup_dump_contents($tablename);\r
-}\r
-\r
-function _backup_dump_structure($tablename) {\r
- \r
- // add command to drop table on restore\r
- echo "DROP TABLE IF EXISTS $tablename;\n";\r
- echo "CREATE TABLE $tablename(\n";\r
-\r
- //\r
- // Ok lets grab the fields...\r
- //\r
- $result = mysql_query("SHOW FIELDS FROM $tablename");\r
- $row = mysql_fetch_array($result);\r
- while ($row) {\r
-\r
- echo ' ' . $row['Field'] . ' ' . $row['Type'];\r
-\r
- if(!empty($row['Default']))\r
- echo ' DEFAULT \'' . $row['Default'] . '\'';\r
-\r
- if($row['Null'] != "YES")\r
- echo ' NOT NULL';\r
-\r
- if($row['Extra'] != "")\r
- echo ' ' . $row['Extra'];\r
-\r
- $row = mysql_fetch_array($result);\r
-\r
- // add comma's except for last one\r
- if ($row)\r
- echo ",\n";\r
- }\r
-\r
- //\r
- // Get any Indexed fields from the database...\r
- //\r
- $result = mysql_query("SHOW KEYS FROM $tablename");\r
- while($row = mysql_fetch_array($result)) {\r
- $kname = $row['Key_name'];\r
-\r
- if(($kname != 'PRIMARY') && ($row['Non_unique'] == 0))\r
- $kname = "UNIQUE|$kname";\r
- if(($kname != 'PRIMARY') && ($row['Index_type'] == 'FULLTEXT'))\r
- $kname = "FULLTEXT|$kname";\r
- \r
- if(!is_array($index[$kname]))\r
- $index[$kname] = array();\r
- \r
- $index[$kname][] = $row['Column_name'];\r
- }\r
-\r
- while(list($x, $columns) = @each($index)) {\r
- echo ", \n";\r
-\r
- if($x == 'PRIMARY')\r
- echo ' PRIMARY KEY (' . implode($columns, ', ') . ')';\r
- elseif (substr($x,0,6) == 'UNIQUE')\r
- echo ' UNIQUE KEY ' . substr($x,7) . ' (' . implode($columns, ', ') . ')';\r
- elseif (substr($x,0,8) == 'FULLTEXT')\r
- echo ' FULLTEXT KEY ' . substr($x,9) . ' (' . implode($columns, ', ') . ')';\r
- elseif (($x == 'ibody') || ($x == 'cbody')) // karma 2004-05-30 quick and dirty fix. fulltext keys were not in SQL correctly.\r
- echo ' FULLTEXT KEY ' . substr($x,9) . ' (' . implode($columns, ', ') . ')'; \r
- else \r
- echo " KEY $x (" . implode($columns, ', ') . ')';\r
- }\r
-\r
- echo "\n);\n\n";\r
-}\r
-\r
-function _backup_dump_contents($tablename) {\r
- //\r
- // Grab the data from the table.\r
- //\r
- $result = mysql_query("SELECT * FROM $tablename");\r
-\r
- if(mysql_numrows($result) > 0)\r
- echo "\n#\n# Table Data for $tablename\n#\n";\r
-\r
- //\r
- // Loop through the resulting rows and build the sql statement.\r
- //\r
- while ($row = mysql_fetch_array($result))\r
- {\r
- $tablename_list = '(';\r
- $num_fields = mysql_num_fields($result);\r
-\r
- //\r
- // Grab the list of field names.\r
- //\r
- for ($j = 0; $j < $num_fields; $j++)\r
- $tablename_list .= mysql_field_name($result, $j) . ', ';\r
-\r
- //\r
- // Get rid of the last comma\r
- //\r
- $tablename_list = ereg_replace(', $', '', $tablename_list);\r
- $tablename_list .= ')';\r
-\r
- // Start building the SQL statement.\r
-\r
- echo "INSERT INTO $tablename $tablename_list VALUES(";\r
-\r
- // Loop through the rows and fill in data for each column\r
- for ($j = 0; $j < $num_fields; $j++) {\r
- if(!isset($row[$j])) {\r
- // no data for column\r
- echo ' NULL';\r
- } elseif ($row[$j] != '') {\r
- // data\r
- echo " '" . addslashes($row[$j]) . "'";\r
- } else {\r
- // empty column (!= no data!)\r
- echo "''";\r
- }\r
-\r
- // only add comma when not last column\r
- if ($j != ($num_fields - 1))\r
- echo ",";\r
- }\r
-\r
- echo ");\n";\r
-\r
- }\r
- \r
- \r
- echo "\n";\r
-\r
-}\r
-\r
-// copied from phpBB\r
-function gzip_PrintFourChars($Val)\r
-{\r
- for ($i = 0; $i < 4; $i ++)\r
- {\r
- $return .= chr($Val % 256);\r
- $Val = floor($Val / 256);\r
- }\r
- return $return;\r
-} \r
-\r
-function do_restore() {\r
- \r
- $uploadInfo = postFileInfo('backup_file');\r
- \r
- // first of all: get uploaded file:\r
- if (empty($uploadInfo['name']))\r
- return 'No file uploaded';\r
- if (!is_uploaded_file($uploadInfo['tmp_name']))\r
- return 'No file uploaded';\r
- \r
- $backup_file_name = $uploadInfo['name'];\r
- $backup_file_tmpname = $uploadInfo['tmp_name'];\r
- $backup_file_type = $uploadInfo['backup_file']['type'];\r
-\r
- if (!file_exists($backup_file_tmpname))\r
- return 'File Upload Error';\r
- \r
- if (!preg_match("/^(text\/[a-zA-Z]+)|(application\/(x\-)?gzip(\-compressed)?)|(application\/octet-stream)$/is", $backup_file_type) )\r
- return 'The uploaded file is not of the correct type';\r
- \r
- if (preg_match("/\.gz/is",$backup_file_name)) \r
- $gzip = 1;\r
- else\r
- $gzip = 0;\r
- \r
- if (!extension_loaded("zlib") && $gzip)\r
- return "Cannot decompress gzipped backup (zlib package not installed)";\r
-\r
- // get sql query according to gzip setting (either decompress, or not)\r
- if($gzip)\r
- {\r
- // decompress and read\r
- $gz_ptr = gzopen($backup_file_tmpname, 'rb');\r
- $sql_query = "";\r
- while( !gzeof($gz_ptr) )\r
- $sql_query .= gzgets($gz_ptr, 100000);\r
- } else {\r
- // just read\r
- $fsize = filesize($backup_file_tmpname);\r
- if ($fsize <= 0)\r
- $sql_query = '';\r
- else\r
- $sql_query = fread(fopen($backup_file_tmpname, 'r'), $fsize);\r
- }\r
-\r
- // time to execute the query\r
- _execute_queries($sql_query);\r
-}\r
-\r
-function _execute_queries($sql_query) {\r
- if (!$sql_query) return;\r
-\r
- // Strip out sql comments...\r
- $sql_query = remove_remarks($sql_query);\r
- $pieces = split_sql_file($sql_query);\r
-\r
- $sql_count = count($pieces);\r
- for($i = 0; $i < $sql_count; $i++)\r
- {\r
- $sql = trim($pieces[$i]);\r
-\r
- if(!empty($sql) and $sql[0] != "#")\r
- {\r
- // DEBUG\r
-// debug("Executing: " . htmlspecialchars($sql) . "\n");\r
-\r
- $result = mysql_query($sql);\r
- if (!$result) debug("SQL Error: " + mysql_error());\r
-\r
- }\r
- }\r
-\r
-}\r
-\r
-//\r
-// remove_remarks will strip the sql comment lines out of an uploaded sql file\r
-//\r
-function remove_remarks($sql)\r
-{\r
- $lines = explode("\n", $sql);\r
- \r
- // try to keep mem. use down\r
- $sql = "";\r
- \r
- $linecount = count($lines);\r
- $output = "";\r
-\r
- for ($i = 0; $i < $linecount; $i++)\r
- {\r
- if (($i != ($linecount - 1)) || (strlen($lines[$i]) > 0))\r
- {\r
- if ($lines[$i][0] != "#")\r
- {\r
- $output .= $lines[$i] . "\n";\r
- }\r
- else\r
- {\r
- $output .= "\n";\r
- }\r
- // Trading a bit of speed for lower mem. use here.\r
- $lines[$i] = "";\r
- }\r
- }\r
- \r
- return $output;\r
- \r
-}\r
-\r
-\r
-//\r
-// split_sql_file will split an uploaded sql file into single sql statements.\r
-// Note: expects trim() to have already been run on $sql.\r
-//\r
-// taken from phpBB\r
-//\r
-function split_sql_file($sql)\r
-{\r
- // Split up our string into "possible" SQL statements.\r
- $tokens = explode( ";", $sql);\r
-\r
- // try to save mem.\r
- $sql = "";\r
- $output = array();\r
- \r
- // we don't actually care about the matches preg gives us.\r
- $matches = array();\r
- \r
- // this is faster than calling count($tokens) every time thru the loop.\r
- $token_count = count($tokens);\r
- for ($i = 0; $i < $token_count; $i++)\r
- {\r
- // Don't wanna add an empty string as the last thing in the array.\r
- if (($i != ($token_count - 1)) || (strlen($tokens[$i] > 0)))\r
- {\r
- \r
- // even number of quotes means a complete SQL statement\r
- if (_evenNumberOfQuotes($tokens[$i]))\r
- {\r
- $output[] = $tokens[$i];\r
- $tokens[$i] = ""; // save memory.\r
- }\r
- else\r
- {\r
- // incomplete sql statement. keep adding tokens until we have a complete one.\r
- // $temp will hold what we have so far.\r
- $temp = $tokens[$i] . ";";\r
- $tokens[$i] = ""; // save memory..\r
- \r
- // Do we have a complete statement yet? \r
- $complete_stmt = false;\r
- \r
- for ($j = $i + 1; (!$complete_stmt && ($j < $token_count)); $j++)\r
- {\r
- // odd number of quotes means a completed statement \r
- // (in combination with the odd number we had already)\r
- if (!_evenNumberOfQuotes($tokens[$j]))\r
- {\r
- $output[] = $temp . $tokens[$j];\r
-\r
- // save memory.\r
- $tokens[$j] = "";\r
- $temp = "";\r
- \r
- // exit the loop.\r
- $complete_stmt = true;\r
- // make sure the outer loop continues at the right point.\r
- $i = $j;\r
- }\r
- else\r
- {\r
- // even number of unescaped quotes. We still don't have a complete statement. \r
- // (1 odd and 1 even always make an odd)\r
- $temp .= $tokens[$j] . ";";\r
- // save memory.\r
- $tokens[$j] = "";\r
- }\r
- \r
- } // for..\r
- } // else\r
- }\r
- }\r
-\r
- return $output;\r
-}\r
-\r
-\r
-function _evenNumberOfQuotes($text) {\r
- // This is the total number of single quotes in the token.\r
- $total_quotes = preg_match_all("/'/", $text, $matches);\r
- // Counts single quotes that are preceded by an odd number of backslashes, \r
- // which means they're escaped quotes.\r
- $escaped_quotes = preg_match_all("/(?<!\\\\)(\\\\\\\\)*\\\\'/", $text, $matches);\r
-\r
- $unescaped_quotes = $total_quotes - $escaped_quotes;\r
-// debug($total_quotes . "-" . $escaped_quotes . "-" . $unescaped_quotes);\r
- return (($unescaped_quotes % 2) == 0);\r
-}\r
-\r
-?>\r
+<?php
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * Scripts to create/restore a backup of the Nucleus database
+ *
+ * Based on code in phpBB (http://phpBB.sourceforge.net)
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: backup.php,v 1.8 2007-02-19 22:27:59 kmorimatsu Exp $
+ * $NucleusJP: backup.php,v 1.7 2007/02/04 06:28:46 kimitake Exp $
+ */
+
+
+/**
+ * This function creates an sql dump of the database and sends it to
+ * the user as a file (can be gzipped if they want)
+ *
+ * @requires
+ * no output may have preceded (new headers are sent)
+ * @param gzip
+ * 1 = compress backup file, 0 = no compression (default)
+ */
+function do_backup($gzip = 0) {
+ global $manager;
+
+ // tables of which backup is needed
+ $tables = array(
+ sql_table('actionlog'),
+ sql_table('ban'),
+ sql_table('blog'),
+ sql_table('comment'),
+ sql_table('config'),
+ sql_table('item'),
+ sql_table('karma'),
+ sql_table('member'),
+ sql_table('skin'),
+ sql_table('skin_desc'),
+ sql_table('team'),
+ sql_table('template'),
+ sql_table('template_desc'),
+ sql_table('plugin'),
+ sql_table('plugin_event'),
+ sql_table('plugin_option'),
+ sql_table('plugin_option_desc'),
+ sql_table('category'),
+ sql_table('activation'),
+ sql_table('tickets'),
+ );
+
+ // add tables that plugins want to backup to the list
+ // catch all output generated by plugins
+ ob_start();
+ $res = sql_query('SELECT pfile FROM '.sql_table('plugin'));
+ while ($plugName = mysql_fetch_object($res)) {
+ $plug =& $manager->getPlugin($plugName->pfile);
+ if ($plug) $tables = array_merge($tables, (array) $plug->getTableList());
+ }
+ ob_end_clean();
+
+ // remove duplicates
+ $tables = array_unique($tables);
+
+ // make sure browsers don't cache the backup
+ header("Pragma: no-cache");
+
+ // don't allow gzip compression when extension is not loaded
+ if (($gzip != 0) && !extension_loaded("zlib"))
+ $gzip = 0;
+
+
+
+ if ($gzip) {
+ // use an output buffer
+ @ob_start();
+ @ob_implicit_flush(0);
+
+ // set filename
+ $filename = 'nucleus_db_backup_'.strftime("%Y%m%d", time()).".sql.gz";
+ } else {
+ $filename = 'nucleus_db_backup_'.strftime("%Y%m%d", time()).".sql";
+ }
+
+
+ // send headers that tell the browser a file is coming
+ header("Content-Type: text/x-delimtext; name=\"$filename\"");
+ header("Content-disposition: attachment; filename=$filename");
+
+ // dump header
+ echo "#\n";
+ echo "# This is a backup file generated by Nucleus \n";
+ echo "# http://www.nucleuscms.org/\n";
+ echo "#\n";
+ echo "# backup-date: " . gmdate("d-m-Y H:i:s", time()) . " GMT\n";
+ global $nucleus;
+ echo "# Nucleus CMS version: " . $nucleus['version'] . "\n";
+ echo "#\n";
+ echo "# WARNING: Only try to restore on servers running the exact same version of Nucleus\n";
+ echo "#\n";
+
+ // dump all tables
+ reset($tables);
+ array_walk($tables, '_backup_dump_table');
+
+ if($gzip)
+ {
+ $Size = ob_get_length();
+ $Crc = crc32(ob_get_contents());
+ $contents = gzcompress(ob_get_contents());
+ ob_end_clean();
+ echo "\x1f\x8b\x08\x00\x00\x00\x00\x00".substr($contents, 0, strlen($contents) - 4).gzip_PrintFourChars($Crc).gzip_PrintFourChars($Size);
+ }
+
+ exit;
+
+}
+
+
+/**
+ * Creates a dump for a single table
+ * ($tablename and $key are filled in by array_walk)
+ */
+function _backup_dump_table($tablename, $key) {
+
+ echo "#\n";
+ echo "# TABLE: " . $tablename . "\n";
+ echo "#\n";
+
+ // dump table structure
+ _backup_dump_structure($tablename);
+
+ // dump table contents
+ _backup_dump_contents($tablename);
+}
+
+function _backup_dump_structure($tablename) {
+
+ // add command to drop table on restore
+ echo "DROP TABLE IF EXISTS $tablename;\n";
+ echo "CREATE TABLE $tablename(\n";
+
+ //
+ // Ok lets grab the fields...
+ //
+ $result = mysql_query("SHOW FIELDS FROM $tablename");
+ $row = mysql_fetch_array($result);
+ while ($row) {
+
+ echo ' ' . $row['Field'] . ' ' . $row['Type'];
+
+ if(isset($row['Default']))
+ echo ' DEFAULT \'' . $row['Default'] . '\'';
+
+ if($row['Null'] != "YES")
+ echo ' NOT NULL';
+
+ if($row['Extra'] != "")
+ echo ' ' . $row['Extra'];
+
+ $row = mysql_fetch_array($result);
+
+ // add comma's except for last one
+ if ($row)
+ echo ",\n";
+ }
+
+ //
+ // Get any Indexed fields from the database...
+ //
+ $result = mysql_query("SHOW KEYS FROM $tablename");
+ while($row = mysql_fetch_array($result)) {
+ $kname = $row['Key_name'];
+
+ if(($kname != 'PRIMARY') && ($row['Non_unique'] == 0))
+ $kname = "UNIQUE|$kname";
+ if(($kname != 'PRIMARY') && ($row['Index_type'] == 'FULLTEXT'))
+ $kname = "FULLTEXT|$kname";
+
+ if(!is_array($index[$kname]))
+ $index[$kname] = array();
+
+ $index[$kname][] = $row['Column_name'] . ( ($row['Sub_part']) ? ' (' . $row['Sub_part'] . ')' : '');
+ }
+
+ while(list($x, $columns) = @each($index)) {
+ echo ", \n";
+
+ if($x == 'PRIMARY')
+ echo ' PRIMARY KEY (' . implode($columns, ', ') . ')';
+ elseif (substr($x,0,6) == 'UNIQUE')
+ echo ' UNIQUE KEY ' . substr($x,7) . ' (' . implode($columns, ', ') . ')';
+ elseif (substr($x,0,8) == 'FULLTEXT')
+ echo ' FULLTEXT KEY ' . substr($x,9) . ' (' . implode($columns, ', ') . ')';
+ elseif (($x == 'ibody') || ($x == 'cbody')) // karma 2004-05-30 quick and dirty fix. fulltext keys were not in SQL correctly.
+ echo ' FULLTEXT KEY ' . substr($x,9) . ' (' . implode($columns, ', ') . ')';
+ else
+ echo " KEY $x (" . implode($columns, ', ') . ')';
+ }
+
+ echo "\n);\n\n";
+}
+
+/**
+ * Returns the field named for the given table in the
+ * following format:
+ *
+ * (column1, column2, ..., columnn)
+ */
+function _backup_get_field_names($result, $num_fields) {
+
+ if (function_exists('mysqli_fetch_fields') ) {
+
+ $fields = mysqli_fetch_fields($result);
+ for ($j = 0; $j < $num_fields; $j++)
+ $fields[$j] = $fields[$j]->name;
+
+ } else {
+
+ $fields = array();
+ for ($j = 0; $j < $num_fields; $j++) {
+ $fields[] = mysql_field_name($result, $j);
+ }
+
+ }
+
+ return '(' . implode(', ', $fields) . ')';
+}
+
+function _backup_dump_contents($tablename) {
+ //
+ // Grab the data from the table.
+ //
+ $result = mysql_query("SELECT * FROM $tablename");
+
+ if(mysql_num_rows($result) > 0)
+ echo "\n#\n# Table Data for $tablename\n#\n";
+
+ $num_fields = mysql_num_fields($result);
+
+ //
+ // Compose fieldname list
+ //
+ $tablename_list = _backup_get_field_names($result, $num_fields);
+
+ //
+ // Loop through the resulting rows and build the sql statement.
+ //
+ while ($row = mysql_fetch_array($result))
+ {
+ // Start building the SQL statement.
+
+ echo "INSERT INTO $tablename $tablename_list VALUES(";
+
+ // Loop through the rows and fill in data for each column
+ for ($j = 0; $j < $num_fields; $j++) {
+ if(!isset($row[$j])) {
+ // no data for column
+ echo ' NULL';
+ } elseif ($row[$j] != '') {
+ // data
+ echo " '" . addslashes($row[$j]) . "'";
+ } else {
+ // empty column (!= no data!)
+ echo "''";
+ }
+
+ // only add comma when not last column
+ if ($j != ($num_fields - 1))
+ echo ",";
+ }
+
+ echo ");\n";
+
+ }
+
+
+ echo "\n";
+
+}
+
+// copied from phpBB
+function gzip_PrintFourChars($Val)
+{
+ for ($i = 0; $i < 4; $i ++)
+ {
+ $return .= chr($Val % 256);
+ $Val = floor($Val / 256);
+ }
+ return $return;
+}
+
+function do_restore() {
+
+ $uploadInfo = postFileInfo('backup_file');
+
+ // first of all: get uploaded file:
+ if (empty($uploadInfo['name']))
+ return 'No file uploaded';
+ if (!is_uploaded_file($uploadInfo['tmp_name']))
+ return 'No file uploaded';
+
+ $backup_file_name = $uploadInfo['name'];
+ $backup_file_tmpname = $uploadInfo['tmp_name'];
+ $backup_file_type = $uploadInfo['type'];
+
+ if (!file_exists($backup_file_tmpname))
+ return 'File Upload Error';
+
+ if (!preg_match("/^(text\/[a-zA-Z]+)|(application\/(x\-)?gzip(\-compressed)?)|(application\/octet-stream)$/is", $backup_file_type) )
+ return 'The uploaded file is not of the correct type';
+
+
+
+ if (preg_match("/\.gz/is",$backup_file_name))
+ $gzip = 1;
+ else
+ $gzip = 0;
+
+ if (!extension_loaded("zlib") && $gzip)
+ return "Cannot decompress gzipped backup (zlib package not installed)";
+
+ // get sql query according to gzip setting (either decompress, or not)
+ if($gzip)
+ {
+ // decompress and read
+ $gz_ptr = gzopen($backup_file_tmpname, 'rb');
+ $sql_query = "";
+ while( !gzeof($gz_ptr) )
+ $sql_query .= gzgets($gz_ptr, 100000);
+ } else {
+ // just read
+ $fsize = filesize($backup_file_tmpname);
+ if ($fsize <= 0)
+ $sql_query = '';
+ else
+ $sql_query = fread(fopen($backup_file_tmpname, 'r'), $fsize);
+ }
+
+ // time to execute the query
+ _execute_queries($sql_query);
+}
+
+function _execute_queries($sql_query) {
+ if (!$sql_query) return;
+
+ // Strip out sql comments...
+ $sql_query = remove_remarks($sql_query);
+ $pieces = split_sql_file($sql_query);
+
+ $sql_count = count($pieces);
+ for($i = 0; $i < $sql_count; $i++)
+ {
+ $sql = trim($pieces[$i]);
+
+ if(!empty($sql) and $sql[0] != "#")
+ {
+ // DEBUG
+// debug("Executing: " . htmlspecialchars($sql) . "\n");
+
+ $result = mysql_query($sql);
+ if (!$result) debug('SQL Error: ' . mysql_error());
+
+ }
+ }
+
+}
+
+//
+// remove_remarks will strip the sql comment lines out of an uploaded sql file
+//
+function remove_remarks($sql)
+{
+ $lines = explode("\n", $sql);
+
+ // try to keep mem. use down
+ $sql = "";
+
+ $linecount = count($lines);
+ $output = "";
+
+ for ($i = 0; $i < $linecount; $i++)
+ {
+ if (($i != ($linecount - 1)) || (strlen($lines[$i]) > 0))
+ {
+ if ($lines[$i][0] != "#")
+ {
+ $output .= $lines[$i] . "\n";
+ }
+ else
+ {
+ $output .= "\n";
+ }
+ // Trading a bit of speed for lower mem. use here.
+ $lines[$i] = "";
+ }
+ }
+
+ return $output;
+
+}
+
+
+//
+// split_sql_file will split an uploaded sql file into single sql statements.
+// Note: expects trim() to have already been run on $sql.
+//
+// taken from phpBB
+//
+function split_sql_file($sql)
+{
+ // Split up our string into "possible" SQL statements.
+ $tokens = explode( ";", $sql);
+
+ // try to save mem.
+ $sql = "";
+ $output = array();
+
+ // we don't actually care about the matches preg gives us.
+ $matches = array();
+
+ // this is faster than calling count($tokens) every time thru the loop.
+ $token_count = count($tokens);
+ for ($i = 0; $i < $token_count; $i++)
+ {
+ // Don't wanna add an empty string as the last thing in the array.
+ if (($i != ($token_count - 1)) || (strlen($tokens[$i] > 0)))
+ {
+
+ // even number of quotes means a complete SQL statement
+ if (_evenNumberOfQuotes($tokens[$i]))
+ {
+ $output[] = $tokens[$i];
+ $tokens[$i] = ""; // save memory.
+ }
+ else
+ {
+ // incomplete sql statement. keep adding tokens until we have a complete one.
+ // $temp will hold what we have so far.
+ $temp = $tokens[$i] . ";";
+ $tokens[$i] = ""; // save memory..
+
+ // Do we have a complete statement yet?
+ $complete_stmt = false;
+
+ for ($j = $i + 1; (!$complete_stmt && ($j < $token_count)); $j++)
+ {
+ // odd number of quotes means a completed statement
+ // (in combination with the odd number we had already)
+ if (!_evenNumberOfQuotes($tokens[$j]))
+ {
+ $output[] = $temp . $tokens[$j];
+
+ // save memory.
+ $tokens[$j] = "";
+ $temp = "";
+
+ // exit the loop.
+ $complete_stmt = true;
+ // make sure the outer loop continues at the right point.
+ $i = $j;
+ }
+ else
+ {
+ // even number of unescaped quotes. We still don't have a complete statement.
+ // (1 odd and 1 even always make an odd)
+ $temp .= $tokens[$j] . ";";
+ // save memory.
+ $tokens[$j] = "";
+ }
+
+ } // for..
+ } // else
+ }
+ }
+
+ return $output;
+}
+
+
+function _evenNumberOfQuotes($text) {
+ // This is the total number of single quotes in the token.
+ $total_quotes = preg_match_all("/'/", $text, $matches);
+ // Counts single quotes that are preceded by an odd number of backslashes,
+ // which means they're escaped quotes.
+ $escaped_quotes = preg_match_all("/(?<!\\\\)(\\\\\\\\)*\\\\'/", $text, $matches);
+
+ $unescaped_quotes = $total_quotes - $escaped_quotes;
+// debug($total_quotes . "-" . $escaped_quotes . "-" . $unescaped_quotes);
+ return (($unescaped_quotes % 2) == 0);
+}
+
+?>