Пример #1
0
/**
 *	parse_options()
 *
 *	Parses various submitted options and settings from step 1.
 *
 *	@return		null
 */
function parse_options()
{
    // Set advanced debug options if user set any.
    if (isset($_POST['skip_files']) && $_POST['skip_files'] == 'on') {
        pb_backupbuddy::$options['skip_files'] = true;
    } else {
        pb_backupbuddy::$options['skip_files'] = false;
    }
    if (isset($_POST['skip_htaccess']) && $_POST['skip_htaccess'] == 'on') {
        pb_backupbuddy::$options['skip_htaccess'] = true;
    } else {
        pb_backupbuddy::$options['skip_htaccess'] = false;
    }
    if (isset($_POST['force_compatibility_medium']) && $_POST['force_compatibility_medium'] == 'on') {
        pb_backupbuddy::$options['force_compatibility_medium'] = true;
    } else {
        pb_backupbuddy::$options['force_compatibility_medium'] = false;
    }
    if (isset($_POST['force_compatibility_slow']) && $_POST['force_compatibility_slow'] == 'on') {
        pb_backupbuddy::$options['force_compatibility_slow'] = true;
    } else {
        pb_backupbuddy::$options['force_compatibility_slow'] = false;
    }
    if (isset($_POST['force_high_security']) && $_POST['force_high_security'] == 'on') {
        pb_backupbuddy::$options['force_high_security'] = true;
    } else {
        pb_backupbuddy::$options['force_high_security'] = false;
    }
    if (isset($_POST['show_php_warnings']) && $_POST['show_php_warnings'] == 'on') {
        pb_backupbuddy::$options['show_php_warnings'] = true;
    } else {
        pb_backupbuddy::$options['show_php_warnings'] = false;
    }
    if (isset($_POST['file']) && $_POST['file'] != '') {
        pb_backupbuddy::$options['file'] = $_POST['file'];
    } else {
        pb_backupbuddy::$options['file'] = '';
    }
    if (isset($_POST['log_level']) && $_POST['log_level'] != '') {
        pb_backupbuddy::$options['log_level'] = $_POST['log_level'];
    } else {
        pb_backupbuddy::$options['log_level'] = '';
    }
    // Set ZIP id (aka serial).
    if (!isset(pb_backupbuddy::$options['file'])) {
        die('No backup zip file specified to process. Go back and make sure you selected a ZIP file to extract and restore on Step 1.');
    }
    pb_backupbuddy::$options['zip_id'] = backupbuddy_core::get_serial_from_file(pb_backupbuddy::$options['file']);
}
 private static function _verb_renderImportBuddy()
 {
     $backupFile = pb_backupbuddy::_POST('backupFile');
     $password = md5(md5(pb_backupbuddy::_POST('backupbuddy_api_key')));
     // Store this serial in settings to cleanup any temp db tables in the future with this serial with periodic cleanup.
     $backupSerial = backupbuddy_core::get_serial_from_file($backupFile);
     pb_backupbuddy::$options['rollback_cleanups'][$backupSerial] = time();
     pb_backupbuddy::save();
     $importFileSerial = backupbuddy_core::deploymentImportBuddy($password, backupbuddy_core::getBackupDirectory() . $backupFile);
     if (is_array($importFileSerial)) {
         die(json_encode(array('success' => false, 'error' => $importFileSerial[1])));
     } else {
         die(json_encode(array('success' => true, 'importFileSerial' => $importFileSerial)));
     }
 }
Пример #3
0
    function restore_file_view()
    {
        pb_backupbuddy::$ui->ajax_header(true, false);
        // js, no padding
        $archive_file = pb_backupbuddy::_GET('archive');
        // archive to extract from.
        $file = pb_backupbuddy::_GET('file');
        // file to extract.
        $serial = backupbuddy_core::get_serial_from_file($archive_file);
        // serial of archive.
        $temp_file = uniqid();
        // temp filename to extract into.
        require_once pb_backupbuddy::plugin_path() . '/lib/zipbuddy/zipbuddy.php';
        $zipbuddy = new pluginbuddy_zipbuddy(backupbuddy_core::getBackupDirectory());
        // Calculate temp directory & lock it down.
        $temp_dir = get_temp_dir();
        $destination = $temp_dir . 'backupbuddy-' . $serial;
        if (!file_exists($destination) && false === mkdir($destination)) {
            $error = 'Error #458485945: Unable to create temporary location.';
            pb_backupbuddy::status('error', $error);
            die($error);
        }
        // If temp directory is within webroot then lock it down.
        $temp_dir = str_replace('\\', '/', $temp_dir);
        // Normalize for Windows.
        $temp_dir = rtrim($temp_dir, '/\\') . '/';
        // Enforce single trailing slash.
        if (FALSE !== stristr($temp_dir, ABSPATH)) {
            // Temp dir is within webroot.
            pb_backupbuddy::anti_directory_browsing($destination);
        }
        unset($temp_dir);
        $message = 'Extracting "' . $file . '" from archive "' . $archive_file . '" into temporary file "' . $destination . '". ';
        echo '<!-- ';
        pb_backupbuddy::status('details', $message);
        echo $message;
        $extractions = array($file => $temp_file);
        $extract_result = $zipbuddy->extract(backupbuddy_core::getBackupDirectory() . $archive_file, $destination, $extractions);
        if (false === $extract_result) {
            // failed.
            echo ' -->';
            $error = 'Error #584984458. Unable to extract.';
            pb_backupbuddy::status('error', $error);
            die($error);
        } else {
            // success.
            _e('Success.', 'it-l10n-backupbuddy');
            echo ' -->';
            ?>
			<textarea readonly="readonly" wrap="off" style="width: 100%; min-height: 175px; height: 100%; margin: 0;"><?php 
            echo file_get_contents($destination . '/' . $temp_file);
            ?>
</textarea>
			<?php 
            //unlink( $destination . '/' . $temp_file );
        }
        // Try to cleanup.
        if (file_exists($destination)) {
            if (false === pb_backupbuddy::$filesystem->unlink_recursive($destination)) {
                pb_backupbuddy::status('details', 'Unable to delete temporary holding directory `' . $destination . '`.');
            } else {
                pb_backupbuddy::status('details', 'Cleaned up temporary files.');
            }
        }
        pb_backupbuddy::$ui->ajax_footer();
        die;
    }
Пример #4
0
    ?>
 );
		}, 2000);
	</script>
	<?php 
}
// Load footer.
pb_backupbuddy::load_view('_iframe_footer');
// Deployment proceed.
if ('true' == pb_backupbuddy::_GET('deploy')) {
    $nextStepNum = 4;
    echo '<!-- AUTOPROCEED TO STEP ' . $nextStepNum . ' -->';
    //echo '<script>console.log( "' . print_r( $restore->_state, true ) . '" );</script>';
    // Write default state overrides.
    global $importbuddy_file;
    $importFileSerial = backupbuddy_core::get_serial_from_file($importbuddy_file);
    $state_file = ABSPATH . 'importbuddy-' . $importFileSerial . '-state.php';
    pb_backupbuddy::status('details', 'Writing to state file `' . $state_file . '`.');
    if (false === ($file_handle = @fopen($state_file, 'w'))) {
        pb_backupbuddy::status('error', 'Error #328937: Temp state file is not creatable/writable. Check your permissions. (' . $state_file . ')');
        return false;
    }
    if (false === fwrite($file_handle, "<?php die('Access Denied.'); // <!-- ?>\n" . base64_encode(serialize($restore->_state)))) {
        pb_backupbuddy::status('error', 'Error #2389373: Unable to write to state file.');
    } else {
        pb_backupbuddy::status('details', 'Wrote to state file.');
    }
    fclose($file_handle);
    ?>
	<form method="post" action="?ajax=<?php 
    echo $nextStepNum;
Пример #5
0
 $parent_class_test['status'] = __('OK', 'it-l10n-backupbuddy');
 array_push($tests, $parent_class_test);
 // Database size WITH EXCLUSIONS accounted for.
 $parent_class_test = array('title' => 'Database Size (Default Exclusions applied)', 'suggestion' => 'n/a', 'value' => '<span id="pb_stats_refresh_database_size_excluded">' . pb_backupbuddy::$format->file_size(pb_backupbuddy::$options['stats']['db_size_excluded']) . '</span> <a class="pb_backupbuddy_refresh_stats" rel="refresh_database_size_excluded" alt="' . pb_backupbuddy::ajax_url('refresh_database_size_excluded') . '" title="' . __('Refresh', 'it-l10n-backupbuddy') . '"><img src="' . pb_backupbuddy::plugin_url() . '/images/refresh_gray.gif" style="vertical-align: -1px;"> <span class="pb_backupbuddy_loading" style="display: none; margin-left: 10px;"><img src="' . pb_backupbuddy::plugin_url() . '/images/loading.gif" alt="' . __('Loading...', 'it-l10n-backupbuddy') . '" title="' . __('Loading...', 'it-l10n-backupbuddy') . '" width="16" height="16" style="vertical-align: -3px;" /></span></a>', 'tip' => __('Total size of your database EXCLUDING any tables you have marked for exclusion.', 'it-l10n-backupbuddy'));
 $parent_class_test['status'] = __('OK', 'it-l10n-backupbuddy');
 array_push($tests, $parent_class_test);
 /***** BEGIN AVERAGE WRITE SPEED *****/
 require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
 $write_speed_samples = 0;
 $write_speed_sum = 0;
 $backups = glob(backupbuddy_core::getBackupDirectory() . '*.zip');
 if (!is_array($backups)) {
     $backups = array();
 }
 foreach ($backups as $backup) {
     $serial = backupbuddy_core::get_serial_from_file($backup);
     pb_backupbuddy::status('details', 'Fileoptions instance #22.');
     $backup_options = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt', $read_only = true);
     if (true !== ($result = $backup_options->is_ok())) {
         pb_backupbuddy::status('warning', 'Unable to open fileoptions file `' . backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt' . '`. Details: `' . $result . '`.');
     }
     if (isset($backup_options->options['integrity']) && isset($backup_options->options['integrity']['size'])) {
         $write_speed_samples++;
         $size = $backup_options->options['integrity']['size'];
         $time_taken = 0;
         if (isset($backup_options->options['steps'])) {
             foreach ($backup_options->options['steps'] as $step) {
                 if ($step['function'] == 'backup_zip_files') {
                     $time_taken = $step['finish_time'] - $step['start_time'];
                     break;
                 }
Пример #6
0
 public static function send($destination_settings, $file, $send_id = '', $delete_after = false)
 {
     if (is_array($file)) {
         // As of v6.1.0.1 no longer accepting multiple files to send.
         $file = $file[0];
     }
     if ('' != $send_id) {
         pb_backupbuddy::add_status_serial('remote_send-' . $send_id);
         pb_backupbuddy::status('details', '----- Initiating master send function for BackupBuddy v' . pb_backupbuddy::settings('version') . '. Post-send deletion: ' . $delete_after);
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         $fileoptions_file = backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt';
         if (!file_exists($fileoptions_file)) {
             //pb_backupbuddy::status( 'details', 'Fileoptions file `' . $fileoptions_file . '` does not exist yet; creating.' );
             //pb_backupbuddy::status( 'details', 'Fileoptions instance #19.' );
             $fileoptions_obj = new pb_backupbuddy_fileoptions($fileoptions_file, $read_only = false, $ignore_lock = true, $create_file = true);
         } else {
             //pb_backupbuddy::status( 'details', 'Fileoptions file exists; loading.' );
             //pb_backupbuddy::status( 'details', 'Fileoptions instance #18.' );
             $fileoptions_obj = new pb_backupbuddy_fileoptions($fileoptions_file, $read_only = false, $ignore_lock = false, $create_file = false);
         }
         if (true !== ($result = $fileoptions_obj->is_ok())) {
             pb_backupbuddy::status('error', __('Fatal Error #9034.2344848. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
             return false;
         }
         //pb_backupbuddy::status( 'details', 'Fileoptions data loaded.' );
         $fileoptions =& $fileoptions_obj->options;
         if ('' == $fileoptions) {
             // Set defaults.
             $fileoptions = backupbuddy_core::get_remote_send_defaults();
             $fileoptions['type'] = $destination_settings['type'];
             $fileoptions['file'] = $file;
             $fileoptions['retries'] = 0;
         }
         $fileoptions['sendID'] = $send_id;
         $fileoptions['destinationSettings'] = $destination_settings;
         // always store the LATEST settings for resume info and retry function.
         $fileoptions['update_time'] = time();
         $fileoptions['deleteAfter'] = $delete_after;
         $fileoptions_obj->save();
         if (isset($fileoptions['status']) && 'aborted' == $fileoptions['status']) {
             pb_backupbuddy::status('warning', 'Destination send triggered on an ABORTED transfer. Ending send function.');
             return false;
         }
         unset($fileoptions_obj);
     }
     if (false === ($destination = self::_init_destination($destination_settings))) {
         echo '{Error #546893498a. Destination configuration file missing.}';
         if ('' != $send_id) {
             pb_backupbuddy::remove_status_serial('remote_send-' . $send_id);
         }
         return false;
     }
     $destination_settings = $destination['settings'];
     // Settings with defaults applied, normalized, etc.
     if (!file_exists($file)) {
         pb_backupbuddy::status('error', 'Error #58459458743. The file that was attempted to be sent to a remote destination, `' . $file . '`, was not found. It either does not exist or permissions prevent accessing it. Check that local backup limits are not causing it to be deleted.');
         if ('' != $send_id) {
             pb_backupbuddy::remove_status_serial('remote_send-' . $send_id);
         }
         return false;
     }
     if (!method_exists($destination['class'], 'send')) {
         pb_backupbuddy::status('error', 'Destination class `' . $destination['class'] . '` does not support send operation -- missing function.');
         if ('' != $send_id) {
             pb_backupbuddy::remove_status_serial('remote_send-' . $send_id);
         }
         return false;
     }
     global $pb_backupbuddy_destination_errors;
     $pb_backupbuddy_destination_errors = array();
     $result = call_user_func_array("{$destination['class']}::send", array($destination_settings, $file, $send_id, $delete_after));
     /* $result values:
      *		false		Transfer FAILED.
      *		true		Non-chunked transfer succeeded.
      *		array()		array(
      *						multipart_id,				// Unique string ID for multipart send. Empty string if last chunk finished sending successfully.
      *						multipart_status_message
      *					)
      */
     if ($result === false) {
         $error_details = implode('; ', $pb_backupbuddy_destination_errors);
         if ('' != $error_details) {
             $error_details = ' Details: ' . $error_details;
         }
         $log_directory = backupbuddy_core::getLogDirectory();
         $preError = 'There was an error sending to the remote destination titled `' . $destination_settings['title'] . '` of type `' . backupbuddy_core::pretty_destination_type($destination_settings['type']) . '`. One or more files may have not been fully transferred. Please see error details for additional information. If the error persists, enable full error logging and try again for full details and troubleshooting. Details: ' . "\n\n";
         $logFile = $log_directory . 'status-remote_send-' . $send_id . '_' . pb_backupbuddy::$options['log_serial'] . '.txt';
         pb_backupbuddy::status('details', 'Looking for remote send log file to send in error email: `' . $logFile . '`.');
         if (!file_exists($logFile)) {
             pb_backupbuddy::status('details', 'Remote send log file not found.');
             backupbuddy_core::mail_error($preError . $error_details);
         } else {
             // Log exists. Attach.
             pb_backupbuddy::status('details', 'Remote send log file found. Attaching to error email.');
             backupbuddy_core::mail_error($preError . $error_details . "\n\nSee the attached log for details.", '', array($logFile));
         }
         // Save error details into fileoptions for this send.
         //pb_backupbuddy::status( 'details', 'About to load fileoptions data.' );
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         pb_backupbuddy::status('details', 'Fileoptions instance #45.');
         $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
         if (true !== ($fileoptions_result = $fileoptions_obj->is_ok())) {
             pb_backupbuddy::status('error', __('Error #9034.32731. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $fileoptions_result);
         }
         //pb_backupbuddy::status( 'details', 'Fileoptions data loaded.' );
         $fileoptions =& $fileoptions_obj->options;
         $fileoptions['status'] = 'failed';
         $fileoptions['error'] = 'Error sending.' . $error_details;
         $fileoptions['updated_time'] = time();
         $fileoptions_obj->save();
         unset($fileoptions_obj);
     }
     if (is_array($result)) {
         // Send is multipart.
         pb_backupbuddy::status('details', 'Multipart chunk mode completed a pass of the send function. Resuming will be needed. Result: `' . print_r($result, true) . '`.');
         if ('' != $send_id) {
             //pb_backupbuddy::status( 'details', 'About to load fileoptions data.' );
             require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
             //pb_backupbuddy::status( 'details', 'Fileoptions instance #17.' );
             $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
             if (true !== ($fileoptions_result = $fileoptions_obj->is_ok())) {
                 pb_backupbuddy::status('error', __('Fatal Error #9034.387462. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $fileoptions_result);
                 return false;
             }
             //pb_backupbuddy::status( 'details', 'Fileoptions data loaded.' );
             $fileoptions =& $fileoptions_obj->options;
             $fileoptions['_multipart_status'] = $result[1];
             $fileoptions['updated_time'] = time();
             pb_backupbuddy::status('details', 'Destination debugging details: `' . print_r($fileoptions, true) . '`.');
             $fileoptions_obj->save();
             unset($fileoptions_obj);
             pb_backupbuddy::status('details', 'Next multipart chunk will be processed shortly. Now waiting on its cron...');
         }
     } else {
         // Single all-at-once send.
         if (false === $result) {
             pb_backupbuddy::status('details', 'Completed send function. Failure. Post-send deletion will be skipped if enabled.');
         } elseif (true === $result) {
             pb_backupbuddy::status('details', 'Completed send function. Success.');
         } else {
             pb_backupbuddy::status('warning', 'Completed send function. Unknown result: `' . $result . '`.');
         }
         pb_backupbuddy::status('details', 'About to load fileoptions data.');
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         pb_backupbuddy::status('details', 'Fileoptions instance #16.');
         $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
         if (true !== ($fileoptions_result = $fileoptions_obj->is_ok())) {
             pb_backupbuddy::status('error', __('Error #9034.387462. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $fileoptions_result);
         }
         pb_backupbuddy::status('details', 'Fileoptions data loaded.');
         $fileoptions =& $fileoptions_obj->options;
         $fileoptions['updated_time'] = time();
         unset($fileoptions_obj);
     }
     // File transfer completely finished successfully.
     if (true === $result) {
         $fileSize = filesize($file);
         $serial = backupbuddy_core::get_serial_from_file($file);
         // Handle deletion of send file if enabled.
         if (true === $delete_after && false !== $result) {
             pb_backupbuddy::status('details', __('Post-send deletion enabled.', 'it-l10n-backupbuddy'));
             if (false === $result) {
                 pb_backupbuddy::status('details', 'Skipping post-send deletion since transfer failed.');
             } else {
                 pb_backupbuddy::status('details', 'Performing post-send deletion since transfer succeeded.');
                 pb_backupbuddy::status('details', 'Deleting local file `' . $file . '`.');
                 // Handle post-send deletion on success.
                 if (file_exists($file)) {
                     $unlink_result = @unlink($file);
                     if (true !== $unlink_result) {
                         pb_backupbuddy::status('error', 'Unable to unlink local file `' . $file . '`.');
                     }
                 }
                 if (file_exists($file)) {
                     // File still exists.
                     pb_backupbuddy::status('details', __('Error. Unable to delete local file `' . $file . '` after send as set in settings.', 'it-l10n-backupbuddy'));
                     backupbuddy_core::mail_error('BackupBuddy was unable to delete local file `' . $file . '` after successful remove transfer though post-remote send deletion is enabled. You may want to delete it manually. This can be caused by permission problems or improper server configuration.');
                 } else {
                     // Deleted.
                     pb_backupbuddy::status('details', __('Deleted local archive after successful remote destination send based on settings.', 'it-l10n-backupbuddy'));
                     pb_backupbuddy::status('archiveDeleted', '');
                 }
             }
         } else {
             pb_backupbuddy::status('details', 'Post-send deletion not enabled.');
         }
         // Send email notification if enabled.
         if ('' != pb_backupbuddy::$options['email_notify_send_finish']) {
             pb_backupbuddy::status('details', __('Sending finished destination send email notification.', 'it-l10n-backupbuddy'));
             $extraReplacements = array();
             $extraReplacements = array('{backup_file}' => $file, '{backup_size}' => $fileSize, '{backup_serial}' => $serial);
             backupbuddy_core::mail_notify_scheduled($serial, 'destinationComplete', __('Destination send complete to', 'it-l10n-backupbuddy') . ' ' . backupbuddy_core::pretty_destination_type($destination_settings['type']), $extraReplacements);
         } else {
             pb_backupbuddy::status('details', __('Finished sending email NOT enabled. Skipping.', 'it-l10n-backupbuddy'));
         }
         // Save notification of final results.
         $data = array();
         $data['serial'] = $serial;
         $data['file'] = $file;
         $data['size'] = $fileSize;
         $data['pretty_size'] = pb_backupbuddy::$format->file_size($fileSize);
         backupbuddy_core::addNotification('remote_send_success', 'Remote file transfer completed', 'A file has successfully completed sending to a remote location.', $data);
     }
     // NOTE: Call this before removing status serial so it shows in log.
     pb_backupbuddy::status('details', 'Ending send() function pass.');
     // Return logging to normal file.
     if ('' != $send_id) {
         pb_backupbuddy::remove_status_serial('remote_send-' . $send_id);
     }
     return $result;
 }
Пример #7
0
 public function start($backupFile, $skipUnzip = false)
 {
     $this->_before(__FUNCTION__);
     if (!file_exists($backupFile)) {
         return $this->_error('Unable to access backup file `' . $backupFile . '`. Verify it still exists and has proper read permissions.');
     }
     $this->_state['archive'] = $backupFile;
     $serial = backupbuddy_core::get_serial_from_file(basename($backupFile));
     $this->_state['serial'] = $serial;
     unset($backupFile);
     unset($serial);
     if (defined('PB_STANDALONE') && true === PB_STANDALONE) {
         $mysql_9010_log = ABSPATH . 'importbuddy/mysql_9010_log-' . pb_backupbuddy::$options['log_serial'] . '.txt';
         if (file_exists($mysql_9010_log)) {
             @unlink($mysql_9010_log);
         }
     }
     if (true !== $skipUnzip) {
         // Get zip meta information.
         $customTitle = 'Backup Details';
         pb_backupbuddy::status('details', 'Attempting to retrieve zip meta data from comment.');
         if (false !== ($metaInfo = backupbuddy_core::getZipMeta($this->_state['archive']))) {
             pb_backupbuddy::status('details', 'Found zip meta data.');
         } else {
             pb_backupbuddy::status('details', 'Did not find zip meta data.');
         }
         pb_backupbuddy::status('details', 'Loading zipbuddy.');
         require_once pb_backupbuddy::plugin_path() . '/lib/zipbuddy/zipbuddy.php';
         $zipbuddy = new pluginbuddy_zipbuddy(dirname($this->_state['archive']));
         pb_backupbuddy::status('details', 'Zipbuddy loaded.');
     }
     // Find DAT file.
     pb_backupbuddy::status('details', 'Calculating possible DAT file locations.');
     $detectedDatLocation = '';
     $possibleDatLocations = array();
     if (isset($metaInfo['dat_path'])) {
         $possibleDatLocations[] = $metaInfo['dat_path'][1];
         // DAT file location encoded in meta info. Should always be valid.
     }
     $possibleDatLocations[] = 'wp-content/uploads/backupbuddy_temp/' . $this->_state['serial'] . '/backupbuddy_dat.php';
     // Full backup.
     $possibleDatLocations[] = 'backupbuddy_dat.php';
     // DB backup. (look for this second in case user left an old dat file in root).
     pb_backupbuddy::status('details', 'Possible DAT file locations: `' . implode(';', $possibleDatLocations) . '`.');
     $possibleDatLocations = array_unique($possibleDatLocations);
     if (true === $skipUnzip) {
         // Only look for DAT file in filesystem. Zip should be pre-extracted, eg by the user manually.
         pb_backupbuddy::status('details', 'Looking for DAT file in local filesystem (instead of in zip) since advanced skip unzip option set.');
         foreach ($possibleDatLocations as $possibleDatLocation) {
             // Look for DAT file in filesystem.
             pb_backupbuddy::status('details', 'Does `' . ABSPATH . $possibleDatLocation . '` exist?');
             if (true === file_exists(ABSPATH . $possibleDatLocation)) {
                 pb_backupbuddy::status('details', 'Yes, exists.');
                 $detectedDatLocation = $possibleDatLocation;
                 break;
             } else {
                 pb_backupbuddy::status('details', 'No, does not exist.');
             }
         }
         if ('' == $detectedDatLocation) {
             $message = 'Unable to find the DAT file for this backup archive pre-extracted in the filesystem. Make sure you have already unzipped this backup into the same directory as importbuddy.php.';
             return $this->_error($message);
         }
     } else {
         // Look for DAT file inside of zip archive.
         pb_backupbuddy::status('details', 'Looking for DAT file in zip archive itself.');
         foreach ($possibleDatLocations as $possibleDatLocation) {
             // Look for DAT file in zip.
             if (true === $zipbuddy->file_exists($this->_state['archive'], $possibleDatLocation, $leave_open = true)) {
                 $detectedDatLocation = $possibleDatLocation;
                 break;
             }
         }
         // end foreach.
     }
     if ('' == $detectedDatLocation) {
         return $this->_error('Unable to determine DAT file location. It may be missing OR the backup zip file may be incomplete or corrupted. Verify the backup zip has fully uploaded or re-upload it. You can try manually unzipping then selecting the advanced option to skip unzip.');
     }
     pb_backupbuddy::status('details', 'Confirmed DAT file location: `' . $detectedDatLocation . '`.');
     $this->_state['datLocation'] = $detectedDatLocation;
     unset($metaInfo);
     // No longer need anything from the meta information.
     if (true !== $skipUnzip) {
         function mkdir_recursive($path)
         {
             if (empty($path)) {
                 // prevent infinite loop on bad path
                 return;
             }
             is_dir(dirname($path)) || mkdir_recursive(dirname($path));
             return is_dir($path) || mkdir($path);
         }
         // Load DAT file contents.
         pb_backupbuddy::status('details', 'Creating temporary file directory `' . $this->_state['tempPath'] . '`.');
         pb_backupbuddy::$filesystem->unlink_recursive($this->_state['tempPath']);
         // Remove if already exists.
         mkdir_recursive($this->_state['tempPath']);
         // Make empty directory.
         // Restore DAT file.
         pb_backupbuddy::status('details', 'Extracting DAT file.');
         $files = array($detectedDatLocation => 'backupbuddy_dat.php');
         require pb_backupbuddy::plugin_path() . '/classes/_restoreFiles.php';
         $result = backupbuddy_restore_files::restore($this->_state['archive'], $files, $this->_state['tempPath'], $zipbuddy);
         echo '<script type="text/javascript">jQuery("#pb_backupbuddy_working").hide();</script>';
         pb_backupbuddy::flush();
         if (false === $result) {
             $this->_error('Error #85484: Unable to retrieve DAT file. This is a fatal error.');
             return false;
         }
         $datFile = $this->_state['tempPath'] . 'backupbuddy_dat.php';
     } else {
         $datFile = $this->_state['datLocation'];
     }
     if (false === ($datData = backupbuddy_core::get_dat_file_array($datFile))) {
         $this->_error('Error #4839484: Unable to retrieve DAT file. The backup may have failed opening due to lack of memory, permissions issues, or other reason. Use ImportBuddy to restore or check the Advanced Log above for details.');
         return false;
     }
     $this->_state['dat'] = $datData;
     pb_backupbuddy::status('details', 'DAT file extracted.');
     if (defined('PB_STANDALONE') && true === PB_STANDALONE) {
         $simpleVersion = substr(pb_backupbuddy::$options['bb_version'], 0, strpos(pb_backupbuddy::$options['bb_version'], ' '));
         if (isset($this->_state['dat']['backupbuddy_version']) && version_compare($this->_state['dat']['backupbuddy_version'], $simpleVersion, '>')) {
             pb_backupbuddy::status('error', 'Warning: You are attempting to restore an archive which was created with a newer version of BackupBuddy (' . $this->_state['dat']['backupbuddy_version'] . ') than this ImportBuddy (' . $simpleVersion . '). For best results use an ImportBuddy that is as least as up to date as the BackupBuddy which created the archive.');
         }
     }
     if ('rollback' == $this->_state['type']) {
         if (site_url() != $this->_state['dat']['siteurl']) {
             $this->_error(__('Error #5849843: Site URL does not match. You cannot roll back the database if the URL has changed or for backups or another site. Use importbuddy.php to restore or migrate instead.', 'it-l10n-backupbuddy'));
             return false;
         }
         global $wpdb;
         if ($this->_state['dat']['db_prefix'] != $wpdb->prefix) {
             $this->_error(__('Error #2389394: Database prefix does not match. You cannot roll back the database if the database prefix has changed or for backups or another site. Use importbuddy.php to restore or migrate instead.', 'it-l10n-backupbuddy'));
             return false;
         }
         pb_backupbuddy::$options['rollback_cleanups'][$this->_state['serial']] = time();
         pb_backupbuddy::save();
         // Generate UNDO script.
         pb_backupbuddy::status('details', 'Generating undo script.');
         $this->_state['undoFile'] = 'backupbuddy_rollback_undo-' . $this->_state['serial'] . '.php';
         $undoURL = rtrim(site_url(), '/\\') . '/' . $this->_state['undoFile'];
         if (false === copy(dirname(__FILE__) . '/_rollback_undo.php', ABSPATH . $this->_state['undoFile'])) {
             $this->_error(__('Warning: Unable to create undo script in site root. You will not be able to automated undoing the rollback if something fails so BackupBuddy will not continue.', 'it-l10n-backupbuddy'));
             return false;
         }
         $this->_state['undoURL'] = $undoURL;
     }
     pb_backupbuddy::status('details', 'Finished starting function.');
     return true;
 }
if (!is_admin()) {
    die('Access denied.');
}
// File viewer (view content only) in the file restore page.
/* restore_file_view()
*
* View contents of a file (text) that is inside a zip archive.
*
*/
pb_backupbuddy::$ui->ajax_header(true, false);
// js, no padding
$archive_file = pb_backupbuddy::_GET('archive');
// archive to extract from.
$file = pb_backupbuddy::_GET('file');
// file to extract.
$serial = backupbuddy_core::get_serial_from_file($archive_file);
// serial of archive.
$temp_file = uniqid();
// temp filename to extract into.
require_once pb_backupbuddy::plugin_path() . '/lib/zipbuddy/zipbuddy.php';
$zipbuddy = new pluginbuddy_zipbuddy(backupbuddy_core::getBackupDirectory());
// Calculate temp directory & lock it down.
$temp_dir = get_temp_dir();
$destination = $temp_dir . 'backupbuddy-' . $serial;
if (!file_exists($destination) && false === mkdir($destination)) {
    $error = 'Error #458485945b: Unable to create temporary location.';
    pb_backupbuddy::status('error', $error);
    die($error);
}
// If temp directory is within webroot then lock it down.
$temp_dir = str_replace('\\', '/', $temp_dir);
Пример #9
0
 $old_backup_dir = backupbuddy_core::getBackupDirectory();
 $new_backup_dir = $backup_directory;
 // Move all files from old backup to new.
 $old_backups_moved = 0;
 $old_backups = glob($old_backup_dir . 'backup*.zip');
 if (!is_array($old_backups) || empty($old_backups)) {
     // On failure glob() returns false or an empty array depending on server settings so normalize here.
     $old_backups = array();
 }
 foreach ($old_backups as $old_backup) {
     if (false === rename($old_backup, $new_backup_dir . basename($old_backup))) {
         pb_backupbuddy::alert('ERROR: Unable to move backup "' . basename($old_backup) . '" to new storage directory. Manually move it or delete it for security and to prevent it from being backed up within backups.');
     } else {
         // rename success.
         $old_backups_moved++;
         $serial = backupbuddy_core::get_serial_from_file(basename($old_backup));
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         $fileoptions_files = glob(backupbuddy_core::getLogDirectory() . 'fileoptions/*.txt');
         if (!is_array($fileoptions_files)) {
             $fileoptions_files = array();
         }
         foreach ($fileoptions_files as $fileoptions_file) {
             pb_backupbuddy::status('details', 'Fileoptions instance #21.');
             $backup_options = new pb_backupbuddy_fileoptions($fileoptions_file);
             if (true !== ($result = $backup_options->is_ok())) {
                 pb_backupbuddy::status('error', __('Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
                 continue;
             }
             if (isset($backup_options->options[$serial])) {
                 if (isset($backup_options->options['archive_file'])) {
                     $backup_options->options['archive_file'] = str_replace($old_backup_dir, $new_backup_dir, $backup_options->options['archive_file']);
Пример #10
0
    public function restore_file_restore()
    {
        $success = false;
        pb_backupbuddy::$ui->ajax_header(true, false);
        // js, no padding
        ?>
		<script type="text/javascript">
			function pb_status_append( status_string ) {
				target_id = 'pb_backupbuddy_status'; // importbuddy_status or pb_backupbuddy_status
				if( jQuery( '#' + target_id ).length == 0 ) { // No status box yet so suppress.
					return;
				}
				jQuery( '#' + target_id ).append( "\n" + status_string );
				textareaelem = document.getElementById( target_id );
				textareaelem.scrollTop = textareaelem.scrollHeight;
			}
		</script>
		<?php 
        global $pb_backupbuddy_js_status;
        $pb_backupbuddy_js_status = true;
        echo pb_backupbuddy::status_box('Restoring . . .');
        echo '<div id="pb_backupbuddy_working" style="width: 100px;"><br><center><img src="' . pb_backupbuddy::plugin_url() . '/images/working.gif" title="Working... Please wait as this may take a moment..."></center></div>';
        pb_backupbuddy::set_status_serial('restore');
        global $wp_version;
        pb_backupbuddy::status('details', 'BackupBuddy v' . pb_backupbuddy::settings('version') . ' using WordPress v' . $wp_version . ' on ' . PHP_OS . '.');
        $archive_file = pb_backupbuddy::_GET('archive');
        // archive to extract from.
        $files = pb_backupbuddy::_GET('files');
        // file to extract.
        $files_array = explode(',', $files);
        $files = array();
        foreach ($files_array as $file) {
            if (substr($file, -1) == '/') {
                // If directory then add wildcard.
                $file = $file . '*';
            }
            $files[$file] = $file;
        }
        unset($files_array);
        $serial = backupbuddy_core::get_serial_from_file($archive_file);
        // serial of archive.
        foreach ($files as $file) {
            $file = str_replace('*', '', $file);
            // Remove any wildcard.
            if (file_exists(ABSPATH . $file) && is_dir(ABSPATH . $file)) {
                if (($file_count = @scandir(ABSPATH . $file)) && count($file_count) > 2) {
                    pb_backupbuddy::status('error', __('Error #9036. The destination directory being restored already exists and is NOT empty. The directory will not be restored to prevent inadvertently losing files within the existing directory. Delete existing directory first if you wish to proceed or restore individual files.', 'it-l10n-backupbuddy') . ' Existing directory: `' . ABSPATH . $file . '`.');
                    echo '<script type="text/javascript">jQuery("#pb_backupbuddy_working").hide();</script>';
                    pb_backupbuddy::flush();
                    pb_backupbuddy::$ui->ajax_footer();
                    die;
                }
            }
        }
        require_once pb_backupbuddy::plugin_path() . '/lib/zipbuddy/zipbuddy.php';
        $zipbuddy = new pluginbuddy_zipbuddy(backupbuddy_core::getBackupDirectory());
        // Calculate temp directory & lock it down.
        $temp_dir = get_temp_dir();
        $destination = $temp_dir . 'backupbuddy-' . $serial;
        if (!file_exists($destination) && false === mkdir($destination, 0777, true)) {
            $error = 'Error #458485945: Unable to create temporary location.';
            pb_backupbuddy::status('error', $error);
            echo '<script type="text/javascript">jQuery("#pb_backupbuddy_working").hide();</script>';
            pb_backupbuddy::flush();
            pb_backupbuddy::$ui->ajax_footer();
            die;
        }
        // If temp directory is within webroot then lock it down.
        $temp_dir = str_replace('\\', '/', $temp_dir);
        // Normalize for Windows.
        $temp_dir = rtrim($temp_dir, '/\\') . '/';
        // Enforce single trailing slash.
        if (FALSE !== stristr($temp_dir, ABSPATH)) {
            // Temp dir is within webroot.
            pb_backupbuddy::anti_directory_browsing($destination);
        }
        unset($temp_dir);
        pb_backupbuddy::status('details', 'Extracting into temporary directory "' . $destination . '".');
        pb_backupbuddy::status('details', 'Files to extract: `' . htmlentities(pb_backupbuddy::_GET('files')) . '`.');
        // Make sure temp subdirectories exist.
        /*
        foreach( $files as $file => $null ) {
        	mkdir( $destination . '/' . basename( $file ), 0777, true );
        }
        */
        pb_backupbuddy::flush();
        $extract_success = true;
        $extract_result = $zipbuddy->extract(backupbuddy_core::getBackupDirectory() . $archive_file, $destination, $files);
        if (false === $extract_result) {
            // failed.
            pb_backupbuddy::status('error', 'Error #584984458b. Unable to extract.');
            $extract_success = false;
        } else {
            // success.
            // Verify all files/directories to be extracted exist in temp destination directory. If any missing then delete everything and bail out.
            foreach ($files as &$file) {
                $file = str_replace('*', '', $file);
                // Remove any wildcard.
                if (!file_exists($destination . '/' . $file)) {
                    // Cleanup.
                    foreach ($files as $file) {
                        @trigger_error('');
                        // Clear out last error.
                        @unlink($destination . '/' . $file);
                        $last_error = error_get_last();
                        if (is_array($last_error)) {
                            pb_backupbuddy::status('error', $last_error['message'] . ' File: `' . $last_error['file'] . '`. Line: `' . $last_error['line'] . '`.');
                        }
                    }
                    pb_backupbuddy::status('error', 'Error #854783474. One or more expected files / directories missing.');
                    $extract_success = false;
                    break;
                }
            }
            unset($file);
        }
        if (true === $extract_success) {
            // Made it this far so files all exist. Move them all.
            foreach ($files as $file) {
                @trigger_error('');
                // Clear out last error.
                if (false === @rename($destination . '/' . $file, ABSPATH . $file)) {
                    $last_error = error_get_last();
                    if (is_array($last_error)) {
                        //print_r( $last_error );
                        pb_backupbuddy::status('error', $last_error['message'] . ' File: `' . $last_error['file'] . '`. Line: `' . $last_error['line'] . '`.');
                    }
                    $error = 'Error #9035. Unable to move restored file `' . $destination . '/' . $file . '` to `' . ABSPATH . $file . '`. Verify permissions on destination location & that the destination directory/file does not already exist.';
                    pb_backupbuddy::status('error', $error);
                } else {
                    $details = 'Moved `' . $destination . '/' . $file . '` to `' . ABSPATH . $file . '`.<br>';
                    pb_backupbuddy::status('details', $details);
                    $success = true;
                }
            }
        }
        // end extract succeeded.
        // Try to cleanup.
        if (file_exists($destination)) {
            if (false === pb_backupbuddy::$filesystem->unlink_recursive($destination)) {
                pb_backupbuddy::status('details', 'Unable to delete temporary holding directory `' . $destination . '`.');
            } else {
                pb_backupbuddy::status('details', 'Cleaned up temporary files.');
            }
        }
        if (true === $success) {
            pb_backupbuddy::status('message', 'Restore completed successfully.');
        }
        echo '<script type="text/javascript">jQuery("#pb_backupbuddy_working").hide();</script>';
        pb_backupbuddy::flush();
        pb_backupbuddy::$ui->ajax_footer();
        die;
    }
Пример #11
0
 public function start($backupFile)
 {
     $this->_before(__FUNCTION__);
     $this->_state['archive'] = $backupFile;
     $serial = backupbuddy_core::get_serial_from_file(basename($backupFile));
     $this->_state['serial'] = $serial;
     $this->_state['tempPath'] = backupbuddy_core::getTempDirectory() . $this->_state['type'] . '_' . $this->_state['serial'] . '/';
     unset($backupFile);
     unset($serial);
     // Get zip meta information.
     $customTitle = 'Backup Details';
     pb_backupbuddy::status('details', 'Attempting to retrieve zip meta data from comment.');
     if (false !== ($metaInfo = backupbuddy_core::getZipMeta($this->_state['archive']))) {
         pb_backupbuddy::status('details', 'Found zip meta data.');
     } else {
         pb_backupbuddy::status('details', 'Did not find zip meta data.');
     }
     //$this->_state['meta'] = $metaInfo;
     pb_backupbuddy::status('details', 'Loading zipbuddy.');
     require_once pb_backupbuddy::plugin_path() . '/lib/zipbuddy/zipbuddy.php';
     $zipbuddy = new pluginbuddy_zipbuddy(backupbuddy_core::getBackupDirectory());
     pb_backupbuddy::status('details', 'Zipbuddy loaded.');
     // Find DAT file.
     pb_backupbuddy::status('details', 'Calculating possible DAT file locations.');
     $possibleDatLocations = array();
     if (isset($metaInfo['dat_path'])) {
         $possibleDatLocations[] = $metaInfo['dat_path'][1];
         // DAT file location encoded in meta info. Should always be valid.
     }
     $possibleDatLocations[] = 'backupbuddy_dat.php';
     // DB backup.
     $possibleDatLocations[] = 'wp-content/uploads/backupbuddy_temp/' . $this->_state['serial'] . '/backupbuddy_dat.php';
     // Full backup.
     pb_backupbuddy::status('details', 'Possible DAT file locations: `' . implode(';', $possibleDatLocations) . '`.');
     $possibleDatLocations = array_unique($possibleDatLocations);
     foreach ($possibleDatLocations as $possibleDatLocation) {
         if (true === $zipbuddy->file_exists($this->_state['archive'], $possibleDatLocation, $leave_open = true)) {
             $detectedDatLocation = $possibleDatLocation;
             break;
         }
     }
     // end foreach.
     pb_backupbuddy::status('details', 'Confirmed DAT file location: `' . $detectedDatLocation . '`.');
     $this->_state['datLocation'] = $detectedDatLocation;
     unset($metaInfo);
     // No longer need anything from the meta information.
     // Load DAT file contents.
     pb_backupbuddy::status('details', 'Creating temporary file directory `' . $this->_state['tempPath'] . '`.');
     pb_backupbuddy::$filesystem->unlink_recursive($this->_state['tempPath']);
     // Remove if already exists.
     mkdir($this->_state['tempPath']);
     // Make empty directory.
     // Restore DAT file.
     pb_backupbuddy::status('details', 'Extracting DAT file.');
     $files = array($detectedDatLocation => 'backupbuddy_dat.php');
     require pb_backupbuddy::plugin_path() . '/classes/_restoreFiles.php';
     $result = backupbuddy_restore_files::restore($this->_state['archive'], $files, $this->_state['tempPath'], $zipbuddy);
     echo '<script type="text/javascript">jQuery("#pb_backupbuddy_working").hide();</script>';
     pb_backupbuddy::flush();
     if (false === $result) {
         $this->_error('Error #85484: Unable to retrieve DAT file. This is a fatal error.');
         return false;
     }
     if (false === ($datData = backupbuddy_core::get_dat_file_array($this->_state['tempPath'] . 'backupbuddy_dat.php'))) {
         $this->_error('Error #4839484: Unable to retrieve DAT file. The backup may have failed opening due to lack of memory, permissions issues, or other reason. Use ImportBuddy to restore or check the Advanced Log above for details.');
         return false;
     }
     $this->_state['dat'] = $datData;
     pb_backupbuddy::status('details', 'DAT file extracted.');
     if (site_url() != $this->_state['dat']['siteurl']) {
         $this->_error(__('Error #5849843: Site URL does not match. You cannot roll back the database if the URL has changed or for backups or another site. Use importbuddy.php to restore or migrate instead.', 'it-l10n-backupbuddy'));
         return false;
     }
     global $wpdb;
     if ($this->_state['dat']['db_prefix'] != $wpdb->prefix) {
         $this->_error(__('Error #2389394: Database prefix does not match. You cannot roll back the database if the database prefix has changed or for backups or another site. Use importbuddy.php to restore or migrate instead.', 'it-l10n-backupbuddy'));
         return false;
     }
     // Store this serial in the db for future cleanup.
     if ('rollback' == $this->_state['type']) {
         pb_backupbuddy::$options['rollback_cleanups'][$this->_state['serial']] = time();
         pb_backupbuddy::save();
         // Generate UNDO script.
         pb_backupbuddy::status('details', 'Generating undo script.');
         $this->_state['undoFile'] = 'backupbuddy_rollback_undo-' . $this->_state['serial'] . '.php';
         $undoURL = rtrim(site_url(), '/\\') . '/' . $this->_state['undoFile'];
         if (false === copy(dirname(__FILE__) . '/_rollback_undo.php', ABSPATH . $this->_state['undoFile'])) {
             $this->_error(__('Warning: Unable to create undo script in site root. You will not be able to automated undoing the rollback if something fails so BackupBuddy will not continue.', 'it-l10n-backupbuddy'));
             return false;
         }
         $this->_state['undoURL'] = $undoURL;
     }
     pb_backupbuddy::status('details', 'Finished starting function.');
     return true;
 }
 public static function send($destination_settings, $files, $send_id = '', $delete_after = false)
 {
     if ('' != $send_id) {
         pb_backupbuddy::add_status_serial('remote_send-' . $send_id);
         pb_backupbuddy::status('details', '----- Initiating master send function. Post-send deletion: ' . $delete_after);
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         $fileoptions_file = backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt';
         if (!file_exists($fileoptions_file)) {
             //pb_backupbuddy::status( 'details', 'Fileoptions file `' . $fileoptions_file . '` does not exist yet; creating.' );
             //pb_backupbuddy::status( 'details', 'Fileoptions instance #19.' );
             $fileoptions_obj = new pb_backupbuddy_fileoptions($fileoptions_file, $read_only = false, $ignore_lock = true, $create_file = true);
         } else {
             //pb_backupbuddy::status( 'details', 'Fileoptions file exists; loading.' );
             //pb_backupbuddy::status( 'details', 'Fileoptions instance #18.' );
             $fileoptions_obj = new pb_backupbuddy_fileoptions($fileoptions_file, $read_only = false, $ignore_lock = false, $create_file = false);
         }
         if (true !== ($result = $fileoptions_obj->is_ok())) {
             pb_backupbuddy::status('error', __('Fatal Error #9034.2344848. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
             return false;
         }
         //pb_backupbuddy::status( 'details', 'Fileoptions data loaded.' );
         $fileoptions =& $fileoptions_obj->options;
         if ('' == $fileoptions) {
             $fileoptions = backupbuddy_core::get_remote_send_defaults();
             $fileoptions['type'] = $destination_settings['type'];
             if (!is_array($files)) {
                 $fileoptions['file'] = $files;
             } else {
                 $fileoptions['file'] = $files[0];
             }
             $fileoptions_obj->save();
         }
         if (isset($fileoptions['status']) && 'aborted' == $fileoptions['status']) {
             pb_backupbuddy::status('warning', 'Destination send triggered on an ABORTED transfer. Ending send function.');
             return false;
         }
         unset($fileoptions_obj);
     }
     if (false === ($destination = self::_init_destination($destination_settings))) {
         echo '{Error #546893498a. Destination configuration file missing.}';
         if ('' != $send_id) {
             pb_backupbuddy::remove_status_serial('remote_send-' . $send_id);
         }
         return false;
     }
     $destination_settings = $destination['settings'];
     // Settings with defaults applied, normalized, etc.
     //$destination_info = $destination['info'];
     if (!is_array($files)) {
         $files = array($files);
     }
     $originalFiles = $files;
     $files_with_sizes = '';
     foreach ($files as $index => $file) {
         if ('' == $file) {
             unset($files[$index]);
             continue;
             // Not actually a file to send.
         }
         if (!file_exists($file)) {
             pb_backupbuddy::status('error', 'Error #58459458743. The file that was attempted to be sent to a remote destination, `' . $file . '`, was not found. It either does not exist or permissions prevent accessing it.');
             if ('' != $send_id) {
                 pb_backupbuddy::remove_status_serial('remote_send-' . $send_id);
             }
             return false;
         }
         $files_with_sizes .= $file . ' (' . pb_backupbuddy::$format->file_size(filesize($file)) . '); ';
     }
     //pb_backupbuddy::status( 'details', 'Sending files `' . $files_with_sizes . '` to destination type `' . $destination_settings['type'] . '` titled `' . $destination_settings['title'] . '`.' );
     unset($files_with_sizes);
     if (!method_exists($destination['class'], 'send')) {
         pb_backupbuddy::status('error', 'Destination class `' . $destination['class'] . '` does not support send operation -- missing function.');
         if ('' != $send_id) {
             pb_backupbuddy::remove_status_serial('remote_send-' . $send_id);
         }
         return false;
     }
     //pb_backupbuddy::status( 'details', 'Calling send function.' );
     //$result = $destination_class::send( $destination_settings, $files );
     global $pb_backupbuddy_destination_errors;
     $pb_backupbuddy_destination_errors = array();
     $result = call_user_func_array("{$destination['class']}::send", array($destination_settings, $files, $send_id, $delete_after));
     if ($result === false) {
         $error_details = implode('; ', $pb_backupbuddy_destination_errors);
         if ('' != $error_details) {
             $error_details = ' Details: ' . $error_details;
         }
         $log_directory = backupbuddy_core::getLogDirectory();
         $preError = 'There was an error sending to the remote destination. One or more files may have not been fully transferred. Please see error details for additional information. If the error persists, enable full error logging and try again for full details and troubleshooting. Details: ' . "\n\n";
         $logFile = $log_directory . 'status-remote_send-' . $send_id . '_' . backupbuddy_core::get_serial_from_file($file) . '.txt';
         pb_backupbuddy::status('details', 'Looking for remote send log file `' . $logFile . '`.');
         if (!file_exists($logFile)) {
             pb_backupbuddy::status('details', 'Remote send log file not found.');
             backupbuddy_core::mail_error($preError . $error_details);
         } else {
             // Log exists. Attach.
             pb_backupbuddy::status('details', 'Remote send log file found. Attaching to error email.');
             backupbuddy_core::mail_error($preError . $error_details . "\n\nSee the attached log for details.", '', array($logFile));
         }
         // Save error details into fileoptions for this send.
         //pb_backupbuddy::status( 'details', 'About to load fileoptions data.' );
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         pb_backupbuddy::status('details', 'Fileoptions instance #45.');
         $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
         if (true !== ($fileoptions_result = $fileoptions_obj->is_ok())) {
             pb_backupbuddy::status('error', __('Error #9034.32731. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $fileoptions_result);
         }
         //pb_backupbuddy::status( 'details', 'Fileoptions data loaded.' );
         $fileoptions =& $fileoptions_obj->options;
         $fileoptions['error'] = 'Error sending.' . $error_details;
         $fileoptions_obj->save();
         unset($fileoptions_obj);
     }
     if (is_array($result)) {
         // Send is multipart.
         pb_backupbuddy::status('details', 'Multipart chunk mode completed a pass of the send function. Resuming will be needed. Result: `' . print_r($result, true) . '`.');
         if ('' != $send_id) {
             //pb_backupbuddy::status( 'details', 'About to load fileoptions data.' );
             require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
             //pb_backupbuddy::status( 'details', 'Fileoptions instance #17.' );
             $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
             if (true !== ($fileoptions_result = $fileoptions_obj->is_ok())) {
                 pb_backupbuddy::status('error', __('Fatal Error #9034.387462. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $fileoptions_result);
                 return false;
             }
             //pb_backupbuddy::status( 'details', 'Fileoptions data loaded.' );
             $fileoptions =& $fileoptions_obj->options;
             $fileoptions['_multipart_status'] = $result[1];
             pb_backupbuddy::status('details', 'Destination debugging details: `' . print_r($fileoptions, true) . '`.');
             $fileoptions_obj->save();
             unset($fileoptions_obj);
             pb_backupbuddy::status('details', 'Next multipart chunk will be processed shortly. Now waiting on its cron...');
         }
     } else {
         // Single all-at-once send.
         if (false === $result) {
             pb_backupbuddy::status('details', 'Completed send function. Failure.');
         } elseif (true === $result) {
             pb_backupbuddy::status('details', 'Completed send function. Success.');
         } else {
             pb_backupbuddy::status('warning', 'Completed send function. Unknown result: `' . $result . '`.');
         }
         if (true === $delete_after) {
             pb_backupbuddy::status('details', __('Post-send deletion enabled.', 'it-l10n-backupbuddy'));
             if (false === $result) {
                 pb_backupbuddy::status('details', 'Skipping post-send deletion since transfer failed.');
             } else {
                 pb_backupbuddy::status('details', 'Performing post-send deletion since transfer succeeded.');
                 pb_backupbuddy::status('details', 'About to load fileoptions data.');
                 require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
                 pb_backupbuddy::status('details', 'Fileoptions instance #16.');
                 $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
                 if (true !== ($fileoptions_result = $fileoptions_obj->is_ok())) {
                     pb_backupbuddy::status('error', __('Error #9034.387462. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $fileoptions_result);
                 }
                 pb_backupbuddy::status('details', 'Fileoptions data loaded.');
                 $fileoptions =& $fileoptions_obj->options;
                 array_push($originalFiles, $fileoptions['file']);
                 // Add file (maybe multipart) into files to clean up.
                 foreach ($originalFiles as $file) {
                     pb_backupbuddy::status('details', 'Deleting local file `' . $file . '`.');
                     // Handle post-send deletion on success.
                     if (file_exists($file)) {
                         $unlink_result = @unlink($file);
                         if (true !== $unlink_result) {
                             pb_backupbuddy::status('error', 'Unable to unlink local file `' . $file . '`.');
                         }
                     }
                     if (file_exists($file)) {
                         // File still exists.
                         pb_backupbuddy::status('details', __('Error. Unable to delete local file `' . $file . '` after send as set in settings.', 'it-l10n-backupbuddy'));
                         backupbuddy_core::mail_error('BackupBuddy was unable to delete local file `' . $file . '` after successful remove transfer though post-remote send deletion is enabled. You may want to delete it manually. This can be caused by permission problems or improper server configuration.');
                     } else {
                         // Deleted.
                         pb_backupbuddy::status('details', __('Deleted local archive after successful remote destination send based on settings.', 'it-l10n-backupbuddy'));
                         pb_backupbuddy::status('archiveDeleted', '');
                     }
                 }
             }
         } else {
             pb_backupbuddy::status('details', 'Post-send deletion not enabled.');
         }
     }
     // NOTE: Call this before removing status serial so it shows in log.
     //pb_backupbuddy::status( 'details', 'Finishing send() function.' );
     if ('' != $send_id) {
         pb_backupbuddy::remove_status_serial('remote_send-' . $send_id);
     }
     return $result;
 }
Пример #13
0
    public static function backups_list($type = 'default', $subsite_mode = false)
    {
        if (pb_backupbuddy::_POST('bulk_action') == 'delete_backup' && is_array(pb_backupbuddy::_POST('items'))) {
            $needs_save = false;
            pb_backupbuddy::verify_nonce(pb_backupbuddy::_POST('_wpnonce'));
            // Security check to prevent unauthorized deletions by posting from a remote place.
            $deleted_files = array();
            foreach (pb_backupbuddy::_POST('items') as $item) {
                if (file_exists(backupbuddy_core::getBackupDirectory() . $item)) {
                    if (@unlink(backupbuddy_core::getBackupDirectory() . $item) === true) {
                        $deleted_files[] = $item;
                        // Cleanup any related fileoptions files.
                        $serial = backupbuddy_core::get_serial_from_file($item);
                        $backup_files = glob(backupbuddy_core::getBackupDirectory() . '*.zip');
                        if (!is_array($backup_files)) {
                            $backup_files = array();
                        }
                        if (count($backup_files) > 5) {
                            // Keep a minimum number of backups in array for stats.
                            $this_serial = self::get_serial_from_file($item);
                            $fileoptions_file = backupbuddy_core::getLogDirectory() . 'fileoptions/' . $this_serial . '.txt';
                            if (file_exists($fileoptions_file)) {
                                @unlink($fileoptions_file);
                            }
                            if (file_exists($fileoptions_file . '.lock')) {
                                @unlink($fileoptions_file . '.lock');
                            }
                            $needs_save = true;
                        }
                    } else {
                        pb_backupbuddy::alert('Error: Unable to delete backup file `' . $item . '`. Please verify permissions.', true);
                    }
                }
                // End if file exists.
            }
            // End foreach.
            if ($needs_save === true) {
                pb_backupbuddy::save();
            }
            pb_backupbuddy::alert(__('Deleted:', 'it-l10n-backupbuddy') . ' ' . implode(', ', $deleted_files));
        }
        // End if deleting backup(s).
        $backups = array();
        $backup_sort_dates = array();
        $files = glob(backupbuddy_core::getBackupDirectory() . 'backup*.zip');
        if (is_array($files) && !empty($files)) {
            // For robustness. Without open_basedir the glob() function returns an empty array for no match. With open_basedir in effect the glob() function returns a boolean false for no match.
            $backup_prefix = self::backup_prefix();
            // Backup prefix for this site. Used for MS checking that this user can see this backup.
            foreach ($files as $file_id => $file) {
                if ($subsite_mode === true && is_multisite()) {
                    // If a Network and NOT the superadmin must make sure they can only see the specific subsite backups for security purposes.
                    // Only allow viewing of their own backups.
                    if (!strstr($file, $backup_prefix)) {
                        unset($files[$file_id]);
                        // Remove this backup from the list. This user does not have access to it.
                        continue;
                        // Skip processing to next file.
                    }
                }
                $serial = backupbuddy_core::get_serial_from_file($file);
                require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
                $backup_options = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt', $read_only = false, $ignore_lock = false, $create_file = true);
                // Will create file to hold integrity data if nothing exists.
                $backup_integrity = backupbuddy_core::backup_integrity_check($file, $backup_options);
                // Backup status.
                $pretty_status = array(true => '<span class="pb_label pb_label-success">Good</span>', 'pass' => '<span class="pb_label pb_label-success">Good</span>', false => '<span class="pb_label pb_label-important">Bad</span>', 'fail' => '<span class="pb_label pb_label-important">Bad</span>');
                // Backup type.
                $pretty_type = array('full' => 'Full', 'db' => 'Database', 'files' => 'Files');
                // Defaults...
                $detected_type = '';
                $file_size = '';
                $modified = '';
                $modified_time = 0;
                $integrity = '';
                if (is_array($backup_options->options)) {
                    // Data intact... put it all together.
                    // Calculate time ago.
                    $time_ago = '';
                    if (isset($backup_options->options['integrity']) && isset($backup_options->options['integrity']['modified'])) {
                        $time_ago = pb_backupbuddy::$format->time_ago($backup_options->options['integrity']['modified']) . ' ago';
                    }
                    $detected_type = pb_backupbuddy::$format->prettify($backup_options->options['integrity']['detected_type'], $pretty_type);
                    if ($detected_type == '') {
                        $detected_type = 'Unknown';
                    } else {
                        if (isset($backup_options->options['profile'])) {
                            $detected_type = '
							<div>
								<span style="color: #AAA; float: left;">' . $detected_type . '</span>
								<span style="display: inline-block; float: left; height: 15px; border-right: 1px solid #EBEBEB; margin-left: 6px; margin-right: 6px;"></span>
								' . htmlentities($backup_options->options['profile']['title']) . '
							</div>
							';
                        }
                    }
                    $file_size = pb_backupbuddy::$format->file_size($backup_options->options['integrity']['size']);
                    $modified = pb_backupbuddy::$format->date(pb_backupbuddy::$format->localize_time($backup_options->options['integrity']['modified']), 'l, F j, Y - g:i:s a');
                    $modified_time = $backup_options->options['integrity']['modified'];
                    if (isset($backup_options->options['integrity']['status'])) {
                        // Pre-v4.0.
                        $status = $backup_options->options['integrity']['status'];
                    } else {
                        // v4.0+
                        $status = $backup_options->options['integrity']['is_ok'];
                    }
                    // Calculate main row string.
                    if ($type == 'default') {
                        // Default backup listing.
                        $main_string = '<a href="' . pb_backupbuddy::ajax_url('download_archive') . '&backupbuddy_backup=' . basename($file) . '" class="backupbuddyFileTitle" title="' . basename($file) . '">' . $modified . ' (' . $time_ago . ')</a>';
                    } elseif ($type == 'migrate') {
                        // Migration backup listing.
                        $main_string = '<a class="pb_backupbuddy_hoveraction_migrate backupbuddyFileTitle" rel="' . basename($file) . '" href="' . pb_backupbuddy::page_url() . '&migrate=' . basename($file) . '&value=' . basename($file) . '" title="' . basename($file) . '">' . $modified . ' (' . $time_ago . ')</a>';
                    } else {
                        $main_string = '{Unknown type.}';
                    }
                    // Add comment to main row string if applicable.
                    if (isset($backup_options->options['integrity']['comment']) && $backup_options->options['integrity']['comment'] !== false && $backup_options->options['integrity']['comment'] !== '') {
                        $main_string .= '<br><span class="description">Note: <span class="pb_backupbuddy_notetext">' . htmlentities($backup_options->options['integrity']['comment']) . '</span></span>';
                    }
                    $integrity = pb_backupbuddy::$format->prettify($status, $pretty_status) . ' ';
                    if (isset($backup_options->options['integrity']['scan_notes']) && count((array) $backup_options->options['integrity']['scan_notes']) > 0) {
                        foreach ((array) $backup_options->options['integrity']['scan_notes'] as $scan_note) {
                            $integrity .= $scan_note . ' ';
                        }
                    }
                    $integrity .= '<a href="' . pb_backupbuddy::page_url() . '&reset_integrity=' . $serial . '" title="Rescan integrity. Last checked ' . pb_backupbuddy::$format->date($backup_options->options['integrity']['scan_time']) . '."><img src="' . pb_backupbuddy::plugin_url() . '/images/refresh_gray.gif" style="vertical-align: -1px;"></a>';
                    $integrity .= '<div class="row-actions"><a title="' . __('Backup Status', 'it-l10n-backupbuddy') . '" href="' . pb_backupbuddy::ajax_url('integrity_status') . '&serial=' . $serial . '&#038;TB_iframe=1&#038;width=640&#038;height=600" class="thickbox">' . __('View Details', 'it-l10n-backupbuddy') . '</a></div>';
                }
                // end if is_array( $backup_options ).
                $backups[basename($file)] = array(array(basename($file), $main_string . '<br><span class="description">' . basename($file) . '</span>'), $detected_type, $file_size, $integrity);
                $backup_sort_dates[basename($file)] = $modified_time;
            }
            // End foreach().
        }
        // End if.
        // Sort backup by date.
        arsort($backup_sort_dates);
        // Re-arrange backups based on sort dates.
        $sorted_backups = array();
        foreach ($backup_sort_dates as $backup_file => $backup_sort_date) {
            $sorted_backups[$backup_file] = $backups[$backup_file];
            unset($backups[$backup_file]);
        }
        unset($backups);
        return $sorted_backups;
    }
Пример #14
0
 public static function deploymentImportBuddy($password, $backupFile, $additionalStateInfo = '')
 {
     if (!file_exists($backupFile)) {
         $error = 'Error #43848378: Backup file `' . $backupFile . '` not found uploaded.';
         pb_backupbuddy::status('error', $error);
         return array(false, $error);
     }
     $backupSerial = backupbuddy_core::get_serial_from_file($backupFile);
     $importFileSerial = pb_backupbuddy::random_string(15);
     $importFilename = 'importbuddy-' . $importFileSerial . '.php';
     backupbuddy_core::importbuddy(ABSPATH . $importFilename, $password);
     // Render default config file overrides. Overrrides default restore.php state data.
     $state = array();
     global $wpdb;
     $state['type'] = 'deploy';
     $state['archive'] = $backupFile;
     $state['siteurl'] = preg_replace('|/*$|', '', site_url());
     // Strip trailing slashes.
     $state['homeurl'] = preg_replace('|/*$|', '', home_url());
     // Strip trailing slashes.
     $state['restoreFiles'] = false;
     $state['migrateHtaccess'] = false;
     $state['remote_api'] = pb_backupbuddy::$options['remote_api'];
     // For use by importbuddy api auth. Enables remote api in this importbuddy.
     $state['databaseSettings']['server'] = DB_HOST;
     $state['databaseSettings']['database'] = DB_NAME;
     $state['databaseSettings']['username'] = DB_USER;
     $state['databaseSettings']['password'] = DB_PASSWORD;
     $state['databaseSettings']['prefix'] = $wpdb->prefix;
     $state['databaseSettings']['renamePrefix'] = true;
     $state['cleanup']['deleteImportBuddy'] = true;
     $state['cleanup']['deleteImportLog'] = true;
     if (is_array($additionalStateInfo)) {
         $state = array_merge($state, $additionalStateInfo);
     }
     // Write default state overrides.
     $state_file = ABSPATH . 'importbuddy-' . $importFileSerial . '-state.php';
     if (false === ($file_handle = @fopen($state_file, 'w'))) {
         $error = 'Error #8384784: Temp state file is not creatable/writable. Check your permissions. (' . $state_file . ')';
         pb_backupbuddy::status('error', $error);
         return array(false, $error);
     }
     fwrite($file_handle, "<?php die('Access Denied.'); // <!-- ?>\n" . base64_encode(serialize($state)));
     fclose($file_handle);
     $undoFile = 'backupbuddy_deploy_undo-' . $backupSerial . '.php';
     //$undoURL = rtrim( site_url(), '/\\' ) . '/' . $undoFile;
     if (false === copy(pb_backupbuddy::plugin_path() . '/classes/_rollback_undo.php', ABSPATH . $undoFile)) {
         $error = 'Error #3289447: Unable to write undo file `' . ABSPATH . $undoFile . '`. Check permissions on directory.';
         pb_backupbuddy::status('error', $error);
         return array(false, $error);
     }
     return $importFileSerial;
 }
Пример #15
0
 public static function getBackupTypeFromFile($file, $quiet = false)
 {
     if (false === $quiet) {
         pb_backupbuddy::status('details', 'Detecting backup type if possible.');
     }
     // Try to figure out type via filename.
     if (stristr($file, '-db-') !== false) {
         $type = 'db';
     } elseif (stristr($file, '-full-') !== false) {
         $type = 'full';
     } elseif (stristr($file, '-files-') !== false) {
         $type = 'files';
     }
     if (isset($type)) {
         if (false === $quiet) {
             pb_backupbuddy::status('details', 'Detected backup type as `' . $type . '` via filename.');
         }
         return $type;
     }
     // See if we can get backup type from fileoptions data.
     require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
     $fileoptionsFile = backupbuddy_core::getLogDirectory() . 'fileoptions/' . backupbuddy_core::get_serial_from_file($file) . '.txt';
     $backup_options = new pb_backupbuddy_fileoptions($fileoptionsFile, $read_only = true, $ignore_lock = true);
     if (true !== ($result = $backup_options->is_ok())) {
         //pb_backupbuddy::status( 'warning', 'Warning only: Unable to open fileoptions file `' . $fileoptionsFile . '`. This may be normal.' );
     } else {
         if (isset($backup_options->options['integrity']['detected_type'])) {
             if (false === $quiet) {
                 pb_backupbuddy::status('details', 'Detected backup type as `' . $backup_options->options['integrity']['detected_type'] . '` via integrity check data.');
             }
             return $backup_options->options['integrity']['detected_type'];
         }
     }
     return '';
     // Type unknown.
 }
Пример #16
0
 public static function send($settings = array(), $files = array(), $send_id = '', $delete_after = false)
 {
     if (!is_array($files)) {
         $files = array($files);
     }
     global $pb_backupbuddy_destination_errors;
     $backup_type_dir = '';
     $region = '';
     $settings['bucket'] = strtolower($settings['bucket']);
     // Buckets must be lowercase.
     if (!is_array($files)) {
         $files = array($files);
     }
     $limit = $settings['archive_limit'];
     $max_chunk_size = $settings['max_chunk_size'];
     $remote_path = self::get_remote_path($settings['directory']);
     // Has leading and trailng slashes.
     if ($settings['ssl'] == '0') {
         $disable_ssl = true;
     } else {
         $disable_ssl = false;
     }
     $multipart_id = $settings['_multipart_id'];
     $multipart_counts = $settings['_multipart_counts'];
     pb_backupbuddy::status('details', 'S3 remote path set to `' . $remote_path . '`.');
     pb_backupbuddy::status('details', 'Loading S3 SDK library file...');
     require_once dirname(dirname(__FILE__)) . '/_s3lib/aws-sdk/sdk.class.php';
     pb_backupbuddy::status('details', 'S3 SDK file loaded.');
     // S3 API talk.
     $manage_data = pb_backupbuddy_destination_s3::get_credentials($settings);
     // Process multipart transfer that we already initiated in a previous PHP load.
     if ($multipart_id != '') {
         // Multipart upload initiated and needs parts sent.
         // Create S3 instance.
         pb_backupbuddy::status('details', 'Creating S3 instance.');
         $s3 = new AmazonS3($manage_data);
         // the key, secret, token
         if ($disable_ssl === true) {
             @$s3->disable_ssl(true);
         }
         pb_backupbuddy::status('details', 'S3 instance created.');
         // Verify bucket exists; create if not. Also set region to the region bucket exists in.
         if (false === self::_prepareBucketAndRegion($s3, $settings)) {
             global $pb_backupbuddy_destination_errors;
             $pb_backupbuddy_destination_errors[] = 'Could not prepare bucket.';
             return false;
         }
         $this_part_number = $settings['_multipart_partnumber'] + 1;
         pb_backupbuddy::status('details', 'S3 beginning upload of part `' . $this_part_number . '` of `' . count($settings['_multipart_counts']) . '` parts of file `' . $settings['_multipart_file'] . '` to remote location `' . $settings['_multipart_remotefile'] . '` with multipart ID `' . $settings['_multipart_id'] . '`.');
         $response = $s3->upload_part($manage_data['bucket'], $settings['_multipart_remotefile'], $settings['_multipart_id'], array('expect' => '100-continue', 'fileUpload' => $settings['_multipart_file'], 'partNumber' => $this_part_number, 'seekTo' => (int) $settings['_multipart_counts'][$settings['_multipart_partnumber']]['seekTo'], 'length' => (int) $settings['_multipart_counts'][$settings['_multipart_partnumber']]['length']));
         if (!$response->isOK()) {
             $this_error = 'S3 unable to upload file part for multipart upload `' . $settings['_multipart_id'] . '`. Details: `' . print_r($response, true) . '`.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         } else {
             // Send success.
             pb_backupbuddy::status('details', 'Success sending chunk. Upload details: `' . print_r($response, true) . '`.');
             $uploaded_size = $response->header['_info']['size_upload'];
             $uploaded_speed = $response->header['_info']['speed_upload'];
             pb_backupbuddy::status('details', 'Uploaded size: ' . pb_backupbuddy::$format->file_size($uploaded_size) . ', Speed: ' . pb_backupbuddy::$format->file_size($uploaded_speed) . '/sec.');
         }
         // Load fileoptions to the send.
         pb_backupbuddy::status('details', 'About to load fileoptions data.');
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         pb_backupbuddy::status('details', 'Fileoptions instance #10.');
         $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
         if (true !== ($result = $fileoptions_obj->is_ok())) {
             pb_backupbuddy::status('error', __('Fatal Error #9034.2344848. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
             global $pb_backupbuddy_destination_errors;
             $pb_backupbuddy_destination_errors[] = '#9034.2344848';
             return false;
         }
         pb_backupbuddy::status('details', 'Fileoptions data loaded.');
         $fileoptions =& $fileoptions_obj->options;
         $update_status = 'Sent part ' . $this_part_number . ' of ' . count($settings['_multipart_counts']) . '.';
         // Made it here so success sending part. Increment for next part to send.
         $settings['_multipart_partnumber']++;
         if (!isset($settings['_multipart_counts'][$settings['_multipart_partnumber']])) {
             // No more parts exist for this file. Tell S3 the multipart upload is complete and move on.
             pb_backupbuddy::status('details', 'S3 getting parts with etags to notify S3 of completed multipart send.');
             $etag_parts = $s3->list_parts($manage_data['bucket'], $settings['_multipart_remotefile'], $settings['_multipart_id']);
             pb_backupbuddy::status('details', 'S3 got parts list. Details: ' . print_r($etag_parts, true));
             pb_backupbuddy::status('details', 'Notifying S3 of multipart upload completion.');
             $response = $s3->complete_multipart_upload($manage_data['bucket'], $settings['_multipart_remotefile'], $settings['_multipart_id'], $etag_parts);
             if (!$response->isOK()) {
                 $this_error = 'S3 unable to notify S3 of completion of all parts for multipart upload `' . $settings['_multipart_id'] . '`.';
                 global $pb_backupbuddy_destination_errors;
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             } else {
                 pb_backupbuddy::status('details', 'S3 notified S3 of multipart completion.');
             }
             pb_backupbuddy::status('details', 'S3 has no more parts left for this multipart upload. Clearing multipart instance variables.');
             $settings['_multipart_partnumber'] = 0;
             $settings['_multipart_id'] = '';
             $settings['_multipart_file'] = '';
             $settings['_multipart_remotefile'] = '';
             // Multipart completed so safe to prevent housekeeping of incomplete multipart uploads.
             $settings['_multipart_transferspeeds'][] = $uploaded_speed;
             // Overall upload speed average.
             $uploaded_speed = array_sum($settings['_multipart_transferspeeds']) / count($settings['_multipart_counts']);
             pb_backupbuddy::status('details', 'Upload speed average of all chunks: `' . pb_backupbuddy::$format->file_size($uploaded_speed) . '`.');
             $settings['_multipart_counts'] = array();
             // Update stats.
             $fileoptions['_multipart_status'] = $update_status;
             $fileoptions['finish_time'] = time();
             $fileoptions['status'] = 'success';
             if (isset($uploaded_speed)) {
                 $fileoptions['write_speed'] = $uploaded_speed;
             }
             $fileoptions_obj->save();
             unset($fileoptions);
         }
         // Schedule to continue if anything is left to upload for this multipart of any individual files.
         if ($settings['_multipart_id'] != '' || count($files) > 0) {
             pb_backupbuddy::status('details', 'S3 multipart upload has more parts left. Scheduling next part send.');
             $cronTime = time();
             $cronArgs = array($settings, $files, $send_id, $delete_after);
             $cronHashID = md5($cronTime . serialize($cronArgs));
             $cronArgs[] = $cronHashID;
             $schedule_result = backupbuddy_core::schedule_single_event($cronTime, pb_backupbuddy::cron_tag('destination_send'), $cronArgs);
             if (true === $schedule_result) {
                 pb_backupbuddy::status('details', 'Next S3 chunk step cron event scheduled.');
             } else {
                 pb_backupbuddy::status('error', 'Next S3 chunk step cron even FAILED to be scheduled.');
             }
             spawn_cron(time() + 150);
             // Adds > 60 seconds to get around once per minute cron running limit.
             update_option('_transient_doing_cron', 0);
             // Prevent cron-blocking for next item.
             return array($settings['_multipart_id'], 'Sent part ' . $this_part_number . ' of ' . count($settings['_multipart_counts']) . ' parts.');
         }
     }
     // end if multipart continuation.
     require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
     // Upload each file.
     foreach ($files as $file_id => $file) {
         // Determine backup type directory (if zip).
         $backup_type_dir = '';
         $backup_type = '';
         if (stristr($file, '.zip') !== false) {
             // If a zip try to determine backup type.
             pb_backupbuddy::status('details', 'S3: Zip file. Detecting backup type if possible.');
             $serial = backupbuddy_core::get_serial_from_file($file);
             // See if we can get backup type from fileoptions data.
             pb_backupbuddy::status('details', 'Fileoptions instance #9.');
             $backup_options = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt', $read_only = true, $ignore_lock = true);
             if (true !== ($result = $backup_options->is_ok())) {
                 pb_backupbuddy::status('error', 'Unable to open fileoptions file `' . backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt' . '`.');
             } else {
                 if (isset($backup_options->options['integrity']['detected_type'])) {
                     pb_backupbuddy::status('details', 'S3: Detected backup type as `' . $backup_options->options['integrity']['detected_type'] . '` via integrity check data.');
                     //$backup_type_dir = $backup_options->options['integrity']['detected_type'] . '/';
                     $backup_type = $backup_options->options['integrity']['detected_type'];
                 }
             }
             // If still do not know backup type then attempt to deduce it from filename.
             if ($backup_type == '') {
                 if (stristr($file, '-db-') !== false) {
                     pb_backupbuddy::status('details', 'S3: Detected backup type as `db` via filename.');
                     //$backup_type_dir = 'db/';
                     $backup_type = 'db';
                 } elseif (stristr($file, '-full-') !== false) {
                     pb_backupbuddy::status('details', 'S3: Detected backup type as `full` via filename.');
                     //$backup_type_dir = 'full/';
                     $backup_type = 'full';
                 } else {
                     pb_backupbuddy::status('details', 'S3: Could not detect backup type via integrity details nor filename.');
                 }
             }
         }
         $credentials = pb_backupbuddy_destination_s3::get_credentials($settings);
         // Create S3 instance.
         pb_backupbuddy::status('details', 'Creating S3 instance.');
         $s3 = new AmazonS3($credentials);
         // the key, secret, token
         if ($disable_ssl === true) {
             @$s3->disable_ssl(true);
         }
         pb_backupbuddy::status('details', 'S3 instance created.');
         // Verify bucket exists; create if not. Also set region to the region bucket exists in.
         if (false === self::_prepareBucketAndRegion($s3, $settings)) {
             global $pb_backupbuddy_destination_errors;
             $pb_backupbuddy_destination_errors[] = 'Could not prepare bucket.';
             return false;
         }
         // Handle chunking of file into a multipart upload (if applicable).
         $file_size = filesize($file);
         if ($max_chunk_size >= self::MINIMUM_CHUNK_SIZE && $file_size / 1024 / 1024 > $max_chunk_size) {
             // minimum chunk size is 5mb. Anything under 5mb we will not chunk.
             // About to chunk so cleanup any previous hanging multipart transfers.
             self::multipart_cleanup($settings, $lessLogs = false);
             pb_backupbuddy::status('details', 'S3 file size of ' . pb_backupbuddy::$format->file_size($file_size) . ' exceeds max chunk size of ' . $max_chunk_size . 'MB set in settings for sending file as multipart upload.');
             // Initiate multipart upload with S3.
             pb_backupbuddy::status('details', 'Initiating S3 multipart upload.');
             $response = $s3->initiate_multipart_upload($settings['bucket'], $remote_path . $backup_type_dir . basename($file), array('encryption' => 'AES256'));
             if (!$response->isOK()) {
                 $this_error = 'S3 was unable to initiate multipart upload.';
                 global $pb_backupbuddy_destination_errors;
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             } else {
                 $upload_id = (string) $response->body->UploadId;
                 pb_backupbuddy::status('details', 'S3 initiated multipart upload with ID `' . $upload_id . '`.');
             }
             // Get chunk parts for multipart transfer.
             pb_backupbuddy::status('details', 'S3 getting multipart counts.');
             $parts = $s3->get_multipart_counts($file_size, $max_chunk_size * 1024 * 1024);
             // Size of chunks expected to be in bytes.
             $multipart_destination_settings = $settings;
             $multipart_destination_settings['_multipart_id'] = $upload_id;
             $multipart_destination_settings['_multipart_partnumber'] = 0;
             $multipart_destination_settings['_multipart_file'] = $file;
             $multipart_destination_settings['_multipart_remotefile'] = $remote_path . basename($file);
             $multipart_destination_settings['_multipart_counts'] = $parts;
             pb_backupbuddy::status('details', 'S3 multipart settings to pass:'******'details', 'S3 scheduling send of next part(s).');
             $cronTime = time();
             $cronArgs = array($multipart_destination_settings, $files, $send_id, $delete_after);
             $cronHashID = md5($cronTime . serialize($cronArgs));
             $cronArgs[] = $cronHashID;
             backupbuddy_core::schedule_single_event($cronTime, pb_backupbuddy::cron_tag('destination_send'), $cronArgs);
             spawn_cron(time() + 150);
             // Adds > 60 seconds to get around once per minute cron running limit.
             update_option('_transient_doing_cron', 0);
             // Prevent cron-blocking for next item.
             pb_backupbuddy::status('details', 'S3 scheduled send of next part(s). Done for this cycle.');
             return array($upload_id, 'Starting send of ' . count($multipart_destination_settings['_multipart_counts']) . ' parts.');
         } else {
             // did not meet chunking criteria.
             if ($max_chunk_size != '0') {
                 if ($file_size / 1024 / 1024 > self::MINIMUM_CHUNK_SIZE) {
                     pb_backupbuddy::status('details', 'File size of ' . pb_backupbuddy::$format->file_size($file_size) . ' is less than the max chunk size of ' . $max_chunk_size . 'MB; not chunking into multipart upload.');
                 } else {
                     pb_backupbuddy::status('details', 'File size of ' . pb_backupbuddy::$format->file_size($file_size) . ' is less than the minimum allowed chunk size of ' . self::MINIMUM_CHUNK_SIZE . 'MB; not chunking into multipart upload.');
                 }
             } else {
                 pb_backupbuddy::status('details', 'Max chunk size set to zero so not chunking into multipart upload.');
             }
         }
         // SEND file.
         if ('standard' == $settings['storage']) {
             $storageVal = AmazonS3::STORAGE_STANDARD;
         } elseif ('reduced' == $settings['storage']) {
             $storageVal = AmazonS3::STORAGE_REDUCED;
         } else {
             pb_backupbuddy::status('error', 'Error #854784: Unknown S3 storage type: `' . $settings['storage'] . '`.');
         }
         pb_backupbuddy::status('details', 'About to put (upload) object to S3: `' . $remote_path . $backup_type_dir . basename($file) . '`. Storage type: `' . $settings['storage'] . ' (' . $storageVal . ')`.');
         $response = $s3->create_object($settings['bucket'], $remote_path . $backup_type_dir . basename($file), array('fileUpload' => $file, 'encryption' => 'AES256', 'storage' => $storageVal));
         unset($storageVal);
         // Validate response. On failure notify S3 API that things went wrong.
         if (!$response->isOK()) {
             // Send FAILED.
             $this_error = 'Failure uploading file to S3 storage. Failure details: `' . print_r($response, true) . '`';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         } else {
             // Send SUCCESS.
             pb_backupbuddy::status('details', 'Success uploading file to S3 storage. Upload details: `' . print_r($response, true) . '`.');
             $uploaded_size = $response->header['_info']['size_upload'];
             $uploaded_speed = $response->header['_info']['speed_upload'];
             pb_backupbuddy::status('details', 'Uploaded size: ' . pb_backupbuddy::$format->file_size($uploaded_size) . ', Speed: ' . pb_backupbuddy::$format->file_size($uploaded_speed) . '/sec.');
         }
         unset($files[$file_id]);
         // Remove from list of files we have not sent yet.
         pb_backupbuddy::status('details', 'S3 success sending file `' . basename($file) . '`. File uploaded and reported to S3 as completed.');
         // Load destination fileoptions.
         pb_backupbuddy::status('details', 'About to load fileoptions data.');
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         pb_backupbuddy::status('details', 'Fileoptions instance #8.');
         $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
         if (true !== ($result = $fileoptions_obj->is_ok())) {
             pb_backupbuddy::status('error', __('Fatal Error #9034.84838. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
             global $pb_backupbuddy_destination_errors;
             $pb_backupbuddy_destination_errors[] = '#9034.84838';
             return false;
         }
         pb_backupbuddy::status('details', 'Fileoptions data loaded.');
         $fileoptions =& $fileoptions_obj->options;
         // Save stats.
         if (isset($uploaded_speed)) {
             $fileoptions['write_speed'] = $uploaded_speed;
             $fileoptions_obj->save();
         }
         unset($fileoptions_obj);
     }
     // end foreach.
     // BEGIN backup limits.
     if ($limit > 0) {
         pb_backupbuddy::status('details', 'S3 archive limit enforcement to `' . $limit . '` archives beginning.');
         // S3 object for managing files.
         $s3_manage = new AmazonS3($manage_data);
         if ($disable_ssl === true) {
             @$s3_manage->disable_ssl(true);
         }
         if (false === self::_prepareBucketAndRegion($s3_manage, $settings)) {
             global $pb_backupbuddy_destination_errors;
             $pb_backupbuddy_destination_errors[] = 'Could not prepare bucket.';
             return false;
         }
         // Get file listing.
         $response_manage = $s3_manage->list_objects($manage_data['bucket'], array('prefix' => $remote_path . $backup_type_dir));
         // list all the files in the subscriber account
         // Create array of backups and organize by date
         $prefix = backupbuddy_core::backup_prefix();
         // List backups associated with this site by date.
         $backups = array();
         foreach ($response_manage->body->Contents as $object) {
             $file = str_replace($remote_path . $backup_type_dir, '', $object->Key);
             if (FALSE !== stristr($file, '/')) {
                 // CRITICAL CODE! Subdir found due to slash. Do NOT display any files within a deeper subdirectory. Without this files could be deleted not belonging to this destination!
                 continue;
             }
             if (!preg_match(self::BACKUP_FILENAME_PATTERN, $file)) {
                 // CRITICAL CODE! Safety against accidental deletion of non-BB files. Do NOT delete files that do not look like a BackupBuddy backup filename.
                 continue;
             }
             if (FALSE === strpos($file, 'backup-' . $prefix . '-')) {
                 // Not a backup for THIS site. Skip interacting with for limits.
                 continue;
             }
             // S3 stores files in a directory per site so no need to check prefix here! if ( false !== strpos( $file, 'backup-' . $prefix . '-' ) ) { // if backup has this site prefix...
             $backups[$file] = strtotime($object->LastModified);
         }
         arsort($backups);
         pb_backupbuddy::status('details', 'S3 found `' . count($backups) . '` backups when checking archive limits.');
         if (count($backups) > $limit) {
             pb_backupbuddy::status('details', 'More archives (' . count($backups) . ') than limit (' . $limit . ') allows. Trimming...');
             $i = 0;
             $delete_fail_count = 0;
             foreach ($backups as $buname => $butime) {
                 $i++;
                 if ($i > $limit) {
                     pb_backupbuddy::status('details', 'Trimming excess file `' . $buname . '`...');
                     $response = $s3_manage->delete_object($manage_data['bucket'], $remote_path . $backup_type_dir . $buname);
                     if (!$response->isOK()) {
                         pb_backupbuddy::status('details', 'Unable to delete excess S3 file `' . $buname . '`. Details: `' . print_r($response, true) . '`.');
                         $delete_fail_count++;
                     }
                 }
             }
             pb_backupbuddy::status('details', 'Finished trimming excess backups.');
             if ($delete_fail_count !== 0) {
                 $error_message = 'S3 remote limit could not delete ' . $delete_fail_count . ' backups.';
                 pb_backupbuddy::status('error', $error_message);
                 backupbuddy_core::mail_error($error_message);
             }
         }
         pb_backupbuddy::status('details', 'S3 completed archive limiting.');
     } else {
         pb_backupbuddy::status('details', 'No S3 archive file limit to enforce.');
     }
     // End remote backup limit
     // END backup limits.
     if (isset($fileoptions_obj)) {
         unset($fileoptions_obj);
     }
     // Success if we made it this far.
     return true;
 }
Пример #17
0
 public static function restore($archive_file, $files, $finalPath, &$zipbuddy = null)
 {
     if (!current_user_can(pb_backupbuddy::$options['role_access'])) {
         die('Error #473623. Access Denied.');
     }
     $serial = backupbuddy_core::get_serial_from_file($archive_file);
     // serial of archive.
     $success = false;
     foreach ($files as $file) {
         $file = str_replace('*', '', $file);
         // Remove any wildcard.
         if (file_exists($finalPath . $file) && is_dir($finalPath . $file)) {
             if (($file_count = @scandir($finalPath . $file)) && count($file_count) > 2) {
                 pb_backupbuddy::status('error', __('Error #9036. The destination directory being restored already exists and is NOT empty. The directory will not be restored to prevent inadvertently losing files within the existing directory. Delete existing directory first if you wish to proceed or restore individual files.', 'it-l10n-backupbuddy') . ' Existing directory: `' . $finalPath . $file . '`.');
                 return false;
             }
         }
     }
     if (null === $zipbuddy) {
         require_once pb_backupbuddy::plugin_path() . '/lib/zipbuddy/zipbuddy.php';
         $zipbuddy = new pluginbuddy_zipbuddy(backupbuddy_core::getBackupDirectory());
     }
     // Calculate temp directory & lock it down.
     $temp_dir = get_temp_dir();
     $destination = $temp_dir . 'backupbuddy-' . $serial;
     if (!file_exists($destination) && false === mkdir($destination, 0777, true)) {
         $error = 'Error #458485945: Unable to create temporary location.';
         pb_backupbuddy::status('error', $error);
         return false;
     }
     // If temp directory is within webroot then lock it down.
     $temp_dir = str_replace('\\', '/', $temp_dir);
     // Normalize for Windows.
     $temp_dir = rtrim($temp_dir, '/\\') . '/';
     // Enforce single trailing slash.
     if (FALSE !== stristr($temp_dir, ABSPATH)) {
         // Temp dir is within webroot.
         pb_backupbuddy::anti_directory_browsing($destination);
     }
     unset($temp_dir);
     pb_backupbuddy::status('details', 'Extracting into temporary directory "' . $destination . '".');
     $prettyFilesList = array();
     foreach ($files as $fileSource => $fileDestination) {
         $prettyFilesList[] = $fileSource . ' => ' . $fileDestination;
     }
     pb_backupbuddy::status('details', 'Files to extract: `' . htmlentities(implode(', ', $prettyFilesList)) . '`.');
     unset($prettyFilesList);
     pb_backupbuddy::flush();
     // Do the actual extraction.
     $extract_success = true;
     if (false === $zipbuddy->extract($archive_file, $destination, $files)) {
         pb_backupbuddy::status('error', 'Error #584984458b. Unable to extract.');
         $extract_success = false;
     }
     if (true === $extract_success) {
         // Verify all files/directories to be extracted exist in temp destination directory. If any missing then delete everything and bail out.
         foreach ($files as &$file) {
             $file = str_replace('*', '', $file);
             // Remove any wildcard.
             if (!file_exists($destination . '/' . $file)) {
                 // Cleanup.
                 foreach ($files as $file) {
                     @trigger_error('');
                     // Clear out last error.
                     @unlink($destination . '/' . $file);
                     $last_error = error_get_last();
                     if (is_array($last_error)) {
                         pb_backupbuddy::status('error', $last_error['message'] . ' File: `' . $last_error['file'] . '`. Line: `' . $last_error['line'] . '`.');
                     }
                 }
                 pb_backupbuddy::status('error', 'Error #854783474. One or more expected files / directories missing.');
                 $extract_success = false;
                 break;
             }
         }
         unset($file);
         // Made it this far so files all exist. Move them all.
         foreach ($files as $file) {
             @trigger_error('');
             // Clear out last error.
             if (false === @rename($destination . '/' . $file, $finalPath . $file)) {
                 $last_error = error_get_last();
                 if (is_array($last_error)) {
                     //print_r( $last_error );
                     pb_backupbuddy::status('error', $last_error['message'] . ' File: `' . $last_error['file'] . '`. Line: `' . $last_error['line'] . '`.');
                 }
                 $error = 'Error #9035. Unable to move restored file `' . $destination . '/' . $file . '` to `' . $finalPath . $file . '`. Verify permissions on destination location & that the destination directory/file does not already exist.';
                 pb_backupbuddy::status('error', $error);
             } else {
                 $details = 'Moved `' . $destination . '/' . $file . '` to `' . $finalPath . $file . '`.<br>';
                 pb_backupbuddy::status('details', $details);
                 $success = true;
             }
         }
     }
     // end extract success.
     // Try to cleanup.
     if (file_exists($destination)) {
         if (false === pb_backupbuddy::$filesystem->unlink_recursive($destination)) {
             pb_backupbuddy::status('details', 'Unable to delete temporary holding directory `' . $destination . '`.');
         } else {
             pb_backupbuddy::status('details', 'Cleaned up temporary files.');
         }
     }
     if (true === $success) {
         pb_backupbuddy::status('message', 'File retrieval completed successfully.');
         return true;
     } else {
         return false;
     }
 }
Пример #18
0
 public function deploy_pull_renderImportBuddy($state)
 {
     if (!file_exists($state['pullLocalArchiveFile'])) {
         pb_backupbuddy::status('error', 'Error #32783732: Backup file `' . $state['pullLocalArchiveFile'] . '` not found.');
         return false;
     }
     $backupSerial = backupbuddy_core::get_serial_from_file($state['pullLocalArchiveFile']);
     $importbuddyPassword = md5(md5($state['destination']['key_public']));
     $siteurl = site_url();
     $additionalStateInfo = array();
     $importFileSerial = backupbuddy_core::deploymentImportBuddy($importbuddyPassword, $state['pullLocalArchiveFile'], $additionalStateInfo);
     if (is_array($importFileSerial)) {
         // Could not generate importbuddy file.
         return false;
     }
     // Store this serial in settings to cleanup any temp db tables in the future with this serial with periodic cleanup.
     pb_backupbuddy::$options['rollback_cleanups'][$backupSerial] = time();
     pb_backupbuddy::save();
     // Create undo file.
     $undoFile = 'backupbuddy_deploy_undo-' . $backupSerial . '.php';
     if (false === copy(pb_backupbuddy::plugin_path() . '/classes/_rollback_undo.php', ABSPATH . $undoFile)) {
         $error = 'Error #3289447: Unable to write undo file `' . ABSPATH . $undoFile . '`. Check permissions on directory.';
         pb_backupbuddy::status('error', $error);
         return false;
     }
     // Start pulling importbuddy log.
     $importbuddyURLRoot = $siteurl . '/importbuddy-' . $importFileSerial . '.php';
     $importbuddyLogURL = $importbuddyURLRoot . '?ajax=getDeployLog&v=' . $importbuddyPassword . '&deploy=true';
     //$state['destination']['siteurl'] . '/importbuddy/'?ajax=2&v=' . $importbuddyPassword . '&deploy=true; //status-' . $response['importFileSerial'] . '.txt';
     $importbuddyURL = $importbuddyURLRoot . '?ajax=2&v=' . $importbuddyPassword . '&deploy=true&direction=pull&file=' . basename($state['pullLocalArchiveFile']);
     pb_backupbuddy::status('details', 'Load importbuddy at `' . $importbuddyURLRoot . '` with verifier `' . $importbuddyPassword . '`.');
     pb_backupbuddy::status('loadImportBuddy', json_encode(array('url' => $importbuddyURL, 'logurl' => $importbuddyLogURL)));
     // Calculate undo URL.
     $undoDeployURL = $siteurl . '/backupbuddy_deploy_undo-' . $this->_backup['serial'] . '.php';
     pb_backupbuddy::status('details', 'To undo deployment of database contents go to the URL: ' . $undoDeployURL);
     pb_backupbuddy::status('undoDeployURL', $undoDeployURL);
     // Pull importbuddy log instead of remote backup log. Nothing else is going to be done on remote server.
     $this->_backup_options->options['deployment_log'] = $importbuddyLogURL;
     $this->_backup_options->save();
     // Next step.
     pb_backupbuddy::status('details', 'Inserting deploy step to run importbuddy steps on remote server.');
     $newStep = array('function' => 'deploy_runningImportBuddy', 'args' => array($state), 'start_time' => 0, 'finish_time' => 0, 'attempts' => 0);
     $this->insert_next_step($newStep);
     return true;
 }
Пример #19
0
                 pb_backupbuddy::status('error', 'Unable to delete orphaned fileoptions file `' . $file . '`.');
             }
             if (file_exists($file . '.lock')) {
                 @unlink($file . '.lock');
             }
         } else {
             // Do not delete orphaned fileoptions because it is not old enough. Recent backups page needs these to list the backup.
         }
     } else {
         // Backup ZIP file exists.
     }
 } else {
     // No archive_file key in fileoptions array.
     // Trim any fileoptions files that are orphaned (no matching backup zip file). Note that above we trim these files that have the archive_file key in them.
     $backupDir = backupbuddy_core::getBackupDirectory();
     $serial = backupbuddy_core::get_serial_from_file('-' . basename($file));
     // Dash needed to trick get_serial_from_file() into thinking this is a valid backup filename.
     $backupFiles = glob($backupDir . '*' . $serial . '*.zip');
     // Try to find a matching backup zip with this serial in its filename.
     if (!is_array($backupFiles)) {
         $backupFiles = array();
     }
     if (0 == count($backupFiles)) {
         // No corresponding backup. Delete file.
         $modified = filemtime($file);
         if (time() - $modified > backupbuddy_constants::MAX_SECONDS_TO_KEEP_ORPHANED_FILEOPTIONS_FILES) {
             // Too many days old so delete.
             if (false === unlink($file)) {
                 pb_backupbuddy::status('error', 'Unable to delete orphaned fileoptions file `' . $file . '`.');
             }
             if (file_exists($file . '.lock')) {
Пример #20
0
function cleanup($restoreData)
{
    if (true !== $restoreData['cleanup']['deleteArchive']) {
        pb_backupbuddy::status('details', 'Skipped deleting backup archive.');
    } else {
        remove_file($restoreData['archive'], 'backup .ZIP file (' . $restoreData['archive'] . ')', true);
    }
    if (true !== $restoreData['cleanup']['deleteTempFiles']) {
        pb_backupbuddy::status('details', 'Skipped deleting temporary files.');
    } else {
        // Full backup .sql file
        remove_file(ABSPATH . 'wp-content/uploads/temp_' . $restoreData['serial'] . '/db.sql', 'db.sql (backup database dump)', false);
        remove_file(ABSPATH . 'wp-content/uploads/temp_' . $restoreData['serial'] . '/db_1.sql', 'db_1.sql (backup database dump)', false);
        remove_file(ABSPATH . 'wp-content/uploads/backupbuddy_temp/' . $restoreData['serial'] . '/db_1.sql', 'db_1.sql (backup database dump)', false);
        // DB only sql file
        remove_file(ABSPATH . 'db.sql', 'db.sql (backup database dump)', false);
        remove_file(ABSPATH . 'db_1.sql', 'db_1.sql (backup database dump)', false);
        // Full backup dat file
        remove_file(ABSPATH . 'wp-content/uploads/temp_' . $restoreData['serial'] . '/backupbuddy_dat.php', 'backupbuddy_dat.php (backup data file)', false);
        remove_file(ABSPATH . 'wp-content/uploads/backupbuddy_temp/' . $restoreData['serial'] . '/backupbuddy_dat.php', 'backupbuddy_dat.php (backup data file)', false);
        // DB only dat file
        remove_file(ABSPATH . 'backupbuddy_dat.php', 'backupbuddy_dat.php (backup data file)', false);
        remove_file(ABSPATH . 'wp-content/uploads/backupbuddy_temp/' . $restoreData['serial'] . '/', 'Temporary backup directory', false);
        // Temp restore dir.
        remove_file(ABSPATH . 'importbuddy/temp_' . $restoreData['serial'] . '/', 'Temporary restore directory', false);
        remove_file(ABSPATH . 'importbuddy/', 'ImportBuddy Directory', true);
        remove_file(ABSPATH . 'importbuddy/_settings_dat.php', '_settings_dat.php (temporary settings file)', false);
        // Remove state file (deployment/default settings).
        global $importbuddy_file;
        $importFileSerial = backupbuddy_core::get_serial_from_file($importbuddy_file);
        $state_file = ABSPATH . 'importbuddy-' . $importFileSerial . '-state.php';
        remove_file($state_file, 'Default state data file', false);
    }
    if (true !== $restoreData['cleanup']['deleteImportBuddy']) {
        pb_backupbuddy::status('details', 'Skipped deleting ' . $importbuddy_file . ' (this script).');
    } else {
        global $importbuddy_file;
        remove_file(ABSPATH . $importbuddy_file, $importbuddy_file . ' (this script)', true);
    }
    // Delete log file last.
    if (true !== $restoreData['cleanup']['deleteImportLog']) {
        pb_backupbuddy::status('details', 'Skipped deleting import log.');
    } else {
        remove_file('importbuddy-' . pb_backupbuddy::$options['log_serial'] . '.txt', 'importbuddy-' . pb_backupbuddy::$options['log_serial'] . '.txt log file', true);
    }
}
Пример #21
0
 public static function send($settings = array(), $files = array(), $send_id = '', $clear_uploads = false)
 {
     global $pb_backupbuddy_destination_errors;
     if (!is_array($files)) {
         $files = array($files);
     }
     if ($clear_uploads === false) {
         // Uncomment the following line to override and always clear.
         //$clear_uploads = true;
     }
     $itxapi_username = $settings['itxapi_username'];
     $itxapi_password = $settings['itxapi_password'];
     $db_archive_limit = $settings['db_archive_limit'];
     $full_archive_limit = $settings['full_archive_limit'];
     $files_archive_limit = $settings['files_archive_limit'];
     $max_chunk_size = $settings['max_chunk_size'];
     $remote_path = self::get_remote_path($settings['directory']);
     // Has leading and trailng slashes.
     if ($settings['ssl'] == '0') {
         $disable_ssl = true;
     } else {
         $disable_ssl = false;
     }
     $multipart_id = $settings['_multipart_id'];
     $multipart_counts = $settings['_multipart_counts'];
     pb_backupbuddy::status('details', 'Stash remote path set to `' . $remote_path . '`.');
     require_once dirname(__FILE__) . '/lib/class.itx_helper.php';
     require_once dirname(dirname(__FILE__)) . '/_s3lib/aws-sdk/sdk.class.php';
     // Stash API talk.
     $stash = new ITXAPI_Helper(pb_backupbuddy_destination_stash::ITXAPI_KEY, pb_backupbuddy_destination_stash::ITXAPI_URL, $itxapi_username, $itxapi_password);
     $manage_data = pb_backupbuddy_destination_stash::get_manage_data($settings);
     if (!is_array($manage_data['credentials'])) {
         pb_backupbuddy::status('error', 'Error #8484383b: Your authentication credentials for Stash failed. Verify your login and password to Stash. You may need to update the Stash destination settings. Perhaps you recently changed your password?');
         return false;
     }
     // Wipe all current uploads.
     if ($clear_uploads === true) {
         pb_backupbuddy::status('details', 'Clearing any current uploads via Stash call to `abort-all`.');
         $abort_url = $stash->get_upload_url(null, 'abort-all');
         $request = new RequestCore($abort_url);
         $response = $request->send_request(true);
     }
     // Process multipart transfer that we already initiated in a previous PHP load.
     if ($multipart_id != '') {
         // Multipart upload initiated and needs parts sent.
         // Create S3 instance.
         pb_backupbuddy::status('details', 'Creating Stash S3 instance.');
         $s3 = new AmazonS3($settings['_multipart_upload_data']['credentials']);
         // the key, secret, token
         if ($disable_ssl === true) {
             @$s3->disable_ssl(true);
         }
         pb_backupbuddy::status('details', 'Stash S3 instance created.');
         $backup_type = str_replace('/', '', $settings['_multipart_backup_type_dir']);
         // For use later by file limiting.
         $this_part_number = $settings['_multipart_partnumber'] + 1;
         pb_backupbuddy::status('details', 'Stash beginning upload of part `' . $this_part_number . '` of `' . count($settings['_multipart_counts']) . '` parts of file `' . $settings['_multipart_file'] . '` with multipart ID `' . $settings['_multipart_id'] . '`.');
         $response = $s3->upload_part($settings['_multipart_upload_data']['bucket'], $settings['_multipart_upload_data']['object'], $settings['_multipart_id'], array('expect' => '100-continue', 'fileUpload' => $settings['_multipart_file'], 'partNumber' => $this_part_number, 'seekTo' => (int) $settings['_multipart_counts'][$settings['_multipart_partnumber']]['seekTo'], 'length' => (int) $settings['_multipart_counts'][$settings['_multipart_partnumber']]['length']));
         if (!$response->isOK()) {
             $this_error = 'Stash unable to upload file part for multipart upload `' . $settings['_multipart_id'] . '`. Details: `' . print_r($response, true) . '`.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         } else {
             $uploaded_size = $response->header['_info']['size_upload'];
             $uploaded_speed = $response->header['_info']['speed_upload'];
             pb_backupbuddy::status('details', 'Uploaded size: ' . pb_backupbuddy::$format->file_size($uploaded_size) . ', Speed: ' . pb_backupbuddy::$format->file_size($uploaded_speed) . '/sec.');
         }
         // Load fileoptions to the send.
         pb_backupbuddy::status('details', 'About to load fileoptions data.');
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
         if (true !== ($result = $fileoptions_obj->is_ok())) {
             pb_backupbuddy::status('error', __('Fatal Error #9034.2344848. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
             return false;
         }
         pb_backupbuddy::status('details', 'Fileoptions data loaded.');
         $fileoptions =& $fileoptions_obj->options;
         $update_status = 'Sent part ' . $this_part_number . ' of ' . count($settings['_multipart_counts']) . '.';
         // Made it here so success sending part. Increment for next part to send.
         $settings['_multipart_partnumber']++;
         if (!isset($settings['_multipart_counts'][$settings['_multipart_partnumber']])) {
             // No more parts exist for this file. Tell S3 the multipart upload is complete and move on.
             pb_backupbuddy::status('details', 'Stash getting parts with etags to notify S3 of completed multipart send.');
             $etag_parts = $s3->list_parts($settings['_multipart_upload_data']['bucket'], $settings['_multipart_upload_data']['object'], $settings['_multipart_id']);
             pb_backupbuddy::status('details', 'Stash got parts list. Notifying S3 of multipart upload completion.');
             $response = $s3->complete_multipart_upload($settings['_multipart_upload_data']['bucket'], $settings['_multipart_upload_data']['object'], $settings['_multipart_id'], $etag_parts);
             if (!$response->isOK()) {
                 $this_error = 'Stash unable to notify S3 of completion of all parts for multipart upload `' . $settings['_multipart_id'] . '`.';
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             } else {
                 pb_backupbuddy::status('details', 'Stash notified S3 of multipart completion.');
             }
             $backup_type_dir = $settings['_multipart_backup_type_dir'];
             // Notify Stash API that things were succesful.
             $done_url = $stash->get_upload_url($settings['_multipart_file'], 'done', $remote_path . $backup_type_dir . basename($settings['_multipart_file']));
             pb_backupbuddy::status('details', 'Notifying Stash of completed multipart upload with done url `' . $done_url . '`.');
             $request = new RequestCore($done_url);
             $response = $request->send_request(true);
             if (!$response->isOK()) {
                 $this_error = 'Error #756834682. Could not finalize Stash upload. Response code: `' . $response->get_response_code() . '`; Response body: `' . $response->get_response_body() . '`; Response headers: `' . $response->get_response_header() . '`.';
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             } else {
                 // Good server response.
                 // See if we got an optional json response.
                 $upload_data = @json_decode($response->body, true);
                 if (isset($upload_data['error'])) {
                     $this_error = 'Stash error(s): `' . implode(' - ', $upload_data['error']) . '`.';
                     $pb_backupbuddy_destination_errors[] = $this_error;
                     pb_backupbuddy::status('error', $this_error);
                     return false;
                 }
                 pb_backupbuddy::status('details', 'Stash success sending file `' . basename($settings['_multipart_file']) . '`. File uploaded via multipart across `' . $this_part_number . '` parts and reported to Stash as completed.');
             }
             pb_backupbuddy::status('details', 'Stash has no more parts left for this multipart upload. Clearing multipart instance variables.');
             $settings['_multipart_partnumber'] = 0;
             $settings['_multipart_id'] = '';
             $settings['_multipart_file'] = '';
             $settings['_multipart_upload_data'] = array();
             $settings['_multipart_transferspeeds'][] = $uploaded_speed;
             // Overall upload speed average.
             $uploaded_speed = array_sum($settings['_multipart_transferspeeds']) / count($settings['_multipart_counts']);
             pb_backupbuddy::status('details', 'Upload speed average of all chunks: `' . pb_backupbuddy::$format->file_size($uploaded_speed) . '`.');
             $settings['_multipart_counts'] = array();
             // Update stats.
             $fileoptions['_multipart_status'] = $update_status;
             $fileoptions['finish_time'] = time();
             $fileoptions['status'] = 'success';
             if (isset($uploaded_speed)) {
                 $fileoptions['write_speed'] = $uploaded_speed;
             }
             $fileoptions_obj->save();
             unset($fileoptions);
         }
         delete_transient('pb_backupbuddy_stashquota_' . $settings['itxapi_username']);
         // Delete quota transient since it probably has changed now.
         // Schedule to continue if anything is left to upload for this multipart of any individual files.
         if ($settings['_multipart_id'] != '' || count($files) > 0) {
             pb_backupbuddy::status('details', 'Stash multipart upload has more parts left. Scheduling next part send.');
             $schedule_result = backupbuddy_core::schedule_single_event(time(), pb_backupbuddy::cron_tag('destination_send'), array($settings, $files, $send_id));
             if (true === $schedule_result) {
                 pb_backupbuddy::status('details', 'Next Stash chunk step cron event scheduled.');
             } else {
                 pb_backupbuddy::status('error', 'Next Stash chunk step cron even FAILED to be scheduled.');
             }
             spawn_cron(time() + 150);
             // Adds > 60 seconds to get around once per minute cron running limit.
             update_option('_transient_doing_cron', 0);
             // Prevent cron-blocking for next item.
             return array($settings['_multipart_id'], 'Sent part ' . $this_part_number . ' of ' . count($settings['_multipart_counts']) . ' parts.');
         }
     }
     // end if multipart continuation.
     require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
     // Upload each file.
     foreach ($files as $file_id => $file) {
         // Determine backup type directory (if zip).
         $backup_type_dir = '';
         $backup_type = '';
         if (stristr($file, '.zip') !== false) {
             // If a zip try to determine backup type.
             pb_backupbuddy::status('details', 'Stash: Zip file. Detecting backup type if possible.');
             $serial = backupbuddy_core::get_serial_from_file($file);
             // See if we can get backup type from fileoptions data.
             $backup_options = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt', $read_only = true, $ignore_lock = true);
             if (true !== ($result = $backup_options->is_ok())) {
                 pb_backupbuddy::status('error', 'Unable to open fileoptions file `' . backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt' . '`.');
             } else {
                 if (isset($backup_options->options['integrity']['detected_type'])) {
                     pb_backupbuddy::status('details', 'Stash: Detected backup type as `' . $backup_options->options['integrity']['detected_type'] . '` via integrity check data.');
                     $backup_type_dir = $backup_options->options['integrity']['detected_type'] . '/';
                     $backup_type = $backup_options->options['integrity']['detected_type'];
                 }
             }
             // If still do not know backup type then attempt to deduce it from filename.
             if ($backup_type == '') {
                 if (stristr($file, '-db-') !== false) {
                     pb_backupbuddy::status('details', 'Stash: Detected backup type as `db` via filename.');
                     $backup_type_dir = 'db/';
                     $backup_type = 'db';
                 } elseif (stristr($file, '-full-') !== false) {
                     pb_backupbuddy::status('details', 'Stash: Detected backup type as `full` via filename.');
                     $backup_type_dir = 'full/';
                     $backup_type = 'full';
                 } elseif (stristr($file, '-files-') !== false) {
                     pb_backupbuddy::status('details', 'Stash: Detected backup type as `files` via filename.');
                     $backup_type_dir = 'files/';
                     $backup_type = 'files';
                 } else {
                     pb_backupbuddy::status('details', 'Stash: Could not detect backup type via integrity details nor filename.');
                 }
             }
         }
         // Interact with Stash API.
         pb_backupbuddy::status('details', 'Determining Stash upload URL for `' . $file . '`.` with destination remote path `' . $remote_path . $backup_type_dir . basename($file) . '`.');
         $upload_url = $stash->get_upload_url($file, 'request', $remote_path . $backup_type_dir . basename($file));
         pb_backupbuddy::status('details', 'Determined upload url: `' . $upload_url . '`.');
         $request = new RequestCore($upload_url);
         pb_backupbuddy::status('details', 'Sending Stash API request.');
         $response = $request->send_request(true);
         // Validate response.
         if (!$response->isOK()) {
             $this_error = 'Stash request for upload credentials failed.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         }
         if (!($upload_data = json_decode($response->body, true))) {
             $this_error = 'Stash API did not give a valid JSON response.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         }
         if (isset($upload_data['error'])) {
             $this_error = 'Stash error(s): `' . implode(' - ', $upload_data['error']) . '`.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         }
         // Create S3 instance.
         pb_backupbuddy::status('details', 'Creating Stash S3 instance.');
         $s3 = new AmazonS3($upload_data['credentials']);
         // the key, secret, token
         if ($disable_ssl === true) {
             @$s3->disable_ssl(true);
         }
         pb_backupbuddy::status('details', 'Stash S3 instance created.');
         // Handle chunking of file into a multipart upload (if applicable).
         $file_size = filesize($file);
         if ($max_chunk_size >= self::MINIMUM_CHUNK_SIZE && $file_size / 1024 / 1024 > $max_chunk_size) {
             // minimum chunk size is 5mb. Anything under 5mb we will not chunk.
             pb_backupbuddy::status('details', 'Stash file size of ' . pb_backupbuddy::$format->file_size($file_size) . ' exceeds max chunk size of ' . $max_chunk_size . 'MB set in settings for sending file as multipart upload.');
             // Initiate multipart upload with S3.
             pb_backupbuddy::status('details', 'Initiating Stash multipart upload.');
             $response = $s3->initiate_multipart_upload($upload_data['bucket'], $upload_data['object'], array('encryption' => 'AES256'));
             if (!$response->isOK()) {
                 $this_error = 'Stash was unable to initiate multipart upload.';
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             } else {
                 $upload_id = (string) $response->body->UploadId;
                 pb_backupbuddy::status('details', 'Stash initiated multipart upload with ID `' . $upload_id . '`.');
             }
             // Get chunk parts for multipart transfer.
             pb_backupbuddy::status('details', 'Stash getting multipart counts.');
             $parts = $s3->get_multipart_counts($file_size, $max_chunk_size * 1024 * 1024);
             // Size of chunks expected to be in bytes.
             $multipart_destination_settings = $settings;
             $multipart_destination_settings['_multipart_id'] = $upload_id;
             $multipart_destination_settings['_multipart_partnumber'] = 0;
             $multipart_destination_settings['_multipart_file'] = $file;
             $multipart_destination_settings['_multipart_counts'] = $parts;
             $multipart_destination_settings['_multipart_upload_data'] = $upload_data;
             $multipart_destination_settings['_multipart_backup_type_dir'] = $backup_type_dir;
             pb_backupbuddy::status('details', 'Stash multipart settings to pass:'******'details', 'Stash scheduling send of next part(s).');
             backupbuddy_core::schedule_single_event(time(), pb_backupbuddy::cron_tag('destination_send'), array($multipart_destination_settings, $files, $send_id));
             spawn_cron(time() + 150);
             // Adds > 60 seconds to get around once per minute cron running limit.
             update_option('_transient_doing_cron', 0);
             // Prevent cron-blocking for next item.
             pb_backupbuddy::status('details', 'Stash scheduled send of next part(s). Done for this cycle.');
             return array($upload_id, 'Starting send of ' . count($multipart_destination_settings['_multipart_counts']) . ' parts.');
         } else {
             // did not meet chunking criteria.
             if ($max_chunk_size != '0') {
                 if ($file_size / 1024 / 1024 > self::MINIMUM_CHUNK_SIZE) {
                     pb_backupbuddy::status('details', 'File size of ' . pb_backupbuddy::$format->file_size($file_size) . ' is less than the max chunk size of ' . $max_chunk_size . 'MB; not chunking into multipart upload.');
                 } else {
                     pb_backupbuddy::status('details', 'File size of ' . pb_backupbuddy::$format->file_size($file_size) . ' is less than the minimum allowed chunk size of ' . self::MINIMUM_CHUNK_SIZE . 'MB; not chunking into multipart upload.');
                 }
             } else {
                 pb_backupbuddy::status('details', 'Max chunk size set to zero so not chunking into multipart upload.');
             }
         }
         // SEND file.
         pb_backupbuddy::status('details', 'About to put (upload) object to Stash.');
         $response = $s3->create_object($upload_data['bucket'], $upload_data['object'], array('fileUpload' => $file, 'encryption' => 'AES256'));
         // Validate response. On failure notify Stash API that things went wrong.
         if (!$response->isOK()) {
             // Send FAILED.
             pb_backupbuddy::status('details', 'Sending upload abort.');
             $request = new RequestCore($abort_url);
             $response = $request->send_request(true);
             $this_error = 'Could not upload to Stash, attempt aborted.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         } else {
             // Send SUCCESS.
             pb_backupbuddy::status('details', 'Success uploading file to Stash storage. Notifying Stash API next. Upload details: `' . print_r($response, true) . '`.');
             $uploaded_size = $response->header['_info']['size_upload'];
             $uploaded_speed = $response->header['_info']['speed_upload'];
             pb_backupbuddy::status('details', 'Uploaded size: ' . pb_backupbuddy::$format->file_size($uploaded_size) . ', Speed: ' . pb_backupbuddy::$format->file_size($uploaded_speed) . '/sec.');
         }
         delete_transient('pb_backupbuddy_stashquota_' . $settings['itxapi_username']);
         // Delete quota transient since it probably has changed now.
         // Notify Stash API that things were succesful.
         $done_url = $stash->get_upload_url($file, 'done', $remote_path . $backup_type_dir . basename($file));
         pb_backupbuddy::status('details', 'Notifying Stash of completed upload with done url `' . $done_url . '`.');
         $request = new RequestCore($done_url);
         $response = $request->send_request(true);
         if (!$response->isOK()) {
             $this_error = 'Error #247568834682. Could not finalize Stash upload. Response code: `' . $response->get_response_code() . '`; Response body: `' . $response->get_response_body() . '`; Response headers: `' . $response->get_response_header() . '`.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         } else {
             // Good server response.
             // See if we got an optional json response.
             $upload_data = @json_decode($response->body, true);
             if (isset($upload_data['error'])) {
                 // Some kind of error.
                 $this_error = 'Stash error(s): `' . implode(' - ', $upload_data['error']) . '`.';
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             }
             unset($files[$file_id]);
             // Remove from list of files we have not sent yet.
             pb_backupbuddy::status('details', 'Stash success sending file `' . basename($file) . '`. File uploaded and reported to Stash as completed.');
             // Load destination fileoptions.
             pb_backupbuddy::status('details', 'About to load fileoptions data.');
             require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
             $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
             if (true !== ($result = $fileoptions_obj->is_ok())) {
                 pb_backupbuddy::status('error', __('Fatal Error #9034.84838. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
                 return false;
             }
             pb_backupbuddy::status('details', 'Fileoptions data loaded.');
             $fileoptions =& $fileoptions_obj->options;
             // Save stats.
             if (isset($uploaded_speed)) {
                 $fileoptions['write_speed'] = $uploaded_speed;
                 $fileoptions_obj->save();
             }
             //$fileoptions['finish_time'] = time();
             //$fileoptions['status'] = 'success';
             unset($fileoptions_obj);
         }
     }
     // end foreach.
     // BEGIN FILE LIMIT PROCESSING. Enforce archive limits if applicable.
     if ($backup_type == 'full') {
         $limit = $full_archive_limit;
         pb_backupbuddy::status('details', 'Stash full backup archive limit of `' . $limit . '` of type `full` based on destination settings.');
     } elseif ($backup_type == 'db') {
         $limit = $db_archive_limit;
         pb_backupbuddy::status('details', 'Stash database backup archive limit of `' . $limit . '` of type `db` based on destination settings.');
     } elseif ($backup_type == 'files') {
         $limit = $db_archive_limit;
         pb_backupbuddy::status('details', 'Stash database backup archive limit of `' . $limit . '` of type `files` based on destination settings.');
     } else {
         $limit = 0;
         pb_backupbuddy::status('warning', 'Warning #54854895. Stash was unable to determine backup type (reported: `' . $backup_type . '`) so archive limits NOT enforced for this backup.');
     }
     if ($limit > 0) {
         pb_backupbuddy::status('details', 'Stash archive limit enforcement beginning.');
         // S3 object for managing files.
         $s3_manage = new AmazonS3($manage_data['credentials']);
         if ($disable_ssl === true) {
             @$s3_manage->disable_ssl(true);
         }
         // Get file listing.
         $response_manage = $s3_manage->list_objects($manage_data['bucket'], array('prefix' => $manage_data['subkey'] . $remote_path . $backup_type_dir));
         // list all the files in the subscriber account
         // Create array of backups and organize by date
         $prefix = backupbuddy_core::backup_prefix();
         // List backups associated with this site by date.
         $backups = array();
         foreach ($response_manage->body->Contents as $object) {
             $file = str_replace($manage_data['subkey'] . $remote_path . $backup_type_dir, '', $object->Key);
             // Stash stores files in a directory per site so no need to check prefix here! if ( false !== strpos( $file, 'backup-' . $prefix . '-' ) ) { // if backup has this site prefix...
             $backups[$file] = strtotime($object->LastModified);
         }
         arsort($backups);
         pb_backupbuddy::status('details', 'Stash found `' . count($backups) . '` backups of this type when checking archive limits.');
         if (count($backups) > $limit) {
             pb_backupbuddy::status('details', 'More archives (' . count($backups) . ') than limit (' . $limit . ') allows. Trimming...');
             $i = 0;
             $delete_fail_count = 0;
             foreach ($backups as $buname => $butime) {
                 $i++;
                 if ($i > $limit) {
                     pb_backupbuddy::status('details', 'Trimming excess file `' . $buname . '`...');
                     $response = $s3_manage->delete_object($manage_data['bucket'], $manage_data['subkey'] . $remote_path . $backup_type_dir . $buname);
                     if (!$response->isOK()) {
                         pb_backupbuddy::status('details', 'Unable to delete excess Stash file `' . $buname . '`. Details: `' . print_r($response, true) . '`.');
                         $delete_fail_count++;
                     }
                 }
             }
             pb_backupbuddy::status('details', 'Finished trimming excess backups.');
             if ($delete_fail_count !== 0) {
                 $error_message = 'Stash remote limit could not delete ' . $delete_fail_count . ' backups.';
                 pb_backupbuddy::status('error', $error_message);
                 backupbuddy_core::mail_error($error_message);
             }
         }
         pb_backupbuddy::status('details', 'Stash completed archive limiting.');
     } else {
         pb_backupbuddy::status('details', 'No Stash archive file limit to enforce.');
     }
     // End remote backup limit
     if (isset($fileoptions_obj)) {
         unset($fileoptions_obj);
     }
     // END FILE LIMIT PROCESSING.
     // Success if we made it this far.
     return true;
 }
Пример #22
0
 public static function process_timed_out_backups()
 {
     require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
     // Mark any backups noted as in progress to timed out if taking too long. Send error email is scheduled and failed or timed out.
     // Also, Purge fileoptions files without matching backup file in existance that are older than 30 days.
     pb_backupbuddy::status('details', 'Cleaning up old backup fileoptions option files.');
     $fileoptions_directory = backupbuddy_core::getLogDirectory() . 'fileoptions/';
     $files = glob($fileoptions_directory . '*.txt');
     if (!is_array($files)) {
         $files = array();
     }
     foreach ($files as $file) {
         pb_backupbuddy::status('details', 'Fileoptions instance #43.');
         $backup_options = new pb_backupbuddy_fileoptions($file, $read_only = false);
         if (true !== ($result = $backup_options->is_ok())) {
             pb_backupbuddy::status('error', 'Error retrieving fileoptions file `' . $file . '`. Err 335353266.');
         } else {
             if (isset($backup_options->options['archive_file'])) {
                 //error_log( print_r( $backup_options->options, true ) );
                 if (FALSE === $backup_options->options['finish_time']) {
                     // Failed & already handled sending notification.
                 } elseif ($backup_options->options['finish_time'] == -1) {
                     // Cancelled manually
                 } elseif ($backup_options->options['finish_time'] >= $backup_options->options['start_time'] && 0 != $backup_options->options['start_time']) {
                     // Completed
                 } else {
                     // Timed out or in progress.
                     $secondsAgo = time() - $backup_options->options['updated_time'];
                     if ($secondsAgo > backupbuddy_constants::TIME_BEFORE_CONSIDERED_TIMEOUT) {
                         // If 24hrs passed since last update to backup then mark this timeout as failed.
                         if ('scheduled' == $backup_options->options['trigger']) {
                             // SCHEDULED BACKUP TIMED OUT.
                             // Determine the first step to not finish.
                             $timeoutStep = '';
                             foreach ($backup_options->options['steps'] as $step) {
                                 if (0 == $step['finish_time']) {
                                     $timeoutStep = $step['function'];
                                     break;
                                 }
                             }
                             $backupCheckSpot = __('Select "View recently made backups" from the BackupBuddy Backups page to find this backup and view its log details and/or manually create a backup to test for problems.', 'it-l10n-backupbuddy');
                             $sendCheckSpot = __('Select "View recently sent files" on the Remote Destinations page to find this backup and view its log details and/or manually create a backup to test for problems.', 'it-l10n-backupbuddy');
                             $timeoutMessage = '';
                             if ('' != $timeoutStep) {
                                 if ('backup_create_database_dump' == $timeoutStep) {
                                     $timeoutMessage = 'The database dump step appears to have timed out. Make sure your database is not full of unwanted logs or clutter. ' . $backupCheckSpot;
                                 } elseif ('backup_zip_files' == $timeoutStep) {
                                     $timeoutMessage = 'The zip archive creation step appears to have timed out. Try turning off zip compression to significantly speed up the process or exclude large files. ' . $backupCheckSpot;
                                 } elseif ('send_remote_destination' == $timeoutStep) {
                                     $timeoutMessage = 'The remote transfer step appears to have timed out. Try turning on chunking in the destination settings to break up the file transfer into multiple steps. ' . $sendCheckSpot;
                                 } else {
                                     $timeoutMessage = 'The step function `' . $timeoutStep . '` appears to have timed out. ' . $backupCheckSpot;
                                 }
                             }
                             $error_message = 'Scheduled BackupBuddy backup `' . $backup_options->options['archive_file'] . '` started `' . pb_backupbuddy::$format->time_ago($backup_options->options['start_time']) . '` ago likely timed out. ' . $timeoutMessage;
                             pb_backupbuddy::status('error', $error_message);
                             if ($secondsAgo < backupbuddy_constants::CLEANUP_MAX_AGE_TO_NOTIFY_TIMEOUT) {
                                 // Prevents very old timed out backups from triggering email send.
                                 backupbuddy_core::mail_error($error_message);
                             }
                         }
                         // end scheduled.
                         $backup_options->options['finish_time'] = FALSE;
                         // Consider officially timed out.  If scheduled backup then an error notification will have been sent.
                         $backup_options->save();
                     }
                 }
                 // Remove fileoptions files which do not have a corresponding local backup. NOTE: This only handles fileoptions files containing the 'archive_file' key in their array. Handle those without this elsewhere.
                 // Cached integrity scans performed when there was not an existing fileoptions file will be missing the archive_file key.
                 $backupDir = backupbuddy_core::getBackupDirectory();
                 if (!file_exists($backup_options->options['archive_file']) && !file_exists($backupDir . basename($backup_options->options['archive_file']))) {
                     // No corresponding backup ZIP file.
                     $modified = filemtime($file);
                     if (time() - $modified > backupbuddy_constants::MAX_SECONDS_TO_KEEP_ORPHANED_FILEOPTIONS_FILES) {
                         // Too many days old so delete.
                         if (false === unlink($file)) {
                             pb_backupbuddy::status('error', 'Unable to delete orphaned fileoptions file `' . $file . '`.');
                         }
                         if (file_exists($file . '.lock')) {
                             @unlink($file . '.lock');
                         }
                     } else {
                         // Do not delete orphaned fileoptions because it is not old enough. Recent backups page needs these to list the backup.
                     }
                 } else {
                     // Backup ZIP file exists.
                 }
             } else {
                 // No archive_file key in fileoptions array.
                 // Trim any fileoptions files that are orphaned (no matching backup zip file). Note that above we trim these files that have the archive_file key in them.
                 $backupDir = backupbuddy_core::getBackupDirectory();
                 $serial = backupbuddy_core::get_serial_from_file('-' . basename($file));
                 // Dash needed to trick get_serial_from_file() into thinking this is a valid backup filename.
                 $backupFiles = glob($backupDir . '*' . $serial . '*.zip');
                 // Try to find a matching backup zip with this serial in its filename.
                 if (!is_array($backupFiles)) {
                     $backupFiles = array();
                 }
                 if (0 == count($backupFiles)) {
                     // No corresponding backup. Delete file.
                     $modified = filemtime($file);
                     if (time() - $modified > backupbuddy_constants::MAX_SECONDS_TO_KEEP_ORPHANED_FILEOPTIONS_FILES) {
                         // Too many days old so delete.
                         if (false === unlink($file)) {
                             pb_backupbuddy::status('error', 'Unable to delete orphaned fileoptions file `' . $file . '`.');
                         }
                         if (file_exists($file . '.lock')) {
                             @unlink($file . '.lock');
                         }
                     } else {
                         // Do not delete orphaned fileoptions because it is not old enough. Recent backups page needs these to list the backup.
                     }
                 } else {
                     //echo 'backupfound<br>';
                 }
             }
         }
     }
     // end foreach.
 }