#!/usr/bin/perl
# cpanel5 - scripts        Copyright(c) 1997-2003 cPanel, Inc.
#                                 All rights Reserved.
# nick@darkorb.net      http://cpanel.net
# This code is subject to the cpanel license. Unauthorized copying is prohibited
system("renice +19 $$"); #Try to reduce the load we put the machine under

BEGIN {
        push(@INC,"/scripts");
}

$ENV{'pkgacct-cpbackup'} = 1;

use iContact;
use POSIX;
POSIX::nice(19);

chomp($host = `hostname`);
#BACKUPDIR /backup
#BACKUPINT daily
#BACKUPENABLE yes
#BACKUPCHECK yes
#BACKUPMOUNT no
#BACKUPINC no
#BACKUPFILES yes
#BACKUPACCTS
#DIEIFNOTMOUNTED no
#BACKUPDAYS 0,1,2,3,4,5,6
#BACKUPLOGS no
#MYSQLBACKUP accounts
#BACKUPTYPE normal,ftp

open(CF,"/var/cpanel/cpanel.config");
while(<CF>) {
   next if (/^#/);
   s/\n//g;
   ($var,$value) = split(/=/, $_);
   $CPCONF{$var} = $value;
}
close(CF);

open(CPUINFO,"/proc/cpuinfo");
while(<CPUINFO>) {
   if (/^processor\s*:\s*(\d+)/) {
      $cpunum = $1;
   }
}
close(CPUINFO);
$cpunum++;
$realcpunum = $cpunum;

if ($CPCONF{'extracpus'} eq "") { $CPCONF{'extracpus'} = 0; }
$cpunum = ($cpunum + $CPCONF{'extracpus'});

#$CPCONF{'root'}/bin/cpuwatch $cpunum.0  
 


open(CPBACK,"/etc/cpbackup.conf");
while(<CPBACK>) {
	s/\n//g;
	my($name,$value) = split(/ /, $_);
	$CONF{$name} = $value;
}
close(CPBACK);



@FILES=("/etc/named.conf","/etc/proftpd.conf","/etc/localdomains",
"/etc/httpd/conf/httpd.conf","/usr/local/apache/conf/httpd.conf","/etc/group","/etc/shadow","/etc/passwd",
"/etc/domainalias","/etc/fstab","/root/.my.cnf","/etc/ips",
"/etc/reservedips","/etc/quota.conf","/etc/wwwacct.conf",
"/etc/rndc.conf","/etc/secondarymx","/etc/my.cnf","/usr/local/cpanel/3rdparty/interchange/interchange.cfg");

@DIRS=("/etc/valiases","/etc/proftpd","/var/named","/etc/vfilters",
"/var/cpanel","/var/spool/cron","/usr/local/frontpage","/var/log/bandwidth",
"/usr/share/ssl","/etc/ssl","/var/ssl","/usr/local/cpanel/3rdparty/mailman");


#BACKUPLOGS no
#MYSQLBACKUP accounts
if ($CONF{'MYSQLBACKUP'} eq "both" || $CONF{'MYSQLBACKUP'} eq "dir") {

my $mysqladmin = find_mysqladmin();

        my($datadir) = '/var/lib/mysql';
        open(MADMIN,"$mysqladmin variables|");
        while(<MADMIN>) {
                s/\|//g;
                if(/[\s\t]+datadir[\s\t]+(\S+)/) {
                        $datadir = $1;
                }
        }
        close(MADMIN);
        while(-l $datadir) {
                $datadir = readlink($datadir);
        }

	push(@DIRS,$datadir);

}


if ($CONF{'BACKUPENABLE'} ne "yes") {
	die "Backup Not Enabled\n";
}
if ($CONF{'BACKUPENABLE'} ne "restoreonly" && $CONF{'BACKUPENABLE'} ne "yes") {
	die "Backup Not Enabled (restore only)\n";
}

if ($CONF{'BACKUPCHECK'} ne "yes") {
	die "Backup must be re-enabled in your WHM\n";
}

if ($CONF{'BACKUPDAYS'} ne "") {
	my @BACKUPDAYS=split(/\,/, $CONF{'BACKUPDAYS'});
	my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
		localtime(time);
	$backupthisday = 0;

	foreach (@BACKUPDAYS) {
		if($wday eq $_) {
			$backupthisday = 1;
		}
	}
	
	if (!$backupthisday) {
		die "Backup is not done today as per whm backup settings";
	}
}

my $basedir = $CONF{'BACKUPDIR'};
if ($CONF{'BACKUPTYPE'} eq "ftp") {
	mkdir("/home/cpbackuptmp",0700);
	$basedir = "/home/cpbackuptmp";
	if ($CONF{'BACKUPTYPE'} eq "ftp") {
		$CONF{'BACKUPINC'} = "no";
		$CONF{'BACKUPFILES'} = "no";
		$CONF{'BACKUPACCTS'} = "yes";
		$CONF{'BACKUPMOUNT'} = "no";
		$CONF{'DIEIFNOTMOUNTED'} = "no";
	}
}

my $basemount = $basedir;


if ($CONF{'BACKUPMOUNT'} eq "yes") {
	system("mount","$basemount");
	system("mount","-o","remount,rw","$basemount");
}

if ($CONF{'DIEIFNOTMOUNTED'} eq "yes") {
	my $ismounted = 0;
	my @MOUNT=split(/\n/,`mount`);
	foreach(@MOUNT) {
		my $point;
		(undef,undef,$point,undef) = split(/ /, $_);
		if ($point eq "$basemount") {
			$ismounted = 1;
		}
	}
	if (!$ismounted) {
		icontact('backup',1,"Backup was not completed on $host",
		"The backup was not able to be completed because $basemount could not be mounted");
		die "$basemount is not mounted";
	}
}

if ($basedir eq "") {
	die "Base dir not set";
}
$basedir .= "/cpbackup";
mkdir($basedir,0700);

if ($CONF{'BACKUPINT'} eq "monthly") {
	if (! -e "${basedir}/monthly") {
		mkdir("${basedir}/monthly",0700);
		backupaccts("${basedir}/monthly");
	} else {
		if (isolderthen(29,"${basedir}/monthly")) {
			backupaccts("${basedir}/monthly");
		} else {
			print "Monthly Backup is up to date\n";
		} 
	}
}


if ($CONF{'BACKUPINT'} eq "weekly") {
	if (! -e "${basedir}/weekly") {
		mkdir("${basedir}/weekly",0700);
		backupaccts("${basedir}/weekly");
	} else {
		if (isolderthen(6,"${basedir}/weekly")) {
			backupaccts("${basedir}/weekly");
		} else {
			print "Weekly Backup is up to date\n";
		}
	}
	if (! -e "${basedir}/monthly" || isolderthen(29,"${basedir}/monthly")) {
		if($CONF{'BACKUPTYPE'} eq "ftp") { 
			mkdir("${basedir}/monthly",0700);
			backupaccts("${basedir}/monthly");
		} else {
			cpusystem("rsync","-a","--delete","${basedir}/weekly/","${basedir}/monthly");
		}
	}
}

if ($CONF{'BACKUPINT'} eq "daily") {
        backupaccts("${basedir}/daily");
}


if ($CONF{'BACKUPMOUNT'} eq "yes") {
	system("mount","-o","remount,ro","$basemount");
	system("umount","$basemount");
}



sub isolderthen {
	my($days,$file) = @_;
	my($mtime);
	
                   (undef,undef,undef,undef,undef,undef,undef,undef,
                      $undef,$mtime,undef,undef,undef)
                          = stat($file);
	if ((time() - $mtime) > (60*60*24*${days})) {
		return(1);
	} else {
		return(0);
	}

}

sub backupaccts {
	my($target) = @_;

	system("touch","${target}");
	#if another cpbackup starts just go bye bye
	
	if (!($CONF{'BACKUPFILES'} eq "no")) {
		if (! -e "$target/files") {
			mkdir("$target/files",0700);
		}
		my($file);
		foreach $file (@FILES) {
			next if (! -e $file);
			my $rawfile = $file;
			$rawfile =~ s/\//_/g;		
			if ($CONF{'BACKUPINC'} eq "yes") {
				cpusystem("rsync","-a","--delete","$file","$target/files/$rawfile");
			} else {
        		        cpusystem("cp","-f","$file","$target/files/$rawfile");
        		        chmod(0600,"$target/files/$rawfile");
        		        cpusystem("gzip","-f","$target/files/$rawfile");
		                chmod(0600,"$target/files/$rawfile.gz");
			}
		}
		my($file);
		if (! -e "$target/dirs") {
			mkdir("$target/dirs",0700);
		}
		foreach $dir (@DIRS) {
			next if (! -e $dir);
			my $rawdir = $dir;
			$rawdir =~ s/\//_/g;		
			if ($CONF{'BACKUPINC'} eq "yes") {
				cpusystem("rsync","-a","--delete","$dir/","$target/dirs/$rawdir");
			} else {
				cpusystem("tar","cfzp","$target/dirs/$rawdir.tar.gz","$dir");
				chmod(0600,"$target/dirs/$rawdir.tar.gz");
			}
		}
	}


#BACKUPLOGS no
#MYSQLBACKUP accounts
	$ENV{'pkgacct-logs'} = 'no';
	if ($CONF{'BACKUPLOGS'} eq "yes") { $ENV{'pkgacct-logs'} = 'yes'; }
	$ENV{'pkgacct-mysql'} = 'yes';
	if ($CONF{'MYSQLBACKUP'} eq "dir") { $ENV{'pkgacct-mysql'} = 'no'; }

	if (!($CONF{'BACKUPACCTS'} eq "no")) {
		while($user = getpwent()) {
			if (-f "/var/cpanel/users/${user}") {
				if (!($CONF{'BACKUPINC'} eq "yes")) {  if (-d "$target/${user}") { cpusystem("rm","-rf","$target/${user}"); } }
				if ($CONF{'BACKUPINC'} eq "yes") { $ENV{'INCBACKUP'} = 1; }
                                cpusystem("/scripts/pkgacct2",$user,$target,"backup");
                                if ($CONF{'BACKUPINC'} eq "yes") { delete $ENV{'INCBACKUP'}; }
				if($CONF{'BACKUPTYPE'} eq "ftp") { 
					ftpsend("$target","${target}/${user}.tar.gz","${user}.tar.gz");
					unlink("${target}/${user}.tar.gz");
				}
			}
		}	
	}

}

sub ftpsend  {
	my($targetdir,$targetfile,$remotefile) = @_;
	my $ftpuser = $CONF{'BACKUPFTPUSER'};
	my $ftppass = $CONF{'BACKUPFTPPASS'};
	my $ftphost = $CONF{'BACKUPFTPHOST'};

	require Net::FTP;

	my @FD = split(/\//, $targetdir);
	my $backtype = $FD[$#FD];

 	my $ftp = Net::FTP->new("$ftphost", Debug => 1);
        $ftp->login("$ftpuser",$ftppass);
	$ftp->binary();
        $ftp->mkdir("cpbackup");
        $ftp->mkdir("cpbackup/${backtype}");
        $ftp->cwd("cpbackup/${backtype}");
        $ftp->put($targetfile,$remotefile);
        $ftp->quit;
	
}

sub cpusystem {
        system(@_);
        return();
}

 
sub find_mysqladmin {
   my(@LOC,$loc);
   @LOC = ("/usr/bin/mysqladmin",
         "/usr/local/bin/mysqladmin");
   foreach $loc (@LOC) {
      if (-e $loc) { return $loc; }
   }
}

