From f17718f87dd8604e0b6ead593861bc9643ce2f05 Mon Sep 17 00:00:00 2001
From: Florian Schaal <florian@schaal-24.de>
Date: Sat, 04 Jan 2014 13:27:07 -0500
Subject: [PATCH] add mail-backup
---
interface/web/mail/lib/lang/en_mail_user.lng | 6
interface/web/mail/templates/mail_user_backup.htm | 39 ++++
interface/web/mail/form/mail_user.tform.php | 34 +++
interface/web/mail/lib/lang/en_mail_backup_list.lng | 12 +
interface/web/mail/mail_user_edit.php | 9 +
server/lib/classes/cron.d/500-backup_mail.inc.php | 175 +++++++++++++++++++
interface/lib/classes/plugin_backuplist_mail.inc.php | 129 ++++++++++++++
interface/web/mail/templates/mail_user_backup_list.htm | 47 +++++
server/plugins-available/backup_plugin.inc.php | 46 ++++
9 files changed, 495 insertions(+), 2 deletions(-)
diff --git a/interface/lib/classes/plugin_backuplist_mail.inc.php b/interface/lib/classes/plugin_backuplist_mail.inc.php
new file mode 100644
index 0000000..5bef570
--- /dev/null
+++ b/interface/lib/classes/plugin_backuplist_mail.inc.php
@@ -0,0 +1,129 @@
+<?php
+
+/*
+Copyright (c) 2013, Florian Schaal, info@schaal-24.de
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class plugin_backuplist_mail extends plugin_base {
+
+ var $module;
+ var $form;
+ var $tab;
+ var $record_id;
+ var $formdef;
+ var $options;
+
+ function onShow() {
+ global $app;
+ $listTpl = new tpl;
+ $listTpl->newTemplate('templates/mail_user_backup_list.htm');
+
+ //* Loading language file
+ $lng_file = "lib/lang/".$_SESSION["s"]["language"]."_mail_backup_list.lng";
+ include($lng_file);
+ $listTpl->setVar($wb);
+
+ $message = '';
+ $error = '';
+
+ if(isset($_GET['backup_action'])) {
+ $backup_id = $app->functions->intval($_GET['backup_id']);
+/*
+ if($_GET['backup_action'] == 'download' && $backup_id > 0) {
+ $sql = "SELECT count(action_id) as number FROM sys_remoteaction WHERE action_state = 'pending' AND action_type = 'backup_download' AND action_param = '$backup_id'";
+ $tmp = $app->db->queryOneRecord($sql);
+ if($tmp['number'] == 0) {
+ $message .= $wb['download_info_txt'];
+ $sql = "INSERT INTO sys_remoteaction (server_id, tstamp, action_type, action_param, action_state, response) " .
+ "VALUES (".
+ (int)$this->form->dataRecord['server_id'] . ", " .
+ time() . ", " .
+ "'backup_download', " .
+ "'".$backup_id."', " .
+ "'pending', " .
+ "''" .
+ ")";
+ $app->db->query($sql);
+ } else {
+ $error .= $wb['download_pending_txt'];
+ }
+ }
+*/
+ if($_GET['backup_action'] == 'restore' && $backup_id > 0) {
+ $sql = "SELECT count(action_id) as number FROM sys_remoteaction WHERE action_state = 'pending' AND action_type = 'backup_restore' AND action_param = '$backup_id'";
+ $tmp = $app->db->queryOneRecord($sql);
+ if($tmp['number'] == 0) {
+ $message .= $wb['restore_info_txt'];
+ $sql = "INSERT INTO sys_remoteaction (server_id, tstamp, action_type, action_param, action_state, response) " .
+ "VALUES (".
+ (int)$this->form->dataRecord['server_id'] . ", " .
+ time() . ", " .
+ "'backup_restore', " .
+ "'".$backup_id."', " .
+ "'pending', " .
+ "''" .
+ ")";
+ $app->db->query($sql);
+ } else {
+ $error .= $wb['restore_pending_txt'];
+ }
+ }
+ }
+
+ //* Get the data
+ $sql = "SELECT * FROM mail_backup WHERE mailuser_id = ".$this->form->id." ORDER BY tstamp DESC";
+ $records = $app->db->queryAllRecords($sql);
+ $bgcolor = "#FFFFFF";
+ if(is_array($records)) {
+ foreach($records as $rec) {
+ // Change of color
+ $bgcolor = ($bgcolor == "#FFFFFF")?"#EEEEEE":"#FFFFFF";
+ $rec["bgcolor"] = $bgcolor;
+ $rec['date'] = date($app->lng('conf_format_datetime'),$rec['tstamp']);
+ $rec['backup_type'] = $wb[('backup_type_'.$rec['backup_type'])];
+ $records_new[] = $rec;
+ }
+ }
+
+ $listTpl->setLoop('records',@$records_new);
+
+ $listTpl->setVar('parent_id',$this->form->id);
+ $listTpl->setVar('msg',$message);
+ $listTpl->setVar('error',$error);
+
+ // Setting Returnto information in the session
+ $list_name = 'backup_list';
+ $_SESSION["s"]["list"][$list_name]["parent_id"] = $this->form->id;
+ $_SESSION["s"]["list"][$list_name]["parent_name"] = $app->tform->formDef["name"];
+ $_SESSION["s"]["list"][$list_name]["parent_tab"] = $_SESSION["s"]["form"]["tab"];
+ $_SESSION["s"]["list"][$list_name]["parent_script"] = $app->tform->formDef["action"];
+ $_SESSION["s"]["form"]["return_to"] = $list_name;
+ return $listTpl->grab();
+ } // end function
+} // end class
+
+?>
diff --git a/interface/web/mail/form/mail_user.tform.php b/interface/web/mail/form/mail_user.tform.php
index 21fc514..03f458a 100644
--- a/interface/web/mail/form/mail_user.tform.php
+++ b/interface/web/mail/form/mail_user.tform.php
@@ -346,5 +346,39 @@
);
}
+//* Backup
+$form["tabs"]['backup'] = array (
+ 'title' => "Backup",
+ 'width' => 100,
+ 'template' => "templates/mail_user_backup.htm",
+ 'readonly' => false,
+ 'fields' => array (
+ ##################################
+ # Begin Datatable fields
+ ##################################
+ 'backup_interval' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'SELECT',
+ 'default' => '',
+ 'value' => array('none' => 'no_backup_txt', 'daily' => 'daily_backup_txt', 'weekly' => 'weekly_backup_txt', 'monthly' => 'monthly_backup_txt')
+ ),
+ 'backup_copies' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'SELECT',
+ 'default' => '',
+ 'value' => array('1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9', '10' => '10')
+ ),
+ ##################################
+ # ENDE Datatable fields
+ ##################################
+ ),
+ 'plugins' => array (
+ 'backup_records' => array (
+ 'class' => 'plugin_backuplist_mail',
+ 'options' => array(
+ )
+ )
+ )
+);
?>
diff --git a/interface/web/mail/lib/lang/en_mail_backup_list.lng b/interface/web/mail/lib/lang/en_mail_backup_list.lng
new file mode 100644
index 0000000..320ff50
--- /dev/null
+++ b/interface/web/mail/lib/lang/en_mail_backup_list.lng
@@ -0,0 +1,12 @@
+<?php
+$wb['list_head_txt'] = 'Existing backups';
+$wb['date_txt'] = 'Date';
+$wb['backup_type_txt'] = 'Type';
+$wb['filename_txt'] = 'Backup file';
+$wb['restore_backup_txt'] = 'Restore';
+$wb['restore_info_txt'] = 'Restore of the backup has been started. This action takes several minutes to be completed.';
+$wb['restore_confirm_txt'] = 'Restoring may overwrite existing files in your mailbox. Do you really want to restore this backup?';
+$wb['download_pending_txt'] = 'There is already a pending backup download job.';
+$wb['restore_pending_txt'] = 'There is already a pending backup restore job.';
+$wb['filesize_txt'] = 'Filesize';
+?>
diff --git a/interface/web/mail/lib/lang/en_mail_user.lng b/interface/web/mail/lib/lang/en_mail_user.lng
index f180dee..c275c1a 100644
--- a/interface/web/mail/lib/lang/en_mail_user.lng
+++ b/interface/web/mail/lib/lang/en_mail_user.lng
@@ -47,4 +47,10 @@
$wb['repeat_password_txt'] = 'Repeat Password';
$wb['password_mismatch_txt'] = 'The passwords do not match.';
$wb['password_match_txt'] = 'The passwords do match.';
+$wb["backup_interval_txt"] = 'Backup interval';
+$wb["backup_copies_txt"] = 'Number of backup copies';
+$wb['no_backup_txt'] = 'No backup';
+$wb['daily_backup_txt'] = 'Daily';
+$wb['weekly_backup_txt'] = 'Weekly';
+$wb['monthly_backup_txt'] = 'Monthly';
?>
diff --git a/interface/web/mail/mail_user_edit.php b/interface/web/mail/mail_user_edit.php
index f71aa7d..61f27cb 100644
--- a/interface/web/mail/mail_user_edit.php
+++ b/interface/web/mail/mail_user_edit.php
@@ -319,6 +319,15 @@
} // end if email addess changed
+ //* Change backup options when user mail backup options have been changed
+ if(isset($this->dataRecord['backup_interval']) && ($this->dataRecord['backup_interval'] != $this->oldDataRecord['backup_interval'] || $this->dataRecord['backup_copies'] != $this->oldDataRecord['backup_copies'])) {
+ $backup_interval = $this->dataRecord['backup_interval'];
+ $backup_copies = $this->dataRecord['backup_copies'];
+ $app->db->datalogUpdate('mail_user', "backup_interval = '$backup_interval', backup_copies = '$backup_copies'", 'mailuser_id', $rec['mailuser_id']);
+ unset($backup_copies);
+ unset($backup_interval);
+ } // end if backup options changed
+
}
}
diff --git a/interface/web/mail/templates/mail_user_backup.htm b/interface/web/mail/templates/mail_user_backup.htm
new file mode 100644
index 0000000..e3aa096
--- /dev/null
+++ b/interface/web/mail/templates/mail_user_backup.htm
@@ -0,0 +1,39 @@
+<h2><tmpl_var name="list_head_txt"></h2>
+<p><tmpl_var name="list_desc_txt"></p>
+
+<tmpl_if name="config_error_msg">
+<div style="background: #ffdfdf; border: 1px solid #df7d7d; border-width: 1px 0; margin: 1.5em 0 1.5em 0; padding: 7px;">
+ <p style="font-face:bold">{tmpl_var name='configuration_error_txt'}</p>
+ <div>
+ <div style="float:left;width:150px;">{tmpl_var name='config_error_tstamp'} : </div><div style="padding-left:150px;">{tmpl_var name='config_error_msg'}</div>
+ </div>
+</div>
+</tmpl_if>
+
+<div class="panel panel_mail_user">
+
+ <div class="pnl_formsarea">
+ <fieldset class="inlineLabels"><legend>Backup</legend>
+ <div class="ctrlHolder">
+ <label for="backup_interval">{tmpl_var name='backup_interval_txt'}</label>
+ <select name="backup_interval" id="backup_interval" class="selectInput">
+ {tmpl_var name='backup_interval'}
+ </select>
+ </div>
+ <div class="ctrlHolder">
+ <label for="backup_copies">{tmpl_var name='backup_copies_txt'}</label>
+ <select name="backup_copies" id="backup_copies" class="selectInput">
+ {tmpl_var name='backup_copies'}
+ </select>
+ </div>
+ </fieldset>
+ {tmpl_var name='backup_records'}
+ <input type="hidden" name="id" value="{tmpl_var name='id'}">
+
+ <div class="buttonHolder buttons">
+ <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onclick="submitForm('pageForm','mail/mail_user_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
+ <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onclick="loadContent('mail/mail_user_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
+ </div>
+ </div>
+
+</div>
diff --git a/interface/web/mail/templates/mail_user_backup_list.htm b/interface/web/mail/templates/mail_user_backup_list.htm
new file mode 100644
index 0000000..7fc61fd
--- /dev/null
+++ b/interface/web/mail/templates/mail_user_backup_list.htm
@@ -0,0 +1,47 @@
+<tmpl_if name="msg">
+ <div id="OKMsg"><p><tmpl_var name="msg"></p></div>
+</tmpl_if>
+<tmpl_if name="error">
+ <div id="errorMsg"><h3>ERROR</h3><ol><tmpl_var name="error"></ol></div>
+</tmpl_if>
+<h3><tmpl_var name="list_head_txt"></h3>
+
+<div class="panel panel_list_mail_backup">
+
+ <div class="pnl_listarea">
+ <fieldset><legend><tmpl_var name="list_head_txt"></legend>
+ <table class="list">
+ <thead>
+ <tr class="caption">
+ <th class="tbl_col_date" scope="col"><tmpl_var name="date_txt"></th>
+ <th class="tbl_col_filename" scope="col"><tmpl_var name="filename_txt"></th>
+ <th class="tbl_col_filename" scope="col"><tmpl_var name="filesize_txt"></th>
+ <th class="tbl_col_limit" scope="col">{tmpl_var name='search_limit'}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tmpl_loop name="records">
+ <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
+ <td class="tbl_col_date">{tmpl_var name="date"}</td>
+ <td class="tbl_col_filename">{tmpl_var name="filename"}</td>
+ <td class="tbl_col_filesize">{tmpl_var name="filesize"}</td>
+ <td class="tbl_col_buttons">
+ <div class="buttons">
+ <button class="button iconstxt icoRestore" type="button" onclick="confirm_action('mail/mail_user_edit.php?id={tmpl_var name='parent_id'}&next_tab=backup&backup_action=restore&backup_id={tmpl_var name='backup_id'}','{tmpl_var name='restore_confirm_txt'}');"><span>{tmpl_var name="restore_backup_txt"}</span></button>
+<!-- <button class="button iconstxt icoDownload" type="button" onclick="loadContent('mail/mail_user_edit.php?id={tmpl_var name='parent_id'}&next_tab=backup&backup_action=download&backup_id={tmpl_var name='backup_id'}');"><span>{tmpl_var name="download_backup_txt"}</span></button>
+-->
+ </div>
+ </td>
+ </tr>
+ </tmpl_loop>
+ <tmpl_unless name="records">
+ <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
+ <td colspan="4">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
+ </tr>
+ </tmpl_unless>
+ </tbody>
+ </table>
+ </fieldset>
+ </div>
+
+</div>
diff --git a/server/lib/classes/cron.d/500-backup_mail.inc.php b/server/lib/classes/cron.d/500-backup_mail.inc.php
new file mode 100644
index 0000000..b5a61f2
--- /dev/null
+++ b/server/lib/classes/cron.d/500-backup_mail.inc.php
@@ -0,0 +1,175 @@
+<?php
+/*
+Copyright (c) 2013, Florian Schaal, info@schaal-24.de
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class cronjob_backup extends cronjob {
+
+ // job schedule
+ protected $_schedule = '0 0 * * *';
+
+ /* this function is optional if it contains no custom code */
+ public function onPrepare() {
+ global $app;
+
+ parent::onPrepare();
+ }
+
+ /* this function is optional if it contains no custom code */
+ public function onBeforeRun() {
+ global $app;
+
+ return parent::onBeforeRun();
+ }
+
+ public function onRunJob() {
+ global $app, $conf;
+
+ $server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
+ $backup_dir = $server_config['backup_dir'];
+ $backup_mode = $server_config['backup_mode'];
+ if($backup_mode == '') $backup_mode = 'userzip';
+ $backup_dir_permissions =0750;
+
+ if($backup_dir != '') {
+/*
+ //* mount backup directory, if necessary
+ $run_backups = true;
+ $server_config['backup_dir_mount_cmd'] = trim($server_config['backup_dir_mount_cmd']);
+ if($server_config['backup_dir_is_mount'] == 'y' && $server_config['backup_dir_mount_cmd'] != ''){
+ if(!$app->system->is_mounted($backup_dir)){
+ exec(escapeshellcmd($server_config['backup_dir_mount_cmd']));
+ sleep(1);
+ if(!$app->system->is_mounted($backup_dir)) $run_backups = false;
+ }
+ }
+*/
+
+ $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail');
+
+ if(!is_dir($backup_dir)) {
+ mkdir(escapeshellcmd($backup_dir), $backup_dir_permissions, true);
+ } else {
+ chmod(escapeshellcmd($backup_dir), $backup_dir_permissions);
+ }
+
+ $sql = "SELECT * FROM mail_user WHERE server_id = '".$conf['server_id']."' AND maildir <> ''";
+ $records = $app->db->queryAllRecords($sql);
+ if(is_array($records)) {
+ foreach($records as $rec) {
+ //* Do the mailbox backup
+ if($rec['backup_interval'] == 'daily' or ($rec['backup_interval'] == 'weekly' && date('w') == 0) or ($rec['backup_interval'] == 'monthly' && date('d') == '01')) {
+ $sql="SELECT * FROM mail_domain WHERE domain = '".$app->db->quote(explode("@",$rec['email'])[1])."'";
+ $domain_rec=$app->db->queryOneRecord($sql);
+ $mail_backup_dir = $backup_dir.'/mail'.$domain_rec['domain_id'];
+
+ if(!is_dir($mail_backup_dir)) mkdir($mail_backup_dir, 0750);
+ chmod($mail_backup_dir, $backup_dir_permissions);
+
+ $domain_dir=explode('/',$rec['maildir']);
+ $_temp=array_pop($domain_dir);unset($_temp);
+ $domain_dir=implode('/',$domain_dir);
+ $source_dir=array_pop(explode('/',$rec['maildir']));
+
+ $mail_backup_file = 'mail'.$rec['mailuser_id'].'_'.date('Y-m-d_H-i');
+
+ if($backup_mode == 'userzip') {
+ $mail_backup_file.='.zip';
+ exec('cd '.$rec['homedir'].' && zip -b /tmp -r '.$mail_backup_dir.'/'.$mail_backup_file.' '.$source_dir.' > /dev/nul');
+ //exec('cd '.$rec['homedir'].' && zip -b /tmp -r '.$mail_backup_dir.'/'.$mail_backup_file.' '.$source_dir.' > /dev/nul');
+ } else {
+ /* Create a tar.gz backup */
+ $mail_backup_file.='.tar.gz';
+ exec(escapeshellcmd('tar pczf '.$mail_backup_dir.'/'.$mail_backup_file.' --directory '.$domain_dir.' '.$source_dir), $tmp_output, $retval);
+ }
+ if($retval == 0){
+ chown($mail_backup_dir.'/'.$mail_backup_file, 'root');
+ chgrp($mail_backup_dir.'/'.$mail_backup_file, 'root');
+ chmod($mail_backup_dir.'/'.$mail_backup_file, 0640);
+ /* Insert mail backup record in database */
+ $sql = "INSERT INTO mail_backup (server_id,parent_domain_id,mailuser_id,backup_mode,tstamp,filename,filesize) VALUES (".$conf['server_id'].",".$domain_rec['domain_id'].",".$rec['mailuser_id'].",'".$backup_mode."',".time().",'".$app->db->quote($mail_backup_file)."','".$app->functions->formatBytes(filesize($mail_backup_dir.'/'.$mail_backup_file))."')";
+ $app->db->query($sql);
+ if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql);
+ } else {
+ /* Backup failed - remove archive */
+ if(is_file($mail_backup_dir.'/'.$mail_backup_file)) unlink($mail_backup_dir.'/'.$mail_backup_file);
+ $app->log($mail_backup_file.' NOK:'.$tmp_output, LOGLEVEL_DEBUG);
+ }
+ /* Remove old backups */
+ $backup_copies = intval($rec['backup_copies']);
+ $dir_handle = dir($mail_backup_dir);
+ $files = array();
+ while (false !== ($entry = $dir_handle->read())) {
+ if($entry != '.' && $entry != '..' && substr($entry,0,4+strlen($rec['mailuser_id'])) == 'mail'.$rec['mailuser_id'] && is_file($mail_backup_dir.'/'.$entry)) {
+ $files[] = $entry;
+ }
+ }
+ $dir_handle->close();
+ rsort($files);
+ for ($n = $backup_copies; $n <= 10; $n++) {
+ if(isset($files[$n]) && is_file($mail_backup_dir.'/'.$files[$n])) {
+ unlink($mail_backup_dir.'/'.$files[$n]);
+ $sql = "DELETE FROM mail_backup WHERE server_id = ".$conf['server_id']." AND parent_domain_id = ".$domain_rec['domain_id']." AND filename = '".$app->db->quote($files[$n])."'";
+ $app->db->query($sql);
+ if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql);
+ }
+ }
+ unset($files);
+ unset($dir_handle);
+ }
+ /* Remove inactive backups */
+ if($rec['backup_interval'] == 'none') {
+ /* remove backups from db */
+ $sql = "DELETE FROM mail_backup WHERE server_id = ".$conf['server_id']." AND parent_domain_id = ".$domain_rec['domain_id']." AND mailuser_id = ".$rec['mailuser_id'];
+ $app->db->query($sql);
+ if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql);
+ /* remove archives */
+ $mail_backup_dir = $backup_dir.'/mail'.$rec['sys_userid'];
+ $mail_backup_file = 'mail'.$rec['mailuser_id'].'_*';
+ if(is_dir($mail_backup_dir)) {
+ foreach (glob($mail_backup_dir.'/'.$mail_backup_file) as $filename) {
+ unlink($filename);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ parent::onRunJob();
+ }
+
+ /* this function is optional if it contains no custom code */
+ public function onAfterRun() {
+ global $app;
+
+ parent::onAfterRun();
+ }
+
+}
+
+?>
diff --git a/server/plugins-available/backup_plugin.inc.php b/server/plugins-available/backup_plugin.inc.php
index 6c6ef14..d2590b4 100644
--- a/server/plugins-available/backup_plugin.inc.php
+++ b/server/plugins-available/backup_plugin.inc.php
@@ -62,6 +62,7 @@
$backup_id = intval($data);
$backup = $app->dbmaster->queryOneRecord("SELECT * FROM web_backup WHERE backup_id = $backup_id");
+ $mail_backup = $app->dbmaster->queryOneRecord("SELECT * FROM mail_backup WHERE backup_id = $backup_id");
if(is_array($backup)) {
@@ -149,9 +150,49 @@
}
}
}
+ //* Restore a mail backup - florian@schaal-24.de
+ } elseif (is_array($mail_backup) && $action_name == 'backup_restore') {
+ $app->uses('ini_parser,file,getconf');
+ $server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
+ $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail');
+
+ $domain_rec = $app->db->queryOneRecord("SELECT * FROM mail_domain WHERE domain_id = ".intval($mail_backup['parent_domain_id']));
+
+ $backup_dir = $server_config['backup_dir'].'/mail'.$domain_rec['domain_id'];
+ $mail_backup_file = $backup_dir.'/'.$mail_backup['filename'];
+
+ $sql = "SELECT * FROM mail_user WHERE server_id = '".$conf['server_id']."' AND mailuser_id = ".intval($mail_backup['mailuser_id']);
+ $record = $app->db->queryOneRecord($sql);
+
+ //* strip mailbox from maildir
+ $domain_dir=explode('/',$record['maildir']);
+ $_temp=array_pop($domain_dir);unset($_temp);
+ $domain_dir=implode('/',$domain_dir);
+ if(file_exists($mail_backup_file) && $record['homedir'] != '' && $record['homedir'] != '/' && !stristr($mail_backup_file,'..') && !stristr($mail_backup_file,'etc') && $mail_config['homedir_path'] == $record['homedir'] && is_dir($domain_dir)) {
+ if($mail_backup['backup_mode'] == 'userzip') {
+ $command = 'sudo -u '.$mail_config['mailuser_name'].' unzip -qq -o '.escapeshellarg($mail_backup_file).' -d '.escapeshellarg($domain_dir).' 2> /dev/null';
+ exec($command,$tmp_output, $retval);
+ if($retval == 0){
+ $app->log('Restored Mail backup '.$mail_backup_file,LOGLEVEL_DEBUG);
+ } else {
+ $app->log('Unable to restore Mail backup '.$mail_backup_file.' '.$tmp_output,LOGLEVEL_ERROR);
+ }
+ }
+ if($mail_backup['backup_mode'] == 'rootgz') {
+ $command='tar xfz '.escapeshellarg($mail_backup_file).' --directory '.escapeshellarg($domain_dir);
+ exec($command,$tmp_output, $retval);
+ if($retval == 0){
+ $app->log('Restored Mail backup '.$mail_backup_file,LOGLEVEL_DEBUG);
+ } else {
+ $app->log('Unable to restore Mail backup '.$mail_backup_file.' '.$tmp_output,LOGLEVEL_ERROR);
+ }
+ }
+ } else {
+ $app->log('Unable to restore Mail backup '.$mail_backup_file.' due to misconfiguration',LOGLEVEL_ERROR);
+ }
} else {
- $app->log('No backup with ID '.$backup_id.' found.', LOGLEVEL_DEBUG);
+ $app->log('No backup with ID '.$backup_id.' found.',LOGLEVEL_DEBUG);
}
return 'ok';
@@ -159,4 +200,5 @@
} // end class
-?>
+?>
+
--
Gitblit v1.9.1