/** * @param string $localPathAndFilename * @param string $remotePathAndFilename */ public function upload($localPathAndFilename, $remotePathAndFilename) { if (!$this->ftp) { $this->initializeFtp(); } $remotePathAndFilename = '/' . $this->zone . '/' . $remotePathAndFilename; $remotePath = dirname($remotePathAndFilename); $dir = new Directory($remotePath); //if ( !$this->ftp->directoryExists($dir) ) { $options = array(FTP::RECURSIVE => true); $this->ftp->create($dir, $options); //} $file = new File($remotePathAndFilename); //if ( !$this->ftp->fileExists($file) ) { $this->ftp->upload($file, $localPathAndFilename); //} }
function store_backup() { foreach ($this->b['storage_servers'] as $s) { $s = $this->s[$s]; switch ($s['type']) { case 'local': $path = backup__($s['path']) . '/' . $this->b['_dirname']; //ensure directory structure if (!is_dir($path)) { mkdir($path, 0755, true); } //would rather use the native copy() here, but by defualt //php doesnt support files > 2GB //see here for a posible solution: //http://ca3.php.net/manual/en/function.fopen.php#37791 $cmd[] = fpbx_which('cp'); $cmd[] = $this->b['_tmpfile']; $cmd[] = $path . '/' . $this->b['_file'] . '.tgz'; exec(implode(' ', $cmd), $error, $status); unset($cmd, $error); if ($status !== 0) { $this->b['error'] = 'Error copying ' . $this->b['_tmpfile'] . ' to ' . $path . '/' . $this->b['_file'] . '.tgz: ' . $error; backup_log($this->b['error']); } //run maintenance on the directory $this->maintenance($s['type'], $s); break; case 'email': //TODO: set agent to something informative, including fpbx & backup versions $email_options = array('useragent' => 'freepbx', 'protocol' => 'mail'); $email = new \CI_Email(); //Generic email $from = '*****@*****.**'; //If we have sysadmin and "from is set" if (function_exists('sysadmin_get_storage_email')) { $emails = sysadmin_get_storage_email(); //Check that what we got back above is a email address if (!empty($emails['fromemail']) && filter_var($emails['fromemail'], FILTER_VALIDATE_EMAIL)) { $from = $emails['fromemail']; } } //If the user set an email in advanced settings it wins, otherwise take whatever won above. $from = filter_var($this->amp_conf['AMPBACKUPEMAILFROM'], FILTER_VALIDATE_EMAIL) ? $this->amp_conf['AMPBACKUPEMAILFROM'] : $from; $msg[] = _('Name') . ': ' . $this->b['name']; $msg[] = _('Created') . ': ' . date('r', $this->b['_ctime']); $msg[] = _('Files') . ': ' . $this->manifest['file_count']; $msg[] = _('Mysql Db\'s') . ': ' . $this->manifest['mysql_count']; $msg[] = _('astDb\'s') . ': ' . $this->manifest['astdb_count']; $email->from($from); $email->to(backup__($s['addr'])); $email->subject($this->amp_conf['FREEPBX_SYSTEM_IDENT'] . ' ' . _('Backup') . ' ' . $this->b['name']); $body = implode("\n", $msg); // If the backup file is more than 25MB, yell $encodedsize = ceil(filesize($this->b['_tmpfile']) / 3) * 4; if ($encodedsize > 26214400) { $email->subject($this->amp_conf['FREEPBX_SYSTEM_IDENT'] . ' ' . _('Backup ERROR (exceeded SMTP limits)') . ' ' . $this->b['name']); $email->message(_('BACKUP NOT ATTACHED') . "\n" . _('The backup file exceeded the maximum SMTP limits of 25MB. It was not attempted to be sent. Please shrink your backup, or use a different method of transferring your backup.') . "\n{$body}\n"); } elseif ($encodedsize > $s['maxsize']) { $email->subject($this->amp_conf['FREEPBX_SYSTEM_IDENT'] . ' ' . _('Backup ERROR (exceeded soft limit)') . ' ' . $this->b['name']); $email->message(_('BACKUP NOT ATTACHED') . "\n" . _('The backup file exceeded the soft limit set in SMTP configuration (%s bytes). It was not attempted to be sent. Please shrink your backup, or use a different method of transferring your backup.') . "\n{$body}\n"); } else { $email->message($body); $email->attach($this->b['_tmpfile']); } $email->send(); unset($msg); break; case 'ftp': //subsitute variables if nesesary $s['host'] = backup__($s['host']); $s['port'] = backup__($s['port']); $s['user'] = backup__($s['user']); $s['password'] = backup__($s['password']); $s['path'] = trim(backup__($s['path']), '/'); $fstype = isset($s['fstype']) ? $s['fstype'] : 'auto'; $path = $s['path'] . '/' . $this->b['_dirname']; $connection = new Connection($s['host'], $s['user'], $s['password'], $s['port'], 90, $s['transfer'] == 'passive'); try { $connection->open(); } catch (\Exception $e) { $this->b['error'] = $e->getMessage(); backup_log($this->b['error']); return; } $wrapper = new FTPWrapper($connection); $permFactory = new PermissionsFactory(); switch ($fstype) { case 'auto': $ftptype = $wrapper->systype(); if (strtolower($ftptype) == "unix") { $fsFactory = new FilesystemFactory($permFactory); } else { $fsFactory = new WindowsFilesystemFactory(); } break; case 'unix': $fsFactory = new FilesystemFactory($permFactory); break; case 'windows': $fsFactory = new WindowsFilesystemFactory(); break; } $manager = new FTPFilesystemManager($wrapper, $fsFactory); $dlVoter = new DownloaderVoter(); $ulVoter = new UploaderVoter(); $ulVoter->addDefaultFTPUploaders($wrapper); $crVoter = new CreatorVoter(); $crVoter->addDefaultFTPCreators($wrapper, $manager); $deVoter = new DeleterVoter(); $deVoter->addDefaultFTPDeleters($wrapper, $manager); $ftp = new FTP($manager, $dlVoter, $ulVoter, $crVoter, $deVoter); if (!$ftp) { $this->b['error'] = _("Error creating the FTP object"); backup_log($this->b['error']); return; } if (!$ftp->directoryExists(new Directory($path))) { backup_log(sprintf(_("Creating directory '%s'"), $path)); try { $ftp->create(new Directory($path), array(FTP::RECURSIVE => true)); } catch (\Exception $e) { $this->b['error'] = sprintf(_("Directory '%s' did not exist and we could not create it"), $path); backup_log($this->b['error']); backup_log($e->getMessage()); return; } } try { backup_log(_("Saving file to remote ftp")); $ftp->upload(new File($path . '/' . $this->b['_file'] . '.tgz'), $this->b['_tmpfile']); } catch (\Exception $e) { $this->b['error'] = _("Unable to upload file to the remote server"); backup_log($this->b['error']); backup_log($e->getMessage()); return; } //run maintenance on the directory $this->maintenance($s['type'], $path, $ftp); break; case 'awss3': //subsitute variables if nesesary $s['bucket'] = backup__($s['bucket']); $s['awsaccesskey'] = backup__($s['awsaccesskey']); $s['awssecret'] = backup__($s['awssecret']); $awss3 = new \S3($s['awsaccesskey'], $s['awssecret']); // Does this bucket already exist? $buckets = $awss3->listBuckets(); if (!in_array($s['bucket'], $buckets)) { // Create the bucket $awss3->putBucket($s['bucket'], \S3::ACL_PUBLIC_READ); } //copy file if ($awss3->putObjectFile($this->b['_tmpfile'], $s['bucket'], $this->b['name'] . "/" . $this->b['_file'] . '.tgz', \S3::ACL_PUBLIC_READ)) { dbug('S3 successfully uploaded your backup file.'); } else { dbug('S3 failed to accept your backup file'); } //run maintenance on the directory $this->maintenance($s['type'], $s, $awss3); break; case 'ssh': //subsitute variables if nesesary $s['path'] = backup__($s['path']); $s['user'] = backup__($s['user']); $s['host'] = backup__($s['host']); $destdir = $s['path'] . '/' . $this->b['_dirname']; //ensure directory structure $cmd = fpbx_which('ssh') . ' -o StrictHostKeyChecking=no -i '; $cmd .= $s['key'] . " -l " . $s['user'] . ' ' . $s['host'] . ' -p ' . $s['port']; $cmd .= " 'mkdir -p {$destdir}'"; exec($cmd, $output, $ret); if ($ret !== 0) { backup_log("SSH Error ({$ret}) - Received " . json_encode($output) . " from {$cmd}"); } $output = null; //put file // Note that SCP (*unlike SSH*) needs IPv6 addresses in ['s. Consistancy is awesome. if (filter_var($s['host'], \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { $scphost = "[" . $s['host'] . "]"; } else { $scphost = $s['host']; } $cmd = fpbx_which('scp') . ' -o StrictHostKeyChecking=no -i ' . $s['key'] . ' -P ' . $s['port']; $cmd .= " " . $this->b['_tmpfile'] . " " . $s['user'] . "@{$scphost}:{$destdir}"; exec($cmd, $output, $ret); if ($ret !== 0) { backup_log("SCP Error ({$ret}) - Received " . json_encode($output) . " from {$cmd}"); } //run maintenance on the directory $this->maintenance($s['type'], $s); break; } } }