예제 #1
0
 public function processPart($absolute_filename, $upload_as = null)
 {
     // Retrieve engine configuration data
     $config = AEFactory::getConfiguration();
     $account = trim($config->get('engine.postproc.azure.account', ''));
     $key = trim($config->get('engine.postproc.azure.key', ''));
     $container = $config->get('engine.postproc.azure.container', 0);
     $directory = $config->get('volatile.postproc.directory', null);
     if (empty($directory)) {
         $directory = $config->get('engine.postproc.azure.directory', 0);
     }
     // Sanity checks
     if (empty($account)) {
         $this->setWarning('You have not set up your Windows Azure account name');
         return false;
     }
     if (empty($key)) {
         $this->setWarning('You have not set up your Windows Azure key');
         return false;
     }
     if (empty($container)) {
         $this->setWarning('You have not set up your Windows Azure container');
         return false;
     }
     // Fix the directory name, if required
     if (!empty($directory)) {
         $directory = trim($directory);
         $directory = ltrim(AEUtilFilesystem::TranslateWinPath($directory), '/');
     } else {
         $directory = '';
     }
     // Parse tags
     $directory = AEUtilFilesystem::replace_archive_name_variables($directory);
     $config->set('volatile.postproc.directory', $directory);
     // Calculate relative remote filename
     $filename = basename($absolute_filename);
     if (!empty($directory) && $directory != '/') {
         $filename = $directory . '/' . $filename;
     }
     // Store the absolute remote path in the class property
     $this->remote_path = $filename;
     // Connect and send
     try {
         $blob = new AEUtilAzure(AEUtilAzureStorage::URL_CLOUD_BLOB, $account, $key);
         $policyNone = new AEUtilAzureNoRetryPolicy();
         $blob->setRetryPolicy($policyNone);
         $blob->putBlob($container, $filename, $absolute_filename);
     } catch (Exception $e) {
         $this->setWarning($e->getMessage());
         return false;
     }
     return true;
 }
예제 #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');
 }
 protected function _getSettings()
 {
     // Retrieve engine configuration data
     $config = AEFactory::getConfiguration();
     $username = trim($config->get('engine.postproc.idrivesync.username', ''));
     $password = trim($config->get('engine.postproc.idrivesync.password', ''));
     $pvtkey = trim($config->get('engine.postproc.idrivesync.pvtkey', ''));
     $this->directory = $config->get('volatile.postproc.directory', null);
     if (empty($this->directory)) {
         $this->directory = $config->get('engine.postproc.idrivesync.directory', '');
     }
     // Sanity checks
     if (empty($username) || empty($password)) {
         $this->setError('You have not set up the connection to your iDriveSync account');
         return false;
     }
     // Fix the directory name, if required
     if (!empty($this->directory)) {
         $this->directory = trim($this->directory);
         $this->directory = ltrim(AEUtilFilesystem::TranslateWinPath($this->directory), '/');
     } else {
         $this->directory = '';
     }
     // Parse tags
     $this->directory = AEUtilFilesystem::replace_archive_name_variables($this->directory);
     $config->set('volatile.postproc.directory', $this->directory);
     $this->idrivesync = new AEUtilIdrivesync($username, $password, $pvtkey);
     return true;
 }
예제 #4
0
    public function notifyFailed()
    {
        $params = JComponentHelper::getParams('com_akeeba');
        // Invalidate stale backups
        AECoreKettenrad::reset(array('global' => true, 'log' => false, 'maxrun' => $params->get('failure_timeout', 180)));
        // Get the last execution and search for failed backups AFTER that date
        $last = $this->getLastCheck();
        // Get failed backups
        $filters[] = array('field' => 'status', 'operand' => '=', 'value' => 'fail');
        $filters[] = array('field' => 'origin', 'operand' => '<>', 'value' => 'restorepoint');
        $filters[] = array('field' => 'backupstart', 'operand' => '>', 'value' => $last);
        $failed = AEPlatform::getInstance()->get_statistics_list(array('filters' => $filters));
        // Well, everything went ok.
        if (!$failed) {
            return array('message' => array("No need to run: no failed backups or they were already notificated"), 'result' => true);
        }
        // Whops! Something went wrong, let's start notifing
        $superAdmins = array();
        $superAdminEmail = $params->get('failure_email_address', '');
        if (!empty($superAdminEmail)) {
            $superAdmins = $this->getSuperAdministrators($superAdminEmail);
        }
        if (empty($superAdmins)) {
            $superAdmins = $this->getSuperAdministrators();
        }
        if (empty($superAdmins)) {
            return array('message' => array("WARNING! Failed backup(s) detected, but there are no configured Super Administrators to receive notifications"), 'result' => false);
        }
        $failedReport = array();
        foreach ($failed as $fail) {
            $string = "Description : " . $fail['description'] . "\n";
            $string .= "Start time  : " . $fail['backupstart'] . "\n";
            $string .= "Origin      : " . $fail['origin'] . "\n";
            $string .= "Type        : " . $fail['type'] . "\n";
            $string .= "Profile ID  : " . $fail['profile_id'];
            $failedReport[] = $string;
        }
        $failedReport = implode("\n#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+#\n", $failedReport);
        $email_subject = $params->get('failure_email_subject', '');
        if (!$email_subject) {
            $email_subject = <<<ENDSUBJECT
THIS EMAIL IS SENT FROM YOUR SITE "[SITENAME]" - Failed backup(s) detected
ENDSUBJECT;
        }
        $email_body = $params->get('failure_email_body', '');
        if (!$email_body) {
            $email_body = <<<ENDBODY
================================================================================
FAILED BACKUP ALERT
================================================================================

Your site has determined that there are failed backups.

The following backups are found to be failing:

[FAILEDLIST]

================================================================================
WHY AM I RECEIVING THIS EMAIL?
================================================================================

This email has been automatically sent by scritp you, or the person who built
or manages your site, has installed and explicitly configured. This script looks
for failed backups and sends an email notification to all Super Users.

If you do not understand what this means, please do not contact the authors of
the software. They are NOT sending you this email and they cannot help you.
Instead, please contact the person who built or manages your site.

================================================================================
WHO SENT ME THIS EMAIL?
================================================================================

This email is sent to you by your own site, [SITENAME]

ENDBODY;
        }
        $jconfig = JFactory::getConfig();
        $mailfrom = $jconfig->get('mailfrom');
        $fromname = $jconfig->get('fromname');
        $email_subject = AEUtilFilesystem::replace_archive_name_variables($email_subject);
        $email_body = AEUtilFilesystem::replace_archive_name_variables($email_body);
        $email_body = str_replace('[FAILEDLIST]', $failedReport, $email_body);
        foreach ($superAdmins as $sa) {
            $mailer = JFactory::getMailer();
            $mailer->setSender(array($mailfrom, $fromname));
            $mailer->addRecipient($sa->email);
            $mailer->setSubject($email_subject);
            $mailer->setBody($email_body);
            $mailer->Send();
        }
        // Let's update the last time we check, so we will avoid to send
        // the same notification several times
        $this->updateLastCheck(intval($last));
        return array('message' => array("WARNING! Found " . count($failed) . " failed backup(s)", "Sent " . count($superAdmins) . " notifications"), 'result' => true);
    }
 private function _getEngineSettings()
 {
     // Retrieve engine configuration data
     $config = AEFactory::getConfiguration();
     $email = trim($config->get('engine.postproc.sugarsync.email', ''));
     $password = trim($config->get('engine.postproc.sugarsync.password', ''));
     $directory = $config->get('volatile.postproc.directory', null);
     if (empty($directory)) {
         $directory = $config->get('engine.postproc.sugarsync.directory', 0);
     }
     // Sanity checks
     if (empty($email)) {
         $this->setWarning('You have not set up your SugarSync email address');
         return false;
     }
     if (empty($password)) {
         $this->setWarning('You have not set up your SugarSync password');
         return false;
     }
     // Fix the directory name, if required
     if (!empty($directory)) {
         $directory = trim($directory);
         $directory = ltrim(AEUtilFilesystem::TranslateWinPath($directory), '/');
     } else {
         $directory = '';
     }
     // Parse tags
     $directory = AEUtilFilesystem::replace_archive_name_variables($directory);
     $config->set('volatile.postproc.directory', $directory);
     return array('email' => $email, 'password' => $password, 'directory' => $directory);
 }
예제 #6
0
 protected function _getSettings()
 {
     // Retrieve engine configuration data
     $config = AEFactory::getConfiguration();
     $token = trim($config->get('engine.postproc.dropbox.token', ''));
     $token_secret = trim($config->get('engine.postproc.dropbox.token_secret', ''));
     $token_uid = trim($config->get('engine.postproc.dropbox.uid', ''));
     $this->chunked = $config->get('engine.postproc.dropbox.chunk_upoad', true);
     $this->chunk_size = $config->get('engine.postproc.dropbox.chunk_upoad_size', 4);
     $this->directory = $config->get('volatile.postproc.directory', null);
     if (empty($this->directory)) {
         $this->directory = $config->get('engine.postproc.dropbox.directory', '');
     }
     // Sanity checks
     if (empty($token) || empty($token_secret) || empty($token_uid)) {
         $this->setError('You have not linked Akeeba Backup with your DropBox account');
         return false;
     }
     // Fix the directory name, if required
     if (!empty($this->directory)) {
         $this->directory = trim($this->directory);
         $this->directory = ltrim(AEUtilFilesystem::TranslateWinPath($this->directory), '/');
     } else {
         $this->directory = '';
     }
     // Parse tags
     $this->directory = AEUtilFilesystem::replace_archive_name_variables($this->directory);
     $config->set('volatile.postproc.directory', $this->directory);
     $token = (object) array('oauth_token_secret' => $token_secret, 'oauth_token' => $token, 'uid' => $token_uid);
     $keys = $this->_getKeys();
     $this->dropbox = new AEUtilDropbox();
     $this->dropbox->setAppKeys($keys);
     $this->dropbox->setToken($token);
     return true;
 }
예제 #7
0
파일: finalization.php 프로젝트: 01J/topm
 /**
  * Sends an email to the administrators
  *
  * @return bool
  */
 private function mail_administrators()
 {
     $this->setStep('Processing emails to administrators');
     $this->setSubstep('');
     // Skip email for back-end backups
     if (AEPlatform::getInstance()->get_backup_origin() == 'backend') {
         return true;
     }
     $must_email = AEPlatform::getInstance()->get_platform_configuration_option('frontend_email_on_finish', 0) != 0;
     if (!$must_email) {
         return true;
     }
     AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Preparing to send e-mail to administrators");
     $email = AEPlatform::getInstance()->get_platform_configuration_option('frontend_email_address', '');
     $email = trim($email);
     if (!empty($email)) {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Using pre-defined list of emails");
         $emails = explode(',', $email);
     } else {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Fetching list of Super Administrator emails");
         $emails = AEPlatform::getInstance()->get_administrator_emails();
     }
     if (!empty($emails)) {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Creating email subject and body");
         // Fetch user's preferences
         $subject = trim(AEPlatform::getInstance()->get_platform_configuration_option('frontend_email_subject', ''));
         $body = trim(AEPlatform::getInstance()->get_platform_configuration_option('frontend_email_body', ''));
         // Get the statistics
         $statistics = AEFactory::getStatistics();
         $stat = $statistics->getRecord();
         $parts = AEUtilStatistics::get_all_filenames($stat, false);
         $profile_number = AEPlatform::getInstance()->get_active_profile();
         $profile_name = AEPlatform::getInstance()->get_profile_name($profile_number);
         $parts = AEUtilStatistics::get_all_filenames($stat, false);
         $stat = (object) $stat;
         $num_parts = $stat->multipart;
         // Non-split archives have a part count of 0
         if ($num_parts == 0) {
             $num_parts = 1;
         }
         $parts_list = '';
         if (!empty($parts)) {
             foreach ($parts as $file) {
                 $parts_list .= "\t" . basename($file) . "\n";
             }
         }
         // Get the remote storage status
         $remote_status = '';
         $post_proc_engine = AEFactory::getConfiguration()->get('akeeba.advanced.proc_engine');
         if (!empty($post_proc_engine) && $post_proc_engine != 'none') {
             if (empty($stat->remote_filename)) {
                 $remote_status = AEPlatform::getInstance()->translate('COM_AKEEBA_EMAIL_POSTPROCESSING_FAILED');
             } else {
                 $remote_status = AEPlatform::getInstance()->translate('COM_AKEEBA_EMAIL_POSTPROCESSING_SUCCESS');
             }
         }
         // Do we need a default subject?
         if (empty($subject)) {
             // Get the default subject
             $subject = AEPlatform::getInstance()->translate('EMAIL_SUBJECT_OK');
         } else {
             // Post-process the subject
             $subject = AEUtilFilesystem::replace_archive_name_variables($subject);
         }
         // Do we need a default body?
         if (empty($body)) {
             $body = AEPlatform::getInstance()->translate('EMAIL_BODY_OK');
             $info_source = AEPlatform::getInstance()->translate('EMAIL_BODY_INFO');
             $body .= "\n\n" . sprintf($info_source, $profile_number, $num_parts) . "\n\n";
             $body .= $parts_list;
         } else {
             // Post-process the body
             $body = AEUtilFilesystem::replace_archive_name_variables($body);
             $body = str_replace('[PROFILENUMBER]', $profile_number, $body);
             $body = str_replace('[PROFILENAME]', $profile_name, $body);
             $body = str_replace('[PARTCOUNT]', $num_parts, $body);
             $body = str_replace('[FILELIST]', $parts_list, $body);
             $body = str_replace('[REMOTESTATUS]', $remote_status, $body);
         }
         // Sometimes $body contains literal \n instead of newlines
         $body = str_replace('\\n', "\n", $body);
         foreach ($emails as $email) {
             AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Sending email to {$email}");
             AEPlatform::getInstance()->send_email($email, $subject, $body);
         }
     } else {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "No email recipients found! Skipping email.");
     }
     return true;
 }
예제 #8
0
 public function processPart($absolute_filename, $upload_as = null)
 {
     // Retrieve engine configuration data
     $config = AEFactory::getConfiguration();
     $accesskey = trim($config->get('engine.postproc.googlestorage.accesskey', ''));
     $secret = trim($config->get('engine.postproc.googlestorage.secretkey', ''));
     $usessl = $config->get('engine.postproc.googlestorage.usessl', 0) == 0 ? false : true;
     $bucket = $config->get('engine.postproc.googlestorage.bucket', '');
     $directory = $config->get('volatile.postproc.directory', null);
     $lowercase = $config->get('engine.postproc.googlestorage.lowercase', 1);
     if (empty($directory)) {
         $directory = $config->get('engine.postproc.googlestorage.directory', 0);
     }
     // Sanity checks
     if (empty($accesskey)) {
         $this->setError('You have not set up your Google Storage Access Key');
         return false;
     }
     if (empty($secret)) {
         $this->setError('You have not set up your Google Storage Secret Key');
         return false;
     }
     if (empty($bucket)) {
         $this->setError('You have not set up your Google Storage Bucket');
         return false;
     } else {
         // Remove any slashes from the bucket
         $bucket = str_replace('/', '', $bucket);
         if ($lowercase) {
             $bucket = strtolower($bucket);
         }
     }
     // Create an S3 instance with the required credentials
     $s3 = AEUtilAmazons3::getInstance($accesskey, $secret, $usessl);
     $s3->defaultHost = 'commondatastorage.googleapis.com';
     // If we are here, we'll have to start uploading the file. Let's prepare ourselves for that.
     // Fix the directory name, if required
     if (!empty($directory)) {
         $directory = trim($directory);
         $directory = ltrim(AEUtilFilesystem::TranslateWinPath($directory), '/');
     } else {
         $directory = '';
     }
     // Parse tags
     $directory = AEUtilFilesystem::replace_archive_name_variables($directory);
     $config->set('volatile.postproc.directory', $directory);
     // Calculate relative remote filename
     $filename = empty($upload_as) ? basename($absolute_filename) : $upload_as;
     if (!empty($directory) && $directory != '/') {
         $filename = $directory . '/' . $filename;
     }
     // Store the absolute remote path in the class property
     $this->remote_path = $filename;
     // Do we have to upload in one go or do a multipart upload instead?
     $filesize = @filesize($absolute_filename);
     AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Google Storage -- Uploading " . basename($absolute_filename));
     // Legacy single part uploads
     $result = $s3->putObject(AEUtilAmazons3::inputFile($absolute_filename, false), $bucket, $filename, AEUtilAmazons3::ACL_BUCKET_OWNER_FULL_CONTROL, array(), array());
     // Return the result
     $this->propagateFromObject($s3);
     return $result;
 }
 public function processPart($absolute_filename)
 {
     // Retrieve engine configuration data
     $config = AEFactory::getConfiguration();
     $accesskey = trim($config->get('engine.postproc.s3.accesskey', ''));
     $secret = trim($config->get('engine.postproc.s3.secretkey', ''));
     $usessl = $config->get('engine.postproc.s3.usessl', 0) == 0 ? false : true;
     $bucket = $config->get('engine.postproc.s3.bucket', '');
     $legacy = $config->get('engine.postproc.s3.legacy', 0);
     $directory = $config->get('volatile.postproc.directory', null);
     $lowercase = $config->get('engine.postproc.s3.lowercase', 1);
     $rrs = $config->get('engine.postproc.s3.rrs', 1);
     $endpoint = $config->get('engine.postproc.s3.customendpoint', '');
     if (empty($directory)) {
         $directory = $config->get('engine.postproc.s3.directory', 0);
     }
     if (!empty($directory)) {
         $directory = str_replace('\\', '/', $directory);
         $directory = rtrim($directory, '/');
     }
     $endpoint = trim($endpoint);
     if (!empty($endpoint)) {
         $protoPos = strpos($endpoint, ':\\');
         if ($protoPos !== false) {
             $endpoint = substr($endpoint, $protoPos + 3);
         }
         $slashPos = strpos($endpoint, '/');
         if ($slashPos !== false) {
             $endpoint = substr($endpoint, $slashPos + 1);
         }
     }
     // Sanity checks
     if (empty($accesskey)) {
         $this->setError('You have not set up your Amazon S3 Access Key');
         return false;
     }
     if (empty($secret)) {
         $this->setError('You have not set up your Amazon S3 Secret Key');
         return false;
     }
     if (empty($bucket)) {
         $this->setError('You have not set up your Amazon S3 Bucket');
         return false;
     } else {
         // Remove any slashes from the bucket
         $bucket = str_replace('/', '', $bucket);
         if ($lowercase) {
             $bucket = strtolower($bucket);
         }
     }
     // Create an S3 instance with the required credentials
     $s3 = AEUtilAmazons3::getInstance($accesskey, $secret, $usessl);
     if (!empty($endpoint)) {
         $s3->defaultHost = $endpoint;
     }
     // Do not use multipart uploads when in an immediate post-processing step,
     // i.e. we are uploading a part right after its creation
     $immediateEnabled = $config->get('engine.postproc.common.after_part', 0);
     if ($immediateEnabled) {
         $noMultipart = true;
     } else {
         $noMultipart = false;
     }
     // Disable multipart uploads if the user requested it
     if ($legacy) {
         $noMultipart = true;
     }
     // Are we already processing a multipart upload?
     if (!empty($this->cache)) {
         // Continue processing an existing file and return
         $filename = $this->cache->filename;
         $absolute_filename = $this->cache->absolute_filename;
         $partNumber = $this->cache->partnumber;
         $uploadID = $this->cache->uploadid;
         $etags = $this->cache->etags;
         $partNumber++;
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "S3 -- Uploading part {$partNumber} of {$uploadID}");
         // DEBUG
         /**
         			$flatetags = implode(', ',$etags);
         			AEUtilLogger::WriteLog(_AE_LOG_DEBUG,"S3 -- Absolute/relative filenames: $absolute_filename ### $filename");
         			AEUtilLogger::WriteLog(_AE_LOG_DEBUG,"S3 -- Etags: ".$flatetags);
         			AEUtilLogger::WriteLog(_AE_LOG_DEBUG,"S3 -- Serialized cache: ".serialize($this->cache));
         			/**/
         $fileInfo = AEUtilAmazons3::inputFile($absolute_filename, false);
         $fileInfo['UploadID'] = $uploadID;
         $fileInfo['etags'] = $etags;
         $fileInfo['PartNumber'] = $partNumber;
         $input = $fileInfo;
         // So that it doesn't get overwritten
         $etag = AEUtilAmazons3::uploadMultipart($input, $bucket, $filename);
         if ($etag === 0) {
             // Done uploading, finalize
             $this->cache = null;
             AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "S3 -- Finalizing multipart upload of " . basename($absolute_filename) . " (part #{$partNumber})");
             $result = AEUtilAmazonS3::finalizeMultipart($fileInfo, $bucket, $filename);
             $this->propagateFromObject($s3);
             if ($result === false) {
                 // Finalization failed
                 return false;
             } else {
                 // Finalization successful
                 return true;
             }
         } elseif ($etag === false) {
             // Upload failed
             $this->propagateFromObject($s3);
             return false;
         } else {
             // Successfully uploaded part
             $this->propagateFromObject($s3);
             $fileInfo['etags'][] = $etag;
             // Update stored values
             $this->cache->partnumber = $partNumber;
             $this->cache->etags = $fileInfo['etags'];
             $this->cache->uploadid = $fileInfo['UploadID'];
             // Return -1 so that we get called again
             return -1;
         }
     }
     // If we are here, we'll have to start uploading the file. Let's prepare ourselves for that.
     // Fix the directory name, if required
     if (!empty($directory)) {
         $directory = trim($directory);
         $directory = ltrim(AEUtilFilesystem::TranslateWinPath($directory), '/');
     } else {
         $directory = '';
     }
     // Parse tags
     $directory = AEUtilFilesystem::replace_archive_name_variables($directory);
     $config->set('volatile.postproc.directory', $directory);
     // Calculate relative remote filename
     $filename = basename($absolute_filename);
     if (!empty($directory) && $directory != '/') {
         $filename = $directory . '/' . $filename;
     }
     // Store the absolute remote path in the class property
     $this->remote_path = $filename;
     // Do we have to upload in one go or do a multipart upload instead?
     $filesize = @filesize($absolute_filename);
     if ($filesize > 5242880 && !$noMultipart) {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "S3 -- Starting multipart upload of " . basename($absolute_filename));
         // Start multipart processing for files over 5Mb
         $fileInfo = AEUtilAmazons3::inputFile($absolute_filename, false);
         $input = $fileInfo;
         // Required to avoid the original array being tampered with
         $uploadID = AEUtilAmazonS3::startMultipart($input, $bucket, $filename, AEUtilAmazons3::ACL_BUCKET_OWNER_FULL_CONTROL, array(), array('x-amz-storage-class' => $rrs ? 'REDUCED_REDUNDANCY' : 'STANDARD'));
         // Necessary warnings propagation, no matter the outcome
         $this->propagateFromObject($s3);
         if ($uploadID === false) {
             // We couldn't start the upload. Bail out at once!
             return false;
         } else {
             // Save the information we need for multipart uploading
             $fileInfo['UploadID'] = $uploadID;
             $fileInfo['etags'] = array();
             $cache = array('absolute_filename' => $absolute_filename, 'filename' => $filename, 'partnumber' => 0, 'uploadid' => $uploadID, 'etags' => array());
             $this->cache = (object) $cache;
             // Return -1 so that we get called again, even on the same step
             return -1;
         }
     } else {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "S3 -- Legacy (single part) upload of " . basename($absolute_filename));
         // Legacy single part uploads
         $result = $s3->putObject(AEUtilAmazons3::inputFile($absolute_filename, false), $bucket, $filename, AEUtilAmazons3::ACL_BUCKET_OWNER_FULL_CONTROL, array(), array('x-amz-storage-class' => $rrs ? 'REDUCED_REDUNDANCY' : 'STANDARD'));
         // Return the result
         $this->propagateFromObject($s3);
         return $result;
     }
 }
 public function processPart($absolute_filename)
 {
     // Retrieve engine configuration data
     $config = AEFactory::getConfiguration();
     $host = $config->get('engine.postproc.ftp.host', '');
     $port = $config->get('engine.postproc.ftp.port', 21);
     $user = $config->get('engine.postproc.ftp.user', '');
     $pass = $config->get('engine.postproc.ftp.pass', 0);
     $directory = $config->get('volatile.postproc.directory', null);
     if (empty($directory)) {
         $directory = $config->get('engine.postproc.ftp.initial_directory', '');
     }
     $ssl = $config->get('engine.postproc.ftp.ftps', 0) == 0 ? false : true;
     $passive = $config->get('engine.postproc.ftp.passive_mode', 0) == 0 ? false : true;
     // Process the initial directory
     $directory = '/' . ltrim(trim($directory), '/');
     // Parse tags
     $directory = AEUtilFilesystem::replace_archive_name_variables($directory);
     $config->set('volatile.postproc.directory', $directory);
     // Connect to the FTP server
     AEUtilLogger::WriteLog(_AE_LOG_DEBUG, __CLASS__ . ':: Connecting to remote FTP');
     if ($ssl) {
         if (function_exists('ftp_ssl_connect')) {
             $ftphandle = @ftp_ssl_connect($host, $port);
         } else {
             $ftphandle = false;
         }
     } else {
         $ftphandle = @ftp_connect($host, $port);
     }
     if ($ftphandle === false) {
         $this->setWarning("Wrong FTP hostname or port (host:port = {$host}:{$port})");
         return false;
     }
     // Login
     if (!@ftp_login($ftphandle, $user, $pass)) {
         $this->setWarning('Invalid username/password for the remote FTP server');
         ftp_close($ftphandle);
         return false;
     }
     // Change to initial directory
     if (!@ftp_chdir($ftphandle, $directory)) {
         $this->setWarning("Invalid initial directory {$directory} for the remote FTP server");
         return false;
     }
     @ftp_pasv($ftphandle, $passive);
     $realdir = substr($directory, -1) == '/' ? substr($directory, 0, strlen($directory) - 1) : $directory;
     $realname = $realdir . '/' . basename($absolute_filename);
     try {
         $res = @ftp_put($ftphandle, $realname, $absolute_filename, FTP_BINARY);
     } catch (Exception $e) {
         // Funny how PHP dies without returning false if you don't use a try/catch statement, eh?
         $res = false;
         $this->setWarning($e->getMessage());
     }
     // Store the absolute remote path in the class property
     $this->remote_path = $realname;
     @ftp_close($ftphandle);
     if (!$res) {
         // If the file was unreadable, just skip it...
         if (is_readable($absolute_filename)) {
             $this->setWarning('Uploading ' . $absolute_filename . ' has failed.');
             return false;
         } else {
             $this->setWarning('Uploading ' . $absolute_filename . ' has failed because the file is unreadable.');
             return true;
         }
     } else {
         return true;
     }
 }
예제 #11
0
 protected function _getSettings()
 {
     // Retrieve engine configuration data
     $config = AEFactory::getConfiguration();
     $username = trim($config->get('engine.postproc.webdav.username', ''));
     $password = trim($config->get('engine.postproc.webdav.password', ''));
     $url = trim($config->get('engine.postproc.webdav.url', ''));
     $this->directory = $config->get('volatile.postproc.directory', null);
     if (empty($this->directory)) {
         $this->directory = $config->get('engine.postproc.webdav.directory', '');
     }
     // Sanity checks
     if (empty($username) || empty($password)) {
         $this->setError('You have not linked Akeeba Backup with your CloudMe account');
         return false;
     }
     // Fix the directory name, if required
     if (!empty($this->directory)) {
         $this->directory = trim($this->directory);
         $this->directory = ltrim(AEUtilFilesystem::TranslateWinPath($this->directory), '/');
     } else {
         $this->directory = '';
     }
     // Parse tags
     $this->directory = AEUtilFilesystem::replace_archive_name_variables($this->directory);
     $config->set('volatile.postproc.directory', $this->directory);
     $settings = array('baseUri' => $url, 'userName' => $username, 'password' => $password);
     $this->webdav = new AEUtilDavclient($settings);
     $this->webdav->addTrustedCertificates(AKEEBA_CACERT_PEM);
     return true;
 }
 public function processPart($absolute_filename)
 {
     // Retrieve engine configuration data
     $config = AEFactory::getConfiguration();
     $host = $config->get('engine.postproc.sftp.host', '');
     $port = $config->get('engine.postproc.sftp.port', 22);
     $user = $config->get('engine.postproc.sftp.user', '');
     $pass = $config->get('engine.postproc.sftp.pass', 0);
     $directory = $config->get('volatile.postproc.directory', null);
     if (empty($directory)) {
         $directory = $config->get('engine.postproc.sftp.initial_directory', '');
     }
     // Process the initial directory
     $directory = '/' . ltrim(trim($directory), '/');
     // Parse tags
     $directory = AEUtilFilesystem::replace_archive_name_variables($directory);
     $config->set('volatile.postproc.directory', $directory);
     // Connect to the SFTP server
     AEUtilLogger::WriteLog(_AE_LOG_DEBUG, __CLASS__ . ':: Connecting to remote SFTP');
     $connection = null;
     $sftphandle = null;
     if (!function_exists('ssh2_connect')) {
         $this->setWarning("Your web server does not have the SSH2 PHP module, therefore can not connect and upload archives to SFTP servers.");
         return false;
     }
     $connection = ssh2_connect($host, $port);
     if ($connection === false) {
         $this->setWarning("Invalid SFTP hostname or port ({$host}:{$port}) or the connection is blocked by your web server's firewall.");
         return false;
     }
     if (!ssh2_auth_password($connection, $user, $pass)) {
         $this->setWarning('Could not authenticate access to SFTP server; check your username and password.');
         return false;
     }
     $sftphandle = ssh2_sftp($connection);
     if ($sftphandle === false) {
         $this->setWarning("Your SSH server does not allow SFTP connections");
         return false;
     }
     // Change to initial directory
     if (!$this->_sftp_chdir($directory, $sftphandle)) {
         $this->setWarning("Invalid initial directory {$directory} for the remote SFTP server");
         return false;
     }
     $realdir = substr($directory, -1) == '/' ? substr($directory, 0, strlen($directory) - 1) : $directory;
     $realname = $realdir . '/' . basename($absolute_filename);
     $fp = @fopen("ssh2.sftp://{$sftphandle}{$realname}", 'w');
     if ($fp === false) {
         $this->setWarning("Could not open remote SFTP file {$realname} for writing");
         return false;
     }
     $localfp = @fopen($absolute_filename, 'rb');
     if ($localfp === false) {
         $this->setWarning("Could not open local file {$absolute_filename} for reading");
         @fclose($fp);
         return false;
     }
     $res = true;
     while (!feof($localfp) && $res !== false) {
         $buffer = @fread($localfp, 65567);
         $res = @fwrite($fp, $buffer);
     }
     @fclose($fp);
     @fclose($localfp);
     ssh2_exec($connection, 'exit;');
     $connection = null;
     if ($res === false) {
         // If the file was unreadable, just skip it...
         if (is_readable($absolute_filename)) {
             $this->setWarning('Uploading ' . $realname . ' has failed.');
             return false;
         } else {
             $this->setWarning('Uploading ' . $realname . ' has failed because the source file is unreadable.');
             return true;
         }
     }
     return true;
 }
예제 #13
0
 private function _getEngineSettings()
 {
     // Retrieve engine configuration data
     $config = AEFactory::getConfiguration();
     $username = trim($config->get('engine.postproc.cloudfiles.username', ''));
     $apikey = trim($config->get('engine.postproc.cloudfiles.apikey', ''));
     $container = $config->get('engine.postproc.cloudfiles.container', 0);
     $directory = $config->get('volatile.postproc.directory', null);
     $isUKAccount = $config->get('engine.postproc.cloudfiles.isukaccount', 0);
     if (empty($directory)) {
         $directory = $config->get('engine.postproc.cloudfiles.directory', 0);
     }
     // Sanity checks
     if (empty($username)) {
         $this->setWarning('You have not set up your CloudFiles user name');
         return false;
     }
     if (empty($apikey)) {
         $this->setWarning('You have not set up your CoudFiles API Key');
         return false;
     }
     if (empty($container)) {
         $this->setWarning('You have not set up your CloudFiles container');
         return false;
     }
     // Fix the directory name, if required
     if (!empty($directory)) {
         $directory = trim($directory);
         $directory = ltrim(AEUtilFilesystem::TranslateWinPath($directory), '/');
     } else {
         $directory = '';
     }
     // Parse tags
     $directory = AEUtilFilesystem::replace_archive_name_variables($directory);
     $config->set('volatile.postproc.directory', $directory);
     return array('username' => $username, 'apikey' => $apikey, 'container' => $container, 'directory' => $directory, 'isUKAccount' => $isUKAccount);
 }
예제 #14
0
	/**
	 * Sends an email to the administrators
	 * @return bool
	 */
	private function mail_administrators()
	{
		$this->setStep('Processing emails to administrators');
		$this->setSubstep('');
		// Skip email for back-end backups
		if(AEPlatform::get_backup_origin() == 'backend' ) return true;

		$must_email = AEPlatform::get_platform_configuration_option('frontend_email_on_finish', 0) != 0;
		if(!$must_email) return true;

		AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Preparing to send e-mail to administrators");

		$email = AEPlatform::get_platform_configuration_option('frontend_email_address', '');
		$email = trim($email);
		if( !empty($email) )
		{
			$emails = array($email);
		}
		else
		{
			$emails = AEPlatform::get_administrator_emails();
		}

		if(!empty($emails))
		{
			// Fetch user's preferences
			$subject = trim(AEPlatform::get_platform_configuration_option('frontend_email_subject',''));
			$body = trim(AEPlatform::get_platform_configuration_option('frontend_email_body',''));

			// Get the statistics
			$statistics =& AEFactory::getStatistics();
			$stat = $statistics->getRecord();
			$parts = AEUtilStatistics::get_all_filenames($stat, false);

			$profile_number = AEPlatform::get_active_profile();
			$profile_name = AEPlatform::get_profile_name($profile_number);
			$parts = AEUtilStatistics::get_all_filenames($stat, false);
			$stat = (object)$stat;
			$num_parts = $stat->multipart;
			if($num_parts == 0) $num_parts = 1; // Non-split archives have a part count of 0
			$parts_list = '';
			if(!empty($parts)) foreach($parts as $file) {
				$parts_list .= "\t".basename($file)."\n";
			}

			// Do we need a default subject?
			if(empty($subject)) {
				// Get the default subject
				$subject = AEPlatform::translate('EMAIL_SUBJECT_OK');
			} else {
				// Post-process the subject
				$subject = AEUtilFilesystem::replace_archive_name_variables($subject);
			}

			// Do we need a default body?
			if(empty($body)) {
				$body = AEPlatform::translate('EMAIL_BODY_OK');
				$info_source = AEPlatform::translate('EMAIL_BODY_INFO');
				$body .= "\n\n" . sprintf($info_source, $profile_number, $num_parts) . "\n\n";
				$body .= $parts_list;
			} else {
				// Post-process the body
				$body = AEUtilFilesystem::replace_archive_name_variables($body);
				$body = str_replace('[PROFILENUMBER]', $profile_number, $body);
				$body = str_replace('[PROFILENAME]', $profile_name, $body);
				$body = str_replace('[PARTCOUNT]', $num_parts, $body);
				$body = str_replace('[FILELIST]', $parts_list, $body);
			}
			// Sometimes $body contains literal \n instead of newlines
			$body = str_replace('\\n',"\n", $body);

			foreach($emails as $email)
			{
				AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Sending email to $email");
				AEPlatform::send_email($email, $subject, $body);
			}
		}

		return true;
	}
예제 #15
0
 public function processPart($absolute_filename, $upload_as = null)
 {
     // Retrieve engine configuration data
     $config = AEFactory::getConfiguration();
     $host = $config->get('engine.postproc.sftp.host', '');
     $port = $config->get('engine.postproc.sftp.port', 22);
     $user = $config->get('engine.postproc.sftp.user', '');
     $pass = $config->get('engine.postproc.sftp.pass', 0);
     $directory = $config->get('volatile.postproc.directory', null);
     if (empty($directory)) {
         $directory = $config->get('engine.postproc.sftp.initial_directory', '');
     }
     // You can't fix stupid, but at least you get to shout at them
     if (strtolower(substr($host, 0, 7)) == 'sftp://') {
         AEUtilLogger::WriteLog(_AE_LOG_WARNING, 'YOU ARE *** N O T *** SUPPOSED TO ENTER THE sftp:// PROTOCOL PREFIX IN THE FTP HOSTNAME FIELD OF THE Upload to Remote SFTP POST-PROCESSING ENGINE.');
         AEUtilLogger::WriteLog(_AE_LOG_WARNING, 'I am trying to fix your bad configuration setting, but the backup might fail anyway. You MUST fix this in your configuration.');
         $host = substr($host, 7);
     }
     // Process the initial directory
     $directory = '/' . ltrim(trim($directory), '/');
     // Parse tags
     $directory = AEUtilFilesystem::replace_archive_name_variables($directory);
     $config->set('volatile.postproc.directory', $directory);
     // Connect to the SFTP server
     AEUtilLogger::WriteLog(_AE_LOG_DEBUG, __CLASS__ . ':: Connecting to remote SFTP');
     $connection = null;
     $sftphandle = null;
     if (!function_exists('ssh2_connect')) {
         $this->setWarning("Your web server does not have the SSH2 PHP module, therefore can not connect and upload archives to SFTP servers.");
         return false;
     }
     $connection = ssh2_connect($host, $port);
     if ($connection === false) {
         $this->setWarning("Invalid SFTP hostname or port ({$host}:{$port}) or the connection is blocked by your web server's firewall.");
         return false;
     }
     if (!ssh2_auth_password($connection, $user, $pass)) {
         $this->setWarning('Could not authenticate access to SFTP server; check your username and password.');
         return false;
     }
     $sftphandle = ssh2_sftp($connection);
     if ($sftphandle === false) {
         $this->setWarning("Your SSH server does not allow SFTP connections");
         return false;
     }
     // Change to initial directory
     if (!$this->_sftp_chdir($directory, $sftphandle)) {
         $this->setWarning("Invalid initial directory {$directory} for the remote SFTP server");
         return false;
     }
     $realdir = substr($directory, -1) == '/' ? substr($directory, 0, strlen($directory) - 1) : $directory;
     $basename = empty($upload_as) ? basename($absolute_filename) : $upload_as;
     $realname = $realdir . '/' . $basename;
     $fp = @fopen("ssh2.sftp://{$sftphandle}{$realname}", 'w');
     if ($fp === false) {
         $this->setWarning("Could not open remote SFTP file {$realname} for writing");
         return false;
     }
     $localfp = @fopen($absolute_filename, 'rb');
     if ($localfp === false) {
         $this->setWarning("Could not open local file {$absolute_filename} for reading");
         @fclose($fp);
         return false;
     }
     $res = true;
     while (!feof($localfp) && $res !== false) {
         $buffer = @fread($localfp, 65567);
         $res = @fwrite($fp, $buffer);
     }
     @fclose($fp);
     @fclose($localfp);
     ssh2_exec($connection, 'exit;');
     $connection = null;
     if ($res === false) {
         // If the file was unreadable, just skip it...
         if (is_readable($absolute_filename)) {
             $this->setWarning('Uploading ' . $realname . ' has failed.');
             return false;
         } else {
             $this->setWarning('Uploading ' . $realname . ' has failed because the source file is unreadable.');
             return true;
         }
     }
     return true;
 }
예제 #16
0
 public function processPart($absolute_filename, $upload_as = null)
 {
     // Retrieve engine configuration data
     $config = AEFactory::getConfiguration();
     $host = $config->get('engine.postproc.ftp.host', '');
     $port = $config->get('engine.postproc.ftp.port', 21);
     $user = $config->get('engine.postproc.ftp.user', '');
     $pass = $config->get('engine.postproc.ftp.pass', 0);
     $directory = $config->get('volatile.postproc.directory', null);
     if (empty($directory)) {
         $directory = $config->get('engine.postproc.ftp.initial_directory', '');
     }
     $ssl = $config->get('engine.postproc.ftp.ftps', 0) == 0 ? false : true;
     $passive = $config->get('engine.postproc.ftp.passive_mode', 0) == 0 ? false : true;
     // You can't fix stupid, but at least you get to shout at them
     if (strtolower(substr($host, 0, 6)) == 'ftp://') {
         AEUtilLogger::WriteLog(_AE_LOG_WARNING, 'YOU ARE *** N O T *** SUPPOSED TO ENTER THE ftp:// PROTOCOL PREFIX IN THE FTP HOSTNAME FIELD OF THE Upload to Remote FTP POST-PROCESSING ENGINE.');
         AEUtilLogger::WriteLog(_AE_LOG_WARNING, 'I am trying to fix your bad configuration setting, but the backup might fail anyway. You MUST fix this in your configuration.');
         $host = substr($host, 6);
     }
     // Process the initial directory
     $directory = '/' . ltrim(trim($directory), '/');
     // Parse tags
     $directory = AEUtilFilesystem::replace_archive_name_variables($directory);
     $config->set('volatile.postproc.directory', $directory);
     // Connect to the FTP server
     AEUtilLogger::WriteLog(_AE_LOG_DEBUG, __CLASS__ . ':: Connecting to remote FTP');
     if ($ssl) {
         if (function_exists('ftp_ssl_connect')) {
             $ftphandle = @ftp_ssl_connect($host, $port);
         } else {
             $ftphandle = false;
         }
     } else {
         $ftphandle = @ftp_connect($host, $port);
     }
     if ($ftphandle === false) {
         $this->setWarning("Wrong FTP hostname or port (host:port = {$host}:{$port})");
         return false;
     }
     // Login
     if (!@ftp_login($ftphandle, $user, $pass)) {
         $this->setWarning('Invalid username/password for the remote FTP server');
         ftp_close($ftphandle);
         return false;
     }
     // Change to initial directory
     if (!@ftp_chdir($ftphandle, $directory)) {
         $this->setWarning("Invalid initial directory {$directory} for the remote FTP server");
         return false;
     }
     @ftp_pasv($ftphandle, $passive);
     $realdir = substr($directory, -1) == '/' ? substr($directory, 0, strlen($directory) - 1) : $directory;
     $basename = empty($upload_as) ? basename($absolute_filename) : $upload_as;
     $realname = $realdir . '/' . $basename;
     try {
         $res = @ftp_put($ftphandle, $realname, $absolute_filename, FTP_BINARY);
     } catch (Exception $e) {
         // Funny how PHP dies without returning false if you don't use a try/catch statement, eh?
         $res = false;
         $this->setWarning($e->getMessage());
     }
     // Store the absolute remote path in the class property
     $this->remote_path = $realname;
     @ftp_close($ftphandle);
     if (!$res) {
         // If the file was unreadable, just skip it...
         if (is_readable($absolute_filename)) {
             $this->setWarning('Uploading ' . $absolute_filename . ' has failed.');
             return false;
         } else {
             $this->setWarning('Uploading ' . $absolute_filename . ' has failed because the file is unreadable.');
             return true;
         }
     } else {
         return true;
     }
 }