/** * Tries to authenticate the user and start the backup, or send him back to the default task */ public function authenticate() { // Enforce raw mode - I need to be in full control! if (!$this->_checkPermissions()) { parent::redirect(); } else { $session = JFactory::getSession(); $session->set('litemodeauthorized', 1, 'akeeba'); $this->_setProfile(); JLoader::import('joomla.utilities.date'); AECoreKettenrad::reset(array('maxrun' => 0)); AEUtilTempvars::reset(AKEEBA_BACKUP_ORIGIN); $kettenrad = AECoreKettenrad::load(AKEEBA_BACKUP_ORIGIN); $dateNow = new JDate(); /* $user = JFactory::getUser(); $userTZ = $user->getParam('timezone',0); $dateNow->setOffset($userTZ); */ $description = JText::_('BACKUP_DEFAULT_DESCRIPTION') . ' ' . $dateNow->format(JText::_('DATE_FORMAT_LC2'), true); $options = array('description' => $description, 'comment' => ''); $kettenrad->setup($options); $ret = $kettenrad->tick(); AECoreKettenrad::save(AKEEBA_BACKUP_ORIGIN); JFactory::getApplication()->redirect(JURI::base() . 'index.php?option=com_akeeba&view=light&task=step&key=' . urlencode($this->input->get('key', '', 'none', 2)) . '&profile=' . $this->input->get('profile', 1, 'int') . '&format=raw'); } }
/** * Implements the _prepare abstract method * */ protected function _prepare() { // Load parameters (description and comment) $jpskey = ''; if (!empty($this->_parametersArray)) { $params = $this->_parametersArray; if (isset($params['description'])) { $this->description = $params['description']; } if (isset($params['comment'])) { $this->comment = $params['comment']; } if (isset($params['jpskey'])) { $jpskey = $params['jpskey']; } } // Load configuration AEPlatform::getInstance()->load_configuration(); // Initialize counters $registry =& AEFactory::getConfiguration(); $registry->set('volatile.step_counter', 0); $registry->set('volatile.operation_counter', 0); if (!empty($jpskey)) { $registry->set('engine.archiver.jps.key', $jpskey); } // Initialize temporary storage AEUtilTempvars::reset(); // Force load the tag $kettenrad =& AEFactory::getKettenrad(); $tag = $kettenrad->getTag(); // Push the comment and description in temp vars for use in the installer phase $registry->set('volatile.core.description', $this->description); $registry->set('volatile.core.comment', $this->comment); $this->setState('prepared'); }
public function step() { // Check permissions $this->_checkPermissions(); // Set the profile $this->_setProfile(); $kettenrad =& AECoreKettenrad::load(AKEEBA_BACKUP_ORIGIN); $array = $kettenrad->tick(); AECoreKettenrad::save(AKEEBA_BACKUP_ORIGIN); if ($array['Error'] != '') { @ob_end_clean(); echo '500 ERROR -- ' . $array['Error']; flush(); JFactory::getApplication()->close(); } elseif ($array['HasRun'] == false) { // All done AEFactory::nuke(); AEUtilTempvars::reset(); @ob_end_clean(); echo '200 OK'; flush(); JFactory::getApplication()->close(); } else { $noredirect = JRequest::getInt('noredirect', 0); if ($noredirect != 0) { @ob_end_clean(); echo "301 More work required"; flush(); JFactory::getApplication()->close(); } else { $this->setRedirect(JURI::base() . 'index.php?option=com_akeeba&view=backup&task=step&key=' . JRequest::getVar('key') . '&profile=' . JRequest::getInt('profile', 1)); } } }
public function step() { // Check permissions $this->_checkPermissions(); // Set the profile $this->_setProfile(); $kettenrad = AECoreKettenrad::load(AKEEBA_BACKUP_ORIGIN); $kettenrad->tick(); $array = $kettenrad->getStatusArray(); $kettenrad->resetWarnings(); // So as not to have duplicate warnings reports AECoreKettenrad::save(AKEEBA_BACKUP_ORIGIN); if ($array['Error'] != '') { @ob_end_clean(); echo '500 ERROR -- ' . $array['Error']; flush(); JFactory::getApplication()->close(); } elseif ($array['HasRun'] == 1) { // All done AEFactory::nuke(); AEUtilTempvars::reset(); @ob_end_clean(); echo '200 OK'; flush(); JFactory::getApplication()->close(); } else { $noredirect = $this->input->get('noredirect', 0, 'int'); if ($noredirect != 0) { @ob_end_clean(); echo "301 More work required"; flush(); JFactory::getApplication()->close(); } else { $this->_customRedirect(JURI::base() . 'index.php?option=com_akeeba&view=backup&task=step&key=' . $this->input->get('key', '', 'none', 2) . '&profile=' . $this->input->get('profile', 1, 'int')); } } }
public function step() { // Check permissions $this->_checkPermissions(); // Set the profile $this->_setProfile(); // Get the backup ID $backupId = $this->input->get('backupid', null, 'raw', 2); if (empty($backupId)) { $backupId = null; } $kettenrad = AECoreKettenrad::load(AKEEBA_BACKUP_ORIGIN, $backupId); $kettenrad->setBackupId($backupId); $kettenrad->tick(); $array = $kettenrad->getStatusArray(); $kettenrad->resetWarnings(); // So as not to have duplicate warnings reports AECoreKettenrad::save(AKEEBA_BACKUP_ORIGIN, $backupId); if ($array['Error'] != '') { @ob_end_clean(); echo '500 ERROR -- ' . $array['Error']; flush(); JFactory::getApplication()->close(); } elseif ($array['HasRun'] == 1) { // All done AEFactory::nuke(); AEUtilTempvars::reset(); @ob_end_clean(); echo '200 OK'; flush(); JFactory::getApplication()->close(); } else { $noredirect = $this->input->get('noredirect', 0, 'int'); if ($noredirect != 0) { @ob_end_clean(); echo "301 More work required"; flush(); JFactory::getApplication()->close(); } else { $curUri = JUri::getInstance(); $ssl = $curUri->isSSL() ? 1 : 0; $tempURL = JRoute::_('index.php?option=com_akeeba', false, $ssl); $uri = new JUri($tempURL); $uri->setVar('view', 'backup'); $uri->setVar('task', 'step'); $uri->setVar('key', $this->input->get('key', '', 'none', 2)); $uri->setVar('profile', $this->input->get('profile', 1, 'int')); if (!empty($backupId)) { $uri->setVar('backupid', $backupId); } // Maybe we have a multilingual site? $lg = F0FPlatform::getInstance()->getLanguage(); $languageTag = $lg->getTag(); $uri->setVar('lang', $languageTag); $redirectionUrl = $uri->toString(); $this->_customRedirect($redirectionUrl); } } }
/** * Resets the Kettenrad state, wipping out any pending backups and/or stale * temporary data. * * @param array $config Configuration parameters for the reset operation */ public static function reset($config = array()) { $default_config = array('global' => true, 'log' => false, 'maxrun' => 0); $config = (object) array_merge($default_config, $config); // Pause logging if so desired if (!$config->log) { AEUtilLogger::WriteLog(false, ''); } $tag = null; if (!$config->global) { // If we're not resetting globally, get a list of running backups per tag $tag = AEPlatform::getInstance()->get_backup_origin(); } // Cache the factory before proceeding $factory = AEFactory::serialize(); $runningList = AEPlatform::getInstance()->get_running_backups($tag); // Origins we have to clean $origins = array(AEPlatform::getInstance()->get_backup_origin()); // 1. Detect failed backups if (is_array($runningList) && !empty($runningList)) { // The current timestamp $now = time(); // Mark running backups as failed foreach ($runningList as $running) { if (empty($tag)) { // Check the timestamp of the log file to decide if it's stuck, // but only if a tag is not set $tstamp = @filemtime(AEUtilLogger::logName($running['origin'])); if ($tstamp !== false) { // We can only check the timestamp if it's returned. If not, we assume the backup is stale $difference = abs($now - $tstamp); // Backups less than 3 minutes old are not considered stale if ($difference < $config->maxrun) { continue; } } } $filenames = AEUtilStatistics::get_all_filenames($running, false); // Process if there are files to delete... if (!is_null($filenames)) { // Delete the failed backup's archive, if exists foreach ($filenames as $failedArchive) { AEPlatform::getInstance()->unlink($failedArchive); } } // Mark the backup failed $running['status'] = 'fail'; $running['multipart'] = 0; $dummy = null; AEPlatform::getInstance()->set_or_update_statistics($running['id'], $running, $dummy); $origins[] = $running['origin']; } } if (!empty($origins)) { $origins = array_unique($origins); foreach ($origins as $tag) { AECoreKettenrad::load($tag); // Remove temporary files AEUtilTempfiles::deleteTempFiles(); // Delete any stale temporary data AEUtilTempvars::reset($tag); } } // Reload the factory AEFactory::unserialize($factory); unset($factory); // Unpause logging if it was previously paused if (!$config->log) { AEUtilLogger::WriteLog(true, ''); } }
public function runBackup() { $ret_array = array(); $ajaxTask = $this->getState('ajax'); switch ($ajaxTask) { case 'start': // Description is passed through a strict filter which removes HTML $description = $this->getState('description'); // The comment is passed through the Safe HTML filter (note: use 2 to force no filtering) $comment = $this->getState('comment'); $jpskey = $this->getState('jpskey'); $tag = $this->getState('tag'); // Try resetting the engine AECoreKettenrad::reset(array('maxrun' => 0)); // Remove any stale memory files left over from the previous step if (empty($tag)) { $tag = AEPlatform::getInstance()->get_backup_origin(); } AEUtilTempvars::reset($tag); $kettenrad = AECoreKettenrad::load($tag); // Take care of System Restore Point setup if ($tag == 'restorepoint') { // Fetch the extension's version information require_once JPATH_COMPONENT_ADMINISTRATOR . '/liveupdate/classes/xmlslurp.php'; $slurp = new LiveUpdateXMLSlurp(); $exttype = $this->getState('type'); switch ($exttype) { case 'component': $extname = 'com_'; break; case 'module': $extname = 'mod_'; break; case 'plugin': $extname = 'plg_'; break; case 'template': $extname = 'tpl_'; break; } $extname .= $this->getState('name'); $info = $slurp->getInfo($extname, ''); // Get the configOverrides for this extension $configOverrides = $this->getConfigOverridesForSRP($extname, $info); // Create an SRP descriptor $srpdescriptor = array('type' => $this->getState('type'), 'name' => $this->getState('name'), 'group' => $this->getState('group'), 'version' => $info['version'], 'date' => $info['date']); // Set the description and comment $description = "System Restore Point - " . JText::_($exttype) . ": {$extname}"; $comment = "---BEGIN SRP---\n" . json_encode($srpdescriptor) . "\n---END SRP---"; $jpskey = ''; // Set a custom finalization action queue $configOverrides['volatile.core.finalization.action_handlers'] = array(new AEFinalizationSrpquotas()); $configOverrides['volatile.core.finalization.action_queue'] = array('remove_temp_files', 'update_statistics', 'update_filesizes', 'apply_srp_quotas'); // Apply the configuration overrides, please $platform = AEPlatform::getInstance(); $platform->configOverrides = $configOverrides; } $options = array('description' => $description, 'comment' => $comment, 'jpskey' => $jpskey); $kettenrad->setup($options); $kettenrad->tick(); if ($kettenrad->getState() != 'running' && $tag == 'restorepoint') { $kettenrad->tick(); } $ret_array = $kettenrad->getStatusArray(); $kettenrad->resetWarnings(); // So as not to have duplicate warnings reports AECoreKettenrad::save($tag); break; case 'step': $tag = $this->getState('tag'); $kettenrad = AECoreKettenrad::load($tag); $kettenrad->tick(); $ret_array = $kettenrad->getStatusArray(); $kettenrad->resetWarnings(); // So as not to have duplicate warnings reports AECoreKettenrad::save($tag); if ($ret_array['HasRun'] == 1) { // Clean up AEFactory::nuke(); AEUtilTempvars::reset($tag); } break; default: break; } return $ret_array; }
private function _apiStepBackup($config) { $defConfig = array('profile' => null, 'tag' => AKEEBA_BACKUP_ORIGIN); $config = array_merge($defConfig, $config); extract($config); // Try to set the profile from the setup parameters if (!empty($profile)) { $registry = AEFactory::getConfiguration(); $session = JFactory::getSession(); $session->set('profile', $profile, 'akeeba'); } $kettenrad = AECoreKettenrad::load($tag); $registry = AEFactory::getConfiguration(); $session = JFactory::getSession(); $session->set('profile', $registry->activeProfile, 'akeeba'); $array = $kettenrad->tick(); $ret_array = $kettenrad->getStatusArray(); $array['Progress'] = $ret_array['Progress']; AECoreKettenrad::save($tag); if ($array['Error'] != '') { // A backup error had occurred. Why are we here?! $this->status = self::STATUS_ERROR; $this->encapsulation = self::ENCAPSULATION_RAW; return 'A backup error had occurred: ' . $array['Error']; } elseif ($array['HasRun'] == false) { AEFactory::nuke(); AEUtilTempvars::reset(); } return $array; }
public function execute() { // Load the language files $paths = array(JPATH_ADMINISTRATOR, JPATH_ROOT); $jlang = JFactory::getLanguage(); $jlang->load('com_akeeba', $paths[0], 'en-GB', true); $jlang->load('com_akeeba', $paths[1], 'en-GB', true); $jlang->load('com_akeeba' . '.override', $paths[0], 'en-GB', true); $jlang->load('com_akeeba' . '.override', $paths[1], 'en-GB', true); // Get the backup profile and description $profile = $this->input->get('profile', 1, 'int'); $description = $this->input->get('description', 'Command-line backup', 'string'); $overrides = $this->getOption('override', array(), false); if (!empty($overrides)) { $override_message = "\nConfiguration variables overriden in the command line:\n"; $override_message .= implode(', ', array_keys($overrides)); $override_message .= "\n"; } else { $override_message = ""; } $debugmessage = ''; if ($this->input->get('debug', -1, 'int') != -1) { if (!defined('AKEEBADEBUG')) { define('AKEEBADEBUG', 1); } $debugmessage = "*** DEBUG MODE ENABLED ***\n"; } $version = AKEEBA_VERSION; $date = AKEEBA_DATE; $start_backup = time(); $memusage = $this->memUsage(); $phpversion = PHP_VERSION; $phpenvironment = PHP_SAPI; $phpos = PHP_OS; if ($this->input->get('quiet', -1, 'int') == -1) { $year = gmdate('Y'); echo <<<ENDBLOCK Akeeba Backup CLI {$version} ({$date}) Copyright (C) 2010-{$year} Nicholas K. Dionysopoulos ------------------------------------------------------------------------------- Akeeba Backup is Free Software, distributed under the terms of the GNU General Public License version 3 or, at your option, any later version. This program comes with ABSOLUTELY NO WARRANTY as per sections 15 & 16 of the license. See http://www.gnu.org/licenses/gpl-3.0.html for details. ------------------------------------------------------------------------------- You are using PHP {$phpversion} ({$phpenvironment}) {$debugmessage} Starting a new backup with the following parameters: Profile ID {$profile} Description "{$description}" {$override_message} Current memory usage: {$memusage} ENDBLOCK; } // Attempt to use an infinite time limit, in case you are using the PHP CGI binary instead // of the PHP CLI binary. This will not work with Safe Mode, though. $safe_mode = true; if (function_exists('ini_get')) { $safe_mode = ini_get('safe_mode'); } if (!$safe_mode && function_exists('set_time_limit')) { if ($this->input->get('quiet', -1, 'int') == -1) { echo "Unsetting time limit restrictions.\n"; } @set_time_limit(0); } elseif (!$safe_mode) { if ($this->input->get('quiet', -1, 'int') == -1) { echo "Could not unset time limit restrictions; you may get a timeout error\n"; } } else { if ($this->input->get('quiet', -1, 'int') == -1) { echo "You are using PHP's Safe Mode; you may get a timeout error\n"; } } if ($this->input->get('quiet', -1, 'int') == -1) { echo "\n"; } // Log some paths if ($this->input->get('quiet', -1, 'int') == -1) { echo "Site paths determined by this script:\n"; echo "JPATH_BASE : " . JPATH_BASE . "\n"; echo "JPATH_ADMINISTRATOR : " . JPATH_ADMINISTRATOR . "\n\n"; } // Load the engine $factoryPath = JPATH_ADMINISTRATOR . '/components/com_akeeba/akeeba/factory.php'; define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_ADMINISTRATOR . '/components/com_akeeba'); define('AKEEBAROOT', JPATH_ADMINISTRATOR . '/components/com_akeeba/akeeba'); if (!file_exists($factoryPath)) { echo "ERROR!\n"; echo "Could not load the backup engine; file does not exist. Technical information:\n"; echo "Path to " . basename(__FILE__) . ": " . __DIR__ . "\n"; echo "Path to factory file: {$factoryPath}\n"; die("\n"); } else { try { require_once $factoryPath; } catch (Exception $e) { echo "ERROR!\n"; echo "Backup engine returned an error. Technical information:\n"; echo "Error message:\n\n"; echo $e->getMessage() . "\n\n"; echo "Path to " . basename(__FILE__) . ":" . __DIR__ . "\n"; echo "Path to factory file: {$factoryPath}\n"; die("\n"); } } // Forced CLI mode settings define('AKEEBA_PROFILE', $profile); define('AKEEBA_BACKUP_ORIGIN', 'cli'); // Force loading CLI-mode translation class $dummy = new AEUtilTranslate(); // Load the profile AEPlatform::getInstance()->load_configuration($profile); // Reset Kettenrad and its storage AECoreKettenrad::reset(array('maxrun' => 0)); AEUtilTempvars::reset(AKEEBA_BACKUP_ORIGIN); // Setup $kettenrad = AEFactory::getKettenrad(); $options = array('description' => $description, 'comment' => ''); if (!empty($overrides)) { AEPlatform::getInstance()->configOverrides = $overrides; } $kettenrad->setup($options); // Dummy array so that the loop iterates once $array = array('HasRun' => 0, 'Error' => ''); $warnings_flag = false; while ($array['HasRun'] != 1 && empty($array['Error'])) { // Recycle the database conenction to minimise problems with database timeouts $db = AEFactory::getDatabase(); $db->close(); $db->open(); AEUtilLogger::openLog(AKEEBA_BACKUP_ORIGIN); AEUtilLogger::WriteLog(true, ''); // Apply overrides in the command line if (!empty($overrides)) { $config = AEFactory::getConfiguration(); foreach ($overrides as $key => $value) { $config->set($key, $value); } } // Apply engine optimization overrides $config = AEFactory::getConfiguration(); $config->set('akeeba.tuning.min_exec_time', 0); $config->set('akeeba.tuning.nobreak.beforelargefile', 1); $config->set('akeeba.tuning.nobreak.afterlargefile', 1); $config->set('akeeba.tuning.nobreak.proactive', 1); $config->set('akeeba.tuning.nobreak.finalization', 1); $config->set('akeeba.tuning.settimelimit', 0); $config->set('akeeba.tuning.nobreak.domains', 0); $kettenrad->tick(); AEFactory::getTimer()->resetTime(); $array = $kettenrad->getStatusArray(); AEUtilLogger::closeLog(); $time = date('Y-m-d H:i:s \\G\\M\\TO (T)'); $memusage = $this->memUsage(); $warnings = "no warnings issued (good)"; $stepWarnings = false; if (!empty($array['Warnings'])) { $warnings_flag = true; $warnings = "POTENTIAL PROBLEMS DETECTED; " . count($array['Warnings']) . " warnings issued (see below).\n"; foreach ($array['Warnings'] as $line) { $warnings .= "\t{$line}\n"; } $stepWarnings = true; $kettenrad->resetWarnings(); } if ($this->input->get('quiet', -1, 'int') == -1 || $stepWarnings) { echo <<<ENDSTEPINFO Last Tick : {$time} Domain : {$array['Domain']} Step : {$array['Step']} Substep : {$array['Substep']} Memory used : {$memusage} Warnings : {$warnings} ENDSTEPINFO; } } // Clean up AEUtilTempvars::reset(AKEEBA_BACKUP_ORIGIN); if (!empty($array['Error'])) { echo "An error has occurred:\n{$array['Error']}\n\n"; $exitCode = 2; } else { if ($this->input->get('quiet', -1, 'int') == -1) { echo "Backup job finished successfully after approximately " . $this->timeago($start_backup, time(), '', false) . "\n"; } $exitCode = 0; } if ($warnings_flag && $this->input->get('quiet', -1, 'int') == -1) { $exitCode = 1; echo "\n" . str_repeat('=', 79) . "\n"; echo "!!!!! W A R N I N G !!!!!\n\n"; echo "Akeeba Backup issued warnings during the backup process. You have to review them\n"; echo "and make sure that your backup has completed successfully. Always test a backup with\n"; echo "warnings to make sure that it is working properly, by restoring it to a local server.\n"; echo "DO NOT IGNORE THIS MESSAGE! AN UNTESTED BACKUP IS AS GOOD AS NO BACKUP AT ALL.\n"; echo "\n" . str_repeat('=', 79) . "\n"; } elseif ($warnings_flag) { $exitCode = 1; } if ($this->input->get('quiet', -1, 'int') == -1) { echo "Peak memory usage: " . $this->peakMemUsage() . "\n\n"; } $this->close($exitCode); }
/** * Returns the backup state ('none','start', or 'step') */ private function getBackupState() { $this->debugInfo = '<h6>Akeeba Backup Lazy Mode</h6><hr/>'; // Make sure we're not locked if($this->isLocked()) { $this->debugInfo .= 'Backup locked'; // If the backup has crashed, clean up if($this->isCrashed) { $this->debugInfo .= 'Crashed backup detected'; AEFactory::nuke(); AEUtilTempvars::reset('lazy'); $this->unsetNonce(); $this->unsetLock(); $this->saveStorage(); } else { return 'none'; } } // Is there a backup running? $this->getNonce(); $action = empty($this->nonce) ? 'start' : 'step'; $this->debugInfo .= '<br/>Action: '.$action; // If there is no running backup, try to figure out if we should start // a new backup. if($action == 'start') { // Get the last backup time $lastBackup = $this->getLastBackupTime(); $this->debugInfo .= '<br/>Last backup: '.$lastBackup.' ('.date('Y/m/d H:i:s',$lastBackup).' GMT)'; // Remove the time part of the backup time (we want the date starting at midnight!) $deconstructedDate = getdate($lastBackup); $lastBackup = mktime( 0,0,0, $deconstructedDate['mon'], $deconstructedDate['mday'], $deconstructedDate['year'] ); $this->debugInfo .= '<br/>Adjusted last backup time: '.$lastBackup.' ('.date('Y/m/d H:i:s',$lastBackup).' GMT)'; // Get the preferences and calculate the next backup time $daysfreq = (int)$this->params->get('daysfreq',1); if($daysfreq <= 0) $daysfreq = 1; $this->debugInfo .= '<br/>Days frequency: '.$daysfreq; $daysfreq *= 86400; $backuptime = $this->params->get('backuptime','00:00'); $this->debugInfo .= '<br/>Backup time: '.$backuptime; $backuptime = trim($backuptime); $parts = explode(':',$backuptime); if(count($parts) != 2) { $backuptime = 0; } else { $hours = (int)$parts[0]; $mins = (int)$parts[1]; $backuptime = $hours * 3600 + $mins * 60; } $this->debugInfo .= ' ('.$backuptime.' seconds)'; $nextBackup = $lastBackup + $daysfreq + $backuptime; $this->debugInfo .= '<br/>Next Backup: '.$nextBackup.' ('.date('Y/m/d H:i:s',$nextBackup).' GMT)'; // The next backup time is in GMT. Convert to local. jimport('joomla.utilities.date'); $date = new JDate($nextBackup, 0); $jreg = JFactory::getConfig(); $offset = $jreg->getValue('config.offset'); $date->setOffset($offset); $nextBackup = $date->toUnix(true); $this->debugInfo .= '<br/>Next Backup: '.$nextBackup.' ('.date('Y/m/d H:i:s',$nextBackup).' LOCAL)'; $this->debugInfo .= '<br/>Time Now: '.time().' ('.date('Y/m/d H:i:s').' LOCAL)'; // Is it time for the next backup to run? if( time() < $nextBackup ) { $this->debugInfo .= '<br/>I will not start a new backup.'; } else { $this->debugInfo .= '<br/><strong>Starting new backup.</strong>'; } if( time() < $nextBackup ) return 'none'; // Create a new nonce $this->setNonce(); $this->saveStorage(); } return $action; }