/** * Add a folder to the TAR archive * * @param array The TAR file handle * @param ?resource The logfile to write to (NULL: no logging) * @param PATH The full path to the folder to add * @param ?integer The maximum file size to add (NULL: no limit) * @param PATH The subpath relative to the path (should be left as the default '', as this is used for the recursion to distinguish the adding base path from where it's currently looking) * @param ?array A map (filename=>1) of files to not back up (NULL: none) * @param ?array A list of directories ONLY to back up from the root (NULL: no restriction) * @param boolean Whether to output spaces as we go to keep the connection alive * @param boolean Whether to not skip "special files" (ones not normally archive) */ function tar_add_folder(&$resource, $logfile, $path, $max_size = NULL, $subpath = '', $avoid_backing_up = NULL, $root_only_dirs = NULL, $tick = false, $all_files = false) { require_code('files'); $_full = $path == '' ? $subpath : $path . '/' . $subpath; if ($_full == '') { $_full = '.'; } if (!is_null($logfile)) { $dh = @opendir($_full); if ($dh === false) { if (fwrite($logfile, 'Could not access ' . $_full . ' [case 2]' . "\n") == 0) { warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE')); } } } else { $dh = opendir($_full); } if ($dh !== false) { while (($entry = readdir($dh)) !== false) { if ($entry == '.' || $entry == '..') { continue; } if ($tick) { @(print ' '); } $_subpath = $subpath == '' ? $entry : $subpath . '/' . $entry; if (($all_files || !should_ignore_file($_subpath)) && $entry != 'backups') { $full = $path == '' ? $_subpath : $path . '/' . $_subpath; if (!is_readable($full)) { if (fwrite($logfile, 'Could not access ' . $full . "\n") == 0) { warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE')); } continue; } if (is_dir($full)) { if (is_null($root_only_dirs) || in_array($entry, $root_only_dirs)) { tar_add_folder($resource, $logfile, $path, $max_size, $_subpath, $avoid_backing_up, NULL, $tick, $all_files); } } else { if ($full != $resource['full'] && (is_null($max_size) || filesize($full) < $max_size * 1024 * 1024) && (is_null($avoid_backing_up) || !array_key_exists($_subpath, $avoid_backing_up))) { //echo $_subpath.'<br />'; tar_add_file($resource, $_subpath, $full, fileperms($full), filemtime($full), true); if (!is_null($logfile) && fwrite($logfile, 'Backed up file ' . $full . ' (' . clean_file_size(filesize($full)) . ')' . "\n") == 0) { warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE')); } } } } } closedir($dh); } }
/** * Backend function to do a backup (meant to be run as a shutdown function - essentially a background task). * * @param ?string The filename to backup to (NULL: get global) * @param ?string The type of backup to do (NULL: get global) * @set full incremental * @param ?integer The maximum size of a file to include in the backup (NULL: get global) */ function make_backup_2($file = NULL, $b_type = NULL, $max_size = NULL) { global $STARTED_BACKUP; if ($STARTED_BACKUP) { return; } $STARTED_BACKUP = true; if (is_null($file)) { global $MB2_FILE, $MB2_B_TYPE, $MB2_MAX_SIZE; $file = $MB2_FILE; $b_type = $MB2_B_TYPE; $max_size = $MB2_MAX_SIZE; } if (function_exists('set_time_limit')) { @set_time_limit(0); } $logfile_path = get_custom_file_base() . '/exports/backups/' . $file . '.txt'; $logfile = @fopen($logfile_path, 'wt') or intelligent_write_error($logfile_path); // .txt file because IIS doesn't allow .log download @ini_set('log_errors', '1'); @ini_set('error_log', $logfile_path); fwrite($logfile, 'This is a log file for an ocPortal backup. The backup is not complete unless this log terminates with a completion message.' . "\n\n"); require_code('tar'); $myfile = tar_open(get_custom_file_base() . '/exports/backups/' . filter_naughty($file), 'wb'); // Write readme.txt file tar_add_file($myfile, 'readme.txt', do_lang('BACKUP_README', get_timezoned_date(time())), 0664, time()); // Write restore.php file $template = get_custom_file_base() . '/data_custom/modules/admin_backup/restore.php.pre'; if (!file_exists($template)) { $template = get_file_base() . '/data/modules/admin_backup/restore.php.pre'; } $_install_php_file = file_get_contents($template); $place = strpos($_install_php_file, '{!!DB!!}'); $__install_php_file = ocp_tempnam('ocpbak'); $install_php_file = fopen($__install_php_file, 'wb'); fwrite($install_php_file, substr($_install_php_file, 0, $place)); get_table_backup($logfile, 'db_meta', 'db_meta_indices', $install_php_file); if (fwrite($install_php_file, substr($_install_php_file, $place + 8)) == 0) { warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE')); } fclose($install_php_file); tar_add_file($myfile, 'restore.php', $__install_php_file, 0664, time(), true); @unlink($__install_php_file); if ($b_type == 'full') { set_value('last_backup', strval(time())); $original_files = get_param_integer('keep_backup_alien', 0) == 1 ? unserialize(file_get_contents(get_file_base() . '/data/files.dat')) : NULL; $root_only_dirs = array_merge(find_all_zones(false, false, true), array('data', 'data_custom', 'exports', 'imports', 'lang', 'lang_custom', 'lang_cached', 'pages', 'persistant_cache', 'safe_mode_temp', 'sources', 'sources_custom', 'text', 'text_custom', 'themes', 'uploads', 'site')); tar_add_folder($myfile, $logfile, get_file_base(), $max_size, '', $original_files, $root_only_dirs, !running_script('cron_bridge'), true); } elseif ($b_type == 'incremental') { $threshold = intval(get_value('last_backup')); set_value('last_backup', strval(time())); $directory = tar_add_folder_incremental($myfile, $logfile, get_file_base(), $threshold, $max_size); $_directory = ''; foreach ($directory as $d) { $a = ''; foreach ($d as $k => $v) { if ($a != '') { $a .= ", "; } $a .= $k . '=' . $v; } $_directory .= $a . "\n"; } tar_add_file($myfile, 'DIRECTORY', $_directory, 0664, time()); } else { set_value('last_backup', strval(time())); } tar_close($myfile); if (!file_exists(get_custom_file_base() . '/exports/backups/' . filter_naughty($file))) { warn_exit(do_lang_tempcode('INTERNAL_ERROR')); } rename(get_custom_file_base() . '/exports/backups/' . filter_naughty($file), get_custom_file_base() . '/exports/backups/' . filter_naughty($file) . '.tar'); sync_file('exports/backups/' . filter_naughty($file) . '.tar'); fix_permissions('exports/backups/' . filter_naughty($file) . '.tar'); $url = get_base_url() . '/exports/backups/' . $file . '.tar'; if (function_exists('gzopen')) { if (fwrite($logfile, "\n" . do_lang('COMPRESSING') . "\n") == 0) { warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE')); } $myfile = gzopen(get_custom_file_base() . '/exports/backups/' . $file . '.tar.gz.tmp', 'wb') or intelligent_write_error(get_custom_file_base() . '/exports/backups/' . $file . '.tar.gz.tmp'); $tar_path = get_custom_file_base() . '/exports/backups/' . filter_naughty($file) . '.tar'; $fp_in = fopen($tar_path, 'rb'); while (!feof($fp_in)) { $read = fread($fp_in, 8192); gzwrite($myfile, $read, strlen($read)); } fclose($fp_in); gzclose($myfile); rename(get_custom_file_base() . '/exports/backups/' . $file . '.tar.gz.tmp', get_custom_file_base() . '/exports/backups/' . $file . '.tar.gz'); fix_permissions(get_custom_file_base() . '/exports/backups/' . $file . '.tar.gz'); sync_file('exports/backups/' . filter_naughty($file) . '.tar.gz'); $url = get_base_url() . '/exports/backups/' . $file . '.tar.gz'; } if (fwrite($logfile, "\n" . do_lang('SUCCESS') . "\n") == 0) { warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE')); } fclose($logfile); sync_file($logfile_path); fix_permissions($logfile_path); sync_file($logfile_path); // Remote backup $copy_server = get_option('backup_server_hostname'); if ($copy_server != '') { $path_stub = get_custom_file_base() . '/exports/backups/'; if (file_exists($path_stub . $file . '.tar.gz')) { $_file = $file . '.tar.gz'; } elseif (file_exists($path_stub . $file . '.tar')) { $_file = $file . '.tar'; } else { $file = NULL; } if (!is_null($file)) { $copy_port = get_option('backup_server_port'); if ($copy_port == '') { $copy_port = '21'; } $copy_user = get_option('backup_server_user'); if ($copy_user == '') { $copy_user = '******'; } $copy_password = get_option('backup_server_password'); if (is_null($copy_password)) { $copy_password = get_option('staff_address'); } $copy_path = get_option('backup_server_path'); if ($copy_path == '') { $copy_path = $_file; } elseif (substr($copy_path, -1) == '/' || $copy_path == '') { $copy_path .= $_file; } $ftp_connection = @ftp_connect($copy_server, intval($copy_port)); if ($ftp_connection !== false) { if (@ftp_login($ftp_connection, $copy_user, $copy_password)) { @ftp_delete($ftp_connection, $path_stub . $_file); @ftp_put($ftp_connection, $copy_path, $path_stub, FTP_BINARY); } @ftp_close($ftp_connection); } } } require_code('notifications'); dispatch_notification('backup_finished', NULL, do_lang('BACKUP', NULL, NULL, NULL, get_site_default_lang()), do_lang('BACKUP_FINISHED', comcode_escape($url), get_site_default_lang()), NULL, A_FROM_SYSTEM_PRIVILEGED); }