Exemplo n.º 1
0
 /**
  * Implements the _run() abstract method
  */
 function _run()
 {
     if ($this->getState() == 'postrun') {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, __CLASS__ . " :: Already finished");
         $this->setStep('');
         $this->setSubstep('');
     } else {
         $this->setState('running');
     }
     // Try to step the archiver
     $archive = AEFactory::getArchiverEngine();
     $ret = $archive->transformJPA($this->xformIndex, $this->offset);
     // Error propagation
     $this->propagateFromObject($archive);
     if ($ret !== false && $archive->getError() == '') {
         $this->offset = $ret['offset'];
         $this->xformIndex = $ret['index'];
         $this->setStep($ret['filename']);
     }
     // Check for completion
     if ($ret['done']) {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, __CLASS__ . ":: archive is initialized");
         $this->setState('finished');
     }
     // Calculate percentage
     $this->runningSize += $ret['chunkProcessed'];
     if ($ret['filesize'] > 0) {
         $this->progress = $this->runningSize / $ret['filesize'];
     }
 }
Exemplo n.º 2
0
 /**
  * Implements the _run() abstract method
  */
 protected function _run()
 {
     if ($this->getState() == 'postrun') {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, __CLASS__ . " :: Already finished");
         $this->setStep('');
         $this->setSubstep('');
         return;
     } else {
         $this->setState('running');
     }
     // Load the version defines
     AEPlatform::getInstance()->load_version_defines();
     $registry = AEFactory::getConfiguration();
     // Write log file's header
     AEUtilLogger::WriteLog(_AE_LOG_INFO, "--------------------------------------------------------------------------------");
     AEUtilLogger::WriteLog(_AE_LOG_INFO, "Akeeba Backup " . AKEEBA_VERSION . ' (' . AKEEBA_DATE . ')');
     AEUtilLogger::WriteLog(_AE_LOG_INFO, "Got backup?");
     AEUtilLogger::WriteLog(_AE_LOG_INFO, "--------------------------------------------------------------------------------");
     // PHP configuration variables are tried to be logged only for debug and info log levels
     if ($registry->get('akeeba.basic.log_level') >= _AE_LOG_INFO) {
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "--- System Information ---");
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "PHP Version        :" . PHP_VERSION);
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "PHP OS             :" . PHP_OS);
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "PHP SAPI           :" . PHP_SAPI);
         if (function_exists('php_uname')) {
             AEUtilLogger::WriteLog(_AE_LOG_INFO, "OS Version         :" . php_uname('s'));
         }
         $db = AEFactory::getDatabase();
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "DB Version         :" . $db->getVersion());
         if (isset($_SERVER['SERVER_SOFTWARE'])) {
             $server = $_SERVER['SERVER_SOFTWARE'];
         } else {
             if ($sf = getenv('SERVER_SOFTWARE')) {
                 $server = $sf;
             } else {
                 $server = 'n/a';
             }
         }
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Web Server         :" . $server);
         $platform = 'Unknown platform';
         $version = '(unknown version)';
         $platformData = AEPlatform::getInstance()->getPlatformVersion();
         AEUtilLogger::WriteLog(_AE_LOG_INFO, $platformData['name'] . " version    :" . $platformData['version']);
         if (isset($_SERVER['HTTP_USER_AGENT'])) {
             AEUtilLogger::WriteLog(_AE_LOG_INFO, "User agent         :" . phpversion() <= "4.2.1" ? getenv("HTTP_USER_AGENT") : $_SERVER['HTTP_USER_AGENT']);
         }
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Safe mode          :" . ini_get("safe_mode"));
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Display errors     :" . ini_get("display_errors"));
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Error reporting    :" . self::error2string());
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Error display      :" . self::errordisplay());
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Disabled functions :" . ini_get("disable_functions"));
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "open_basedir restr.:" . ini_get('open_basedir'));
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Max. exec. time    :" . ini_get("max_execution_time"));
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Memory limit       :" . ini_get("memory_limit"));
         if (function_exists("memory_get_usage")) {
             AEUtilLogger::WriteLog(_AE_LOG_INFO, "Current mem. usage :" . memory_get_usage());
         }
         if (function_exists("gzcompress")) {
             AEUtilLogger::WriteLog(_AE_LOG_INFO, "GZIP Compression   : available (good)");
         } else {
             AEUtilLogger::WriteLog(_AE_LOG_INFO, "GZIP Compression   : n/a (no compression)");
         }
         AEPlatform::getInstance()->log_platform_special_directories();
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Output directory   :" . $registry->get('akeeba.basic.output_directory'));
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "--------------------------------------------------------------------------------");
     }
     // Quirks reporting
     $quirks = AEUtilQuirks::get_quirks(true);
     if (!empty($quirks)) {
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Akeeba Backup has detected the following potential problems:");
         foreach ($quirks as $q) {
             AEUtilLogger::WriteLog(_AE_LOG_INFO, '- ' . $q['code'] . ' ' . $q['description'] . ' (' . $q['severity'] . ')');
         }
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "You probably do not have to worry about them, but you should be aware of them.");
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "--------------------------------------------------------------------------------");
     }
     if (!version_compare(PHP_VERSION, '5.3.0', 'ge')) {
         AEUtilLogger::WriteLog(_AE_LOG_WARNING, "You are using an outdated version of PHP. Akeeba Engine may not work properly. Please upgrade to PHP 5.3 or later.");
     }
     // Report profile ID
     $profile_id = AEPlatform::getInstance()->get_active_profile();
     AEUtilLogger::WriteLog(_AE_LOG_INFO, "Loaded profile #{$profile_id}");
     // Get archive name
     AEUtilFilesystem::get_archive_name($relativeArchiveName, $absoluteArchiveName);
     // ==== Stats initialisation ===
     $origin = AEPlatform::getInstance()->get_backup_origin();
     // Get backup origin
     $profile_id = AEPlatform::getInstance()->get_active_profile();
     // Get active profile
     $registry = AEFactory::getConfiguration();
     $backupType = $registry->get('akeeba.basic.backup_type');
     AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Backup type is now set to '" . $backupType . "'");
     // Substitute "variables" in the archive name
     $description = AEUtilFilesystem::replace_archive_name_variables($this->description);
     $comment = AEUtilFilesystem::replace_archive_name_variables($this->comment);
     if ($registry->get('volatile.writer.store_on_server', true)) {
         // Archive files are stored on our server
         $stat_relativeArchiveName = $relativeArchiveName;
         $stat_absoluteArchiveName = $absoluteArchiveName;
     } else {
         // Archive files are not stored on our server (FTP backup, cloud backup, sent by email, etc)
         $stat_relativeArchiveName = '';
         $stat_absoluteArchiveName = '';
     }
     $kettenrad = AEFactory::getKettenrad();
     $temp = array('description' => $description, 'comment' => $comment, 'backupstart' => AEPlatform::getInstance()->get_timestamp_database(), 'status' => 'run', 'origin' => $origin, 'type' => $backupType, 'profile_id' => $profile_id, 'archivename' => $stat_relativeArchiveName, 'absolute_path' => $stat_absoluteArchiveName, 'multipart' => 0, 'filesexist' => 1, 'tag' => $kettenrad->getTag());
     // Save the entry
     $statistics = AEFactory::getStatistics();
     $statistics->setStatistics($temp);
     if ($statistics->getError()) {
         $this->setError($statistics->getError());
         return;
     }
     $statistics->release_multipart_lock();
     // Initialize the archive.
     if (AEUtilScripting::getScriptingParameter('core.createarchive', true)) {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Expanded archive file name: " . $absoluteArchiveName);
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Initializing archiver engine");
         $archiver = AEFactory::getArchiverEngine();
         $archiver->initialize($absoluteArchiveName);
         $archiver->setComment($comment);
         // Add the comment to the archive itself.
         $archiver->propagateToObject($this);
         if ($this->getError()) {
             return;
         }
     }
     $this->setState('postrun');
 }
Exemplo n.º 3
0
 /**
  * Implements the _finalize() abstract method
  *
  */
 protected function _finalize()
 {
     $this->setState('finished');
     // If we are in db backup mode, don't create a databases.ini
     $configuration = AEFactory::getConfiguration();
     if (!AEUtilScripting::getScriptingParameter('db.databasesini', 1)) {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, __CLASS__ . " :: Skipping databases.ini");
     } else {
         // Create the databases.ini contents
         if ($this->installerSettings->databasesini) {
             $this->createDatabasesINI();
             AEUtilLogger::WriteLog(_AE_LOG_DEBUG, __CLASS__ . " :: Creating databases.ini");
             // Create a new string
             $databasesINI = $this->databases_ini;
             // BEGIN FIX 1.2 Stable -- databases.ini isn't written on disk
             AEUtilLogger::WriteLog(_AE_LOG_DEBUG, __CLASS__ . " :: Writing databases.ini contents");
             $archiver = AEFactory::getArchiverEngine();
             $virtualLocation = AEUtilScripting::getScriptingParameter('db.saveasname', 'normal') == 'short' ? '' : $this->installerSettings->sqlroot;
             $archiver->addVirtualFile('databases.ini', $virtualLocation, $databasesINI);
             // Error propagation
             $this->propagateFromObject($archiver);
             if ($this->getError()) {
                 return false;
             }
         }
     }
     // On alldb mode, we have to finalize the archive as well
     if (AEUtilScripting::getScriptingParameter('db.finalizearchive', 0)) {
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Finalizing database dump archive");
         $archiver = AEFactory::getArchiverEngine();
         $archiver->finalize();
         // Error propagation
         $this->propagateFromObject($archiver);
         if ($this->getError()) {
             return false;
         }
     }
     // In CLI mode we'll also close the database connection
     if (defined('AKEEBACLI')) {
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Closing the database connection to the main database");
         $db = AEFactory::unsetDatabase();
     }
     return true;
 }
Exemplo n.º 4
0
 /**
  * Try to pack some files in the $file_list, restraining ourselves not to reach the max
  * number of files or max fragment size while doing so. If this process is over and we are
  * left without any more files, reset $done_scanning to false in order to instruct the class
  * to scan for more files.
  *
  * @return bool True if there were files packed, false otherwise (empty filelist)
  */
 private function pack_files()
 {
     // Get a reference to the archiver and the timer classes
     $archiver = AEFactory::getArchiverEngine();
     $timer = AEFactory::getTimer();
     $configuration = AEFactory::getConfiguration();
     // If post-processing after part creation is enabled, make sure we do post-process each part before moving on
     if ($configuration->get('engine.postproc.common.after_part', 0)) {
         if (!empty($archiver->finishedPart)) {
             $filename = array_shift($archiver->finishedPart);
             AEUtilLogger::WriteLog(_AE_LOG_INFO, 'Preparing to post process ' . basename($filename));
             $post_proc = AEFactory::getPostprocEngine();
             $result = $post_proc->processPart($filename);
             $this->propagateFromObject($post_proc);
             if ($result === false) {
                 $this->setWarning('Failed to process file ' . basename($filename));
             } else {
                 AEUtilLogger::WriteLog(_AE_LOG_INFO, 'Successfully processed file ' . basename($filename));
             }
             // Should we delete the file afterwards?
             if ($configuration->get('engine.postproc.common.delete_after', false) && $post_proc->allow_deletes && $result !== false) {
                 AEUtilLogger::WriteLog(_AE_LOG_DEBUG, 'Deleting already processed file ' . basename($filename));
                 AEPlatform::getInstance()->unlink($filename);
             }
             if ($post_proc->break_after && $result !== false) {
                 $configuration->set('volatile.breakflag', true);
                 return true;
             }
             // This is required to let the backup continue even after a post-proc failure
             $this->resetErrors();
             $this->setState('running');
         }
     }
     // If the archiver has work to do, make sure it finished up before continuing
     if ($configuration->get('volatile.engine.archiver.processingfile', false)) {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Continuing file packing from previous step");
         $result = $archiver->addFile('', '', '');
         $this->propagateFromObject($archiver);
         if ($this->getError()) {
             return false;
         }
         // If that was the last step, mark a file done
         if (!$configuration->get('volatile.engine.archiver.processingfile', false)) {
             $this->progressMarkFileDone();
         }
     }
     // Did it finish, or does it have more work to do?
     if ($configuration->get('volatile.engine.archiver.processingfile', false)) {
         // More work to do. Let's just tell our parent that we finished up successfully.
         return true;
     }
     // Normal file backup loop; we keep on processing the file list, packing files as we go.
     if (count($this->file_list) == 0) {
         // No files left to pack -- This should never happen! We catch this condition at the end of this method!
         $this->done_scanning = false;
         $this->progressMarkFolderDone();
         return false;
     } else {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Packing files");
         $packedSize = 0;
         $numberOfFiles = 0;
         list($usec, $sec) = explode(" ", microtime());
         $opStartTime = (double) $usec + (double) $sec;
         while (count($this->file_list) > 0) {
             $file = @array_shift($this->file_list);
             $size = 0;
             if (file_exists($file)) {
                 $size = @filesize($file);
             }
             // Anticipatory file size algorithm
             if ($numberOfFiles > 0 && $size > AELargeFileThreshold) {
                 if (!AEFactory::getConfiguration()->get('akeeba.tuning.nobreak.beforelargefile', 0)) {
                     // If the file is bigger than the big file threshold, break the step
                     // to avoid potential timeouts
                     $this->setBreakFlag();
                     AEUtilLogger::WriteLog(_AE_LOG_INFO, "Breaking step _before_ large file: " . $file . " - size: " . $size);
                     // Push the file back to the list.
                     array_unshift($this->file_list, $file);
                     // Mark that we are not done packing files
                     $this->done_scanning = true;
                     return true;
                 }
             }
             // Proactive potential timeout detection
             // Rough estimation of packing speed in bytes per second
             list($usec, $sec) = explode(" ", microtime());
             $opEndTime = (double) $usec + (double) $sec;
             if ($opEndTime - $opStartTime == 0) {
                 $_packSpeed = 0;
             } else {
                 $_packSpeed = $packedSize / ($opEndTime - $opStartTime);
             }
             // Estimate required time to pack next file. If it's the first file of this operation,
             // do not impose any limitations.
             $_reqTime = $_packSpeed - 0.01 <= 0 ? 0 : $size / $_packSpeed;
             // Do we have enough time?
             if ($timer->getTimeLeft() < $_reqTime) {
                 if (!AEFactory::getConfiguration()->get('akeeba.tuning.nobreak.proactive', 0)) {
                     array_unshift($this->file_list, $file);
                     AEUtilLogger::WriteLog(_AE_LOG_INFO, "Proactive step break - file: " . $file . " - size: " . $size . " - req. time " . sprintf('%2.2f', $_reqTime));
                     $this->setBreakFlag();
                     $this->done_scanning = true;
                     return true;
                 }
             }
             $packedSize += $size;
             $numberOfFiles++;
             $ret = $archiver->addFile($file, $this->remove_path_prefix, $this->path_prefix);
             // If no more processing steps are required, mark a done file
             if (!$configuration->get('volatile.engine.archiver.processingfile', false)) {
                 $this->progressMarkFileDone();
             }
             // Error propagation
             $this->propagateFromObject($archiver);
             if ($this->getError()) {
                 return false;
             }
             // If this was the first file of the fragment and it exceeded the fragment's capacity,
             // break the step. Continuing with more operations after packing such a big file is
             // increasing the risk to hit a timeout.
             if ($packedSize > AELargeFileThreshold && $numberOfFiles == 1) {
                 if (!AEFactory::getConfiguration()->get('akeeba.tuning.nobreak.afterlargefile', 0)) {
                     AEUtilLogger::WriteLog(_AE_LOG_INFO, "Breaking step *after* large file: " . $file . " - size: " . $size);
                     $this->setBreakFlag();
                     return true;
                 }
             }
             // If we have to continue processing the file, break the file packing loop forcibly
             if ($configuration->get('volatile.engine.archiver.processingfile', false)) {
                 return true;
             }
         }
         $this->done_scanning = count($this->file_list) > 0;
         if (!$this->done_scanning) {
             $this->progressMarkFolderDone();
         }
         return true;
     }
 }
 /**
  * Creates a new dump part
  */
 protected function getNextDumpPart()
 {
     // On database dump only mode we mustn't create part files!
     if (AEUtilScripting::getScriptingParameter('db.saveasname', 'normal') == 'output') {
         return false;
     }
     // If the archiver is still processing, quit
     $finished = true;
     $configuration = AEFactory::getConfiguration();
     $archiver = AEFactory::getArchiverEngine();
     if ($configuration->get('volatile.engine.archiver.processingfile', false)) {
         return false;
     }
     // We have to add the dump file to the archive
     $this->closeFile();
     AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Adding the SQL dump part to the archive");
     $archiver->addFileRenamed($this->tempFile, $this->saveAsName);
     if ($this->getError()) {
         return false;
     }
     $finished = !$configuration->get('volatile.engine.archiver.processingfile', false);
     if (!$finished) {
         return false;
     }
     // Return if the file didn't finish getting added to the archive
     // Remove the old file
     AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Removing dump part's temporary file");
     AEUtilTempfiles::unregisterAndDeleteTempFile($this->tempFile, true);
     // Create the new dump part
     $this->partNumber++;
     $this->getBackupFilePaths($this->partNumber);
     $null = null;
     $this->writeline($null);
     return true;
 }
Exemplo n.º 6
0
 /**
  * Steps the files scanning of the current directory
  *
  * @return  boolean  True on success, false on fatal error
  */
 private function scanFiles()
 {
     $engine = AEFactory::getScanEngine();
     list($root, $translated_root, $dir) = $this->getCleanDirectoryComponents();
     // Get a filters instance
     $filters = AEFactory::getFilters();
     if (is_null($this->getFiles_position)) {
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Scanning files of " . $this->current_directory);
         $this->processed_files_counter = 0;
     } else {
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Resuming scanning files of " . $this->current_directory);
     }
     // Get file listing
     $fileList = $engine->getFiles($this->current_directory, $this->getFiles_position);
     // Error propagation
     $this->propagateFromObject($engine);
     // If the list contains "too many" items, please break this step!
     if (AEFactory::getConfiguration()->get('volatile.breakflag', false)) {
         // Log the step break decision, for debugging reasons
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Large directory " . $this->current_directory . " while scanning for files; I will resume scanning in next step.");
         // Return immediately, marking that we are not done yet!
         return true;
     }
     // Error control
     if ($this->getError()) {
         return false;
     }
     // Do I have an unreadable directory?
     if ($fileList === false) {
         $this->setWarning('Unreadable directory ' . $this->current_directory);
         $this->done_file_scanning = true;
     } else {
         if (is_array($fileList) && !empty($fileList)) {
             // Add required trailing slash to $dir
             if (!empty($dir)) {
                 $dir .= '/';
             }
             // Scan all directory entries
             foreach ($fileList as $fileName) {
                 $check = $dir . basename($fileName);
                 if (_AKEEBA_IS_WINDOWS) {
                     $check = AEUtilFilesystem::TranslateWinPath($check);
                 }
                 // Do I need this? $dir contains a path relative to the root anyway...
                 $check = ltrim(str_replace($translated_root, '', $check), '/');
                 $byFilter = '';
                 $skipThisFile = $filters->isFilteredExtended($check, $root, 'file', 'all', $byFilter);
                 if ($skipThisFile) {
                     AEUtilLogger::WriteLog(_AE_LOG_INFO, "Skipping file {$fileName} (filter: {$byFilter})");
                 } else {
                     $this->file_list[] = $fileName;
                     $this->processed_files_counter++;
                     $this->progressAddFile();
                 }
             }
         }
     }
     // If the scanner engine nullified the next position we are done
     // scanning for files
     if (is_null($this->getFiles_position)) {
         $this->done_file_scanning = true;
     }
     // If the directory was genuinely empty we will have to add an empty
     // directory entry in the archive, otherwise this directory will never
     // be restored.
     if ($this->done_file_scanning && $this->processed_files_counter == 0) {
         AEUtilLogger::WriteLog(_AE_LOG_INFO, "Empty directory " . $this->current_directory);
         $archiver = AEFactory::getArchiverEngine();
         if ($this->current_directory != $this->remove_path_prefix) {
             $archiver->addFile($this->current_directory, $this->remove_path_prefix, $this->path_prefix);
         }
         // Error propagation
         $this->propagateFromObject($archiver);
         // Check for errors
         if ($this->getError()) {
             return false;
         }
         unset($archiver);
     }
     return true;
 }
Exemplo n.º 7
0
 /**
  * Returns the relative and absolute path to the archive, if defined
  *
  * @param    string $relative The relative path
  * @param    string $absolute The absolute path
  */
 public static function get_archive_name(&$relative, &$absolute)
 {
     static $relative_path = null;
     static $absolute_path = null;
     if (is_null($relative_path) || is_null($absolute_path)) {
         $registry = AEFactory::getConfiguration();
         // Import volatile scripting keys to the registry
         AEUtilScripting::importScriptingToRegistry();
         // Determine the extension
         $force_extension = AEUtilScripting::getScriptingParameter('core.forceextension', null);
         if (is_null($force_extension)) {
             $archiver = AEFactory::getArchiverEngine();
             $extension = $archiver->getExtension();
         } else {
             $extension = $force_extension;
         }
         // Get the template name
         $templateName = $registry->get('akeeba.basic.archive_name');
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Archive template name: {$templateName}");
         // Parse all tags
         $templateName = self::replace_archive_name_variables($templateName);
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Expanded template name: {$templateName}");
         $ds = DIRECTORY_SEPARATOR;
         $relative_path = $templateName . $extension;
         $absolute_path = AEUtilFilesystem::TranslateWinPath($registry->get('akeeba.basic.output_directory') . $ds . $relative_path);
     }
     $relative = $relative_path;
     $absolute = $absolute_path;
 }