Basically it's a lightweight backup tool. First it archive files to backup. Then it compares to last backup archive. If it's different, the archive is ftped to a remote server. A brief log and a detailed log are generated meanwhile.
It works pretty well and stable. The source code is shown as following.
#!/usr/bin/perl
use strict;
use warnings;
my ($logdir, $log, $detailedlogdir, $detailedlog, $lastsuccessfilename);
my ($targetdir, $target, $targetprefix, $targetnameonly);
my $cbserver;
my @source;
my ($timeforfilename, $timestring);
sub get_timestring {
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdat);
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdat) = localtime;
$year+=1900;
$mon = sprintf("%02d", $mon+1);
$mday = sprintf("%02d", $mday);
$timeforfilename = $year.$mon.$mday;
return $year."/".$mon."/".$mday."-".$hour.":".$min.":".$sec;
}
sub print_usage {
print "usage: squarrel daily|weekly|monthly\n";
}
sub get_argv {
if ($#ARGV!=0) {
&print_usage;
exit;
}
if ($ARGV[0] eq "daily") {
@source="..."; # file or directories to backup on daily base.
} elsif ($ARGV[0] eq "weekly") {
@source="..."; # file or directories to backup on weekly base.
} elsif ($ARGV[0] eq "monthly") {
@source="..."; # file or directories to backup on monthly base.
} else {
&print_usage;
exit;
}
$targetprefix=$ARGV[0];
}
sub init {
$logdir = "/var/www/html"; # log is written in httpd directory so I can check it via browser
$log = "$logdir"."/emc.log";
$detailedlogdir = "/home/emc";
$detailedlog = "$detailedlogdir"."/emcdetailed.log";
if (-e $log) {
open LOGFILE, ">> $log" or die $!;
} else {
open LOGFILE, "> $log" or die $!;
}
if (-e $detailedlog) {
open DETAILEDLOG, ">> $detailedlog" or die $!;
} else {
open DETAILEDLOG, "> $detailedlog" or die $!;
}
print LOGFILE "----------------------------------------------------\n";
print DETAILEDLOG "----------------------------------------------------\n";
$timestring = &get_timestring;
print LOGFILE "$timestring backup($targetprefix) starts\n";
print DETAILEDLOG "$timestring backup($targetprefix) starts\n";
$targetdir = "/home/bt/crossbackup";
# $targetnameonly = "backup".$timeforfilename.".tar.bz2";
$targetnameonly=$targetprefix.$timeforfilename.".tar.bz2";
$target = "$targetdir/".$targetnameonly;
$lastsuccessfilename = "$detailedlogdir"."/lastsuccess_".$targetprefix;
$cbserver = "..."; # remote server address
}
sub archive {
my ($archivecmd, $result);
$archivecmd = "tar cvfj $target @source";
$timestring = &get_timestring;
print LOGFILE "$timestring $archivecmd\n";
print DETAILEDLOG "$timestring $archivecmd\n";
system("$archivecmd >>$detailedlog 2>> $detailedlog");
$result = $?;
$timestring = &get_timestring;
if ($result == 0) {
print LOGFILE "$timestring archiving finish successfully\n";
print DETAILEDLOG "$timestring archiving finish successfully\n";
} else {
print LOGFILE "$timestring archiving fail $result\n";
print DETAILEDLOG "$timestring archiving fail $result\n";
}
return $result;
}
sub check_identical {
my $lastsuccesstarget;
my $different;
if (-e $lastsuccessfilename) {
open LASTSUCCESS, "$lastsuccessfilename" or die "Write $lastsuccessfilename";
$lastsuccesstarget=
chop($lastsuccesstarget);
close LASTSUCCESS;
$timestring = &get_timestring;
print LOGFILE "$timestring compare $target $lastsuccesstarget\n";
print DETAILEDLOG "$timestring compare $target $lastsuccesstarget\n";
system("diff -q $lastsuccesstarget $target >> $detailedlog 2>> $detailedlog");
if ($?) {
$timestring = &get_timestring;
print LOGFILE "$timestring $target is different to $lastsuccesstarget\n";
print DETAILEDLOG "$timestring $target is different $lastsuccesstarget\n";
return 1;
} else {
$timestring = &get_timestring;
print LOGFILE "$timestring $target is identical to $lastsuccesstarget\n";
print DETAILEDLOG "$timestring $target is identical to $lastsuccesstarget\n";
system("rm -f $lastsuccesstarget\n");
$timestring = &get_timestring;
print LOGFILE "$timestring remove $lastsuccesstarget\n";
print DETAILEDLOG "$timestring remove $lastsuccesstarget\n";
return 0;
}
} else {
return 1;
}
}
sub ftp_upload {
my $ftpcmd;
my $result;
$ftpcmd = '"user username password\nbinary\nput '.$target.' '.$targetnameonly.'\nquit\n"';
$timestring = &get_timestring;
print LOGFILE "$timestring ftp -v -d $cbserver <<$ftpcmd\n"; print DETAILEDLOG "$timestring ftp -v -d $cbserver <<$ftpcmd\n"; system("echo -e $ftpcmd | ftp -v -d $cbserver>> $log 2>> $log");
$result=$?;
$timestring = &get_timestring;
if ($result == 0) {
print LOGFILE "$timestring uploading finish successfully\n";
print DETAILEDLOG "$timestring uploading finish successfully\n";
} else {
print LOGFILE "$timestring uploading fail $result\n";
print DETAILEDLOG "$timestring uploading fail $result\n";
}
return $result;
}
sub done {
my ($result, $stage) = @_;
$timestring = &get_timestring;
if ($result == 0) {
open LASTSUCCESS, ">$lastsuccessfilename" or die "Write $lastsuccessfilename";
print LOGFILE "$timestring backup($targetnameonly) succeed\n";
print DETAILEDLOG "$timestring backup($targetnameonly) succeed\n";
print LASTSUCCESS "$target\n";
close LASTSUCCESS;
} else {
print LOGFILE "$timestring backup($targetnameonly) failed in stage $stage\n";
print DETAILEDLOG "$timestring backup($targetnameonly) failed in stage $stage\n";
}
close LOGFILE;
close DETAILEDLOG;
}
my $result;
&get_argv;
&init;
$result = &archive;
if ($result) {
&done(1, "archive");
exit (1);
}
$result = &check_identical;
if ($result==0) {
&done(0, "");
exit(0);
}
$result = &ftp_upload;
if ($result) {
&done(2, "upload");
exit (2);
}
&done(0, "");
exit(0);