package ONO::Cron::CronSync::Backup;
################################################################################
# COPYRIGHT / LICENSE #
################################################################################
#
# This file is part of the ONO Software Project.
#
# Copyright (C) 2000-2025 Jos KIRPS [ www.kirps.com | jos_AT_kirps_DOT_com ]
# and The Joopita Project [ www.joopita.org | contact_AT_joopita_DOT_com ]
#
# This file, as well as other parts of the ONO Software Project or related
# elements, are FREE SOFTWARE available under the ARTISTIC LICENSE 2.0.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# For the full license, see /ono/osr/license/LICENSE.txt, or write to
# jos_AT_kirps_DOT_com or contact_AT_joopita_DOT_com.
#
################################################################################
# END OF COPYRIGHT / LICENSE, HERE COMES THE CODE ... #
################################################################################
use strict;
use ONO::IO;
use ONO::Core::HostIO;
use ONO::Cron::CronSync::ToolBox;
use ONO::Lib::DateTime::ToolBox;
use ONO::Lib::Code::RandomID;
use ONO::ToolBox::SendMail;
use ONO::Render;
###############################################################################
# ONO
###############################################################################
#: Backup related services for ONO's CronSync service.
sub run {
my (
$self,
$CRON_DIR,
$job,
$data_ref,
$TYPE_ref,
$vars_ref,
$vpath,
$sec,$min,$hour,
$mday,$mon,$year,
$wday,$yday,
$timestamp,
$switches,
) = @_;
#: Execution logic.
my %data = %$data_ref;
my %TYPE = %$TYPE_ref;
my %vars = %$vars_ref;
my ($DATA,$MAIL);
if ($data{'type'} eq "bak_local") {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': $TYPE{$data{'type'}} ($data{'type'})",$switches);
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': backup target: $data{'bak_target'}",$switches);
my $ID = ONO::Lib::Code::RandomID->make;
my $ori_target = $data{'bak_target'};
if ($data{'bak_target'} =~ /[A-Za-z0-9]/) {
ONO::IO->mkdir("$data{'bak_target'}",777);
ONO::IO->htaccess("$data{'bak_target'}",":");
my $title = lc $data{'title'};
$title =~ s~( |_)~~g;
$title =~ s~[^a-z0-9\-]~~g;
$data{'bak_target'} .= "/$title";
ONO::IO->mkdir("$data{'bak_target'}",777);
ONO::IO->mkdir("$data{'bak_target'}/$ID",777);
}
if (ONO::IO->exists("$data{'bak_target'}/$ID")) {
if (!$data{'bak_sql_setup_mysqldump'}) {
$data{'bak_sql_setup_mysqldump'} = ONO::IO->which("mysqldump");
}
if ($data{'bak_sql'} && $data{'bak_sql_setup_mysqldump'} =~ m~^/~ && $data{'bak_sql_setup_username'} && $data{'bak_sql_setup_database'}) {
foreach my $opt ('bak_sql_setup_mysqldump','bak_sql_setup_username','bak_sql_setup_password','bak_sql_setup_database') {
$data{$opt} =~ s~[^A-Za-z0-9\/]~~g;
}
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': creating backup: ONO SQL DB ...",$switches);
ONO::IO->mkdir("$data{'bak_target'}/$ID/sql",777);
ONO::IO->store(
"$data{'bak_target'}/$ID/sql/$data{'bak_sql_setup_database'}.sql",
ONO::IO->exec3("$data{'bak_sql_setup_mysqldump'} --user=$data{'bak_sql_setup_username'} --password=$data{'bak_sql_setup_password'} --databases $data{'bak_sql_setup_database'}"),
);
}
foreach my $opt ('images','media','var') {
if ($data{"bak_dir_$opt"}) {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': creating backup: $opt/ -> $data{'bak_target'}",$switches);
ONO::IO->mkdir("$data{'bak_target'}/$ID/$opt",777);
foreach my $dir (ONO::IO->ls("$opt")) {
if ($dir =~ /[A-Za-z0-9]/) {
ONO::IO->cpr("$opt/$dir","$data{'bak_target'}/$ID/$opt/$dir");
if ($data{"bak_zip_$opt"}) {
ONO::IO->tar("$data{'bak_target'}/$ID/$opt/$dir","$data{'bak_target'}/$ID/$opt/$dir.gz");
if ($data{"bak_zipcleanup_$opt"}) {
ONO::IO->rmdir("$data{'bak_target'}/$ID/$opt/$dir");
}
}
}
}
}
}
if ($data{'bak_dir_var_community'}) {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': creating backup: var/community/ -> $data{'bak_target'}",$switches);
ONO::IO->mkdir("$data{'bak_target'}/$ID/community",777);
foreach my $dir (ONO::IO->ls("var/community")) {
if ($dir =~ /[A-Za-z0-9]/) {
ONO::IO->cpr("var/community/$dir","$data{'bak_target'}/$ID/community/$dir");
if ($data{'bak_zip_var_community'}) {
ONO::IO->tar("$data{'bak_target'}/$ID/community/$dir","$data{'bak_target'}/$ID/community/$dir.gz");
if ($data{'bak_zipcleanup_var_community'}) {
ONO::IO->rmdir("$data{'bak_target'}/$ID/community/$dir");
}
}
}
}
}
if ($data{'bak_dir_web'}) {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': creating backup: web/ -> $data{'bak_target'}",$switches);
my $sites = 0;
foreach my $opt ('web','schoolweb') {
if (ONO::IO->exists($opt)) {
ONO::IO->mkdir("$data{'bak_target'}/$ID/$opt");
foreach my $d1 (ONO::IO->ls("$opt/")) {
if ($d1 =~ /[A-Za-z0-9]/ && $d1 !~ /\./ && length $d1 == 1) {
foreach my $d2 (ONO::IO->ls("$opt/$d1")) {
if ($d2 =~ /[A-Za-z0-9]/ && length $d2 == 2) {
foreach my $d3 (ONO::IO->ls("$opt/$d1/$d2")) {
if ($d3 =~ /[A-Za-z0-9]/ && length $d3 == 3) {
foreach my $d4 (ONO::IO->ls("$opt/$d1/$d2/$d3")) {
if ($d4 =~ /[A-Za-z0-9]/ && length $d4 == 10) {
$sites++;
ONO::IO->cpr("$opt/$d1/$d2/$d3/$d4","$data{'bak_target'}/$ID/$opt");
if ($data{'bak_zip_web'}) {
ONO::IO->tar("$data{'bak_target'}/$ID/$opt/$d4","$data{'bak_target'}/$ID/$opt/$d4.gz");
if ($data{'bak_zipcleanup_web'}) {
ONO::IO->rmdir("$data{'bak_target'}/$ID/$opt/$d4");
}
}
# still missing: SQL table entries
# still missing: publisher texts linked via SQL
}
}
}
}
}
}
}
}
}
}
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': $sites websites saved",$switches);
}
if ($data{'bak_dir_community_portal'}) {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': creating backup: community/portal/ -> $data{'bak_target'}",$switches);
ONO::IO->mkdir("$data{'bak_target'}/$ID/school");
foreach my $opt ('data','school') {
ONO::IO->mkdir("$data{'bak_target'}/$ID/school/$opt");
my $counter = 0;
foreach my $dir (ONO::IO->ls("community/portal/$opt")) {
if ($dir =~ /[0-9]/) {
$counter++;
ONO::IO->cpr("community/portal/$opt/$dir","$data{'bak_target'}/$ID/school/$opt");
if ($data{'bak_zip_community_portal'}) {
ONO::IO->tar("$data{'bak_target'}/$ID/school/$opt/$dir","$data{'bak_target'}/$ID/school/$opt/$dir.gz");
if ($data{'bak_zipcleanup_community_portal'}) {
ONO::IO->rmdir("$data{'bak_target'}/$ID/school/$opt/$dir");
}
}
}
}
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': $counter $opt dirs saved",$switches);
}
}
foreach my $copy ('daily','weekly','monthly','yearly') {
if ($copy eq "daily" || ($copy eq "weekly" && $wday == 0) || ($copy eq "monthly" && $mday == 1) || ($copy eq "yearly" && $mday == 1 && $mon == 1)) {
if ($data{"bak_opt_keep_$copy"}) {
my $copydir = "$year$mon$mday";
if ($copy eq "weekly") {
}
if ($copy eq "monthly") {
$copydir = "$year$mon";
}
if ($copy eq "yearly") {
$copydir = $year;
}
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': preparing for a $copy copy ($copydir) ...",$switches);
my $BAKDIR = "$data{'bak_target'}/$copydir/";
$BAKDIR =~ s~//~/~g;
ONO::IO->mkdir($BAKDIR,777);
ONO::IO->cpr("$data{'bak_target'}/$ID/",$BAKDIR);
}
}
}
ONO::IO->mv("$data{'bak_target'}/latest","$data{'bak_target'}/remove_$ID" );
ONO::IO->mv("$data{'bak_target'}/$ID", "$data{'bak_target'}/latest" );
ONO::IO->rmdir("$data{'bak_target'}/remove_$ID");
ONO::IO->cp("$CRON_DIR/lastrun/job_$job.txt","$ori_target/BACKUP_TIMESTAMP.txt");
} else {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': ERROR: target directory '$data{'bak_target'}' could not be created - ABORT",$switches);
}
}
if ($data{'type'} eq "bak_local_os") {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': $TYPE{$data{'type'}} ($data{'type'})",$switches);
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': backup target: /backups/os/",$switches);
if (ONO::Core::HostIO->exists("/backups/os")) {
foreach my $dir (
'/bin',
'/boot',
'/etc',
'/lib',
'/lib64',
'/opt',
'/sbin',
'/usr',
) {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': running backup: /$dir -> /backups/os/$dir ...",$switches);
ONO::IO->exec3("rsync -ar $dir /backups/os/ --delete");
}
ONO::IO->exec3("cp $vpath/$CRON_DIR/lastrun/job_$job.txt /backups/os/BACKUP_TIMESTAMP.txt");
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': backup completed [OK]",$switches);
} else {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': target does not exist [ABORT]",$switches);
}
}
if ($data{'type'} eq "bak_remote") {
if (!$data{'bak_protocol'}) {
$data{'bak_protocol'} = "scp";
}
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': $TYPE{$data{'type'}} ($data{'type'})",$switches);
# backup /var/mail first
if ($data{'bak_mail'}) {
# $DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': starting local /var/mail backups...",$switches);
#
# ONO::IO->mkdir("var/mail");
# ONO::IO->mkdir("var/mail/$year$mon$mday");
#
# foreach my $mailbox (ONO::Core::HostIO->ls("/var/mail")) {
#
# if ($mailbox =~ /^ono-mail-/) {
#
# $DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': copying: $mailbox to ONO's /var/mail...",$switches);
#
# ONO::Core::HostIO->cpr("/var/mail/$mailbox","$vpath/var/mail/$year$mon$mday");
#
# }
#
# }
#
# # ONO::IO->chmod("var/mail/$year$mon$mday","-R 777");
#
# # remove older mail backups
#
# foreach my $old (ONO::IO->ls("var/mail")) {
# $old =~ s~[^0-9]~~g;
# if (length $old == 8 && $old ne "$year$mon$mday") {
# ONO::IO->rmdir("var/mail/$old");
# }
# }
}
# get the target
my $TARGET = $data{'bak_target'};
$TARGET =~ s~^(.*)\@~~;
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': backup target: $TARGET",$switches);
# dirs
my @dirs;
if ($data{'bak_site'}) {
foreach my $dir (ONO::IO->ls("/")) {
if ($dir =~ /[A-Za-z0-9]/ && $dir !~ /^(\.|\_)/ && $dir !~ /^cgi-bin/ && $dir !~ /^ono/ && $dir !~ /^syslog/ && $dir !~ /^(bak|backup)/) {
@dirs = (@dirs,$dir);
}
}
} else {
if ($data{'bak_dir_var_community'}) {
@dirs = (@dirs,"var/community");
}
if ($data{'bak_dir_images'}) {
@dirs = (@dirs,"images");
}
if ($data{'bak_dir_media'}) {
@dirs = (@dirs,"media");
}
if ($data{'bak_dir_web'}) {
@dirs = (@dirs,"web","schoolweb");
}
if ($data{'bak_dir_community_portal'}) {
@dirs = (@dirs,"community/portal");
}
}
if ($data{'bak_cgibin'}) {
@dirs = (@dirs,"cgi-bin");
}
if ($data{'bak_ono'}) {
@dirs = (@dirs,"ono");
}
my ($status,$user,$pass,$server,$path) = &bak_target("",$data{'bak_target'});
if ($status) {
foreach my $dir (@dirs) {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': backup via $data{'bak_protocol'}: $dir",$switches);
if (!$data{'bak_protocol'} || $data{'bak_protocol'} eq "scp") {
my $RES = ONO::IO->exec2(qq~sshpass -p "$pass" scp -r $vpath/$dir $user\@$server:$path~);
}
if ($data{'bak_protocol'} eq "rsync") {
ONO::IO->exec3(qq~sshpass -p "$pass" rsync -ar --perms --chmod=a+rwx $vpath/$dir $user\@$server:$path --delete~);
}
}
# sql
if ($data{'bak_sql'} || $data{'bak_site'}) {
if (!$data{'bak_sql_setup_mysqldump'}) {
$data{'bak_sql_setup_mysqldump'} = ONO::IO->which("mysqldump");
}
foreach my $opt ('bak_sql_setup_mysqldump','bak_sql_setup_username','bak_sql_setup_password','bak_sql_setup_database') {
$data{$opt} =~ s~[^A-Za-z0-9\/]~~g;
}
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': creating backup: ONO SQL DB ...",$switches);
ONO::IO->mkdir("var/tmp/sql",777);
ONO::IO->store(
"var/tmp/sql/mysqldump_$year$mon$mday.sql",
ONO::IO->exec3("$data{'bak_sql_setup_mysqldump'} --user=$data{'bak_sql_setup_username'} --password=$data{'bak_sql_setup_password'} --databases $data{'bak_sql_setup_database'}"),
);
if (!$data{'bak_protocol'} || $data{'bak_protocol'} eq "scp") {
my $SSH = qq~sshpass -p "$pass" scp -r $vpath/var/tmp/sql/mysqldump_$year$mon$mday.sql $user\@$server:$path/var/BACKUP_MYSQLDUMP.sql~;
my $RES = ONO::IO->exec2($SSH);
}
if ($data{'bak_protocol'} eq "rsync") {
my $RSY = qq~sshpass -p "$pass" rsync -ar $vpath/var/tmp/sql/mysqldump_$year$mon$mday.sql $user\@$server:$path/var/BACKUP_MYSQLDUMP.sql~;
my $RES = ONO::IO->exec2($RSY);
}
ONO::IO->rm("var/tmp/sql/mysqldump_$year$mon$mday.sql");
}
if (!$data{'bak_protocol'} || $data{'bak_protocol'} eq "scp") {
my $SSH = qq~sshpass -p "$pass" scp -r $vpath/$CRON_DIR/lastrun/job_$job.txt $user\@$server:$path/var/BACKUP_TIMESTAMP.txt~;
my $RES = ONO::IO->exec2($SSH);
}
if ($data{'bak_protocol'} eq "rsync") {
my $RSY = qq~sshpass -p "$pass" rsync -ar $vpath/$CRON_DIR/lastrun/job_$job.txt $user\@$server:$path/var/BACKUP_TIMESTAMP.txt~;
my $RES = ONO::IO->exec2($RSY);
}
}
}
if ($data{'type'} eq "bak_server") {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': $TYPE{$data{'type'}} ($data{'type'})",$switches);
$data{'bak_target'} =~ s~[^A-Za-z0-9\:\@\.\-\_\/\[\]]~~gi;
my ($status,$user,$pass,$server,$path) = &bak_target("",$data{'bak_target'});
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': backup target: $path",$switches);
my $PORT;
$data{'bak_port'} =~ s~[^0-9]~~gi;
if ($data{'bak_port'}) {
$PORT = "-e 'ssh -p$data{'bak_port'}'";
}
if (!$data{'bak_format'} || $data{'bak_format'} eq "files") {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': starting complete backup (files)",$switches);
foreach my $dir (
'/bin',
'/boot',
'/etc',
'/lib',
'/lib64',
'/opt',
'/sbin',
'/usr',
'/var',
) {
ONO::IO->exec3(qq~sshpass -p "$pass" rsync -ar $PORT $dir $user\@$server:$path --delete~);
}
ONO::IO->exec3(qq~sshpass -p "$pass" scp -r $vpath/$CRON_DIR/lastrun/job_$job.txt $user\@$server:${path}BACKUP_TIMESTAMP.txt~);
}
if ($data{'bak_format'} eq "tar") {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': starting complete backup (archives)",$switches);
ONO::IO->exec3("mkdir /tmp/ono/");
# everything except var
foreach my $dir (ONO::IO->sys("ls","/")) {
if ($dir !~ /^\./ && $dir !~ /^(backups|dev|disks|proc|sys|tmp|run|mnt|media|lost\+found|var)$/ && $dir !~ /^(Network|Volumes)$/) {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': tar: /$dir",$switches);
ONO::IO->exec3("tar cpzf /tmp/ono/$dir.tar.gz /$dir");
ONO::IO->exec3(qq~sshpass -p "$pass" rsync -aAXr $PORT /tmp/ono/$dir.tar.gz $user\@$server:$path/$dir.tar.gz~);
ONO::IO->exec3("rm /tmp/ono/$dir.tar.gz");
}
}
# everything in var, except www
foreach my $dir (ONO::IO->sys("ls","/var")) {
if ($dir ne "." && $dir ne ".." && $dir ne "www") {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': tar: /var/$dir",$switches);
ONO::IO->exec3("tar cpzf /tmp/ono/var_$dir.tar.gz /var/$dir");
ONO::IO->exec3(qq~sshpass -p "$pass" rsync -aAXr $PORT /tmp/ono/var_$dir.tar.gz $user\@$server:$path~);
ONO::IO->exec3("rm /tmp/ono/var_$dir.tar.gz");
}
}
# var/www
foreach my $dir (ONO::IO->sys("ls","/var/www")) {
if ($dir ne "." && $dir ne "..") {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': tar: /var/www/$dir",$switches);
ONO::IO->exec3("tar cpzf /tmp/ono/var_www_$dir.tar.gz /var/www/$dir");
ONO::IO->exec3(qq~sshpass -p "$pass" rsync -aAXr $PORT /tmp/ono/var_www_$dir.tar.gz $user\@$server:$path~);
ONO::IO->exec3("rm /tmp/ono/var_www_$dir.tar.gz");
}
}
}
}
if ($data{'type'} eq "bak_mail") {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': $TYPE{$data{'type'}} ($data{'type'})",$switches);
$data{'bak_target'} =~ s~[^A-Za-z0-9\:\@\.\-\_\/\[\]]~~gi;
my ($status,$user,$pass,$server,$path) = &bak_target("",$data{'bak_target'});
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': backup target: $server:$path",$switches);
if ($status) {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': starting mail backup (files)",$switches);
ONO::IO->exec3(qq~sshpass -p "$pass" rsync -ar /var/mail/* $user\@$server:$path --delete~);
foreach my $dir ('postfix','dovecot','courier','mail','passwd','spamassassin','default') {
ONO::IO->exec3(qq~sshpass -p "$pass" rsync -ar /etc/$dir $user\@$server:$path --delete~);
}
ONO::IO->exec3(qq~sshpass -p "$pass" scp -r $vpath/$CRON_DIR/lastrun/job_$job.txt $user\@$server:${path}BACKUP_TIMESTAMP.txt~);
} else {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': config error [ABORT]",$switches);
}
}
if ($data{'type'} eq "bak_restore_live") {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': $TYPE{$data{'type'}} ($data{'type'})",$switches);
foreach my $dir (ONO::Core::HostIO->ls("/var/www")) {
if ($dir !~ /^\./ && $dir =~ /[A-Za-z0-9]/ && ONO::Core::HostIO->exists("/var/www/$dir/html/var")) {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': - Checking web '$dir' has been found",$switches);
if (ONO::Core::HostIO->exists("/var/www/$dir/html/var/BACKUP_TIMESTAMP.txt") && !ONO::Core::HostIO->exists("/var/www/$dir/html/var/BACKUP_RESTORED.txt")) {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': - Web '$dir' is a backup that can be restored [PROCESSING...]",$switches);
# instantly mark dir web as being processed...
ONO::Core::HostIO->store("/var/www/$dir/html/var/BACKUP_RESTORED.txt",$timestamp);
# SQL processing...
if (ONO::Core::HostIO->exists("/var/www/$dir/html/var/BACKUP_MYSQLDUMP.sql")) {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': - Processing SQL DB for '$dir' ...",$switches);
my $mysql = ONO::IO->which("mysql");
if ($mysql) {
my %db_conf;
foreach my $line (ONO::Core::HostIO->list("/var/www/$dir/html/etc/sql/ono.conf")) {
$line =~ s~(\n|\r|\t)~~g;
$line =~ m~^(.*?) (.*?)$~;
$db_conf{$1} = $2;
}
if ($db_conf{'username'} && $db_conf{'password'} && $db_conf{'database'}) {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': - SQL config is looking good [EXECUTE]",$switches);
ONO::IO->exec3("$mysql --user=$db_conf{'username'} --password=$db_conf{'password'} < /var/www/$dir/html/var/BACKUP_MYSQLDUMP.sql");
} else {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': - ERROR: /etc/ono.conf is missing, or data is missing [ABORT]",$switches);
}
} else {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': ERROR: mysql command not found [ABORT]",$switches);
}
}
# make sure the mark can be removed, so that rsync may delete it when completing the next backing
ONO::Core::HostIO->chmod("/var/www/$dir/html/var/BACKUP_RESTORED.txt",777);
} else {
$DATA .= ONO::Cron::CronSync::ToolBox->print("Job '$data{'title'}': - Web '$dir' is not a backup, or it has already been restored [ABORT]",$switches);
}
}
}
}
return ($DATA,$MAIL);
}
sub bak_target {
# username:password@server:/path/...
my $string = $_[1];
$string =~ s~[^A-Za-z0-9\:\@\.\-\_\/\[\]]~~gi;
my ($user,$pass,$server,$path);
if ($string =~ m~^(.*?):(.*?)\@(.*):(.*?)$~) {
$user = $1;
$pass = $2;
$server = $3;
$path = $4;
$user =~ s~[^A-Za-z0-9]~~gi;
$pass =~ s~[^A-Za-z0-9]~~gi;
$server =~ s~[^A-Za-z0-9\-\.\:]~~gi;
$path =~ s~[^A-Za-z0-9\-\_\.\:\/]~~gi;
if ($server =~ /:/ && $server !~ /\[/) {
$server = "\\\[$server\\\]";
}
if ($user && $pass && $server && $path) {
return (1,$user,$pass,$server,$path);
} else {
return (0);
}
} else {
return (0);
}
}
###############################################################################
# end of script
###############################################################################
1;
__END__