DumpDatabase.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <?php
  2. /**
  3. * This file has a single job - database backup.
  4. *
  5. * Simple Machines Forum (SMF)
  6. *
  7. * @package SMF
  8. * @author Simple Machines http://www.simplemachines.org
  9. * @copyright 2011 Simple Machines
  10. * @license http://www.simplemachines.org/about/smf/license.php BSD
  11. *
  12. * @version 2.0
  13. */
  14. if (!defined('SMF'))
  15. die('Hacking attempt...');
  16. /**
  17. * Dumps the database.
  18. * It writes all of the database to standard output.
  19. * It uses gzip compression if compress is set in the URL/post data.
  20. * It may possibly time out, and mess up badly if you were relying on it. :P
  21. * The data dumped depends on whether "struct" and "data" are passed.
  22. * It requires an administrator and the session hash by post.
  23. * It is called from ManageMaintenance.php.
  24. */
  25. function DumpDatabase2()
  26. {
  27. global $db_name, $scripturl, $context, $modSettings, $crlf, $smcFunc, $db_prefix;
  28. // Administrators only!
  29. if (!allowedTo('admin_forum'))
  30. fatal_lang_error('no_dump_database', 'critical');
  31. // You can't dump nothing!
  32. if (!isset($_REQUEST['struct']) && !isset($_REQUEST['data']))
  33. $_REQUEST['data'] = true;
  34. checkSession('post');
  35. // We will need this, badly!
  36. db_extend();
  37. // Attempt to stop from dying...
  38. @set_time_limit(600);
  39. if (@ini_get('memory_limit') < 256)
  40. @ini_set('memory_limit', '256M');
  41. // Start saving the output... (don't do it otherwise for memory reasons.)
  42. if (isset($_REQUEST['compress']) && function_exists('gzencode'))
  43. {
  44. // Make sure we're gzipping output, but then say we're not in the header ^_^.
  45. if (empty($modSettings['enableCompressedOutput']))
  46. @ob_start('ob_gzhandler');
  47. // Try to clean any data already outputted.
  48. elseif (ob_get_length() != 0)
  49. {
  50. ob_end_clean();
  51. @ob_start('ob_gzhandler');
  52. }
  53. // Send faked headers so it will just save the compressed output as a gzip.
  54. header('Content-Type: application/x-gzip');
  55. header('Accept-Ranges: bytes');
  56. header('Content-Encoding: none');
  57. // Gecko browsers... don't like this. (Mozilla, Firefox, etc.)
  58. if (!$context['browser']['is_gecko'])
  59. header('Content-Transfer-Encoding: binary');
  60. // The file extension will include .gz...
  61. $extension = '.sql.gz';
  62. }
  63. else
  64. {
  65. // Get rid of the gzipping alreading being done.
  66. if (!empty($modSettings['enableCompressedOutput']))
  67. @ob_end_clean();
  68. // If we can, clean anything already sent from the output buffer...
  69. elseif (function_exists('ob_clean') && ob_get_length() != 0)
  70. ob_clean();
  71. // Tell the client to save this file, even though it's text.
  72. header('Content-Type: ' . ($context['browser']['is_ie'] || $context['browser']['is_opera'] ? 'application/octetstream' : 'application/octet-stream'));
  73. header('Content-Encoding: none');
  74. // This time the extension should just be .sql.
  75. $extension = '.sql';
  76. }
  77. // This should turn off the session URL parser.
  78. $scripturl = '';
  79. // If this database is flat file and has a handler function pass it to that.
  80. if (!empty($smcFunc['db_get_backup']))
  81. {
  82. $smcFunc['db_get_backup']();
  83. exit;
  84. }
  85. // Send the proper headers to let them download this file.
  86. header('Content-Disposition: filename="' . $db_name . '-' . (empty($_REQUEST['struct']) ? 'data' : (empty($_REQUEST['data']) ? 'structure' : 'complete')) . '_' . strftime('%Y-%m-%d') . $extension . '"');
  87. header('Cache-Control: private');
  88. header('Connection: close');
  89. // This makes things simpler when using it so very very often.
  90. $crlf = "\r\n";
  91. // SQL Dump Header.
  92. echo
  93. '-- ==========================================================', $crlf,
  94. '--', $crlf,
  95. '-- Database dump of tables in `', $db_name, '`', $crlf,
  96. '-- ', timeformat(time(), false), $crlf,
  97. '--', $crlf,
  98. '-- ==========================================================', $crlf,
  99. $crlf;
  100. // Get all tables in the database....
  101. if (preg_match('~^`(.+?)`\.(.+?)$~', $db_prefix, $match) != 0)
  102. {
  103. $db = strtr($match[1], array('`' => ''));
  104. $dbp = str_replace('_', '\_', $match[2]);
  105. }
  106. else
  107. {
  108. $db = false;
  109. $dbp = $db_prefix;
  110. }
  111. // Dump each table.
  112. $tables = $smcFunc['db_list_tables'](false, $db_prefix . '%');
  113. foreach ($tables as $tableName)
  114. {
  115. if (function_exists('apache_reset_timeout'))
  116. @apache_reset_timeout();
  117. // Are we dumping the structures?
  118. if (isset($_REQUEST['struct']))
  119. {
  120. echo
  121. $crlf,
  122. '--', $crlf,
  123. '-- Table structure for table `', $tableName, '`', $crlf,
  124. '--', $crlf,
  125. $crlf,
  126. $smcFunc['db_table_sql']($tableName), ';', $crlf;
  127. }
  128. // How about the data?
  129. if (!isset($_REQUEST['data']) || substr($tableName, -10) == 'log_errors')
  130. continue;
  131. // Are there any rows in this table?
  132. $get_rows = $smcFunc['db_insert_sql']($tableName);
  133. // No rows to get - skip it.
  134. if (empty($get_rows))
  135. continue;
  136. echo
  137. $crlf,
  138. '--', $crlf,
  139. '-- Dumping data in `', $tableName, '`', $crlf,
  140. '--', $crlf,
  141. $crlf,
  142. $get_rows,
  143. '-- --------------------------------------------------------', $crlf;
  144. }
  145. echo
  146. $crlf,
  147. '-- Done', $crlf;
  148. exit;
  149. }
  150. ?>