pb_backupbuddy::$options['data_version'] = '4';
    // Update data structure version to 4.
    pb_backupbuddy::$options['role_access'] = 'activate_plugins';
    // Change default role from `administrator` to `activate_plugins` capability.
    pb_backupbuddy::save();
}
// ********** END 3.1.8.2 -> 3.1.8.3 DATA MIGRATION **********
// ********** BEGIN 3.3.0 -> 3.3.0.1 BACKUP DATASTRUCTURE OPTIONS to FILEOPTIONS MIGRATION **********
if (pb_backupbuddy::$options['data_version'] < 5) {
    if (isset(pb_backupbuddy::$options['backups']) && count(pb_backupbuddy::$options['backups']) > 0) {
        pb_backupbuddy::anti_directory_browsing(backupbuddy_core::getLogDirectory() . 'fileoptions/');
        require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
        foreach (pb_backupbuddy::$options['backups'] as $serial => $backup) {
            $backup_options = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt', $read_only = false, $ignore_lock = false, $create_file = true);
            $backup_options->options = $backup;
            if (true === $backup_options->save()) {
                unset(pb_backupbuddy::$options['backups'][$serial]);
            }
            unset($backup_options);
        }
    }
    pb_backupbuddy::$options['data_version'] = '5';
    pb_backupbuddy::save();
}
// ********** END 3.3.0 -> 3.3.0.1 BACKUP DATASTRUCTURE OPTIONS to FILEOPTIONS MIGRATION **********
// ********** BEGIN 4.0 UPGRADE **********
if (pb_backupbuddy::$options['data_version'] < 6) {
    // Migrate profile-specific settings into 'Defaults' key profile.
    pb_backupbuddy::$options['profiles'][0]['skip_database_dump'] = pb_backupbuddy::$options['skip_database_dump'];
    unset(pb_backupbuddy::$options['skip_database_dump']);
    pb_backupbuddy::$options['profiles'][0]['backup_nonwp_tables'] = pb_backupbuddy::$options['backup_nonwp_tables'];
Пример #2
0
 public static function test($settings)
 {
     $settings = self::_init($settings);
     $sendOK = false;
     $deleteOK = false;
     $send_id = 'TEST-' . pb_backupbuddy::random_string(12);
     // Try sending a file.
     if ('1' == $settings['stash_mode']) {
         // Stash mode.
         $settings['type'] = 'stash2';
     }
     $send_response = pb_backupbuddy_destinations::send($settings, dirname(dirname(__FILE__)) . '/remote-send-test.php', $send_id);
     // 3rd param true forces clearing of any current uploads.
     if (true === $send_response) {
         $send_response = __('Success.', 'it-l10n-backupbuddy');
         $sendOK = true;
     } else {
         global $pb_backupbuddy_destination_errors;
         $send_response = 'Error sending test file to S3 (v2). Details: `' . implode(', ', $pb_backupbuddy_destination_errors) . '`.';
     }
     pb_backupbuddy::add_status_serial('remote_send-' . $send_id);
     // Delete sent file if it was sent.
     $delete_response = 'n/a';
     if (true === $sendOK) {
         pb_backupbuddy::status('details', 'Preparing to delete sent test file.');
         if ('1' == $settings['stash_mode']) {
             // Stash mode.
             if (true === ($delete_response = pb_backupbuddy_destination_stash2::deleteFile($settings, 'remote-send-test.php'))) {
                 // success
                 $delete_response = __('Success.', 'it-l10n-backupbuddy');
                 $deleteOK = true;
             } else {
                 // error
                 $error = 'Unable to delete Stash test file `remote-send-test.php`. Details: `' . $delete_response . '`.';
                 $delete_response = $error;
                 $deleteOK = false;
             }
         } else {
             // S3 mode.
             if (true === ($delete_response = self::deleteFile($settings, 'remote-send-test.php'))) {
                 $delete_response = __('Success.', 'it-l10n-backupbuddy');
                 $deleteOK = true;
             } else {
                 $error = 'Unable to delete test file `remote-send-test.php`. Details: `' . $delete_response . '`.';
                 pb_backupbuddy::status('details', $error);
                 $delete_response = $error;
                 $deleteOK = false;
             }
         }
     } else {
         // end if $sendOK.
         pb_backupbuddy::status('details', 'Skipping test delete due to failed send.');
     }
     // 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 #7.');
     $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())) {
         return self::_error(__('Fatal Error #9034.84838. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
     }
     pb_backupbuddy::status('details', 'Fileoptions data loaded.');
     $fileoptions =& $fileoptions_obj->options;
     if (true !== $sendOK || true !== $deleteOK) {
         $fileoptions['status'] = 'failure';
         $fileoptions_obj->save();
         unset($fileoptions_obj);
         return 'Send details: `' . $send_response . '`. Delete details: `' . $delete_response . '`.';
     } else {
         $fileoptions['status'] = 'success';
         $fileoptions['finish_time'] = time();
     }
     $fileoptions_obj->save();
     unset($fileoptions_obj);
     pb_backupbuddy::status('details', 'Finished test function.');
     return true;
 }
Пример #3
0
 public static function send($settings = array(), $files = array(), $send_id = '', $delete_after = false)
 {
     if (!is_array($files)) {
         $files = array($files);
     }
     pb_backupbuddy::status('details', 'Dropbox2 send function started. Remote send id: `' . $send_id . '`.');
     // Normalize settings, apply defaults, etc.
     $settings = self::_normalizeSettings($settings);
     // Connect to Dropbox.
     if (false === self::_connect($settings['access_token'])) {
         // Try to connect. Return false if fail.
         return false;
     }
     $max_chunk_size_bytes = $settings['max_chunk_size'] * 1024 * 1024;
     /***** BEGIN MULTIPART CHUNKED CONTINUE *****/
     // Continue Multipart Chunked Upload
     if ($settings['_chunk_upload_id'] != '') {
         $file = $settings['_chunk_file'];
         pb_backupbuddy::status('details', 'Dropbox (PHP 5.3+) preparing to send chunked multipart upload part ' . ($settings['_chunk_sent_count'] + 1) . ' of ' . $settings['_chunk_total_count'] . ' with set chunk size of `' . $settings['max_chunk_size'] . '` MB. Dropbox Upload ID: `' . $settings['_chunk_upload_id'] . '`.');
         pb_backupbuddy::status('details', 'Opening file `' . basename($file) . '` to send.');
         $f = @fopen($file, 'rb');
         if (false === $f) {
             pb_backupbuddy::status('error', 'Error #87954435. Unable to open file `' . $file . '` to send to Dropbox.');
             return false;
         }
         // Seek to next chunk location.
         pb_backupbuddy::status('details', 'Seeking file to byte `' . $settings['_chunk_next_offset'] . '`.');
         if (0 != fseek($f, $settings['_chunk_next_offset'])) {
             // return of 0 is success.
             pb_backupbuddy::status('error', 'Unable to seek file to proper location offset `' . $settings['_chunk_next_offset'] . '`.');
         } else {
             pb_backupbuddy::status('details', 'Seek success.');
         }
         // Read this file chunk into memory.
         pb_backupbuddy::status('details', 'Reading chunk into memory.');
         try {
             $data = self::readFully($f, $settings['_chunk_maxsize']);
         } catch (\Exception $e) {
             pb_backupbuddy::status('error', 'Dropbox Error #484938376: ' . $e->getMessage());
             return false;
         }
         pb_backupbuddy::status('details', 'About to put chunk to Dropbox for continuation.');
         $send_time = -microtime(true);
         try {
             $result = self::$_dbxClient->chunkedUploadContinue($settings['_chunk_upload_id'], $settings['_chunk_next_offset'], $data);
         } catch (\Exception $e) {
             pb_backupbuddy::status('error', 'Dropbox Error #8754646: ' . $e->getMessage());
             return false;
         }
         // Examine response from Dropbox.
         if (true === $result) {
             // Upload success.
             pb_backupbuddy::status('details', 'Chunk upload continuation success with valid offset.');
         } elseif (false === $result) {
             // Failed.
             pb_backupbuddy::status('error', 'Chunk upload continuation failed at offset `' . $settings['_chunk_next_offset'] . '`.');
             return false;
         } elseif (is_numeric($result)) {
             // offset wrong. Update to use this.
             pb_backupbuddy::status('details', 'Chunk upload continuation received an updated offset response of `' . $result . '` when we tried `' . $settings['_chunk_next_offset'] . '`.');
             $settings['_chunk_next_offset'] = $result;
             // Try resending with corrected offset.
             try {
                 $result = self::$_dbxClient->chunkedUploadContinue($settings['_chunk_upload_id'], $settings['_chunk_next_offset'], $data);
             } catch (\Exception $e) {
                 pb_backupbuddy::status('error', 'Dropbox Error #8263836: ' . $e->getMessage());
                 return false;
             }
         }
         $send_time += microtime(true);
         $data_length = strlen($data);
         unset($data);
         // Calculate some stats to log.
         $chunk_transfer_speed = $data_length / $send_time;
         pb_backupbuddy::status('details', 'Dropbox chunk transfer stats - Sent: `' . pb_backupbuddy::$format->file_size($data_length) . '`, Transfer duration: `' . $send_time . '`, Speed: `' . pb_backupbuddy::$format->file_size($chunk_transfer_speed) . '`.');
         // Set options for subsequent step chunks.
         $chunked_destination_settings = $settings;
         $chunked_destination_settings['_chunk_offset'] = $data_length;
         $chunked_destination_settings['_chunk_sent_count']++;
         $chunked_destination_settings['_chunk_next_offset'] = $data_length * $chunked_destination_settings['_chunk_sent_count'];
         // First chunk was sent initiationg multipart send.
         $chunked_destination_settings['_chunk_transfer_speeds'][] = $chunk_transfer_speed;
         // 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 #15.');
         $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;
         // Multipart send completed. Send finished signal to Dropbox to seal the deal.
         if (true === feof($f)) {
             pb_backupbuddy::status('details', 'At end of file. Finishing transfer and notifying Dropbox of file transfer completion.');
             $chunked_destination_settings['_chunk_upload_id'] = '';
             // Unset since chunking finished.
             try {
                 $result = self::$_dbxClient->chunkedUploadFinish($settings['_chunk_upload_id'], $settings['directory'] . '/' . basename($file), dbx\WriteMode::add());
             } catch (\Exception $e) {
                 pb_backupbuddy::status('error', 'Dropbox Error #549838979: ' . $e->getMessage());
                 return false;
             }
             pb_backupbuddy::status('details', 'Chunked upload finish results: `' . print_r($result, true) . '`.');
             if (filesize($settings['_chunk_file']) != $result['bytes']) {
                 pb_backupbuddy::status('error', 'Error #8958944. Dropbox reported file size differs from local size. The file upload may have been corrupted.');
                 return false;
             }
             $fileoptions['write_speed'] = array_sum($chunked_destination_settings['_chunk_transfer_speeds']) / $chunked_destination_settings['_chunk_sent_count'];
             $fileoptions['_multipart_status'] = 'Sent part ' . $chunked_destination_settings['_chunk_sent_count'] . ' of ' . $chunked_destination_settings['_chunk_total_count'] . '.';
             $fileoptions['finish_time'] = time();
             $fileoptions['status'] = 'success';
             $fileoptions_obj->save();
             unset($fileoptions_obj);
         }
         fclose($f);
         pb_backupbuddy::status('details', 'Sent chunk number `' . $chunked_destination_settings['_chunk_sent_count'] . '` to Dropbox with upload ID: `' . $chunked_destination_settings['_chunk_upload_id'] . '`. Next offset: `' . $chunked_destination_settings['_chunk_next_offset'] . '`.');
         // Schedule to continue if anything is left to upload for this multipart of any individual files.
         if ($chunked_destination_settings['_chunk_upload_id'] != '' || count($files) > 0) {
             pb_backupbuddy::status('details', 'Dropbox multipart upload has more parts left. Scheduling next part send.');
             $cronTime = time();
             $cronArgs = array($chunked_destination_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 Dropbox chunk step cron event scheduled.');
             } else {
                 pb_backupbuddy::status('error', 'Next Dropbox 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($chunked_destination_settings['_chunk_upload_id'], 'Sent ' . $chunked_destination_settings['_chunk_sent_count'] . ' of ' . $chunked_destination_settings['_chunk_total_count'] . ' parts.');
         }
     }
     // end continue multipart chunked upload.
     /***** END MULTIPART CHUNKED CONTINUE *****/
     pb_backupbuddy::status('details', 'Looping through files to send to Dropbox.');
     foreach ($files as $file_id => $file) {
         $file_size = filesize($file);
         pb_backupbuddy::status('details', 'Opening file `' . basename($file) . '` to send.');
         $f = @fopen($file, 'rb');
         if (false === $f) {
             pb_backupbuddy::status('error', 'Error #8457573. Unable to open file `' . $file . '` to send to Dropbox.');
             return false;
         }
         if ($settings['max_chunk_size'] >= 5 && $file_size / 1024 / 1024 > $settings['max_chunk_size']) {
             // chunked send.
             pb_backupbuddy::status('details', 'File exceeds chunking limit of `' . $settings['max_chunk_size'] . '` MB. Using chunked upload for this file transfer.');
             // Read first file chunk into memory.
             pb_backupbuddy::status('details', 'Reading first chunk into memory.');
             try {
                 $data = self::readFully($f, $max_chunk_size_bytes);
             } catch (\Exception $e) {
                 pb_backupbuddy::status('error', 'Dropbox Error #5684574373: ' . $e->getMessage());
                 return false;
             }
             // Start chunk upload to get upload ID. Sends first chunk piece.
             $send_time = -microtime(true);
             pb_backupbuddy::status('details', 'About to start chunked upload & put first chunk of file `' . basename($file) . '` to Dropbox (PHP 5.3+).');
             try {
                 $result = self::$_dbxClient->chunkedUploadStart($data);
             } catch (\Exception $e) {
                 pb_backupbuddy::status('error', 'Dropbox Error: ' . $e->getMessage());
                 return false;
             }
             $send_time += microtime(true);
             @fclose($f);
             $data_length = strlen($data);
             unset($data);
             // Calculate some stats to log.
             $chunk_transfer_speed = $data_length / $send_time;
             pb_backupbuddy::status('details', 'Dropbox chunk transfer stats - Sent: `' . pb_backupbuddy::$format->file_size($data_length) . '`, Transfer duration: `' . $send_time . '`, Speed: `' . pb_backupbuddy::$format->file_size($chunk_transfer_speed) . '`.');
             // Set options for subsequent step chunks.
             $chunked_destination_settings = $settings;
             $chunked_destination_settings['_chunk_file'] = $file;
             $chunked_destination_settings['_chunk_maxsize'] = $max_chunk_size_bytes;
             $chunked_destination_settings['_chunk_upload_id'] = $result;
             $chunked_destination_settings['_chunk_offset'] = $data_length;
             $chunked_destination_settings['_chunk_next_offset'] = $data_length;
             // First chunk was sent initiationg multipart send.
             $chunked_destination_settings['_chunk_sent_count'] = 1;
             $chunked_destination_settings['_chunk_total_count'] = ceil($file_size / $max_chunk_size_bytes);
             $chunked_destination_settings['_chunk_transfer_speeds'][] = $chunk_transfer_speed;
             pb_backupbuddy::status('details', 'Sent first chunk to Dropbox with upload ID: `' . $chunked_destination_settings['_chunk_upload_id'] . '`. Offset: `' . $chunked_destination_settings['_chunk_offset'] . '`.');
             // Remove this file from list to send before passing $files to schedule next cron. Multipart will handle this from here on out.
             unset($files[$file_id]);
             // Schedule next chunk to send.
             pb_backupbuddy::status('details', 'Dropbox (PHP 5.3+) scheduling send of next part(s).');
             $cronTime = time();
             $cronArgs = array($chunked_destination_settings, $files, $send_id, $delete_after);
             $cronHashID = md5($cronTime . serialize($cronArgs));
             $cronArgs[] = $cronHashID;
             if (false === backupbuddy_core::schedule_single_event($cronTime, pb_backupbuddy::cron_tag('destination_send'), $cronArgs)) {
                 pb_backupbuddy::status('error', 'Error #948844: Unable to schedule next Dropbox2 cron chunk.');
                 return false;
             } else {
                 pb_backupbuddy::status('details', 'Success scheduling next cron chunk.');
             }
             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', 'Dropbox (PHP 5.3+) scheduled send of next part(s). Done for this cycle.');
             return array($chunked_destination_settings['_chunk_upload_id'], 'Sent 1 of ' . $chunked_destination_settings['_chunk_total_count'] . ' parts.');
         } else {
             // normal (non-chunked) send.
             pb_backupbuddy::status('details', 'Dropbox send not set to be chunked.');
             pb_backupbuddy::status('details', 'About to put file `' . basename($file) . '` (' . pb_backupbuddy::$format->file_size($file_size) . ') to Dropbox (PHP 5.3+).');
             $send_time = -microtime(true);
             try {
                 $result = self::$_dbxClient->uploadFile($settings['directory'] . '/' . basename($file), dbx\WriteMode::add(), $f);
             } catch (\Exception $e) {
                 pb_backupbuddy::status('error', 'Dropbox Error: ' . $e->getMessage());
                 return false;
             }
             $send_time += microtime(true);
             @fclose($f);
             pb_backupbuddy::status('details', 'About to load fileoptions data.');
             require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
             pb_backupbuddy::status('details', 'Fileoptions instance #14.');
             $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;
             // Calculate some stats to log.
             $data_length = $file_size;
             $transfer_speed = $data_length / $send_time;
             pb_backupbuddy::status('details', 'Dropbox (non-chunked) transfer stats - Sent: `' . pb_backupbuddy::$format->file_size($data_length) . '`, Transfer duration: `' . $send_time . '`, Speed: `' . pb_backupbuddy::$format->file_size($transfer_speed) . '/sec`.');
             $fileoptions['write_speed'] = $transfer_speed;
             $fileoptions_obj->save();
             unset($fileoptions_obj);
         }
         // end normal (non-chunked) send.
         pb_backupbuddy::status('message', 'Success sending `' . basename($file) . '` to Dropbox!');
         // Start remote backup limit
         if ($settings['archive_limit'] > 0) {
             pb_backupbuddy::status('details', 'Dropbox file limit in place. Proceeding with enforcement.');
             $meta_data = self::$_dbxClient->getMetadataWithChildren($settings['directory']);
             // Create array of backups and organize by date
             $bkupprefix = backupbuddy_core::backup_prefix();
             $backups = array();
             foreach ((array) $meta_data['contents'] as $looping_file) {
                 if ($looping_file['is_dir'] == '1') {
                     // JUST IN CASE. IGNORE anything that is a directory.
                     continue;
                 }
                 // check if file is backup
                 if (strpos($looping_file['path'], 'backup-' . $bkupprefix . '-') !== false) {
                     // Appears to be a backup file.
                     $backups[$looping_file['path']] = strtotime($looping_file['modified']);
                 }
             }
             arsort($backups);
             if (count($backups) > $settings['archive_limit']) {
                 pb_backupbuddy::status('details', 'Dropbox backup file count of `' . count($backups) . '` exceeds limit of `' . $settings['archive_limit'] . '`.');
                 $i = 0;
                 $delete_fail_count = 0;
                 foreach ($backups as $buname => $butime) {
                     $i++;
                     if ($i > $settings['archive_limit']) {
                         if (!self::$_dbxClient->delete($buname)) {
                             // Try to delete backup on Dropbox. Increment failure count if unable to.
                             pb_backupbuddy::status('details', 'Unable to delete excess Dropbox file: `' . $buname . '`');
                             $delete_fail_count++;
                         } else {
                             pb_backupbuddy::status('details', 'Deleted excess Dropbox file: `' . $buname . '`');
                         }
                     }
                 }
                 if ($delete_fail_count !== 0) {
                     backupbuddy_core::mail_error(sprintf(__('Dropbox remote limit could not delete %s backups.', 'it-l10n-backupbuddy'), $delete_fail_count));
                 }
             }
         } else {
             pb_backupbuddy::status('details', 'No Dropbox file limit to enforce.');
         }
         // End remote backup limit
     }
     // end foreach.
     pb_backupbuddy::status('details', 'All files sent.');
     return true;
     // Success if made it this far.
 }
Пример #4
0
                     $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');
Пример #5
0
 public static function send($destination_settings, $files, $send_id = '')
 {
     if ('' != $send_id) {
         pb_backupbuddy::add_status_serial('remote_send-' . $send_id);
         pb_backupbuddy::status('details', '----- Initiating master send function.');
         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.');
             $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.');
             $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);
     }
     $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));
     if ($result === false) {
         $error_details = implode('; ', $pb_backupbuddy_destination_errors);
         backupbuddy_core::mail_error('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" . $error_details);
     }
     if (is_array($result)) {
         // Send is multipart.
         pb_backupbuddy::status('details', 'Completed send function. Multipart chunk mode. 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';
             $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 sent shortly...');
         }
     } else {
         // Single all-at-once send.
         pb_backupbuddy::status('details', 'Completed send function. Result: `' . $result . '`.');
     }
     if ('' != $send_id) {
         pb_backupbuddy::remove_status_serial('remote_send-' . $send_id);
     }
     return $result;
 }
<?php

backupbuddy_core::verifyAjaxAccess();
// Abort an in-process remote destination send.
/* remotesend_abort()
 *
 * Abort an in-progress demote destination file transfer. Dies with outputting "1" on success.
 *
 */
$send_id = pb_backupbuddy::_GET('send_id');
$send_id = str_replace('/\\', '', $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 #25.');
$fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = true, $create_file = false);
if (true !== ($result = $fileoptions_obj->is_ok())) {
    pb_backupbuddy::status('error', __('Fatal Error #9034.324544. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
    return false;
}
pb_backupbuddy::status('details', 'Fileoptions data loaded.');
$fileoptions =& $fileoptions_obj->options;
$fileoptions['status'] = 'aborted';
$fileoptions_obj->save();
die('1');
Пример #7
0
 public static function send($settings = array(), $files = array(), $send_id = '')
 {
     global $pb_backupbuddy_destination_errors;
     if ('1' == $settings['disabled']) {
         $pb_backupbuddy_destination_errors[] = __('Error #48933: This destination is currently disabled. Enable it under this destination\'s Advanced Settings.', 'it-l10n-backupbuddy');
         return false;
     }
     if (!is_array($files)) {
         $files = array($files);
     }
     pb_backupbuddy::status('details', 'FTP class send() function started.');
     self::_init();
     // Connect to server.
     $server = $settings['address'];
     $port = '22';
     // Default sFTP port.
     if (strstr($server, ':')) {
         // Handle custom sFTP port.
         $server_params = explode(':', $server);
         $server = $server_params[0];
         $port = $server_params[1];
     }
     pb_backupbuddy::status('details', 'Connecting to sFTP server...');
     $sftp = new Net_SFTP($server, $port);
     if (!$sftp->login($settings['username'], $settings['password'])) {
         pb_backupbuddy::status('error', 'Connection to sFTP server FAILED.');
         pb_backupbuddy::status('details', 'sFTP log (if available & enabled via full logging mode): `' . $sftp->getSFTPLog() . '`.');
         return false;
     } else {
         pb_backupbuddy::status('details', 'Success connecting to sFTP server.');
     }
     pb_backupbuddy::status('details', 'Attempting to create path (if it does not exist)...');
     if (true === $sftp->mkdir($settings['path'])) {
         // Try to make directory.
         pb_backupbuddy::status('details', 'Directory created.');
     } else {
         pb_backupbuddy::status('details', 'Directory not created.');
     }
     // Change to directory.
     pb_backupbuddy::status('details', 'Attempting to change into directory...');
     if (true === $sftp->chdir($settings['path'])) {
         pb_backupbuddy::status('details', 'Changed into directory `' . $settings['path'] . '`. All uploads will be relative to this.');
     } else {
         pb_backupbuddy::status('error', 'Unable to change into specified path. Verify the path is correct with valid permissions.');
         pb_backupbuddy::status('details', 'sFTP log (if available & enabled via full logging mode): `' . $sftp->getSFTPLog() . '`.');
         return false;
     }
     // Upload files.
     $total_transfer_size = 0;
     $total_transfer_time = 0;
     foreach ($files as $file) {
         if (!file_exists($file)) {
             pb_backupbuddy::status('error', 'Error #859485495. Could not upload local file `' . $file . '` to send to sFTP as it does not exist. Verify the file exists, permissions of file, parent directory, and that ownership is correct. You may need suphp installed on the server.');
         }
         if (!is_readable($file)) {
             pb_backupbuddy::status('error', 'Error #8594846548. Could not read local file `' . $file . '` to send to sFTP as it is not readable. Verify permissions of file, parent directory, and that ownership is correct. You may need suphp installed on the server.');
         }
         $filesize = filesize($file);
         $total_transfer_size += $filesize;
         $destination_file = basename($file);
         pb_backupbuddy::status('details', 'About to put to sFTP local file `' . $file . '` of size `' . pb_backupbuddy::$format->file_size($filesize) . '` to remote file `' . $destination_file . '`.');
         $send_time = -microtime(true);
         $upload = $sftp->put($destination_file, $file, NET_SFTP_LOCAL_FILE);
         $send_time += microtime(true);
         $total_transfer_time += $send_time;
         if ($upload === false) {
             // Failed sending.
             $error_message = 'ERROR #9012b ( http://ithemes.com/codex/page/BackupBuddy:_Error_Codes#9012 ).  sFTP file upload failed. Check file permissions & disk quota.';
             pb_backupbuddy::status('error', $error_message);
             backupbuddy_core::mail_error($error_message);
             pb_backupbuddy::status('details', 'sFTP log (if available & enabled via full logging mode): `' . $sftp->getSFTPLog() . '`.');
             return false;
         } else {
             // Success sending.
             pb_backupbuddy::status('details', 'Success completely sending `' . basename($file) . '` to destination.');
             // Start remote backup limit
             if ($settings['archive_limit'] > 0) {
                 pb_backupbuddy::status('details', 'Archive limit enabled. Getting contents of backup directory.');
                 $contents = $sftp->rawlist($settings['path']);
                 // already in destination directory/path.
                 // Create array of backups
                 $bkupprefix = backupbuddy_core::backup_prefix();
                 $backups = array();
                 foreach ($contents as $filename => $backup) {
                     // check if file is backup
                     $pos = strpos($filename, 'backup-' . $bkupprefix . '-');
                     if ($pos !== FALSE) {
                         $backups[] = array('file' => $filename, 'modified' => $backup['mtime']);
                     }
                 }
                 function backupbuddy_number_sort($a, $b)
                 {
                     return $a['modified'] < $b['modified'];
                 }
                 // Sort by modified using custom sort function above.
                 usort($backups, 'backupbuddy_number_sort');
                 if (count($backups) > $settings['archive_limit']) {
                     pb_backupbuddy::status('details', 'More backups found (' . count($backups) . ') than limit permits (' . $settings['archive_limit'] . ').' . print_r($backups, true));
                     $delete_fail_count = 0;
                     $i = 0;
                     foreach ($backups as $backup) {
                         $i++;
                         if ($i > $settings['archive_limit']) {
                             if (false === $sftp->delete($settings['path'] . '/' . $backup['file'])) {
                                 pb_backupbuddy::status('details', 'Unable to delete excess sFTP file `' . $backup['file'] . '` in path `' . $settings['path'] . '`.');
                                 $delete_fail_count++;
                             } else {
                                 pb_backupbuddy::status('details', 'Deleted excess sFTP file `' . $backup['file'] . '` in path `' . $settings['path'] . '`.');
                             }
                         }
                     }
                     if ($delete_fail_count != 0) {
                         backupbuddy_core::mail_error(sprintf(__('sFTP remote limit could not delete %s backups. Please check and verify file permissions.', 'it-l10n-backupbuddy'), $delete_fail_count));
                         pb_backupbuddy::status('error', 'Unable to delete one or more excess backup archives. File storage limit may be exceeded. Manually clean up backups and check permissions.');
                     } else {
                         pb_backupbuddy::status('details', 'No problems encountered deleting excess backups.');
                     }
                 } else {
                     pb_backupbuddy::status('details', 'Not enough backups found to exceed limit. Skipping limit enforcement.');
                 }
             } else {
                 pb_backupbuddy::status('details', 'No sFTP archive file limit to enforce.');
             }
             // End remote backup limit
         }
     }
     // end $files loop.
     // 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 #6.');
     $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.843498. 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.
     $fileoptions['write_speed'] = $total_transfer_size / $total_transfer_time;
     $fileoptions_obj->save();
     unset($fileoptions_obj);
     return true;
 }
Пример #8
0
 public function set_backup_note()
 {
     if (!isset(pb_backupbuddy::$classes['zipbuddy'])) {
         require_once pb_backupbuddy::plugin_path() . '/lib/zipbuddy/zipbuddy.php';
         pb_backupbuddy::$classes['zipbuddy'] = new pluginbuddy_zipbuddy(pb_backupbuddy::$options['backup_directory']);
     }
     $backup_file = pb_backupbuddy::$options['backup_directory'] . pb_backupbuddy::_POST('backup_file');
     $note = pb_backupbuddy::_POST('note');
     $note = ereg_replace("[[:space:]]+", ' ', $note);
     $note = ereg_replace("[^[:print:]]", '', $note);
     $note = substr($note, 0, 200);
     // Returns true on success, else the error message.
     $old_comment = pb_backupbuddy::$classes['zipbuddy']->get_comment($backup_file);
     $comment = pb_backupbuddy::$classes['core']->normalize_comment_data($old_comment);
     $comment['note'] = $note;
     //$new_comment = base64_encode( serialize( $comment ) );
     $comment_result = pb_backupbuddy::$classes['zipbuddy']->set_comment($backup_file, $comment);
     if ($comment_result !== true) {
         echo $comment_result;
     } else {
         echo '1';
     }
     // Even if we cannot save the note into the archive file, store it in internal settings.
     $serial = pb_backupbuddy::$classes['core']->get_serial_from_file($backup_file);
     require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
     $backup_options = new pb_backupbuddy_fileoptions(pb_backupbuddy::$options['log_directory'] . 'fileoptions/' . $serial . '.txt');
     if (true === ($result = $backup_options->is_ok())) {
         $backup_options->options['integrity']['comment'] = $note;
         $backup_options->save();
     }
     die;
 }
 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;
 }
Пример #10
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;
 }
Пример #11
0
 public static function test($settings)
 {
     $settings = self::_init($settings);
     // Try sending a file.
     $send_response = pb_backupbuddy_destinations::send($settings, dirname(dirname(__FILE__)) . '/remote-send-test.php', $send_id = 'TEST-' . pb_backupbuddy::random_string(12));
     // 3rd param true forces clearing of any current uploads.
     if (false === $send_response) {
         $send_response = 'Error sending test file to S3.';
     } else {
         $send_response = 'Success.';
     }
     // Delete sent file.
     $delete_response = 'Success.';
     try {
         $delete_response = self::$_client->delete_object(array('Bucket' => $settings['bucket'], 'Key' => $settings['directory'] . 'remote-send-test.php'));
         $delete_response = 'Success.';
     } catch (Exception $e) {
         pb_backupbuddy::status('details', 'Unable to delete test S3 file `remote-send-test.php`. Details: `' . $e->getMessage() . '`.');
     }
     // 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 #7.');
     $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())) {
         return self::_error(__('Fatal Error #9034.84838. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
     }
     pb_backupbuddy::status('details', 'Fileoptions data loaded.');
     $fileoptions =& $fileoptions_obj->options;
     if ('Success.' != $send_response || 'Success.' != $delete_response) {
         $fileoptions['status'] = 'failure';
         $fileoptions_obj->save();
         unset($fileoptions_obj);
         return 'Send details: `' . $send_response . '`. Delete details: `' . $delete_response . '`.';
     } else {
         $fileoptions['status'] = 'success';
         $fileoptions['finish_time'] = time();
     }
     $fileoptions_obj->save();
     unset($fileoptions_obj);
     return true;
 }
Пример #12
0
 private static function _processSignatures($type, $newFileSignatures)
 {
     pb_backupbuddy::status('details', 'About to load fileoptions data in create mode.');
     require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
     pb_backupbuddy::status('details', 'Fileoptions instance #88.');
     $existingSignaturesObj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'live/' . $type . '-' . pb_backupbuddy::$options['log_serial'] . '.txt', $read_only = false, $ignore_lock = false, $create_file = true);
     if (true !== ($result = $existingSignaturesObj->is_ok())) {
         pb_backupbuddy::status('error', 'Error #382983. Unable to create or access fileoptions file for media. Details: `' . $result . '`.');
         return false;
     }
     pb_backupbuddy::status('details', 'Fileoptions data loaded.');
     if (!isset($existingSignaturesObj->options['signatures'])) {
         $existingSignaturesObj->options = array('signatures' => array(), 'stats' => array('totalFiles' => 0, 'needsSent' => 0, 'needsDelete' => 0));
     }
     $existingSignatures =& $existingSignaturesObj->options['signatures'];
     // Loop through local files to see if they differ from previous scan.
     pb_backupbuddy::status('details', 'Comparing new signatures with existing ones.');
     $addOrUpdateCount = 0;
     foreach ($newFileSignatures as $file => $signature) {
         $addOrUpdateFile = false;
         if (!isset($existingSignatures[$file])) {
             // This is a new file. Append to list.
             $addOrUpdateFile = true;
             $existingSignaturesObj->options['stats']['totalFiles']++;
         } else {
             // File exists on remote. See if content is the same.
             if (isset($signature['sha1']) && $signature['sha1'] != $existingSignatures[$file]['sha1']) {
                 // Hash mismatch. Needs updating.
                 $addOrUpdateFile = true;
             } elseif (!isset($signature['sha1']) || '' == $signature['sha1']) {
                 // sha1 not calculated. size may be too large. compare size to see if changed.
                 if ($signature['size'] != $existingSignatures[$file]['size']) {
                     // size mismatch
                     $addOrUpdateFile = true;
                 }
             }
         }
         // File is new and needs added to list to be sent to remote.
         if (true === $addOrUpdateFile) {
             $existingSignatures[$file] = $signature;
             $signature['added'] = time();
             // When did we first notice file?
             $signature['sent'] = false;
             // Has file been sent to Stash?
             $existingSignaturesObj->options['stats']['needsSent']++;
             pb_backupbuddy::status('details', 'New or modified file found `' . $file . '`.');
             $addOrUpdateCount++;
         }
     }
     // Loop through remote files to see if any no longer exist locally and therefore need deleted.
     $deleteCount = 0;
     foreach ($existingSignatures as $file => $signature) {
         if (!isset($newFileSignatures[$file])) {
             $existingSignatures[$file]['delete'] = true;
             $existingSignaturesObj->options['stats']['needsDelete']++;
             $existingSignaturesObj->options['stats']['totalFiles']--;
             pb_backupbuddy::status('details', 'Remote file that no longer exists locally found. Flagging `' . $file . '` for deletion.');
         }
     }
     // Save.
     pb_backupbuddy::status('details', 'Saving updated `' . $type . '` signatures... Added `' . $addOrUpdateCount . '`. Deleted `' . $deleteCount . '`. Total files: `' . $existingSignaturesObj->options['stats']['totalFiles'] . '`. Needs sent: `' . $existingSignaturesObj->options['stats']['needsSent'] . '`. Needs delete: `' . $existingSignaturesObj->options['stats']['needsDelete'] . '`.');
     $existingSignaturesObj->save();
     pb_backupbuddy::status('details', 'Signatures saved.');
     return true;
 }
Пример #13
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.
 }
Пример #14
0
 private static function _step_process_file_deletions($startAt = 0)
 {
     if ($startAt < 0) {
         $startAt = 0;
     }
     $start_time = microtime(true);
     if (false === self::_load_catalog()) {
         return false;
     }
     // Build Stash2 destination settings based on Live settings.
     $destination_settings = self::get_destination_settings();
     pb_backupbuddy::status('details', 'Starting deletions at point: `' . $startAt . '`.');
     // Loop through files in the catalog.
     $loopCount = 0;
     $checkCount = 0;
     $filesDeleted = 0;
     $deleteQueue = array();
     // Files queued to delete.
     $last_save = microtime(true);
     foreach (self::$_catalog as $signatureFile => &$signatureDetails) {
         if (0 != $startAt) {
             // Resuming...
             if ($loopCount < $startAt) {
                 $loopCount++;
                 continue;
             }
         } else {
             $loopCount++;
         }
         $checkCount++;
         // Skip non-deleted files.
         if (true !== $signatureDetails['d']) {
             continue;
         }
         // Made it here then we will be deleting a file.
         // Cancel any in-process remote sends of deleted files.
         $sendFileoptions = glob(backupbuddy_core::getLogDirectory() . 'fileoptions/send-live_' . md5($signatureFile) . '-*.txt');
         if (!is_array($sendFileoptions)) {
             $sendFileoptions = array();
         }
         foreach ($sendFileoptions as $sendFileoption) {
             $fileoptions_obj = new pb_backupbuddy_fileoptions($sendFileoption, $read_only = false, $ignore_lock = true, $create_file = false);
             if (true !== ($result = $fileoptions_obj->is_ok())) {
                 pb_backupbuddy::status('error', __('Error #9034.32393. Unable to access fileoptions data related to file `' . $signatureFile . '`. Skipping cleanup of file send.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
                 continue;
             }
             // Something wrong with fileoptions. Let cleanup handle it later.
             if (!isset($fileoptions_obj->options['status'])) {
                 continue;
             }
             // Don't do anything for success, failure, or already-marked as -1 finish time.
             if ('success' == $fileoptions_obj->options['status'] || 'failure' == $fileoptions_obj->options['status'] || -1 == $fileoptions_obj->options['finish_time']) {
                 continue;
             }
             // Cancel this send.
             $fileoptions_obj->options['finish_time'] = -1;
             $fileoptions_obj->save();
             pb_backupbuddy::status('details', 'Cancelled in-progress send of deleted file `' . $signatureFile . '`.');
             unset($fileoptions_obj);
         }
         // If file has been backed up to server then we need to QUEUE the file for deletion.
         if (0 != $signatureDetails['b']) {
             $deleteQueue[] = $signatureFile;
         }
         // Is the queue full to the delete burst limit? Process queue.
         if (count($deleteQueue) >= $destination_settings['max_delete_burst']) {
             pb_backupbuddy::status('details', 'File deletion queue full to burst limit. Triggering deletions call.');
             self::_process_internal_delete_queue($destination_settings, $deleteQueue, $filesDeleted);
             // Process any items in the deletion queue. $deleteQueue and $filesDeleted are references.
         }
         // See if it's time to save our progress so far.
         if (time() - $last_save > self::SAVE_SIGNATURES_EVERY_X_SECONDS) {
             pb_backupbuddy::status('details', 'Time to save progress so far. Triggering deletions call then saving.');
             self::_process_internal_delete_queue($destination_settings, $deleteQueue, $filesDeleted);
             // Process any items in the deletion queue. $deleteQueue and $filesDeleted are references.
             self::$_stateObj->save();
             self::$_catalogObj->save();
             $last_save = microtime(true);
         }
         // Do we have enough time to continue or do we need to chunk?
         if (microtime(true) - $start_time + self::TIME_WIGGLE_ROOM > $destination_settings['max_time']) {
             // Running out of time! Chunk.
             pb_backupbuddy::status('details', 'Running out of time processing deletions. Took `' . (microtime(true) - $start_time) . '` seconds. Triggering deletions call then saving.');
             //self::_process_internal_delete_queue( $destination_settings, $deleteQueue, $filesDeleted ); // Process any items in the deletion queue. $deleteQueue and $filesDeleted are references.
             // Do not process queue here. Anything in the queuecan be handled during the next chunk.
             self::$_stateObj->save();
             self::$_catalogObj->save();
             return array('Processing deletions', array());
             //array( $startAt+$loopCount-$filesDeleted ) );
         }
     }
     // end foreach.
     // Wrap up any lingering deletions.
     pb_backupbuddy::status('details', 'Processing any lingering deletions in queue at finish then saving.');
     self::_process_internal_delete_queue($destination_settings, $deleteQueue, $filesDeleted);
     // Process any items in the deletion queue. $deleteQueue and $filesDeleted are references.
     // Save and finish.
     self::$_stateObj->save();
     self::$_catalogObj->save();
     pb_backupbuddy::status('details', 'Deletions processed. Checked `' . $checkCount . '` files. Deleted `' . $filesDeleted . '` files. Took `' . (microtime(true) - $start_time) . '` seconds.');
     return true;
 }
Пример #15
0
$fileoptions_file = backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '-filetree.txt';
// Purge cache if too old.
if (file_exists($fileoptions_file) && time() - filemtime($fileoptions_file) > $max_cache_time) {
    if (false === unlink($fileoptions_file)) {
        pb_backupbuddy::alert('Error #456765545. Unable to wipe cached fileoptions file `' . $fileoptions_file . '`.');
    }
}
$fileoptions = new pb_backupbuddy_fileoptions($fileoptions_file);
// Either we are getting cached file tree information or we need to create afresh
if (true !== ($result = $fileoptions->is_ok())) {
    // Get file listing.
    require_once pb_backupbuddy::plugin_path() . '/lib/zipbuddy/zipbuddy.php';
    pb_backupbuddy::$classes['zipbuddy'] = new pluginbuddy_zipbuddy(ABSPATH, array(), 'unzip');
    $files = pb_backupbuddy::$classes['zipbuddy']->get_file_list(backupbuddy_core::getBackupDirectory() . str_replace('\\/', '', pb_backupbuddy::_GET('zip_viewer')));
    $fileoptions->options = $files;
    $fileoptions->save();
} else {
    $files =& $fileoptions->options;
}
// Just make sure we have a sensible files listing
if (!is_array($files)) {
    die('Error #548484.  Unable to retrieve file listing from backup file `' . htmlentities(pb_backupbuddy::_GET('zip_viewer')) . '`.');
}
// To record subdirs of this root
$subdirs = array();
// Strip out any files/subdirs that are not actually directly under the given root
foreach ($files as $key => $file) {
    // If shorter than root length then certainly is not within this (root) directory.
    // It's a quick test that is more effective the longer the root (the deeper you go
    // into the tree)
    if (strlen($file[0]) < $root_len) {
Пример #16
0
 public static function send($settings = array(), $files = array(), $send_id = '', $delete_after = false, $delete_remote_after = false)
 {
     global $pb_backupbuddy_destination_errors;
     if ('1' == $settings['disabled']) {
         $pb_backupbuddy_destination_errors[] = __('Error #48933: This destination is currently disabled. Enable it under this destination\'s Advanced Settings.', 'it-l10n-backupbuddy');
         return false;
     }
     if (!is_array($files)) {
         $files = array($files);
     }
     pb_backupbuddy::status('details', 'Google Drive send() function started. Settings: `' . print_r($settings, true) . '`.');
     self::$_timeStart = microtime(true);
     $settings = self::_normalizeSettings($settings);
     if (false === ($settings = self::_connect($settings))) {
         // $settings =
         return self::_error('Error #38923923: Unable to connect with Google Drive. See log for details.');
     }
     $folderID = $settings['folderID'];
     if ('' == $folderID) {
         $folderID = 'root';
     }
     $chunkSizeBytes = $settings['max_burst'] * 1024 * 1024;
     // Send X mb at a time to limit memory usage.
     foreach ($files as $file) {
         // Determine backup type for limiting later.
         $backup_type = '';
         if (stristr($file, '-db-') !== false) {
             $backup_type = 'db';
         } elseif (stristr($file, '-full-') !== false) {
             $backup_type = 'full';
         } elseif (stristr($file, '-files-') !== false) {
             $backup_type = 'files';
         } elseif (stristr($file, '-export-') !== false) {
             $backup_type = 'export';
         }
         if (!file_exists($file)) {
             return self::_error('Error #37792: File selected to send not found: `' . $file . '`.');
         }
         $fileSize = filesize($file);
         $fileinfo = pathinfo($file);
         $fileextension = $fileinfo['extension'];
         if ('zip' == $fileextension) {
             $mimeType = 'application/zip';
         } elseif ('php' == $fileextension) {
             $mimeType = 'application/x-httpd-php';
         } else {
             $mimeType = '';
         }
         pb_backupbuddy::status('details', 'About to upload file `' . $file . '` of size `' . $fileSize . '` with mimetype `' . $mimeType . '` into folder `' . $folderID . '`. Internal chunk size of `' . $chunkSizeBytes . '` bytes.');
         if ($fileSize > $chunkSizeBytes) {
             pb_backupbuddy::status('details', 'File size `' . pb_backupbuddy::$format->file_size($fileSize) . '` exceeds max burst size `' . $settings['max_burst'] . ' MB` so this will be sent in bursts. If time limit nears then send will be chunked across multiple PHP loads.');
             $settings['_chunks_total'] = ceil($fileSize / $chunkSizeBytes);
         }
         if (0 == $settings['_chunks_total']) {
             $settings['_chunks_total'] = 1;
         }
         //Insert a file
         $driveFile = new Google_Service_Drive_DriveFile();
         $driveFile->setTitle(basename($file));
         $driveFile->setDescription('BackupBuddy file');
         $driveFile->setMimeType($mimeType);
         // Set the parent folder.
         if ('root' != $folderID) {
             $parentsCollectionData = new Google_Service_Drive_ParentReference();
             $parentsCollectionData->setId($folderID);
             $driveFile->setParents(array($parentsCollectionData));
         }
         self::$_client->setDefer(true);
         try {
             $insertRequest = self::$_drive->files->insert($driveFile);
         } catch (Exception $e) {
             pb_backupbuddy::alert('Error #3232783268336: initiating upload. Details: ' . $e->getMessage());
             return false;
         }
         // Handle getting resume information to see if resuming is still an option.
         $resumable = false;
         if ('' != $settings['_media_resumeUri']) {
             $headers = array('content-range' => 'bytes */' . $fileSize);
             $request = new Google_Http_Request($settings['_media_resumeUri'], 'PUT', $headers, '');
             $response = self::$_client->getIo()->makeRequest($request);
             if (308 == $response->getResponseHttpCode()) {
                 $range = $response->getResponseHeader('range');
                 if (!empty($range) && preg_match('/bytes=0-(\\d+)$/', $range, $matches)) {
                     $resumable = true;
                     pb_backupbuddy::status('details', 'Last send reported next byte to be `' . $settings['_media_progress'] . '`.');
                     $settings['_media_progress'] = $matches[1] + 1;
                     pb_backupbuddy::status('details', 'Google Drive resuming is available. Google Drive reports next byte to be `' . $settings['_media_progress'] . '`. Range: `' . $range . '`.');
                 }
             }
             if (!$resumable) {
                 pb_backupbuddy::status('details', 'Google Drive could not resume. Too much time may have passed or some other cause.');
             }
             if ($settings['_media_progress'] >= $fileSize) {
                 pb_backupbuddy::status('details', 'Google Drive resuming not needed. Remote file meets or exceeds file size. Completed.');
                 return true;
             }
         }
         // See https://developers.google.com/api-client-library/php/guide/media_upload
         try {
             $media = new Google_Http_MediaFileUpload(self::$_client, $insertRequest, $mimeType, null, true, $chunkSizeBytes);
         } catch (Exception $e) {
             pb_backupbuddy::alert('Error #3893273937: initiating upload. Details: ' . $e->getMessage());
             return;
         }
         $media->setFileSize($fileSize);
         // Reset these internal variables. NOTE: These are by default private. Must modify MediaFileUpload.php to make this possible by setting these vars public. Thanks Google!
         if ('' != $settings['_media_resumeUri']) {
             $media->resumeUri = $settings['_media_resumeUri'];
             $media->progress = $settings['_media_progress'];
         }
         pb_backupbuddy::status('details', 'Opening file for sending in binary mode.');
         $fs = fopen($file, 'rb');
         // If chunked resuming then seek to the correct place in the file.
         if ('' != $settings['_media_progress'] && $settings['_media_progress'] > 0) {
             // Resuming send of a partially transferred file.
             if (0 !== fseek($fs, $settings['_media_progress'])) {
                 // Go off the resume point as given by Google in case it didnt all make it. //$settings['resume_point'] ) ) { // Returns 0 on success.
                 pb_backupbuddy::status('error', 'Error #3872733: Failed to seek file to resume point `' . $settings['_media_progress'] . '` via fseek().');
                 return false;
             }
             $prevPointer = $settings['_media_progress'];
             //$settings['resume_point'];
         } else {
             // New file send.
             $prevPointer = 0;
         }
         $needProcessChunking = false;
         // Set true if we need to spawn off resuming to a new PHP page load.
         $uploadStatus = false;
         while (!$uploadStatus && !feof($fs)) {
             $chunk = fread($fs, $chunkSizeBytes);
             pb_backupbuddy::status('details', 'Chunk of size `' . pb_backupbuddy::$format->file_size($chunkSizeBytes) . '` read into memory. Total bytes summed: `' . ($settings['_media_progress'] + strlen($chunk)) . '` of filesize: `' . $fileSize . '`.');
             pb_backupbuddy::status('details', 'Sending burst file data next. If next message is not "Burst file data sent" then the send likely timed out. Try reducing burst size. Sending now...');
             // Send chunk of data.
             try {
                 $uploadStatus = $media->nextChunk($chunk);
             } catch (Exception $e) {
                 global $pb_backupbuddy_destination_errors;
                 $pb_backupbuddy_destination_errors[] = $e->getMessage();
                 $error = $e->getMessage();
                 pb_backupbuddy::status('error', 'Error #8239832: Error sending burst data. Details: `' . $error . '`.');
                 return false;
             }
             $settings['_chunks_sent']++;
             self::$_chunksSentThisRound++;
             pb_backupbuddy::status('details', 'Burst file data sent.');
             $maxTime = $settings['max_time'];
             if ('' == $maxTime || !is_numeric($maxTime)) {
                 pb_backupbuddy::status('details', 'Max time not set in settings so detecting server max PHP runtime.');
                 $maxTime = backupbuddy_core::detectMaxExecutionTime();
             }
             //return;
             // Handle splitting up across multiple PHP page loads if needed.
             if (!feof($fs) && 0 != $maxTime) {
                 // More data remains so see if we need to consider chunking to a new PHP process.
                 // If we are within X second of reaching maximum PHP runtime then stop here so that it can be picked up in another PHP process...
                 $totalSizeSent = self::$_chunksSentThisRound * $chunkSizeBytes;
                 // Total bytes sent this PHP load.
                 $bytesPerSec = $totalSizeSent / (microtime(true) - self::$_timeStart);
                 $timeRemaining = $maxTime - (microtime(true) - self::$_timeStart + self::TIME_WIGGLE_ROOM);
                 if ($timeRemaining < 0) {
                     $timeRemaining = 0;
                 }
                 $bytesWeCouldSendWithTimeLeft = $bytesPerSec * $timeRemaining;
                 pb_backupbuddy::status('details', 'Total sent: `' . pb_backupbuddy::$format->file_size($totalSizeSent) . '`. Speed (per sec): `' . pb_backupbuddy::$format->file_size($bytesPerSec) . '`. Time Remaining (w/ wiggle): `' . $timeRemaining . '`. Size that could potentially be sent with remaining time: `' . pb_backupbuddy::$format->file_size($bytesWeCouldSendWithTimeLeft) . '` with chunk size of `' . pb_backupbuddy::$format->file_size($chunkSizeBytes) . '`.');
                 if ($bytesWeCouldSendWithTimeLeft < $chunkSizeBytes) {
                     // We can send more than a whole chunk (including wiggle room) so send another bit.
                     pb_backupbuddy::status('message', 'Not enough time left (~`' . $timeRemaining . '`) with max time of `' . $maxTime . '` sec to send another chunk at `' . pb_backupbuddy::$format->file_size($bytesPerSec) . '` / sec. Ran for ' . round(microtime(true) - self::$_timeStart, 3) . ' sec. Proceeding to use chunking.');
                     @fclose($fs);
                     // Tells next chunk where to pick up.
                     if (isset($chunksTotal)) {
                         $settings['_chunks_total'] = $chunksTotal;
                     }
                     // Grab these vars from the class.  Note that we changed these vars from private to public to make chunked resuming possible.
                     $settings['_media_resumeUri'] = $media->resumeUri;
                     $settings['_media_progress'] = $media->progress;
                     // Schedule cron.
                     $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, 'destination_send', $cronArgs);
                     if (true === $schedule_result) {
                         pb_backupbuddy::status('details', 'Next Site chunk step cron event scheduled.');
                     } else {
                         pb_backupbuddy::status('error', 'Next Site 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($prevPointer, 'Sent part ' . $settings['_chunks_sent'] . ' of ~' . $settings['_chunks_total'] . ' parts.');
                     // filepointer location, elapsed time during the import
                 } else {
                     // End if.
                     pb_backupbuddy::status('details', 'Not approaching limits.');
                 }
             } else {
                 pb_backupbuddy::status('details', 'No more data remains (eg for chunking) so finishing up.');
                 if ('' != $send_id) {
                     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.397237. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
                         return false;
                     }
                     pb_backupbuddy::status('details', 'Fileoptions data loaded.');
                     $fileoptions =& $fileoptions_obj->options;
                     $fileoptions['_multipart_status'] = 'Sent part ' . $settings['_chunks_sent'] . ' of ~' . $settings['_chunks_total'] . ' parts.';
                     $fileoptions['finish_time'] = microtime(true);
                     $fileoptions['status'] = 'success';
                     $fileoptions_obj->save();
                     unset($fileoptions_obj);
                 }
             }
         }
         fclose($fs);
         self::$_client->setDefer(false);
         if (false == $uploadStatus) {
             global $pb_backupbuddy_destination_errors;
             $pb_backupbuddy_destination_errors[] = 'Error #84347474 sending. Details: ' . $uploadStatus;
             return false;
         } else {
             // Success.
             if (true === $delete_remote_after) {
                 self::deleteFile($settings, $uploadStatus->id);
             }
         }
     }
     // end foreach.
     $db_archive_limit = $settings['db_archive_limit'];
     $full_archive_limit = $settings['full_archive_limit'];
     $files_archive_limit = $settings['files_archive_limit'];
     // BEGIN FILE LIMIT PROCESSING. Enforce archive limits if applicable.
     if ($backup_type == 'full') {
         $limit = $full_archive_limit;
     } elseif ($backup_type == 'db') {
         $limit = $db_archive_limit;
     } elseif ($backup_type == 'files') {
         $limit = $files_archive_limit;
     } else {
         $limit = 0;
         pb_backupbuddy::status('warning', 'Warning #34352453244. Google Drive was unable to determine backup type (reported: `' . $backup_type . '`) so archive limits NOT enforced for this backup.');
     }
     pb_backupbuddy::status('details', 'Google Drive database backup archive limit of `' . $limit . '` of type `' . $backup_type . '` based on destination settings.');
     if ($limit > 0) {
         pb_backupbuddy::status('details', 'Google Drive archive limit enforcement beginning.');
         // Get file listing.
         $searchCount = 1;
         $remoteFiles = array();
         while (count($remoteFiles) == 0 && $searchCount < 5) {
             pb_backupbuddy::status('details', 'Checking archive limits. Attempt ' . $searchCount . '.');
             $remoteFiles = pb_backupbuddy_destination_gdrive::listFiles($settings, "title contains 'backup-' AND title contains '-" . $backup_type . "-' AND '" . $folderID . "' IN parents AND trashed=false");
             //"title contains 'backup' and trashed=false" );
             sleep(1);
             $searchCount++;
         }
         // List backups associated with this site by date.
         $backups = array();
         $prefix = backupbuddy_core::backup_prefix();
         foreach ($remoteFiles as $remoteFile) {
             if ('application/vnd.google-apps.folder' == $remoteFile->mimeType) {
                 // Ignore folders.
                 continue;
             }
             if (strpos($remoteFile->originalFilename, 'backup-' . $prefix . '-') !== false) {
                 // Appears to be a backup file for this site.
                 $backups[$remoteFile->id] = strtotime($remoteFile->modifiedDate);
             }
         }
         arsort($backups);
         pb_backupbuddy::status('details', 'Google Drive 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 . '`...');
                     if (true !== self::deleteFile($settings, $buname)) {
                         pb_backupbuddy::status('details', 'Unable to delete excess Google Drive file `' . $buname . '`. Details: `' . print_r($pb_backupbuddy_destination_errors, true) . '`.');
                         $delete_fail_count++;
                     }
                 }
             }
             pb_backupbuddy::status('details', 'Finished trimming excess backups.');
             if ($delete_fail_count !== 0) {
                 $error_message = 'Google Drive 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', 'Google Drive completed archive limiting.');
     } else {
         pb_backupbuddy::status('details', 'No Google Drive archive file limit to enforce.');
     }
     // End remote backup limit
     // Made it this far then success.
     return true;
 }
Пример #17
0
 function remotesend_abort()
 {
     $send_id = pb_backupbuddy::_GET('send_id');
     $send_id = str_replace('/\\', '', $send_id);
     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 = true, $create_file = false);
     if (true !== ($result = $fileoptions_obj->is_ok())) {
         pb_backupbuddy::status('error', __('Fatal Error #9034.324544. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
         return false;
     }
     pb_backupbuddy::status('details', 'Fileoptions data loaded.');
     $fileoptions =& $fileoptions_obj->options;
     $fileoptions['status'] = 'aborted';
     $fileoptions_obj->save();
     die('1');
 }
Пример #18
0
 public static function test($settings)
 {
     if ($settings['address'] == '' || $settings['username'] == '' || $settings['password'] == '') {
         return __('Missing required input.', 'it-l10n-backupbuddy');
     }
     // Try sending a file.
     $send_response = pb_backupbuddy_destinations::send($settings, dirname(dirname(__FILE__)) . '/remote-send-test.php', $send_id = 'TEST-' . pb_backupbuddy::random_string(12));
     // 3rd param true forces clearing of any current uploads.
     if (false === $send_response) {
         $send_response = 'Error sending test file to FTP.';
     } else {
         $send_response = 'Success.';
     }
     // Now we will need to go and cleanup this potentially uploaded file.
     $delete_response = 'Error deleting test file from FTP.';
     // Default.
     // Settings.
     $server = $settings['address'];
     $username = $settings['username'];
     $password = $settings['password'];
     $path = $settings['path'];
     $ftps = $settings['ftps'];
     if ($settings['active_mode'] == '0') {
         $active_mode = false;
     } else {
         $active_mode = true;
     }
     $url = $settings['url'];
     // optional url for using with migration.
     $port = '21';
     if (strstr($server, ':')) {
         $server_params = explode(':', $server);
         $server = $server_params[0];
         $port = $server_params[1];
     }
     // Connect.
     if ($ftps == '0') {
         $conn_id = @ftp_connect($server, $port, 10);
         // timeout of 10 seconds.
         if ($conn_id === false) {
             $error = __('Unable to connect to FTP address `' . $server . '` on port `' . $port . '`.', 'it-l10n-backupbuddy');
             $error .= "\n" . __('Verify the server address and port (default 21). Verify your host allows outgoing FTP connections.', 'it-l10n-backupbuddy');
             return $send_response . ' ' . $error;
         }
     } else {
         if (function_exists('ftp_ssl_connect')) {
             $conn_id = @ftp_ssl_connect($server, $port);
             if ($conn_id === false) {
                 return $send_response . ' ' . __('Destination server does not support FTPS?', 'it-l10n-backupbuddy');
             }
         } else {
             return $send_response . ' ' . __('Your web server doesnt support FTPS.', 'it-l10n-backupbuddy');
         }
     }
     $login_result = @ftp_login($conn_id, $username, $password);
     if (!$conn_id || !$login_result) {
         pb_backupbuddy::status('details', 'FTP test: Invalid user/pass.');
         $response = __('Unable to login. Bad user/pass.', 'it-l10n-backupbuddy');
         if ($ftps != '0') {
             $response .= "\n\nNote: You have FTPs enabled. You may get this error if your host does not support encryption at this address/port.";
         }
         return $send_response . ' ' . $response;
     }
     pb_backupbuddy::status('details', 'FTP test: Success logging in.');
     // Handle active/pasive mode.
     if ($active_mode === true) {
         // do nothing, active is default.
         pb_backupbuddy::status('details', 'Active FTP mode based on settings.');
     } elseif ($active_mode === false) {
         // Turn passive mode on.
         pb_backupbuddy::status('details', 'Passive FTP mode based on settings.');
         ftp_pasv($conn_id, true);
     } else {
         pb_backupbuddy::status('error', 'Unknown FTP active/passive mode: `' . $active_mode . '`.');
     }
     // Delete test file.
     pb_backupbuddy::status('details', 'FTP test: Deleting temp test file.');
     if (true === ftp_delete($conn_id, $path . '/remote-send-test.php')) {
         $delete_response = 'Success.';
     }
     // Close FTP connection.
     pb_backupbuddy::status('details', 'FTP test: Closing FTP connection.');
     @ftp_close($conn_id);
     // 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 #12.');
     $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.72373. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
         return false;
     }
     pb_backupbuddy::status('details', 'Fileoptions data loaded.');
     $fileoptions =& $fileoptions_obj->options;
     if ('Success.' != $send_response || 'Success.' != $delete_response) {
         $fileoptions['status'] = 'failure';
         $fileoptions_obj->save();
         unset($fileoptions_obj);
         return 'Send details: `' . $send_response . '`. Delete details: `' . $delete_response . '`.';
     } else {
         $fileoptions['status'] = 'success';
         $fileoptions['finish_time'] = time();
     }
     $fileoptions_obj->save();
     unset($fileoptions_obj);
     return true;
 }
Пример #19
0
 public static function send_remote_destination($destination_id, $file, $trigger = '', $send_importbuddy = false, $delete_after = false, $identifier = '', $destination_settings = '')
 {
     if (defined('PB_DEMO_MODE')) {
         return false;
     }
     if (!file_exists($file)) {
         pb_backupbuddy::status('error', 'Error #8583489734: Unable to send file `' . $file . '` to remote destination as it no longer exists. It may have been deleted or permissions are invalid.');
         return false;
     }
     $migrationkey_transient_time = 60 * 60 * 24;
     if ('' == $file) {
         $backup_file_size = 50000;
         // not sure why anything current would be sending importbuddy but NOT sending a backup but just in case...
     } else {
         $backup_file_size = filesize($file);
     }
     // Generate remote send ID for reference and add it as a new logging serial for better recording details.
     if ('' == $identifier) {
         $identifier = pb_backupbuddy::random_string(12);
     }
     // Set migration key for later determining last initiated migration.
     if ('migration' == $trigger) {
         set_transient('pb_backupbuddy_migrationkey', $identifier, $migrationkey_transient_time);
     }
     pb_backupbuddy::status('details', 'Sending file `' . $file . '` to remote destination `' . $destination_id . '` with ID `' . $identifier . '` triggered by `' . $trigger . '`.');
     //pb_backupbuddy::status( 'details', 'About to create initial fileoptions data.' );
     require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
     pb_backupbuddy::status('details', 'Fileoptions instance #35.');
     $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $identifier . '.txt', $read_only = false, $ignore_lock = true, $create_file = true);
     if (true !== ($result = $fileoptions_obj->is_ok())) {
         pb_backupbuddy::status('error', __('Fatal Error #9034 A. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
         return false;
     }
     //pb_backupbuddy::status( 'details', 'Fileoptions data loaded.' );
     $fileoptions =& $fileoptions_obj->options;
     // Set reference.
     // Record some statistics.
     $fileoptions = array_merge(self::get_remote_send_defaults(), array('destination' => $destination_id, 'file' => $file, 'file_size' => $backup_file_size, 'trigger' => $trigger, 'send_importbuddy' => $send_importbuddy, 'start_time' => time(), 'finish_time' => 0, 'status' => 'running', 'write_speed' => 0));
     pb_backupbuddy::save();
     // Destination settings were not passed so get them based on the destination ID provided.
     if (!is_array($destination_settings)) {
         $destination_settings =& pb_backupbuddy::$options['remote_destinations'][$destination_id];
     }
     // For Stash we will check the quota prior to initiating send.
     if (pb_backupbuddy::$options['remote_destinations'][$destination_id]['type'] == 'stash') {
         // Pass off to destination handler.
         require_once pb_backupbuddy::plugin_path() . '/destinations/bootstrap.php';
         $send_result = pb_backupbuddy_destinations::get_info('stash');
         // Used to kick the Stash destination into life.
         $stash_quota = pb_backupbuddy_destination_stash::get_quota(pb_backupbuddy::$options['remote_destinations'][$destination_id], true);
         if ($file != '') {
             $backup_file_size = filesize($file);
         } else {
             $backup_file_size = 50000;
         }
         if ($backup_file_size + $stash_quota['quota_used'] > $stash_quota['quota_total']) {
             $message = '';
             $message .= "You do not have enough Stash storage space to send this file. Please upgrade your Stash storage at http://ithemes.com/member/panel/stash.php or delete files to make space.\n\n";
             $message .= 'Attempting to send file of size ' . pb_backupbuddy::$format->file_size($backup_file_size) . ' but you only have ' . $stash_quota['quota_available_nice'] . ' available. ';
             $message .= 'Currently using ' . $stash_quota['quota_used_nice'] . ' of ' . $stash_quota['quota_total_nice'] . ' (' . $stash_quota['quota_used_percent'] . '%).';
             pb_backupbuddy::status('error', $message);
             backupbuddy_core::mail_error($message);
             $fileoptions['status'] = 'Failure. Insufficient destination space.';
             $fileoptions_obj->save();
             return false;
         } else {
             if (isset($stash_quota['quota_warning']) && $stash_quota['quota_warning'] != '') {
                 // We log warning of usage but dont send error email.
                 $message = '';
                 $message .= 'WARNING: ' . $stash_quota['quota_warning'] . "\n\nPlease upgrade your Stash storage at http://ithemes.com/member/panel/stash.php or delete files to make space.\n\n";
                 $message .= 'Currently using ' . $stash_quota['quota_used_nice'] . ' of ' . $stash_quota['quota_total_nice'] . ' (' . $stash_quota['quota_used_percent'] . '%).';
                 pb_backupbuddy::status('details', $message);
                 //backupbuddy_core::mail_error( $message );
             }
         }
     }
     // end if stash.
     /*
     if ( $send_importbuddy === true ) {
     	pb_backupbuddy::status( 'details', 'Generating temporary importbuddy.php file for remote send.' );
     	pb_backupbuddy::anti_directory_browsing( backupbuddy_core::getTempDirectory(), $die = false );
     	$importbuddy_temp = backupbuddy_core::getTempDirectory() . 'importbuddy.php'; // Full path & filename to temporary importbuddy
     	self::importbuddy( $importbuddy_temp ); // Create temporary importbuddy.
     	pb_backupbuddy::status( 'details', 'Generated temporary importbuddy.' );
     	$files[] = $importbuddy_temp; // Add importbuddy file to the list of files to send.
     	$send_importbuddy = true; // Track to delete after finished.
     } else {
     	pb_backupbuddy::status( 'details', 'Not sending importbuddy.' );
     }
     */
     // Clear fileoptions so other stuff can access it if needed.
     $fileoptions_obj->save();
     $fileoptions_obj->unlock();
     unset($fileoptions_obj);
     // Pass off to destination handler.
     require_once pb_backupbuddy::plugin_path() . '/destinations/bootstrap.php';
     pb_backupbuddy::status('details', 'Calling destination send() function.');
     $send_result = pb_backupbuddy_destinations::send($destination_settings, $file, $identifier, $delete_after);
     pb_backupbuddy::status('details', 'Finished destination send() function.');
     self::kick_db();
     // Kick the database to make sure it didn't go away, preventing options saving.
     // Reload fileoptions.
     pb_backupbuddy::status('details', 'About to load fileoptions data for saving send status.');
     require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
     pb_backupbuddy::status('details', 'Fileoptions instance #34.');
     $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $identifier . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
     if (true !== ($result = $fileoptions_obj->is_ok())) {
         pb_backupbuddy::status('error', __('Fatal Error #9034 G. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
         return false;
     }
     pb_backupbuddy::status('details', 'Fileoptions data loaded for ID `' . $identifier . '`.');
     $fileoptions =& $fileoptions_obj->options;
     // Set reference.
     // Update stats.
     $fileoptions[$identifier]['finish_time'] = microtime(true);
     if ($send_result === true) {
         // succeeded.
         $fileoptions['status'] = 'success';
         $fileoptions['finish_time'] = microtime(true);
         pb_backupbuddy::status('details', 'Remote send SUCCESS.');
     } elseif ($send_result === false) {
         // failed.
         $fileoptions['status'] = 'failure';
         pb_backupbuddy::status('details', 'Remote send FAILURE.');
     } elseif (is_array($send_result)) {
         // Array so multipart.
         $fileoptions['status'] = 'multipart';
         $fileoptions['finish_time'] = 0;
         $fileoptions['_multipart_id'] = $send_result[0];
         $fileoptions['_multipart_status'] = $send_result[1];
         pb_backupbuddy::status('details', 'Multipart send in progress.');
     } else {
         pb_backupbuddy::status('error', 'Error #5485785576463. Invalid status send result: `' . $send_result . '`.');
     }
     $fileoptions_obj->save();
     // If we sent importbuddy then delete the local copy to clean up.
     if ($send_importbuddy !== false) {
         @unlink($importbuddy_temp);
         // Delete temporary importbuddy.
     }
     // As of v5.0: Post-send deletion now handled within destinations/bootstrap.php send() to support chunked sends.
     return $send_result;
 }
Пример #20
0
 public static function test($settings)
 {
     if (class_exists('CFRuntime')) {
         die('CFRuntime already defined. Another plugin may be incorrectly loading its copy of S3 libraries on BackupBuddy pages.');
     }
     require_once dirname(dirname(__FILE__)) . '/_s3lib/aws-sdk/sdk.class.php';
     $remote_path = self::get_remote_path($settings['directory']);
     // Has leading and trailng slashes.
     $settings['bucket'] = strtolower($settings['bucket']);
     // Buckets must be lowercase.
     /*
     if ( FALSE !== strpos( $settings['bucket'], ' ' ) ) {
     	$message = 'Bucket names cannot have spaces in them.';
     	return $message;
     }
     */
     // Try sending a file.
     $send_response = pb_backupbuddy_destinations::send($settings, dirname(dirname(__FILE__)) . '/remote-send-test.php', $send_id = 'TEST-' . pb_backupbuddy::random_string(12));
     // 3rd param true forces clearing of any current uploads.
     if (false === $send_response) {
         $send_response = 'Error sending test file to S3.';
     } else {
         $send_response = 'Success.';
     }
     // S3 object for managing files.
     $credentials = pb_backupbuddy_destination_s3::get_credentials($settings);
     $s3_manage = new AmazonS3($credentials);
     if ($settings['ssl'] == 0) {
         @$s3_manage->disable_ssl(true);
     }
     // Verify bucket exists; create if not. Also set region to the region bucket exists in.
     if (false === self::_prepareBucketAndRegion($s3_manage, $settings)) {
         return false;
     }
     // Delete sent file.
     $delete_response = 'Success.';
     $delete_response = $s3_manage->delete_object($credentials['bucket'], $remote_path . 'remote-send-test.php');
     if (!$delete_response->isOK()) {
         $delete_response = 'Unable to delete test S3 file `remote-send-test.php`.';
         pb_backupbuddy::status('details', $delete_response . ' Details: `' . print_r($delete_response, true) . '`.');
     } else {
         $delete_response = 'Success.';
     }
     // 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 #7.');
     $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;
     if ('Success.' != $send_response || 'Success.' != $delete_response) {
         $fileoptions['status'] = 'failure';
         $fileoptions_obj->save();
         unset($fileoptions_obj);
         return 'Send details: `' . $send_response . '`. Delete details: `' . $delete_response . '`.';
     } else {
         $fileoptions['status'] = 'success';
         $fileoptions['finish_time'] = time();
     }
     $fileoptions_obj->save();
     unset($fileoptions_obj);
     return true;
 }
Пример #21
0
 public static function send($settings = array(), $files = array(), $send_id = '', $delete_after = false)
 {
     global $pb_backupbuddy_destination_errors;
     if ('1' == $settings['disabled']) {
         $pb_backupbuddy_destination_errors[] = __('Error #48933: This destination is currently disabled. Enable it under this destination\'s Advanced Settings.', 'it-l10n-backupbuddy');
         return false;
     }
     if (!is_array($files)) {
         $files = array($files);
     }
     self::$_timeStart = microtime(true);
     if (count($files) > 1) {
         $message = 'Error #84545894585: This destination currently only supports one file per send.';
         pb_backupbuddy::status('error', $message);
         global $pb_backupbuddy_destination_errors;
         $pb_backupbuddy_destination_errors[] = $message;
         return false;
     }
     require_once pb_backupbuddy::plugin_path() . '/classes/remote_api.php';
     $apiSettings = backupbuddy_remote_api::key_to_array($settings['api_key']);
     if (site_url() == $apiSettings['siteurl']) {
         $message = 'Error #4389843. You are trying to use this site\'s own API key. You must use the API key from the remote destination site.';
         pb_backupbuddy::status('error', $message);
         global $pb_backupbuddy_destination_errors;
         $pb_backupbuddy_destination_errors[] = $message;
         return false;
     }
     $apiURL = $apiSettings['siteurl'];
     $file = $files[0];
     $filePath = '';
     if ('' != $settings['sendFilePath']) {
         $filePath = $settings['sendFilePath'];
     }
     $maxPayload = $settings['max_payload'] * 1024 * 1024;
     // Convert to bytes.
     $encodeReducedPayload = floor(($settings['max_payload'] - $settings['max_payload'] * 0.37) * 1024 * 1024);
     // Take into account 37% base64 encoding overhead. Convert to bytes. Remove any decimals down via floor.
     // Open file for reading.
     if (FALSE === ($fs = @fopen($file, 'r'))) {
         pb_backupbuddy::status('error', 'Error #438934894: Unable to open file `' . $file . '` for reading.');
         return false;
     }
     // If chunked resuming then seek to the correct place in the file.
     if ('' != $settings['resume_point'] && $settings['resume_point'] > 0) {
         // Resuming send of a partially transferred file.
         if (0 !== fseek($fs, $settings['resume_point'])) {
             // Returns 0 on success.
             pb_backupbuddy::status('error', 'Error #327834783: Failed to seek file to resume point `' . $settings['resume_point'] . '` via fseek().');
             return false;
         }
         $prevPointer = $settings['resume_point'];
     } else {
         // New file send.
         $size = filesize($file);
         $encodedSize = $size * 0.37 + $size;
         pb_backupbuddy::status('details', 'File size of file to send: ' . pb_backupbuddy::$format->file_size($size) . '. After encoding overhead: ' . pb_backupbuddy::$format->file_size($encodedSize));
         if ($encodedSize > $maxPayload) {
             $settings['chunks_total'] = ceil($encodedSize / $maxPayload);
             // $maxPayload );
             pb_backupbuddy::status('details', 'This file + encoding exceeds the maximum per-chunk payload size so will be read in and sent in chunks of ' . $settings['max_payload'] . 'MB (' . $maxPayload . ' bytes) totaling approximately ' . $settings['chunks_total'] . ' chunks.');
         } else {
             pb_backupbuddy::status('details', 'This file + encoding does not exceed per-chunk payload size of ' . $settings['max_payload'] . 'MB (' . $maxPayload . ' bytes) so sending in one pass.');
         }
         $prevPointer = 0;
     }
     pb_backupbuddy::status('details', 'Reading in `' . $encodeReducedPayload . '` bytes at a time to send.');
     $dataRemains = true;
     //$loopCount = 0;
     //$loopTimeSum = 0; // Used for average send time per chunk.
     while (TRUE === $dataRemains && FALSE !== ($fileData = fread($fs, $encodeReducedPayload))) {
         // Grab one chunk of data at a time.
         pb_backupbuddy::status('details', 'Read in file data.');
         if (feof($fs)) {
             pb_backupbuddy::status('details', 'Read to end of file (feof true). No more chunks left after this send.');
             $dataRemains = false;
         }
         $isFileTest = false;
         if (false !== stristr(basename($file), 'remote-send-test.php')) {
             $isFileTest = true;
             $settings['sendType'] = 'test';
         }
         if (true === $dataRemains) {
             $isFileDone = false;
         } else {
             $isFileDone = true;
         }
         if (!isset($size)) {
             $size = '';
         }
         pb_backupbuddy::status('details', 'Connecting to remote server to send data.');
         $response = backupbuddy_remote_api::remoteCall($apiSettings, 'sendFile_' . $settings['sendType'], array(), $settings['max_time'], $file, $fileData, $prevPointer, $isFileTest, $isFileDone, $size, $filePath);
         unset($fileData);
         // Free up memory.
         $settings['chunks_sent']++;
         if (true === $dataRemains) {
             // More chunks remain.
             pb_backupbuddy::status('details', 'Connection finished sending part ' . $settings['chunks_sent'] . ' of ~' . $settings['chunks_total'] . '.');
         } else {
             // No more chunks remain.
             pb_backupbuddy::status('details', 'Connection finished sending final part ' . $settings['chunks_sent'] . '.');
         }
         if (false === $response) {
             echo implode(', ', backupbuddy_remote_api::getErrors()) . ' ';
             pb_backupbuddy::status('error', 'Errors encountered details: ' . implode(', ', backupbuddy_remote_api::getErrors()));
             global $pb_backupbuddy_destination_errors;
             $pb_backupbuddy_destination_errors[] = backupbuddy_remote_api::getErrors();
             return false;
             //implode( ', ', backupbuddy_remote_api::getErrors() );
         }
         if (FALSE === ($prevPointer = ftell($fs))) {
             pb_backupbuddy::status('error', 'Error #438347844: Unable to get ftell pointer of file handle for passing to prevPointer.');
             @fclose($fs);
             return false;
         } else {
             pb_backupbuddy::status('details', 'File pointer: `' . $prevPointer . '`.');
         }
         if (true === $dataRemains) {
             // More data remains so see if we need to consider chunking to a new PHP process.
             // If we are within X second of reaching maximum PHP runtime then stop here so that it can be picked up in another PHP process...
             if (microtime(true) - self::$_timeStart + self::TIME_WIGGLE_ROOM >= $settings['max_time']) {
                 pb_backupbuddy::status('message', 'Approaching limit of available PHP chunking time of `' . $settings['max_time'] . '` sec. Ran for ' . round(microtime(true) - self::$_timeStart, 3) . ' sec. Proceeding to use chunking.');
                 @fclose($fs);
                 // Tells next chunk where to pick up.
                 $settings['resume_point'] = $prevPointer;
                 // Schedule cron.
                 $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 Site chunk step cron event scheduled.');
                 } else {
                     pb_backupbuddy::status('error', 'Next Site 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($prevPointer, 'Sent part ' . $settings['chunks_sent'] . ' of ~' . $settings['chunks_total'] . ' parts.');
                 // filepointer location, elapsed time during the import
             } else {
                 // End if.
                 pb_backupbuddy::status('details', 'Not approaching time limit.');
             }
         } else {
             pb_backupbuddy::status('details', 'No more data remains (eg for chunking) so finishing up.');
         }
     }
     // end while data remains in file.
     // Update fileoptions stats.
     pb_backupbuddy::status('details', 'About to load fileoptions data.');
     require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
     pb_backupbuddy::status('details', 'Fileoptions instance #20.');
     $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.279327. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
         return false;
     }
     pb_backupbuddy::status('details', 'Fileoptions data loaded.');
     $fileoptions =& $fileoptions_obj->options;
     $fileoptions['finish_time'] = microtime(true);
     $fileoptions['status'] = 'success';
     $fileoptions['_multipart_status'] = 'Sent all parts.';
     if (isset($uploaded_speed)) {
         $fileoptions['write_speed'] = $uploaded_speed;
     }
     $fileoptions_obj->save();
     unset($fileoptions);
     // Made it this far so completed!
     pb_backupbuddy::status('message', 'Finished sending file. Took ' . round(microtime(true) - self::$_timeStart, 3) . ' seconds this round.');
     pb_backupbuddy::status('deployFileSent', 'File sent.');
     return true;
 }
Пример #22
0
 function backup_integrity_check($file, $fileoptions = '', $options = array())
 {
     $options = array_merge(array('skip_database_dump' => '0'), $options);
     pb_backupbuddy::status('details', 'Started backup_integrity_check() function.');
     $serial = $this->get_serial_from_file($file);
     // User selected to rescan a file.
     if (pb_backupbuddy::_GET('reset_integrity') == $serial) {
         pb_backupbuddy::alert('Rescanning backup integrity for backup file `' . basename($file) . '`');
     }
     if ($fileoptions != '') {
         $backup_options =& $fileoptions;
     } else {
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         $backup_options = new pb_backupbuddy_fileoptions(pb_backupbuddy::$options['log_directory'] . 'fileoptions/' . $serial . '.txt', $read_only = false, $ignore_lock = false, $create_file = true);
         // Will create file to hold integrity data if nothing exists.
         if (true !== ($result = $backup_options->is_ok())) {
             pb_backupbuddy::status('error', __('Fatal Error #9034 C. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error on file `' . pb_backupbuddy::$options['log_directory'] . 'fileoptions/' . $serial . '.txt' . '`: ' . $result);
             pb_backupbuddy::status('action', 'halt_script');
             // Halt JS on page.
             return false;
         }
         if (isset($backup_options->options['profile'])) {
             $options = $backup_options->options['profile'];
             $options = array_merge(pb_backupbuddy::settings('profile_defaults'), $options);
         }
     }
     if (isset($backup_options->options['integrity']) && count($backup_options->options['integrity']) > 0 && pb_backupbuddy::_GET('reset_integrity') != $serial) {
         // Already have integrity data and NOT resetting this one.
         pb_backupbuddy::status('details', 'Integrity data for backup `' . $serial . '` is cached; not scanning again.');
         return true;
     } elseif (pb_backupbuddy::_GET('reset_integrity') == $serial) {
         // Resetting this one.
         pb_backupbuddy::status('details', 'Resetting backup integrity stats for backup with serial `' . $serial . '`.');
     } else {
         // No integrity data; not resetting. Just keep going...
     }
     if (pb_backupbuddy::$options['profiles'][0]['integrity_check'] == '0' && pb_backupbuddy::_GET('reset_integrity') == '') {
         // Integrity checking disabled. Allows run if manually rescanning on backups page.
         pb_backupbuddy::status('details', 'Integrity check disabled. Skipping scan.');
         $file_stats = @stat($file);
         if ($file_stats === false) {
             // stat failure.
             pb_backupbuddy::status('error', 'Error #4539774. Unable to get file details ( via stat() ) for file `' . $file . '`. The file may be corrupt or too large for the server.');
             $file_size = 0;
             $file_modified = 0;
         } else {
             // stat success.
             $file_size = $file_stats['size'];
             $file_modified = $file_stats['mtime'];
         }
         unset($file_stats);
         $integrity = array('status' => 'Unknown', 'tests' => array(), 'scan_time' => 0, 'detected_type' => 'unknown', 'size' => $file_size, 'modified' => $file_modified, 'file' => basename($file), 'comment' => false);
         $backup_options->options['integrity'] = array_merge(pb_backupbuddy::settings('backups_integrity_defaults'), $integrity);
         $backup_options->save();
         return true;
     }
     //***** BEGIN CALCULATING STATUS DETAILS.
     $backup_type = '';
     if (!isset(pb_backupbuddy::$classes['zipbuddy'])) {
         require_once pb_backupbuddy::plugin_path() . '/lib/zipbuddy/zipbuddy.php';
         pb_backupbuddy::$classes['zipbuddy'] = new pluginbuddy_zipbuddy(pb_backupbuddy::$options['backup_directory']);
     }
     pb_backupbuddy::status('details', 'Redirecting status logging temporarily.');
     $previous_status_serial = pb_backupbuddy::get_status_serial();
     // Store current status serial setting to reset back later.
     pb_backupbuddy::set_status_serial('zipbuddy_test');
     // Redirect logging output to a certain log file.
     // Look for comment.
     pb_backupbuddy::status('details', 'Verifying comment in zip archive.');
     $raw_comment = pb_backupbuddy::$classes['zipbuddy']->get_comment($file);
     $comment = pb_backupbuddy::$classes['core']->normalize_comment_data($raw_comment);
     $comment = $comment['note'];
     $tests = array();
     // Check for DAT file.
     $pass = false;
     pb_backupbuddy::status('details', 'Verifying DAT file in zip archive.');
     if (pb_backupbuddy::$classes['zipbuddy']->file_exists($file, 'wp-content/uploads/backupbuddy_temp/' . $serial . '/backupbuddy_dat.php') === true) {
         // Post 2.0 full backup
         $backup_type = 'full';
         $pass = true;
     }
     if (pb_backupbuddy::$classes['zipbuddy']->file_exists($file, 'wp-content/uploads/temp_' . $serial . '/backupbuddy_dat.php') === true) {
         // Pre 2.0 full backup
         $backup_type = 'full';
         $pass = true;
     }
     if (pb_backupbuddy::$classes['zipbuddy']->file_exists($file, 'backupbuddy_dat.php') === true) {
         // DB backup
         $backup_type = 'db';
         $pass = true;
     }
     $tests[] = array('test' => 'BackupBackup data file exists', 'pass' => $pass);
     // Skip database checks if needed.
     //if ( $options['skip_database_dump'] != '1' ) {
     // Check for DB SQL file.
     $pass = false;
     pb_backupbuddy::status('details', 'Verifying database SQL file in zip archive.');
     if ($options['skip_database_dump'] == '1') {
         pb_backupbuddy::status('warning', 'WARNING: Database .SQL file does NOT exist because the database dump has been set to be SKIPPED based on settings. Use with cuation!');
     } else {
         if (pb_backupbuddy::$classes['zipbuddy']->file_exists($file, 'wp-content/uploads/backupbuddy_temp/' . $serial . '/db_1.sql') === true) {
             // post 2.0 full backup
             $backup_type = 'full';
             $pass = true;
         }
         if (pb_backupbuddy::$classes['zipbuddy']->file_exists($file, 'wp-content/uploads/temp_' . $serial . '/db.sql') === true) {
             // pre 2.0 full backup
             $backup_type = 'full';
             $pass = true;
         }
         if (pb_backupbuddy::$classes['zipbuddy']->file_exists($file, 'db_1.sql') === true) {
             // db only backup 2.0+
             $backup_type = 'db';
             $pass = true;
         }
         if (pb_backupbuddy::$classes['zipbuddy']->file_exists($file, 'db.sql') === true) {
             // db only backup pre-2.0
             $backup_type = 'db';
             $pass = true;
         }
     }
     $tests[] = array('test' => 'Database SQL file exists', 'pass' => $pass);
     // NOTE: As of 4.0 ALL db dumps append into db_1.sql. Future: break out into individual files. Check DB SQL files for BREAKOUT tables.
     /*
     if ( isset( $backup_options->options['breakout_tables'] ) && ( count( $backup_options->options['breakout_tables'] ) > 0 ) ) {
     	foreach( $backup_options->options['breakout_tables'] as $breakout_table ) {
     		$pass = false;
     		if ( pb_backupbuddy::$classes['zipbuddy']->file_exists( $file, 'wp-content/uploads/backupbuddy_temp/' . $serial . '/' . $breakout_table . '.sql' ) === true ) { // Full backup.
     			$pass = true;
     		}
     		if ( pb_backupbuddy::$classes['zipbuddy']->file_exists( $file, $breakout_table . '.sql' ) === true ) { // DB backup.
     			$pass = true;
     		}
     		$tests[] = array(
     			'test'		=>	'Breakout Database SQL file exists (' . $breakout_table . '.sql)',
     			'pass'		=>	$pass,
     		);
     	}
     }
     */
     // }
     if ('full' == $backup_type) {
         // Check for WordPress config file.
         $pass = false;
         pb_backupbuddy::status('details', 'Verifying WordPress wp-config.php configuration file in zip archive.');
         if (pb_backupbuddy::$classes['zipbuddy']->file_exists($file, 'wp-config.php') === true) {
             $pass = true;
         }
         if (pb_backupbuddy::$classes['zipbuddy']->file_exists($file, 'wp-content/uploads/backupbuddy_temp/' . $serial . '/wp-config.php') === true) {
             $pass = true;
         }
         $tests[] = array('test' => 'WordPress wp-config.php exists (full backups only)', 'pass' => $pass);
     }
     // Get zip scan log details.
     pb_backupbuddy::status('details', 'Retrieving zip scan log.');
     $temp_details = pb_backupbuddy::get_status('zipbuddy_test');
     // Get zipbuddy scan log.
     $scan_log = array();
     foreach ($temp_details as $temp_detail) {
         $scan_log[] = $temp_detail[4];
     }
     pb_backupbuddy::set_status_serial($previous_status_serial);
     // Stop redirecting log to a specific file & set back to what it was prior.
     pb_backupbuddy::status('details', 'Stopped temporary redirection of status logging.');
     pb_backupbuddy::status('details', 'Calculating integrity scan status,');
     // Check for any failed tests.
     $is_ok = true;
     $integrity_description = '';
     foreach ($tests as $test) {
         if ($test['pass'] !== true) {
             $is_ok = false;
             $error = 'Error #389434. Integrity test FAILED. Test: `' . $test['test'] . '`. ';
             pb_backupbuddy::status('error', $error);
             $integrity_description .= $error;
         }
     }
     if (true === $is_ok) {
         $integrity_status = 'Pass';
     } else {
         $integrity_status = 'Fail';
     }
     pb_backupbuddy::status('details', 'Status: `' . $integrity_status . '`. Description: `' . $integrity_description . '`.');
     //***** END CALCULATING STATUS DETAILS.
     // Get file information from file system.
     pb_backupbuddy::status('details', 'Getting file details such as size, timestamp, etc.');
     $file_stats = @stat($file);
     if ($file_stats === false) {
         // stat failure.
         pb_backupbuddy::status('error', 'Error #4539774b. Unable to get file details ( via stat() ) for file `' . $file . '`. The file may be corrupt or too large for the server.');
         $file_size = 0;
         $file_modified = 0;
     } else {
         // stat success.
         $file_size = $file_stats['size'];
         $file_modified = $file_stats['ctime'];
         // Created time.
     }
     unset($file_stats);
     // Compile array of results for saving into data structure.
     $integrity = array('is_ok' => $is_ok, 'tests' => $tests, 'scan_time' => time(), 'scan_log' => $scan_log, 'detected_type' => $backup_type, 'size' => $file_size, 'modified' => $file_modified, 'file' => basename($file), 'comment' => $comment);
     pb_backupbuddy::status('details', 'Saving backup file integrity check details.');
     $backup_options->options['integrity'] = array_merge(pb_backupbuddy::settings('backups_integrity_defaults'), $integrity);
     $backup_options->save();
     return $is_ok;
 }
Пример #23
0
 public static function test($settings)
 {
     $remote_path = self::get_remote_path($settings['directory']);
     // Has leading and trailng slashes.
     $manage_data = pb_backupbuddy_destination_stash::get_manage_data($settings);
     if (!is_array($manage_data['credentials'])) {
         // Credentials were somehow faulty. User changed password after prior page? Unlikely but you never know...
         $error_msg = 'Error #8484383c: 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?';
         pb_backupbuddy::status('error', $error_msg);
         return $error_msg;
     }
     // Try sending a file.
     $send_response = pb_backupbuddy_destinations::send($settings, dirname(dirname(__FILE__)) . '/remote-send-test.php', $send_id = 'TEST-' . pb_backupbuddy::random_string(12));
     // 3rd param true forces clearing of any current uploads.
     if (false === $send_response) {
         $send_response = 'Error sending test file to Stash.';
     } else {
         $send_response = 'Success.';
     }
     // S3 object for managing files.
     $credentials = pb_backupbuddy_destination_stash::get_manage_data($settings);
     $s3_manage = new AmazonS3($manage_data['credentials']);
     if ($settings['ssl'] == 0) {
         @$s3_manage->disable_ssl(true);
     }
     // Delete sent file.
     $delete_response = 'Success.';
     $delete_response = $s3_manage->delete_object($manage_data['bucket'], $manage_data['subkey'] . $remote_path . 'remote-send-test.php');
     if (!$delete_response->isOK()) {
         $delete_response = 'Unable to delete test Stash file `remote-send-test.php`. Details: `' . print_r($response, true) . '`.';
         pb_backupbuddy::status('details', $delete_response);
     } else {
         $delete_response = 'Success.';
     }
     // 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;
     if ('Success.' != $send_response || 'Success.' != $delete_response) {
         $fileoptions['status'] = 'failure';
         $fileoptions_obj->save();
         unset($fileoptions_obj);
         return 'Send details: `' . $send_response . '`. Delete details: `' . $delete_response . '`.';
     } else {
         $fileoptions['status'] = 'success';
         $fileoptions['finish_time'] = time();
     }
     $fileoptions_obj->save();
     unset($fileoptions_obj);
     return true;
 }
Пример #24
0
 public static function test($settings)
 {
     // Try sending a file.
     $send_response = pb_backupbuddy_destinations::send($settings, dirname(dirname(__FILE__)) . '/remote-send-test.php', $send_id = 'TEST-' . pb_backupbuddy::random_string(12));
     // 3rd param true forces clearing of any current uploads.
     if (false === $send_response) {
         $send_response = 'Error sending test file to Stash (v2).';
     } else {
         $send_response = 'Success.';
     }
     die;
     // Delete sent file.
     $delete_response = 'Success.';
     $delete_response = self::delete('remote-send-test.php');
     if (!$delete_response->isOK()) {
         $delete_response = 'Unable to delete test Stash file `remote-send-test.php`. Details: `' . print_r($response, true) . '`.';
         pb_backupbuddy::status('details', $delete_response);
     } else {
         $delete_response = 'Success.';
     }
     // 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 #223.');
     $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.828238. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
         return false;
     }
     pb_backupbuddy::status('details', 'Fileoptions data loaded.');
     $fileoptions =& $fileoptions_obj->options;
     if ('Success.' != $send_response || 'Success.' != $delete_response) {
         $fileoptions['status'] = 'failure';
         $fileoptions_obj->save();
         unset($fileoptions_obj);
         return 'Send details: `' . $send_response . '`. Delete details: `' . $delete_response . '`.';
     } else {
         $fileoptions['status'] = 'success';
         $fileoptions['finish_time'] = microtime(true);
     }
     $fileoptions_obj->save();
     unset($fileoptions_obj);
     return true;
 }