0,0 → 1,970 |
#!/usr/bin/perl |
# fsbackup - file system backup and synchronization utility. |
# |
# http://www.opennet.ru/dev/fsbackup/ |
# Copyright (c) 2001-2002 by Maxim Chirkov. <mc@tyumen.ru> |
# |
# ëÌÀÞÉ: |
# -n - ÓÏÚÄÁÅÍ ÎÏ×ÙÊ ÁÒÈÉ× ÎÅÚÁ×ÉÓÉÍÏ ÏÔ ÓÏÓÔÏÑÎÉÑ ÈÜÛÁ. |
# -f - full_backup - ÐÏÌÎÙÊ ÂÜËÁÐ × ÁÒÈÉ×, ÂÅÚ ÈÜÛÁ. |
# -h - hash - ÔÏÌØËÏ ÇÅÎÅÒÁÃÉÑ ÈÜÛÁ, ÂÅÚ ÐÏÍÅÝÅÎÉÑ ÆÁÊÌÏ× × ÁÒÈÉ×. |
# -c - clean - ÏÞÉÓËÁ ÈÒÁÎÉÌÉÝÁ Ó ÉÎËÒÅÍÅÎÔÁÌØÎÙÍ ÂÜËÁÐÏÍ É ÓÏÚÄÁÎÉÅ ÎÏ×ÏÇÏ ÂÜËÁÐÁ. |
|
############################################# |
use constant DB_DEF_CACHE_SIZE => 4096000; # òÁÚÍÅÒ ËÜÛÁ ÄÌÑ ÒÁÚÍÅÖÅÎÉÑ ÈÜÛÁ × ÐÁÍÑÔÉ |
|
use POSIX; |
use File::Find; |
use Digest::MD5 qw(md5_base64); |
use Net::FTP; |
use DB_File; |
|
use constant VERB_SILENT => 0; # Silent mode, suspend all output. |
use constant VERB_ERROR => 1; # Output all errors and warnings. |
use constant VERB_ALL => 2; # Output all the available data. |
|
my $list_lines_cnt = 0; |
my $del_lines_cnt = 0; |
my $cur_time = time(); |
my %active_hash_last; |
my %active_hash_new; |
my $cfg_new_flag = 0; |
my $cfg_clean_flag = 0; |
my $config = 0; |
my $cur_backup_size = 1536; # òÁÚÍÅÒ ÂÌÏËÁ tar |
my $backup_file_base; |
my $prog_pgp_filter; |
my $prog_gzip_filter; |
my $arc_ext; |
my $ftp; |
my $cur_increment_level; |
my $cur_dir; |
my $cur_path; |
my $cur_file; |
my $cur_pathitem; |
my $file_fullpath; |
my $file_fullpath_md5; |
my $key; |
my $dbobj_new; |
my $dbobj_last; |
my $db_hashinfo; |
my $db_hashinfo2; |
my $file; |
my @volume_position=(0); |
my @fs_path=(); # /dir[/file] - ÐÕÔØ Ë ÆÁÊÌÕ/ÄÉÒÅËÔÏÒÉÉ ÄÌÑ ÂÜËÁÐÁ. |
my @fs_notpath=(); # ! - ÏÔÒÉÃÁÎÉÅ ÐÕÔÉ, ÎÅ ÐÏÍÅÝÁÔØ × ÂÜËÁÐ. ÷ÓÅÇÄÁ ÄÏÌÖÅÎ ÂÙÔØ ÐÅÒ×ÙÍ ÓÉÍ×ÏÌÏÍ. |
my @fs_mask=(); # =~ - ÍÁÓËÁ ÄÌÑ ÆÁÊÌÁ ÉÌÉ ÄÉÒÅËÔÏÒÉÉ, Á ÎÅ ÁÂÓÏÌÀÔÎÙÊ ÐÕÔØ. ðÅÒ×ÙÊ ÉÌÉ ×ÔÏÒÏÊ ÓÉÍ×ÏÌ. |
my @fs_filemask=(); # f~ - ÍÁÓËÁ ÄÌÑ ÆÁÊÌÁ. ðÅÒ×ÙÊ ÉÌÉ ×ÔÏÒÏÊ ÓÉÍ×ÏÌ. |
my @fs_dirmask=(); # d~ - ÍÁÓËÁ ÄÌÑ ÄÉÒÅËÔÏÒÉÉ. ðÅÒ×ÙÊ ÉÌÉ ×ÔÏÒÏÊ ÓÉÍ×ÏÌ. |
my @fs_notmask=(); # =! - "îå" ÍÁÓËÁ ÄÌÑ ÆÁÊÌÁ ÉÌÉ ÄÉÒÅËÔÏÒÉÉ, Á ÎÅ ÁÂÓÏÌÀÔÎÙÊ ÐÕÔØ. ðÅÒ×ÙÊ ÉÌÉ ×ÔÏÒÏÊ ÓÉÍ×ÏÌ. |
my @fs_notfilemask=(); # f! - "îå" ÍÁÓËÁ ÄÌÑ ÆÁÊÌÁ. ðÅÒ×ÙÊ ÉÌÉ ×ÔÏÒÏÊ ÓÉÍ×ÏÌ. |
my @fs_notdirmask=(); # d! - "îå" ÍÁÓËÁ ÄÌÑ ÄÉÒÅËÔÏÒÉÉ. ðÅÒ×ÙÊ ÉÌÉ ×ÔÏÒÏÊ ÓÉÍ×ÏÌ. |
|
# ------------- ïÂÒÁÂÏÔËÁ ÐÁÒÁÍÅÔÒÏ× ËÏÍÁÎÄÎÏÊ ÓÔÒÏËÉ |
|
if ($ARGV[0] eq "-n" || $ARGV[0] eq "-h" || $ARGV[0] eq "-f" || $ARGV[0] eq "-c"){ |
$cfg_new_flag=1; |
$config = $ARGV[1]; |
} else { |
$cfg_new_flag=0; |
$config = $ARGV[0]; |
} |
|
if ( ! -f $config){ |
die "Usage: fsbackup.pl [-n|-f|-h|-c] config_name\n"; |
} |
|
|
require "$config"; |
|
if ( ! -d $cfg_cache_dir){ |
die "\$cfg_cache_dir ($cfg_cache_dir) not found. Set \$cfg_cache_dir varisble in fsbackup.pl\n"; |
} |
|
$cfg_time_limit *= 60 * 60 * 24; # äÎÉ × ÓÅËÕÎÄÙ. |
$cfg_size_limit *= 1024; # ëÉÌÏÂÁÊÔÙ × ÂÁÊÔÙ. |
$cfg_maximum_archive_size *= 1024; # ëÉÌÏÂÁÊÔÙ × ÂÁÊÔÙ. |
|
if (-d $cfg_root_path){ |
chdir($cfg_root_path); |
} else { |
die "Invalid \$cfg_root_path path ($cfg_root_path)\n"; |
} |
|
if ($ARGV[0] eq "-h"){ |
$cfg_backup_style = "hash"; |
} |
if ($ARGV[0] eq "-f" ){ |
$cfg_backup_style = "full_backup"; |
} |
|
if ($ARGV[0] eq "-c" ){ |
$cfg_clean_flag=1; |
} else { |
$cfg_clean_flag=0; |
} |
|
#------------------- ðÒÏ×ÅÒÑÅÍ ÐÅÒÅÍÅÎÎÙÅ × ÆÁÊÌÅ ËÏÎÆÉÇÕÒÁÃÉÉ. |
if ($cfg_backup_name !~ /^[\w\d\_]+$/){ |
die "Found illegal characters in $cfg_backup_name ($cfg_backup_name)."; |
} |
|
if (! grep {$_ eq $cfg_checksum} ("md5", "timesize")){ |
die "Unknown checksum method:\$cfg_checksum=$cfg_checksum (allowed md5 or timesize)\n"; |
} |
|
if (! grep {$_ eq $cfg_backup_style} ("backup", "full_backup", "sync", "hash")){ |
die "Unknown backup_style:\$cfg_backup_style=$cfg_backup_style\n"; |
} |
|
if ($cfg_remote_ftp_mode != 1){ |
$cfg_remote_ftp_mode = 0; |
} |
|
if ($cfg_backup_style eq "full_backup" || $cfg_backup_style eq "hash"){ |
$cfg_new_flag=1; |
$cfg_clean_flag=1; |
} |
|
if (! grep {$_ eq $cfg_type} ("local", "remote_ssh", "remote_ftp")){ |
die "Unknown backup target:\$cfg_type=$cfg_type\n"; |
} |
|
if (($cfg_type eq "local") && (! -d $cfg_local_path)){ |
die "Can't find \$cfg_local_path ($cfg_local_path)"; |
} |
|
if ($cfg_backup_style eq "backup"){ |
my ($sec,$min,$hour,$mday,$mon,$year) = localtime($cur_time); |
$backup_file_base = sprintf ("%s-%4.4d.%2.2d.%2.2d.%2.2d.%2.2d.%2.2d", |
$cfg_backup_name,$year+1900,$mon+1,$mday,$hour,$min,$sec); |
}else{ |
$backup_file_base="$cfg_backup_name"; |
} |
|
print "Creating $cfg_type $cfg_backup_style: $cfg_backup_name\n" if ($cfg_verbose == &VERB_ALL); |
|
if ($cfg_pgp_userid ne "" && $prog_pgp ne ""){ |
print "PGP: enabled\n" if ($cfg_verbose == &VERB_ALL); |
|
# PGP 2.6 (pgp) |
# $prog_pgp_filter="| $prog_pgp -ef $cfg_pgp_userid -z'$cfg_pgp_userid' "; |
# PGP 5.0 (pgpe) |
# $prog_pgp_filter="| $prog_pgp -f $cfg_pgp_userid"; |
# GnuPG (pgp) |
$prog_pgp_filter="| $prog_pgp -v --batch -e -r $cfg_pgp_userid"; |
} else { |
$prog_pgp_filter=""; |
} |
|
if ($prog_gzip ne ""){ |
$prog_gzip_filter="| $prog_gzip"; |
$arc_ext=".gz"; |
} else { |
$prog_gzip_filter=""; |
$arc_ext=""; |
|
} |
|
if (! -d "$cfg_cache_dir/$cfg_backup_name"){ |
mkdir("$cfg_cache_dir/$cfg_backup_name", 0700); |
} |
|
# ---------- áËÔÉ×ÉÒÕÅÍ FTP ÓÏÅÄÉÎÅÎÉÅ |
|
ftp_connect(); |
|
#----------- ÷ÙÞÉÓÌÑÅÍ ÕÒÏ×ÅÎØ ÉÎËÒÅÍÅÎÔÁÌØÎÏÓÔÉ. |
if ($cfg_increment_level != 0 && $cfg_backup_style eq "backup"){ |
$cur_increment_level=0; |
|
if ( $cfg_type eq "local"){ |
opendir( DIR, "$cfg_local_path"); |
while ($cur_dir = readdir DIR){ |
if ($cur_dir =~ /\-0\.tar${arc_ext}$/){ |
$cur_increment_level++; |
} |
} |
closedir (DIR); |
|
} elsif ( $cfg_type eq "remote_ssh"){ |
|
open (DIR, "$prog_ssh -l $cfg_remote_login $cfg_remote_host 'ls $cfg_remote_path/' |") || print "SSH connection failed: $?\n"; |
while (<DIR>){ |
$cur_dir = $_; |
if ($cur_dir =~ /\-0\.tar${arc_ext}$/){ |
$cur_increment_level++; |
} |
} |
close (DIR); |
} elsif ( $cfg_type eq "remote_ftp"){ |
foreach $cur_dir ($ftp->ls()){ |
if ($cur_dir =~ /\-0\.tar${arc_ext}$/){ |
$cur_increment_level++; |
} |
} |
} |
if ($cur_increment_level >= $cfg_increment_level){ |
$cfg_new_flag=1; |
$cfg_clean_flag=1; |
} |
print "Current increment number: $cur_increment_level\n" if ($cfg_verbose == &VERB_ALL); |
} |
################################################ |
#----------- óÞÉÔÙ×ÁÅÍ ÈÜÛ × ÐÁÍÑÔØ. |
|
if ( (-f "$cfg_cache_dir/$cfg_backup_name/.hash" || $cfg_type ne "local" ) && $cfg_new_flag == 0){ |
# óÞÉÔÙ×ÁÅÍ ÔÅËÕÝÉÊ ÈÅÛ × ÐÁÍÑÔØ. |
|
if ( $cfg_type eq "local"){ |
rename ("$cfg_cache_dir/$cfg_backup_name/.hash", "$cfg_cache_dir/$cfg_backup_name/.hash.last"); |
}elsif ( $cfg_type eq "remote_ssh"){ |
system ("$prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat $cfg_remote_path/.hash' > $cfg_cache_dir/$cfg_backup_name/.hash.last") == 0 || print "SSH connection failed: $?\n"; |
} elsif ( $cfg_type eq "remote_ftp"){ |
unlink ("$cfg_cache_dir/$cfg_backup_name/.hash.last"); |
$ftp->get(".hash", "$cfg_cache_dir/$cfg_backup_name/.hash.last")|| print "FTP error, Can't GET .hash\n"; |
} |
$db_hashinfo = new DB_File::HASHINFO ; |
$db_hashinfo->{'cachesize'} = DB_DEF_CACHE_SIZE; |
if (! ($dbobj_last = tie(%active_hash_last, "DB_File", "$cfg_cache_dir/$cfg_backup_name/.hash.last", O_RDWR|O_CREAT, 0644, $db_hashinfo ))){ |
print "WARNING: Error in hash, creating full backup.\n" if ($cfg_verbose >= &VERB_ERROR); |
unlink "$cfg_cache_dir/$cfg_backup_name/.hash.last"; |
$dbobj_last = tie(%active_hash_last, "DB_File", "$cfg_cache_dir/$cfg_backup_name/.hash.last", O_RDWR|O_CREAT, 0644, $db_hashinfo )||print "Can't create or open DB File!"; |
} |
# $dbobj->del($key); |
# $dbobj->sync(); |
|
} |
|
# úÁËÒÙ×ÁÅÍ ftp ÓÏÅÄÉÎÅÎÉÅ. óÌÅÄÕÀÝÉÊ ÂÌÏË ÍÏÖÅÔ ×ÙÐÏÌÎÑÔØÓÑ ÇÏÒÁÚÄÏ ÄÏÌØÛÅ |
# ÞÅÍ ÔÁÊÍÁÕÔ ftp. |
if ( $cfg_type eq "remote_ftp"){ |
$ftp->quit; |
} |
#óÏÚÄÁÅÍ ÎÏ×ÙÊ ÈÅÛ. |
unlink("$cfg_cache_dir/$cfg_backup_name/.hash"); |
$db_hashinfo2 = new DB_File::HASHINFO ; |
$db_hashinfo2->{'cachesize'} = 100000; |
$dbobj_new = tie(%active_hash_new, "DB_File", "$cfg_cache_dir/$cfg_backup_name/.hash", O_RDWR|O_CREAT, 0644, $db_hashinfo2) || print "Can't create or open DB File!\n"; |
|
# óÏÚÄÁÅÍ ÓÐÉÓÏË ÆÁÊÌÏ× ÄÌÑ ÐÏÍÅÝÅÎÉÑ × ÁÒÈÉ×. |
open (LIST, ">$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list")|| print "Can't create list file ($cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list).\n"; |
flock (LIST, 2); |
|
# óÐÉÓÏË Ó ÕËÁÚÁÎÉÅÍ ÒÁÚÍÅÒÏ× ÆÁÊÌÏ×. |
open (LIST_SIZE, ">$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.lsize")|| print "Can't create list file ($cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.lsize).\n"; |
flock (LIST_SIZE, 2); |
|
# óÏÚÄÁÅÍ ÓÐÉÓÏË ÄÉÒÅËÔÏÒÉÊ × ÁÒÈÉ×Å. |
open (DIRS, ">$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.dir")|| print "Can't create list file ($cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.dir).\n"; |
flock (DIRS, 2); |
|
# óÞÉÔÙ×ÁÅÍ ÓÐÉÓÏË ÐÏÄÌÅÖÁÝÉÈ ÂÜËÁÐÕ ÄÉÒÅËÔÏÒÉÊ × ÐÁÍÑÔØ. |
|
while(<DATA>){ |
chomp; |
$cur_path = $_; |
if ($cur_path =~ /^\!(.*)$/){ # ! |
push @fs_notpath, $1; |
|
} elsif ($cur_path =~ /^\=\~(.*)$/){ # =~ |
push @fs_mask, $1; |
|
} elsif ($cur_path =~ /^f\~(.*)$/){ # f~ |
push @fs_filemask, $1; |
|
} elsif ($cur_path =~ /^d\~(.*)$/){ # d~ |
push @fs_dirmask, $1; |
|
} elsif ($cur_path =~ /^\=\!(.*)$/){ # =! |
push @fs_notmask, $1; |
|
} elsif ($cur_path =~ /^f\!(.*)$/){ # f! |
push @fs_notfilemask, $1; |
|
} elsif ($cur_path =~ /^d\!(.*)$/){ # d! |
push @fs_notdirmask, $1; |
|
} elsif ($cur_path =~ /^#/ || $cur_path =~ /^\s*$/){ # comment |
next; |
|
} elsif ($cur_path =~ /[\/\w]+/) { # /dir[/file] |
if ($cur_path =~ /^$cfg_root_path/){ |
push @fs_path, "$cur_path"; |
} else { |
push @fs_path, "$cfg_root_path$cur_path"; |
} |
|
} else { |
print STDERR "Syntax error: $cur_path, ingnored.\n" if ($cfg_verbose >= &VERB_ALL); |
} |
} |
|
#-------------------------------------------------------------------- |
# ðÏÓÌÅÄÏ×ÁÔÅÌØÎÏ ÐÒÏÓÍÁÔÒÉÒÉ×ÁÅÍ ×ÅÓØ ÓÐÉÓÏË ÄÉÒÅËÔÏÒÉÊ ÏÔÍÅÞÅÎÎÙÈ ÄÌÑ ÂÜËÁÐÁ |
|
|
foreach $cur_pathitem (@fs_path){ |
print "Adding $cur_pathitem....\n" if ($cfg_verbose == &VERB_ALL); |
find (\&add_to_backup, $cur_pathitem); |
chdir($cfg_root_path); # ðÅÒÅÈÏÄÉÍ × ËÏÒÅÎØ, ÔÁË ËÁË find ÄÅÌÁÅÔ chdir. |
print "done\n" if ($cfg_verbose == &VERB_ALL); |
} |
close (LIST); |
close (LIST_SIZE); |
close (DIRS); |
#------------ |
# óÏÓÔÁ×ÌÑÅÍ ÓÐÉÓÏË ÕÄÁÌÅÎÎÙÈ ÆÁÊÌÏ×. |
|
open (DEL, ">$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.del")|| print "Can't create list file ($cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.del).\n"; |
flock (DEL, 2); |
if ($cfg_backup_style ne "hash"){ |
while(($file, $key)= each(%active_hash_last)){ |
$file =~ s/\'/\'\\\'\'/g; |
$file =~ s/^\/(.*)$/$1/; |
print DEL "rm -rf '$file'\n"; |
$del_lines_cnt++; |
} |
} |
close(DEL); |
|
# úÁÐÉÓÙ×ÁÅÍ ÈÜÛ ÎÁ ÄÉÓË. |
$dbobj_new->sync(); |
untie %active_hash_new; |
untie %active_hash_last; |
|
|
# áËÔÉ×ÉÒÕÅÍ FTP ÓÏÅÄÉÎÅÎÉÅ ×ÔÏÒÏÊ ÒÁÚ. |
ftp_connect(); |
|
#------------ |
# åÓÌÉ ÔÏÌØËÏ ÏÂÎÏ×ÌÑÅÍ ÈÜÛ, ÔÏ ÚÁÐÉÓÙ×ÁÅÍ ÅÇÏ É ×ÙÈÏÄÉÍ. |
|
if ($cfg_backup_style eq "hash"){ # ôÏÌØËÏ ÓÏÚÄÁÔØ ÈÜÛØ ÂÅÚ ÁÒÈÉ×ÉÒÏ×ÁÎÉÑ. |
|
if ( $cfg_type eq "local"){ |
system( "cp -f $cfg_cache_dir/$cfg_backup_name/.hash $cfg_local_path/.hash") == 0 || print "Local FS copy hash failed: $?"; |
} elsif ( $cfg_type eq "remote_ssh"){ |
system( "cat $cfg_cache_dir/$cfg_backup_name/.hash | $prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat - > $cfg_remote_path/.hash'") == 0 || print "SSH connection failed (copy hash): $?\n"; |
} elsif ( $cfg_type eq "remote_ftp"){ |
$ftp->delete(".hash"); |
$ftp->put("$cfg_cache_dir/$cfg_backup_name/.hash", ".hash")|| print "Can't upload .hash to remote server via FTP\n"; |
} |
exit (0); |
} |
|
#------------ |
# áÒÈÉ×ÉÒÕÅÍ É ÐÅÒÅÄÁÅÍ × ÈÒÁÎÉÌÉÝÅ. |
|
if ($list_lines_cnt == 0 && $del_lines_cnt == 0){ |
print "WARNING: Nothing to backup.\n" if ($cfg_verbose >= &VERB_ALL); |
exit; |
} |
if ( $cfg_type eq "local"){ |
|
print "Storing local backup...\n" if ($cfg_verbose == &VERB_ALL); |
if ($cfg_backup_style eq "sync"){ |
if ($cfg_clean_flag == 1){ # õÄÁÌÉÔØ ÓÔÁÒÙÅ ËÏÐÉÉ |
print "WARNING: If you really shure to delete $cfg_local_path before sync operatioun uncomment line 'system( \"find \$cfg_local_path ! -path '\$cfg_local_path' -maxdepth 1 -exec \$prog_rm -rf \{\} \\;\");'" if ($cfg_verbose >= &VERB_ALL); |
# system( "find $cfg_local_path ! -path '$cfg_local_path' -maxdepth 1 -exec $prog_rm -rf \{\} \\;"); |
} |
|
system( "cd $cfg_local_path; sh $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.del"); |
system( "$prog_tar -c -f - -T $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list| $prog_tar -xf - -C $cfg_local_path") == 0 || print "Local FS sync failed (tar|untar): $?\n"; |
system( "cd $cfg_local_path; sh $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.dir"); |
system( "cp -f $cfg_cache_dir/$cfg_backup_name/.hash $cfg_local_path/$backup_file_base.hash") == 0 || print "Local FS copy failed: $?\n"; |
|
} else { |
if ($cfg_clean_flag == 1){ # õÄÁÌÉÔØ ÓÔÁÒÙÅ ËÏÐÉÉ |
if ($cfg_save_old_backup == 0){ |
system( "$prog_rm -f $cfg_local_path/*"); |
} else { |
if (! -d "$cfg_local_path/OLD"){ |
system( "mkdir $cfg_local_path/OLD"); |
} |
system( "$prog_rm -f $cfg_local_path/OLD/*"); |
system( "mv -f $cfg_local_path/$cfg_backup_name* $cfg_local_path/OLD/"); |
# system( "$prog_rm -f $cfg_local_path/*"); |
} |
} |
system( "cp -f $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list $cfg_local_path/$backup_file_base.list") == 0 || print "Local FS .list copy failed: $?\n"; |
system( "cp -f $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.lsize $cfg_local_path/$backup_file_base.lsize") == 0 || print "Local FS .lsize copy failed: $?\n"; |
system( "cp -f $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.dir $cfg_local_path/$backup_file_base.dir") == 0 || print "Local FS .dir copy failed: $?\n"; |
system( "cp -f $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.del $cfg_local_path/$backup_file_base.del") == 0 || print "Local FS .del copy failed: $?\n"; |
system( "cp -f $cfg_cache_dir/$cfg_backup_name/.hash $cfg_local_path/$backup_file_base.hash") == 0 || print "Local FS .hash copy failed: $?\n"; |
# ïÂÒÁÂÁÔÙ×ÁÅÍ ÒÁÚÂÉÅÎÉÅ ÎÁ ÔÏÍÁ |
for ($arc_block_level=0; $arc_block_level <= $#volume_position; $arc_block_level++){ |
my $tmp_list_file = crate_tmp_list($arc_block_level, $volume_position[$arc_block_level], $volume_position[$arc_block_level+1], "$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list"); |
system( "$prog_tar -c -f - -T $tmp_list_file $prog_gzip_filter $prog_pgp_filter > $cfg_local_path/$backup_file_base-$arc_block_level.tar${arc_ext}") == 0 || print "Local FS tar backup failed: $?\n"; |
} |
} |
|
} elsif ( $cfg_type eq "remote_ssh"){ |
print "Storing remote ssh backup...\n" if ($cfg_verbose == &VERB_ALL); |
if ($cfg_backup_style eq "sync"){ |
if ($cfg_clean_flag == 1){ # õÄÁÌÉÔØ ÓÔÁÒÙÅ ËÏÐÉÉ |
system( "$prog_ssh -l $cfg_remote_login $cfg_remote_host find $cfg_remote_path ! -path '$cfg_remote_path' -maxdepth 1 -exec rm -rf \{\} \\;"); |
} |
system( "cat $cfg_cache_dir/$cfg_backup_name/.hash | $prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat - > $cfg_remote_path/.hash'") == 0 || print "SSH connection failed (store .hash): $?\n"; |
system( "cat $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.del | $prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat - > $cfg_remote_path/.del'") == 0 || print "SSH connection failed (store .hash): $?\n"; |
system( "cat $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.dir | $prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat - > $cfg_remote_path/.dir'") == 0 || print "SSH connection failed (store .hash): $?\n"; |
system("$prog_ssh -l $cfg_remote_login $cfg_remote_host '(cd $cfg_remote_path; sh .del)'"); |
system( "$prog_tar -c -f - -T $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list $prog_gzip_filter| $prog_ssh -l $cfg_remote_login $cfg_remote_host tar -xf - -C $cfg_remote_path") == 0 || print "SSH connection failed (tar): $?\n";; |
system("$prog_ssh -l $cfg_remote_login $cfg_remote_host '(cd $cfg_remote_path; sh .dir)'"); |
|
|
open (DEL, "<$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.del"); |
flock (DEL, 1); |
while(<DEL>){ |
chomp; |
$cur_file = $_; |
$cur_file =~ s/\'/\'\\\'\'/g; |
system("$prog_ssh -l $cfg_remote_login $cfg_remote_host rm -f '$cfg_remote_path/$cur_file'"); |
} |
close(DEL); |
} else { |
if ($cfg_clean_flag == 1){ # õÄÁÌÉÔØ ÓÔÁÒÙÅ ËÏÐÉÉ |
|
if ($cfg_save_old_backup == 0){ |
system( "$prog_ssh -l $cfg_remote_login $cfg_remote_host rm -f $cfg_remote_path/*"); |
} else { |
system( "$prog_ssh -l $cfg_remote_login $cfg_remote_host '(if [ ! -d $cfg_remote_path/OLD ]; then mkdir $cfg_remote_path/OLD; fi)'"); |
system( "$prog_ssh -l $cfg_remote_login $cfg_remote_host rm -f $cfg_remote_path/OLD/*"); |
system( "$prog_ssh -l $cfg_remote_login $cfg_remote_host mv -f $cfg_remote_path/$cfg_backup_name* $cfg_remote_path/OLD/"); |
# system( "$prog_ssh -l $cfg_remote_login $cfg_remote_host rm -f $cfg_remote_path/*"); |
} |
} |
system( "cat $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list | $prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat - > $cfg_remote_path/$backup_file_base.list'") == 0 || print "SSH connection failed (copy .list): $?\n"; |
system( "cat $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.lsize | $prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat - > $cfg_remote_path/$backup_file_base.lsize'") == 0 || print "SSH connection failed (copy .lsize): $?\n"; |
system( "cat $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.dir | $prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat - > $cfg_remote_path/$backup_file_base.dir'") == 0 || print "SSH connection failed (copy .dir): $?\n"; |
system( "cat $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.del | $prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat - > $cfg_remote_path/$backup_file_base.del'") == 0 || print "SSH connection failed (copy .del): $?\n"; |
system( "cat $cfg_cache_dir/$cfg_backup_name/.hash | $prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat - > $cfg_remote_path/$backup_file_base.hash'") == 0 || print "SSH connection failed (copy .hash): $?\n"; |
system( "cat $cfg_cache_dir/$cfg_backup_name/.hash | $prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat - > $cfg_remote_path/.hash'") == 0 || print "SSH connection failed (cache .hash): $?\n"; |
# ïÂÒÁÂÁÔÙ×ÁÅÍ ÒÁÚÂÉÅÎÉÅ ÎÁ ÔÏÍÁ |
for ($arc_block_level=0; $arc_block_level <= $#volume_position; $arc_block_level++){ |
my $tmp_list_file = crate_tmp_list($arc_block_level, $volume_position[$arc_block_level], $volume_position[$arc_block_level+1], "$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list"); |
system( "$prog_tar -c -f - -T $tmp_list_file $prog_gzip_filter $prog_pgp_filter| $prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat - > $cfg_remote_path/$backup_file_base-$arc_block_level.tar${arc_ext}'") == 0 || print "SSH connection failed (tar): $?\n"; |
} |
} |
} elsif ( $cfg_type eq "remote_ftp"){ |
print "Storing remote ftp backup...\n" if ($cfg_verbose == &VERB_ALL); |
|
if ($cfg_backup_style eq "sync"){ |
print "WARNING: Backup style 'sync' only allowed for local and remote_ssh storage.\n" if ($cfg_verbose >= &VERB_ALL); |
} else { |
if ($cfg_clean_flag == 1){ # õÄÁÌÉÔØ ÓÔÁÒÙÅ ËÏÐÉÉ |
if ($cfg_save_old_backup == 0){ |
foreach $cur_dir ($ftp->ls()){ |
$ftp->delete($cur_dir); |
} |
} else { |
$ftp->mkdir("$cfg_remote_path/OLD"); |
$ftp->cwd("$cfg_remote_path/OLD"); |
foreach $cur_dir ($ftp->ls()){ |
$ftp->delete($cur_dir); |
} |
$ftp->cwd("$cfg_remote_path"); |
foreach $cur_dir ($ftp->ls()){ |
if ($cur_dir =~ /$cfg_backup_name/){ |
$ftp->rename($cur_dir,"$cfg_remote_path/OLD/$cur_dir"); |
} |
} |
foreach $cur_dir ($ftp->ls()){ |
$ftp->delete($cur_dir); |
} |
} |
} |
$ftp->delete("$backup_file_base.list"); |
$ftp->put("$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list", "$backup_file_base.list") || print "Can't PUT .list file to remote FTP server\n"; |
$ftp->delete("$backup_file_base.lsize"); |
$ftp->put("$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.lsize", "$backup_file_base.lsize") || print "Can't PUT .lsize file to remote FTP server\n"; |
$ftp->delete("$backup_file_base.dir"); |
$ftp->put("$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.dir", "$backup_file_base.dir")|| print "Can't PUT .dir file to remote FTP server\n"; |
$ftp->delete("$backup_file_base.del"); |
$ftp->put("$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.del", "$backup_file_base.del")|| print "Can't PUT .del file to remote FTP server\n"; |
$ftp->delete("$backup_file_base.hash"); |
$ftp->put("$cfg_cache_dir/$cfg_backup_name/.hash", "$backup_file_base.hash")|| print "Can't PUT old .hash file to remote FTP server\n"; |
$ftp->delete(".hash"); |
$ftp->put("$cfg_cache_dir/$cfg_backup_name/.hash", ".hash")|| print "Can't PUT new .hash file to remote FTP server\n"; |
# ïÂÒÁÂÁÔÙ×ÁÅÍ ÒÁÚÂÉÅÎÉÅ ÎÁ ÔÏÍÁ |
for ($arc_block_level=0; $arc_block_level <= $#volume_position; $arc_block_level++){ |
|
# # ðÒÏÂÌÅÍÁ ÂÙÌÁ × ÍÏÄÕÌÅ Net::FTP |
# if ($arc_block_level > 0){ |
# # ðÅÒÅÏÔËÔÙ×ÁÅÍ ftp ÓÅÓÓÉÀ, ÄÌÑ ÏÂÈÏÄÁ ÐÒÏÂÌÅÍÙ '2Gb' |
# $ftp->quit; |
# sleep(5); |
# ftp_connect(); |
# } |
|
my $tmp_list_file = crate_tmp_list($arc_block_level, $volume_position[$arc_block_level], $volume_position[$arc_block_level+1], "$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list"); |
$ftp->delete("$backup_file_base-$arc_block_level.list"); |
$ftp->put("$tmp_list_file", "$backup_file_base-$arc_block_level.list") || print "Can't PUT .list file to remote FTP server\n"; |
$ftp->delete("$backup_file_base-$arc_block_level.tar${arc_ext}"); |
open (TAR,"$prog_tar -c -f - -T $tmp_list_file $prog_gzip_filter $prog_pgp_filter|")|| print "tar failed: $?\n"; |
flock(TAR,1); |
$ftp->put(*TAR, "$backup_file_base-$arc_block_level.tar${arc_ext}")|| print "Can't store backup archive to remote FTP server.\n"; |
close(TAR); |
} |
$ftp->quit; |
} |
} |
|
if ( $cfg_type eq "remote_ftp"){ |
$ftp->quit; |
} |
print "***** Backup successful complete.\n" if ($cfg_verbose == &VERB_ALL); |
exit (0); |
|
|
######################################## |
sub add_to_backup{ |
my($file_name, $file_dir, $md5_checksum_stat, $checksum_stat); |
my($tmp, $stat_mode, $stat_uid, $stat_gid, $stat_size, $stat_mtime, $stat_time); |
|
$file_name = $_; |
$file_fullpath = $File::Find::name; |
$file_dir = $File::Find::dir; |
$file_fullpath =~ s/^$cfg_root_path/\.\//; |
my $file_fullpath_esc = $file_fullpath; |
$file_fullpath_esc =~ s/\'/\'\\\'\'/g; |
|
# óÏÚÄÁÅÍ ÓÐÉÓÏË ÄÉÒÅËÔÏÒÉÊ |
if ((-d "$cfg_root_path/$file_fullpath") && (! -l "$cfg_root_path/$file_fullpath")){ |
if (check_path($file_dir, $file_name) == 1){ |
if ($cfg_backup_style ne "hash"){ |
($tmp, $tmp, $stat_mode, $tmp, $stat_uid, $stat_gid, $tmp, $stat_size, $tmp, $stat_mtime, $stat_time) = stat("$cfg_root_path/$file_fullpath"); |
$stat_mode = sprintf ("%04o", $stat_mode & 07777); |
$file_fullpath_esc =~ s/^\/(.*)$/$1/; |
$stat_uid = getpwuid($stat_uid) || $stat_uid; |
$stat_gid = getgrgid($stat_gid) || $stat_gid; |
my ($sec,$min,$hour,$mday,$mon,$year) = localtime($stat_time); |
$stat_time = sprintf ("%4.4d%2.2d%2.2d%2.2d%2.2d.%2.2d", |
$year+1900,$mon+1,$mday,$hour,$min,$sec); |
print DIRS "mkdir '$file_fullpath_esc'\n"; |
print DIRS "chmod $stat_mode '$file_fullpath_esc'\n"; |
print DIRS "chown $stat_uid:$stat_gid '$file_fullpath_esc'\n"; |
print DIRS "touch -t $stat_time '$file_fullpath_esc'\n"; |
$cur_backup_size += int(length($file_fullpath)/100.0 + 1)*512; |
if ($cfg_maximum_archive_size > 0 && $cur_backup_size + 10240 >= $cfg_maximum_archive_size){ |
my $old_val = $cur_backup_size - $stat_size - int(length($file_fullpath)/100.0 + 1)*512; |
my $tmp_pos= $#volume_position+1; |
print "Volume $tmp_pos Done. Size: $old_val\n" if ($cfg_verbose == &VERB_ALL); |
$cur_backup_size = $stat_size + int(length($file_fullpath)/100.0 + 1)*512 + 1536; |
push @volume_position, $list_lines_cnt; |
} |
} |
} else { |
if ($cfg_stopdir_prune == 1){ |
$File::Find::prune = 1; |
return; |
} |
} |
# òÁÂÏÔÁÅÍ Ó ÆÁÊÌÁÍÉ |
} elsif ((-f "$cfg_root_path/$file_fullpath") || (-l "$cfg_root_path/$file_fullpath")){ |
if (check_path($file_dir, $file_name) == 1){ |
($tmp, $tmp, $stat_mode, $tmp, $stat_uid, $stat_gid, $tmp, $stat_size, $tmp, $stat_mtime) = stat("$cfg_root_path/$file_fullpath"); |
$checksum_stat= md5_base64("$stat_mtime/$stat_size/$stat_mode/$stat_uid/$stat_gid"); |
# $file_fullpath_md5 = md5_base64($file_fullpath); |
$file_fullpath_md5 = $file_fullpath; |
if ($cfg_time_limit != 0 && $cur_time - $cfg_time_limit > $stat_mtime){ |
print "Time limit: $cur_time - $cfg_time_limit > $stat_mtime, file $file_fullpath ignored.\n" if ($cfg_verbose == &VERB_ALL); |
next; |
} |
if ($cfg_size_limit != 0 && $cfg_size_limit < $stat_size){ |
print "Size limit: $cfg_size_limit < $stat_size, file $file_fullpath ignored.\n" if ($cfg_verbose == &VERB_ALL); |
next; |
} |
|
if (($cfg_checksum eq "md5") && (! -l "$cfg_root_path/$file_fullpath")){ |
($md5_checksum_stat, $tmp) = split(/\s+/, `$prog_md5sum '$cfg_root_path/$file_fullpath_esc'`); |
$active_hash_new{$file_fullpath_md5} = "$checksum_stat/$md5_checksum_stat"; |
check_update($file_fullpath, "$checksum_stat/$md5_checksum_stat", $file_fullpath_md5, $stat_size); |
} else { |
$active_hash_new{$file_fullpath} = $checksum_stat; |
check_update($file_fullpath, $checksum_stat, $file_fullpath, $stat_size); |
} |
} |
} |
} |
|
############################################### |
# ðÒÏ×ÅÒÑÅÍ ÉÚÍÅÎÉÌÓÑ ÌÉ ÆÁÊÌ ÉÌÉ ÎÅÔ, ÅÓÌÉ ÄÁ ÁÐÄÅÊÔÉÍ ÌÏÇ. |
sub check_update{ |
my ($file, $checksum, $filesum, $stat_size) = @_; |
|
if ( $active_hash_last{$filesum} ne $checksum){ |
if ($cfg_backup_style ne "hash"){ |
$file =~ s/^\/(.*)$/$1/; |
print LIST "$file\n"; |
print LIST_SIZE "$stat_size\t$file\n"; |
|
# ïÂÒÁÂÁÔÙ×ÁÅÍ ÓÌÕÞÁÊ ÒÁÚÂÉÅÎÉÑ ÇÉÇÁÎÓËÉÈ ÁÒÈÉ×Ï×. |
if (-l "/$file"){ |
$stat_size = 0; |
} |
$cur_backup_size += $stat_size + int(length($file)/100.0 + 1)*512; |
# print "$cur_backup_size:$stat_size:$file\n"; |
if ($cfg_maximum_archive_size > 0 && $cur_backup_size + 10240 >= $cfg_maximum_archive_size){ |
my $old_val = $cur_backup_size - $stat_size - int(length($file)/100.0 + 1)*512; |
my $tmp_pos= $#volume_position+1; |
print "Volume $tmp_pos Done. Size: $old_val\n" if ($cfg_verbose == &VERB_ALL); |
$cur_backup_size = $stat_size + int(length($file)/100.0 + 1)*512 + 1536; |
push @volume_position, $list_lines_cnt; |
} |
|
} |
$list_lines_cnt++; |
} |
delete $active_hash_last{$filesum}; |
if (defined $dbobj_last){ |
$dbobj_last->del($filesum); |
} |
} |
|
############################################### |
# 0 - ÎÅ ÄÏÂÁ×ÌÑÔØ ÆÁÊÌ |
# 1 - ÄÏÂÁ×ÔØ ÆÁÊÌ |
|
sub check_path { |
my ($dir_name, $file_name) = @_; |
my ($item, $path); |
|
$path = "$dir_name/$file_name"; |
|
foreach $item (@fs_notmask){ |
if ($path =~ /$item/){ |
return 0; |
} |
} |
|
foreach $item (@fs_notfilemask){ |
if ($file_name =~ /$item/){ |
return 0; |
} |
} |
|
foreach $item (@fs_filemask){ |
if ($file_name =~ /$item/){ |
return 1; |
} |
} |
|
foreach $item (@fs_notdirmask){ |
if ($dir_name =~ /$item/){ |
return 0; |
} |
} |
|
|
foreach $item (@fs_mask){ |
if ($path =~ /$item/){ |
return 1; |
} |
} |
|
foreach $item (@fs_dirmask){ |
if ($dir_name =~ /$item/){ |
return 1; |
} |
} |
|
|
foreach $item (@fs_notpath){ |
if (($dir_name eq $item) || ($path eq $item) || ($dir_name =~ /^$item\//)){ |
return 0; |
} |
} |
|
return 1; |
} |
############################################### |
# õÓÔÁÎÁ×ÌÉ×ÁÅÍ ÓÏÅÄÉÎÅÎÉÅ Ó ÕÄÁÌÅÎÎÙÍ ÓÅÒ×ÅÒÏÍ ÐÏ FTP. |
|
sub ftp_connect{ |
if ( $cfg_type eq "remote_ftp"){ |
$ftp = Net::FTP->new($cfg_remote_host, Timeout => 30, Debug => 0, Passive => $cfg_remote_ftp_mode) || die "Can't connect to ftp server.\n"; |
$ftp->login($cfg_remote_login, $cfg_remote_password) || die "Can't login to ftp server.\n"; |
$ftp->cwd($cfg_remote_path) || die "Path $cfg_remote_path not found on ftp server.\n"; |
$ftp->binary(); |
} |
} |
############################################### |
# óÏÄÁÎÉÅ ÓÐÉÓËÁ ÆÁÊÌÏ× ÄÌÑ ÐÏÍÅÝÅÎÉÑ × ÏÐÒÅÄÅÌÅÎÎÙÊ ÔÏÍ ÍÎÏÇÏÔÏÍÎÏÇÏ ÁÒÈÉ×Á. |
|
sub crate_tmp_list{ |
my ($arc_block_level, $position1, $position2, $full_list_path) = @_; |
my ($tmp_list_path, $pos_counter); |
|
if ($arc_block_level == 0 && $position1 == 0 && $position2 eq ''){ |
$tmp_list_path = $full_list_path; |
} else { |
$pos_counter = 0; |
$tmp_list_path = "$full_list_path.$arc_block_level"; |
open(FULL_LIST, "<$full_list_path")|| die "Can't open full list $full_list_path\n"; |
flock(FULL_LIST, 1); |
open(TMP_LIST, ">$tmp_list_path")|| die "Can't create temp list $tmp_list_path\n"; |
flock(TMP_LIST, 2); |
while(<FULL_LIST>){ |
if (($pos_counter >= $position1) && ($pos_counter < $position2 || $position2 eq '')){ |
print TMP_LIST $_; |
} |
$pos_counter++; |
} |
close(TMP_LIST); |
close(FULL_LIST); |
} |
return $tmp_list_path; |
} |
############################################### |
############################################### |
|
__END__ |
|
=head1 NAME |
|
fsbackup - file system backup and synchronization utility. |
|
=head1 SYNOPSIS |
|
fsbackup.pl [options] <configuration file> |
|
=head1 DESCRIPTION |
|
C<fsbackup.pl> is a incremental backup creation utility. |
C<fsbackup.pl> support backup compression and encryption. Backup can be stored |
on local file system and on remote host stored over SSH or FTP. Some addition |
scripts allow backups SQL tables from PostgreSQL and MySQL (C<pgsql_backup.sh> |
and C<mysql_backup.sh>)), save system configuration files and list of installed |
packages (C<sysbackup.sh>). |
Backuped with C<fsbackup.pl> files can be recovered by script C<fsrestore.sh>, |
backuped with C<sysbackup.sh> system packeges can be reinstalled by C<sysrestore.sh> |
|
=head1 OPTIONS |
|
The following command-line options can be used with C<fsbackup.pl>: |
|
=over |
|
=item C<-n> |
|
Create new backup without checking files in previously stored hash. |
|
=item C<-f> |
|
Create full backup, like as C<-n> option. |
|
=item C<-h> |
|
Only rebuild hash, no storing files in backup archive. |
|
=item C<-c> |
|
Clean incremental backup storage and create new full backup without checking |
$cfg_increment_level config parameter. |
|
=head1 ADDITION SCRIPTS |
|
=item C<create_backup.sh> |
|
Backup planner running from C<crontab>. For example: |
|
18 4 * * * /usr/local/fsbackup/create_backup.sh |
|
=item C<install.pl> |
|
Script to install fsbackup package and some required perl modules. |
|
=item C<fsbackup.pl> |
|
File system backup utility. |
|
=item C<cfg_example> |
|
Example of configuration file. |
|
=item C<scripts/pgsql_backup.sh> |
|
=item C<scripts/mysql_backup.sh> |
|
Script for backup SQL tables from PostreSQL and MySQL. |
|
=item C<scripts/sysbackup.sh> |
|
Script for store system configuration files and information about installed |
packages. |
|
=item C<scripts/fsrestore.sh> |
|
Script for restore files backuped by C<fsbackup.pl>. |
|
=item C<scripts/sysrestore.sh> |
|
Script for reinstall packages stored by C<sysbackup.sh>. |
|
|
=head1 CONFIGURATION FILE |
|
=item B<$cfg_backup_name> = 'test_host' |
|
Name of backup, single word. |
|
=item B<$cfg_cache_dir> = '/usr/local/fsbackup/cache' |
|
Path of internal cache directory for local backup method. |
|
=item B<$prog_md5sum> = 'md5sum -b' |
|
=item B<$prog_tar> = 'tar' |
|
=item B<$prog_ssh> = 'ssh' |
|
=item B<$prog_rm> = 'rm' |
|
=item B<$prog_gzip> = 'gzip' |
|
=item B<$prog_pgp> = 'gpg' |
|
Full path of some external program running from C<fsbackup.pl>. |
B<$prog_gzip = ''> - not use compression, B<$prog_pgp = ''> - not use |
encryption. |
|
=item B<$cfg_checksum> = 'timesize' |
|
File checksum method: |
|
timesize - checksum of file attributes (default, best speed) |
|
md5 - checksum of file attributes + MD5 checksum of file content. |
|
=item B<$cfg_backup_style> = 'backup' |
|
Backup style: |
|
backup - incremental backup (copy only new and changed files). |
|
full_backup - full backup (copy all files). |
|
sync - file tree synchronization. |
|
hash - hash creation without storing archive (spying for new or changed files). |
|
=item B<$cfg_increment_level> = 7 |
|
Incremental level (after how many incremental copy make full refresh of backup) |
|
=item B<$cfg_type> = 'remote_ssh' |
|
Type of backup storage: |
|
local - store backup on local file system. |
remote_ssh - store backup on remote host over SSH connection. |
remote_ftp - store backup on remote FTP server. |
|
|
=item B<$cfg_remote_host> = 'backup-server.test.ru' |
|
=item B<$cfg_remote_login> = 'backup_login' |
|
=item B<$cfg_remote_path> = '/home/backup_login/backup' |
|
Connection parameters for remote_ssh storage type. |
|
=item B<$cfg_remote_password> = 'Test1234' |
|
Password of remote login for remote_ftp storage type. |
|
=item B<$cfg_remote_ftp_mode> = 0 |
|
FTP transfer mode. 0 - Active mode, 1 - Passive mode. |
|
=item B<$cfg_local_path> = '/var/backup/' |
|
Path of directory to store backup on local file system for local storage type. |
|
=item B<$cfg_time_limit> = 0 |
|
Limit of file creation time in days. If not 0, don't backup files created or |
modified later then $cfg_time_limit (days). |
|
=item B<$cfg_size_limit> = 0 |
|
Limit of maximum file size. If not 0, don't backup files witch size more then |
$cfg_time_limit kilobytes. |
|
=item B<$cfg_root_path> = '/' |
|
Root path for initial chdir. |
|
=item B<$cfg_pgp_userid> = '' |
|
Name of user in public key ring with public key will be used for PGP encryption. |
Not use encryption if not set. |
|
=item B<$cfg_verbose> = 3 |
|
Verbose level. |
|
0 - Silent mode, suspend all output, except fatal configuration errors. |
1 - Output errors and warnings. |
2 - Output all the available data. |
|
=item B<$cfg_save_old_backup> = 1 |
|
Save previous backup to OLD directory before rotation or before storing full backup. |
|
0 - don't save old backup |
1 - save old backup. |
|
=item B<$cfg_maximum_archive_size> = 0 |
|
Size of maximum size (in KiloBytes) of single unpacked archive file (0 - unlimited file size). |
|
=item B<$cfg_stopdir_prune> = 0 |
|
Recursive review of the prohibited directories. |
0 - Recursively to view all contents of directories marked for backup, including contents of directories prohibited by '!', '!d' and '=! rules. |
1 - not use a recursive entrance to directory prohibited for backup (speed is increased, reduces flexibility of customization). |
|
=item B<__DATA__> - list of backuped path and regexp mask. |
|
/dir[/file] - backup file or directory. |
!/dir[/file] - NOT include this file or directory to backup. |
# - ignore this line. |
|
Mask: |
|
=~ - regexp mask for include file or directory to backup. |
f~ - regexp file mask for include file to backup. |
d~ - regexp directory mask for include directory to backup. |
=! - regexp mask for NOT include file or directory to backup. |
f! - regexp file mask for NOT include file to backup. |
d! - regexp directory mask for NOT include directory to backup. |
|
|
Operation priority: |
|
1. =! |
2. f! |
3. f~ |
4. d! |
5. =~ |
6. d~ |
7. !path |
8. path |
|
|
=head1 COPYRIGHT |
|
Copyright (c) 2001 by Maxim Chirkov <mc@tyumen.ru> |
http://www.opennet.ru/dev/fsbackup/ |
|
=head1 BUGS |
|
Look TODO file. |
|
=head1 AUTHORS |
|
Maxim Chirkov <mc@tyumen.ru> |
|
=cut |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |