"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "lib/BackupPC/Xfer/Rsync.pm" between
BackupPC-4.3.2.tar.gz and BackupPC-4.4.0.tar.gz

About: BackupPC is a high-performance, enterprise-grade system for backing up Linux and WinXX PCs and laptops to a server’s disk (http/cgi user interface).

Rsync.pm  (BackupPC-4.3.2):Rsync.pm  (BackupPC-4.4.0)
skipping to change at line 33 skipping to change at line 33
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
#======================================================================== #========================================================================
# #
# Version 4.3.2, released 17 Feb 2020. # Version 4.4.0, released 20 Jun 2020.
# #
# See http://backuppc.sourceforge.net. # See http://backuppc.sourceforge.net.
# #
#======================================================================== #========================================================================
package BackupPC::Xfer::Rsync; package BackupPC::Xfer::Rsync;
use strict; use strict;
use BackupPC::View; use BackupPC::View;
use Encode qw/from_to encode/; use Encode qw/from_to encode/;
skipping to change at line 60 skipping to change at line 60
my $t = BackupPC::Xfer::Protocol->new($bpc, $args); my $t = BackupPC::Xfer::Protocol->new($bpc, $args);
$t->{logSave} = []; $t->{logSave} = [];
$t->{logInfo} = {}; $t->{logInfo} = {};
return bless($t, $class); return bless($t, $class);
} }
sub start sub start
{ {
my($t) = @_; my($t) = @_;
my $bpc = $t->{bpc}; my $bpc = $t->{bpc};
my $conf = $t->{conf}; my $conf = $t->{conf};
my(@fileList, $rsyncArgs, $logMsg, $rsyncCmd); my(@fileList, $rsyncArgs, $logMsg, $rsyncCmd);
my $binDir = $t->{bpc}->BinDir(); my $binDir = $t->{bpc}->BinDir();
my $shareNamePath = $t->shareName2Path($t->{shareName}); my $shareNamePath = $t->shareName2Path($t->{shareName});
alarm(0); alarm(0);
# #
# We add a slash to the share name we pass to rsync # We add a slash to the share name we pass to rsync
# #
($t->{shareNameSlash} = "$shareNamePath/") =~ s{//+$}{/}; ($t->{shareNameSlash} = "$shareNamePath/") =~ s{//+$}{/};
if ( $t->{type} eq "restore" ) { if ( $t->{type} eq "restore" ) {
my $remoteDir = "$shareNamePath/$t->{pathHdrDest}"; my $remoteDir = "$shareNamePath/$t->{pathHdrDest}";
$remoteDir =~ s{//+}{/}g; $remoteDir =~ s{//+}{/}g;
my $filesFd; my $filesFd;
my $srcList; my $srcList;
my $srcDir = "/"; my $srcDir = "/";
#from_to($remoteDir, "utf8", $conf->{ClientCharset}) #from_to($remoteDir, "utf8", $conf->{ClientCharset})
# if ( $conf->{ClientCharset} ne "" ); # if ( $conf->{ClientCharset} ne "" );
$rsyncArgs = [@{$conf->{RsyncRestoreArgs}}]; $rsyncArgs = [@{$conf->{RsyncRestoreArgs}}];
if ( ref($conf->{RsyncRestoreArgsExtra}) eq 'ARRAY' ) {
push(@$rsyncArgs, @{$conf->{RsyncRestoreArgsExtra}});
}
# #
# Each name in the fileList starts with $t->{pathHdrSrc}. The # Each name in the fileList starts with $t->{pathHdrSrc}. The
# default $t->{pathHdrDest} also ends in $t->{pathHdrSrc}, although # default $t->{pathHdrDest} also ends in $t->{pathHdrSrc}, although
# the user might have changed that. So we have $t->{pathHdrSrc} # the user might have changed that. So we have $t->{pathHdrSrc}
# appearing twice: in the fileList and in the target directory. # appearing twice: in the fileList and in the target directory.
# We have to remove one or the other. # We have to remove one or the other.
# #
# Since the client rsync only tries to create the last directory # Since the client rsync only tries to create the last directory
# in $t->{pathHdrDest} (rather than the full path), it will fail # in $t->{pathHdrDest} (rather than the full path), it will fail
skipping to change at line 108 skipping to change at line 111
# #
if ( $remoteDir =~ m{(.*)\Q$t->{pathHdrSrc}\E(/*)$} ) { if ( $remoteDir =~ m{(.*)\Q$t->{pathHdrSrc}\E(/*)$} ) {
$remoteDir = "$1$2"; $remoteDir = "$1$2";
$remoteDir = "/" if ( $remoteDir eq "" ); $remoteDir = "/" if ( $remoteDir eq "" );
$t->{XferLOG}->write(\"Trimming $t->{pathHdrSrc} from remoteDir -> $ remoteDir\n"); $t->{XferLOG}->write(\"Trimming $t->{pathHdrSrc} from remoteDir -> $ remoteDir\n");
} else { } else {
for ( my $i = 0 ; $i < @{$t->{fileList}} ; $i++ ) { for ( my $i = 0 ; $i < @{$t->{fileList}} ; $i++ ) {
$t->{fileList}[$i] = substr($t->{fileList}[$i], length($t->{path HdrSrc})); $t->{fileList}[$i] = substr($t->{fileList}[$i], length($t->{path HdrSrc}));
$t->{fileList}[$i] = "." if ( $t->{fileList}[$i] eq "" ); $t->{fileList}[$i] = "." if ( $t->{fileList}[$i] eq "" );
} }
$srcDir = $t->{pathHdrSrc} if ($t->{pathHdrSrc}); $srcDir = $t->{pathHdrSrc} if ( $t->{pathHdrSrc} );
$t->{XferLOG}->write(\"Trimming $t->{pathHdrSrc} from filesList\n"); $t->{XferLOG}->write(\"Trimming $t->{pathHdrSrc} from filesList\n");
} }
$t->{filesFrom} = "$conf->{TopDir}/pc/$t->{client}/.rsyncFilesFrom$$"; $t->{filesFrom} = "$conf->{TopDir}/pc/$t->{client}/.rsyncFilesFrom$$";
if ( open($filesFd, ">", $t->{filesFrom}) ) { if ( open($filesFd, ">", $t->{filesFrom}) ) {
syswrite($filesFd, join("\n", @{$t->{fileList}})); syswrite($filesFd, join("\n", @{$t->{fileList}}));
close($filesFd); close($filesFd);
$t->{XferLOG}->write(\"Wrote source file list to $t->{filesFrom}: @{ $t->{fileList}}\n"); $t->{XferLOG}->write(\"Wrote source file list to $t->{filesFrom}: @{ $t->{fileList}}\n");
$srcList = ["--files-from=$t->{filesFrom}", $srcDir]; $srcList = ["--files-from=$t->{filesFrom}", $srcDir];
} else { } else {
$t->{XferLOG}->write(\"Failed to open/create file list $t->{filesFro m}\n"); $t->{XferLOG}->write(\"Failed to open/create file list $t->{filesFro m}\n");
$t->{_errStr} = "Failed to open/create file list $t->{filesFrom}"; $t->{_errStr} = "Failed to open/create file list $t->{filesFrom}";
return; return;
} }
if ( $t->{XferMethod} eq "rsync" ) { if ( $t->{XferMethod} eq "rsync" ) {
unshift(@$rsyncArgs, "--rsync-path=$conf->{RsyncClientPath}") unshift(@$rsyncArgs, "--rsync-path=$conf->{RsyncClientPath}")
if ( $conf->{RsyncClientPath} ne "" ); if ( $conf->{RsyncClientPath} ne "" );
unshift(@$rsyncArgs, @{$conf->{RsyncSshArgs}}) unshift(@$rsyncArgs, @{$conf->{RsyncSshArgs}})
if ( ref($conf->{RsyncSshArgs}) eq 'ARRAY' ); if ( ref($conf->{RsyncSshArgs}) eq 'ARRAY' );
push(@$rsyncArgs, @$srcList, "$t->{hostIP}:$remoteDir"); push(@$rsyncArgs, @$srcList, "$t->{hostIP}:$remoteDir");
} else { } else {
if ( length($conf->{RsyncdPasswd}) ) { if ( length($conf->{RsyncdPasswd}) ) {
my($pwFd, $ok); my($pwFd, $ok);
$t->{pwFile} = "$conf->{TopDir}/pc/$t->{client}/.rsyncdpw$$"; $t->{pwFile} = "$conf->{TopDir}/pc/$t->{client}/.rsyncdpw$$";
if ( open($pwFd, ">", $t->{pwFile}) ) { if ( open($pwFd, ">", $t->{pwFile}) ) {
$ok = 1; $ok = 1;
$ok = 0 if ( $ok && chmod(0400, $t->{pwFile}) != 1 ); $ok = 0 if ( $ok && chmod(0400, $t->{pwFile}) != 1 );
$ok = 0 if ( $ok && !binmode($pwFd) ); $ok = 0 if ( $ok && !binmode($pwFd) );
$ok = 0 if ( $ok && syswrite($pwFd, $conf->{RsyncdPasswd}) ! = length($conf->{RsyncdPasswd}) ); $ok = 0 if ( $ok && syswrite($pwFd, $conf->{RsyncdPasswd}) ! = length($conf->{RsyncdPasswd}) );
$ok = 0 if ( $ok && !close($pwFd) ); $ok = 0 if ( $ok && !close($pwFd) );
push(@$rsyncArgs, "--password-file=$t->{pwFile}"); push(@$rsyncArgs, "--password-file=$t->{pwFile}");
} }
if ( !$ok ) { if ( !$ok ) {
$t->{XferLOG}->write(\"Failed to open/create rsynd pw file $ t->{pwFile} ($!)\n"); $t->{XferLOG}->write(\"Failed to open/create rsynd pw file $ t->{pwFile} ($!)\n");
$t->{_errStr} = "Failed to open/create rsynd pw file $t->{pw File} ($!)"; $t->{_errStr} = "Failed to open/create rsynd pw file $t->{pw File} ($!)";
return; return;
} }
} }
#my $shareName = $t->{shareName}; #my $shareName = $t->{shareName};
#from_to($shareName, "utf8", $conf->{ClientCharset}) #from_to($shareName, "utf8", $conf->{ClientCharset})
# if ( $conf->{ClientCharset} ne "" ); # if ( $conf->{ClientCharset} ne "" );
if ( $conf->{RsyncdClientPort} != 873 ) { if ( $conf->{RsyncdClientPort} != 873 ) {
push(@$rsyncArgs, "--port=$conf->{RsyncdClientPort}"); push(@$rsyncArgs, "--port=$conf->{RsyncdClientPort}");
} }
if ( $conf->{ClientCharset} ne "" ) { if ( $conf->{ClientCharset} ne "" && $conf->{ClientCharset} ne "utf8 " ) {
push(@$rsyncArgs, "--iconv=utf8,$conf->{ClientCharset}"); push(@$rsyncArgs, "--iconv=utf8,$conf->{ClientCharset}");
} }
push(@$rsyncArgs, push(@$rsyncArgs, @$srcList, "$conf->{RsyncdUserName}\@$t->{hostIP}:
@$srcList, :$remoteDir");
"$conf->{RsyncdUserName}\@$t->{hostIP}::$remoteDir");
} }
# #
# Merge variables into $rsyncArgs # Merge variables into $rsyncArgs
# #
$rsyncArgs = $bpc->cmdVarSubstitute($rsyncArgs, { $rsyncArgs = $bpc->cmdVarSubstitute(
host => $t->{host}, $rsyncArgs,
hostIP => $t->{hostIP}, {
client => $t->{client}, host => $t->{host},
shareNameOrig => $t->{shareName}, hostIP => $t->{hostIP},
shareName => $shareNamePath, client => $t->{client},
confDir => $conf->{ConfDir}, shareNameOrig => $t->{shareName},
sshPath => $conf->{SshPath}, shareName => $shareNamePath,
}); confDir => $conf->{ConfDir},
sshPath => $conf->{SshPath},
}
);
# #
# create --bpc-bkup-merge list. This is the list of backups that have t o # create --bpc-bkup-merge list. This is the list of backups that have t o
# be merged to create the correct "view" of the backup being restore. # be merged to create the correct "view" of the backup being restore.
# #
my($srcIdx, $i, $mergeInfo); my($srcIdx, $i, $mergeInfo);
my $mergeIdxList = []; my $mergeIdxList = [];
for ( $i = 0 ; $i < @{$t->{backups}} ; $i++ ) { for ( $i = 0 ; $i < @{$t->{backups}} ; $i++ ) {
if ( $t->{backups}[$i]{num} == $t->{bkupSrcNum} ) { if ( $t->{backups}[$i]{num} == $t->{bkupSrcNum} ) {
$srcIdx = $i; $srcIdx = $i;
skipping to change at line 212 skipping to change at line 217
# #
# For V4+ backups, we merge backward from the following filled backu p. # For V4+ backups, we merge backward from the following filled backu p.
# #
for ( $i = $srcIdx ; $i < @{$t->{backups}} ; $i++ ) { for ( $i = $srcIdx ; $i < @{$t->{backups}} ; $i++ ) {
unshift(@$mergeIdxList, $i); unshift(@$mergeIdxList, $i);
last if ( !$t->{backups}[$i]{noFill} ); last if ( !$t->{backups}[$i]{noFill} );
} }
} }
foreach my $i ( @$mergeIdxList ) { foreach my $i ( @$mergeIdxList ) {
$mergeInfo .= "," if ( length($mergeInfo) ); $mergeInfo .= "," if ( length($mergeInfo) );
$mergeInfo .= sprintf("%d/%d/%d", $t->{backups}[$i]{num}, $t->{backu $mergeInfo .=
ps}[$i]{compress}, int($t->{backups}[$i]{version})); sprintf("%d/%d/%d", $t->{backups}[$i]{num}, $t->{backups}[$i]{comp
ress}, int($t->{backups}[$i]{version}));
} }
unshift(@$rsyncArgs, unshift(
'--bpc-top-dir', $conf->{TopDir}, @$rsyncArgs,
'--bpc-host-name', $t->{bkupSrcHost}, '--bpc-top-dir', $conf->{TopDir}, # perltidy p
'--bpc-share-name', $t->{bkupSrcShare}, rotect
'--bpc-bkup-num', $t->{backups}[$srcIdx]{num}, '--bpc-host-name', $t->{bkupSrcHost},
'--bpc-bkup-comp', $t->{backups}[$srcIdx]{compress}, '--bpc-share-name', $t->{bkupSrcShare},
'--bpc-bkup-merge', $mergeInfo, '--bpc-bkup-num', $t->{backups}[$srcIdx]{num},
'--bpc-bkup-comp', $t->{backups}[$srcIdx]{compress},
'--bpc-bkup-merge', $mergeInfo,
'--bpc-log-level', $conf->{XferLogLevel},
'--bpc-attrib-new', '--bpc-attrib-new',
'--bpc-log-level', $conf->{XferLogLevel},
); );
$logMsg = "restore started below directory $t->{shareName}" $logMsg = "restore started below directory $t->{shareName} to host $t->{
. " to host $t->{host}"; host}";
} else { } else {
# #
# Turn $conf->{BackupFilesOnly} and $conf->{BackupFilesExclude} # Turn $conf->{BackupFilesOnly} and $conf->{BackupFilesExclude}
# into a hash of arrays of files, and $conf->{RsyncShareName} # into a hash of arrays of files, and $conf->{RsyncShareName}
# to an array # to an array
# #
$bpc->backupFileConfFix($conf, "RsyncShareName"); $bpc->backupFileConfFix($conf, "RsyncShareName");
if ( defined($conf->{BackupFilesOnly}{$t->{shareName}}) ) { if ( defined($conf->{BackupFilesOnly}{$t->{shareName}}) ) {
my(@inc, @exc, %incDone, %excDone); my(@inc, @exc, %incDone, %excDone);
foreach my $file2 ( @{$conf->{BackupFilesOnly}{$t->{shareName}}} ) { foreach my $file2 ( @{$conf->{BackupFilesOnly}{$t->{shareName}}} ) {
# #
# If the user wants to just include /home/craig, then # If the user wants to just include /home/craig, then
# we need to do create include/exclude pairs at # we need to do create include/exclude pairs at
# each level: # each level:
# --include /home --exclude /* # --include /home --exclude /*
# --include /home/craig --exclude /home/* # --include /home/craig --exclude /home/*
skipping to change at line 260 skipping to change at line 266
# --include /home/craig --exclude /home/* # --include /home/craig --exclude /home/*
# --include /var/log --exclude /var/* # --include /var/log --exclude /var/*
# #
# To make this easier we do all the includes first and all # To make this easier we do all the includes first and all
# of the excludes at the end (hopefully they commute). # of the excludes at the end (hopefully they commute).
# #
my $file = $file2; my $file = $file2;
$file =~ s{/$}{}; $file =~ s{/$}{};
$file = "/$file"; $file = "/$file";
$file =~ s{//+}{/}g; $file =~ s{//+}{/}g;
if ( $file eq "/" ) { if ( $file eq "/" ) {
# #
# This is a special case: if the user specifies # This is a special case: if the user specifies
# "/" then just include it and don't exclude "/*". # "/" then just include it and don't exclude "/*".
# #
push(@inc, $file) if ( !$incDone{$file} ); push(@inc, $file) if ( !$incDone{$file} );
next; next;
} }
my $f = ""; my $f = "";
while ( $file =~ m{^/([^/]*)(.*)} ) { while ( $file =~ m{^/([^/]*)(.*)} ) {
my $elt = $1; my $elt = $1;
$file = $2; $file = $2;
if ( $file eq "/" ) { if ( $file eq "/" ) {
# #
# preserve a tailing slash # preserve a tailing slash
# #
$file = ""; $file = "";
$elt = "$elt/"; $elt = "$elt/";
} }
push(@exc, "$f/*") if ( !$excDone{"$f/*"} ); push(@exc, "$f/*") if ( !$excDone{"$f/*"} );
$excDone{"$f/*"} = 1; $excDone{"$f/*"} = 1;
$f = "$f/$elt"; $f = "$f/$elt";
push(@inc, $f) if ( !$incDone{$f} ); push(@inc, $f) if ( !$incDone{$f} );
$incDone{$f} = 1; $incDone{$f} = 1;
} }
} }
foreach my $file ( @inc ) { foreach my $file ( @inc ) {
$file = encode($conf->{ClientCharset}, $file) $file = encode($conf->{ClientCharset}, $file)
if ( $conf->{ClientCharset} ne "" ); if ( $conf->{ClientCharset} ne "" );
push(@fileList, "--include=$file"); push(@fileList, "--include=$file");
} }
foreach my $file ( @exc ) { foreach my $file ( @exc ) {
$file = encode($conf->{ClientCharset}, $file) $file = encode($conf->{ClientCharset}, $file)
if ( $conf->{ClientCharset} ne "" ); if ( $conf->{ClientCharset} ne "" );
push(@fileList, "--exclude=$file"); push(@fileList, "--exclude=$file");
} }
} }
if ( defined($conf->{BackupFilesExclude}{$t->{shareName}}) ) { if ( defined($conf->{BackupFilesExclude}{$t->{shareName}}) ) {
foreach my $file2 ( @{$conf->{BackupFilesExclude}{$t->{shareName}}} ) { foreach my $file2 ( @{$conf->{BackupFilesExclude}{$t->{shareName}}} ) {
# #
# just append additional exclude lists onto the end # just append additional exclude lists onto the end
# #
my $file = $file2; my $file = $file2;
$file = encode($conf->{ClientCharset}, $file) $file = encode($conf->{ClientCharset}, $file)
if ( $conf->{ClientCharset} ne "" ); if ( $conf->{ClientCharset} ne "" );
push(@fileList, "--exclude=$file"); push(@fileList, "--exclude=$file");
} }
} }
# #
# A full dump is implemented with $Conf{RsyncFullArgsExtra}, # A full dump is implemented with $Conf{RsyncFullArgsExtra},
# which is normally --checksum. This causes the client to # which is normally --checksum. This causes the client to
# generate and send a full-file checksum for each file with # generate and send a full-file checksum for each file with
# the file list. That can be directly compared with the # the file list. That can be directly compared with the
# V4 full-file digest. # V4 full-file digest.
# #
skipping to change at line 341 skipping to change at line 347
push(@$rsyncArgs, @{$conf->{RsyncIncrArgsExtra}}); push(@$rsyncArgs, @{$conf->{RsyncIncrArgsExtra}});
} elsif ( ref($conf->{RsyncIncrArgsExtra}) eq '' && $conf->{RsyncInc rArgsExtra} ne "" ) { } elsif ( ref($conf->{RsyncIncrArgsExtra}) eq '' && $conf->{RsyncInc rArgsExtra} ne "" ) {
push(@$rsyncArgs, $conf->{RsyncIncrArgsExtra}); push(@$rsyncArgs, $conf->{RsyncIncrArgsExtra});
} }
} }
# #
# Add any additional rsync args # Add any additional rsync args
# #
push(@$rsyncArgs, @{$conf->{RsyncArgsExtra}}) push(@$rsyncArgs, @{$conf->{RsyncArgsExtra}})
if ( ref($conf->{RsyncArgsExtra}) eq 'ARRAY' ); if ( ref($conf->{RsyncArgsExtra}) eq 'ARRAY' );
if ( $conf->{ClientCharset} ne "" ) { if ( $conf->{ClientCharset} ne "" && $conf->{ClientCharset} ne "utf8" )
{
push(@$rsyncArgs, "--iconv=utf8,$conf->{ClientCharset}"); push(@$rsyncArgs, "--iconv=utf8,$conf->{ClientCharset}");
} }
if ( $conf->{ClientTimeout} > 0 && $conf->{ClientTimeout} =~ /^\d+$/ ) { if ( $conf->{ClientTimeout} > 0 && $conf->{ClientTimeout} =~ /^\d+$/ ) {
push(@$rsyncArgs, "--timeout=$conf->{ClientTimeout}"); push(@$rsyncArgs, "--timeout=$conf->{ClientTimeout}");
} }
if ( $t->{XferMethod} eq "rsync" ) { if ( $t->{XferMethod} eq "rsync" ) {
unshift(@$rsyncArgs, "--rsync-path=$conf->{RsyncClientPath}") unshift(@$rsyncArgs, "--rsync-path=$conf->{RsyncClientPath}")
if ( $conf->{RsyncClientPath} ne "" ); if ( $conf->{RsyncClientPath} ne "" );
unshift(@$rsyncArgs, @{$conf->{RsyncSshArgs}}) unshift(@$rsyncArgs, @{$conf->{RsyncSshArgs}})
if ( ref($conf->{RsyncSshArgs}) eq 'ARRAY' ); if ( ref($conf->{RsyncSshArgs}) eq 'ARRAY' );
} else { } else {
if ( $conf->{RsyncdClientPort} != 873 ) { if ( $conf->{RsyncdClientPort} != 873 ) {
push(@$rsyncArgs, "--port=$conf->{RsyncdClientPort}"); push(@$rsyncArgs, "--port=$conf->{RsyncdClientPort}");
} }
} }
# #
# Merge variables into $rsyncArgs # Merge variables into $rsyncArgs
# #
$rsyncArgs = $bpc->cmdVarSubstitute($rsyncArgs, { $rsyncArgs = $bpc->cmdVarSubstitute(
host => $t->{host}, $rsyncArgs,
hostIP => $t->{hostIP}, {
client => $t->{client}, host => $t->{host},
shareNameOrig => $t->{shareName}, hostIP => $t->{hostIP},
shareName => $shareNamePath, client => $t->{client},
confDir => $conf->{ConfDir}, shareNameOrig => $t->{shareName},
sshPath => $conf->{SshPath}, shareName => $shareNamePath,
}); confDir => $conf->{ConfDir},
sshPath => $conf->{SshPath},
}
);
if ( $t->{XferMethod} eq "rsync" ) { if ( $t->{XferMethod} eq "rsync" ) {
my $shareNameSlash = $t->{shareNameSlash}; my $shareNameSlash = $t->{shareNameSlash};
#from_to($shareNameSlash, "utf8", $conf->{ClientCharset}) #from_to($shareNameSlash, "utf8", $conf->{ClientCharset})
# if ( $conf->{ClientCharset} ne "" ); # if ( $conf->{ClientCharset} ne "" );
push(@$rsyncArgs, @fileList) if ( @fileList ); push(@$rsyncArgs, @fileList) if ( @fileList );
push(@$rsyncArgs, "$t->{hostIP}:$shareNameSlash", "/"); push(@$rsyncArgs, "$t->{hostIP}:$shareNameSlash", "/");
} else { } else {
my $pwFd; my $pwFd;
$t->{pwFile} = "$conf->{TopDir}/pc/$t->{client}/.rsyncdpw$$"; $t->{pwFile} = "$conf->{TopDir}/pc/$t->{client}/.rsyncdpw$$";
if ( !length($conf->{RsyncdPasswd}) ) { if ( !length($conf->{RsyncdPasswd}) ) {
$t->{XferLOG}->write(\"\$Conf{RsyncdPasswd} is empty; host's rsy ncd auth will fail\n"); $t->{XferLOG}->write(\"\$Conf{RsyncdPasswd} is empty; host's rsy ncd auth will fail\n");
skipping to change at line 400 skipping to change at line 410
binmode($pwFd); binmode($pwFd);
syswrite($pwFd, $conf->{RsyncdPasswd}); syswrite($pwFd, $conf->{RsyncdPasswd});
close($pwFd); close($pwFd);
push(@$rsyncArgs, "--password-file=$t->{pwFile}"); push(@$rsyncArgs, "--password-file=$t->{pwFile}");
} else { } else {
$t->{XferLOG}->write(\"Failed to open/create rsynd pw file $t->{ pwFile}\n"); $t->{XferLOG}->write(\"Failed to open/create rsynd pw file $t->{ pwFile}\n");
$t->{_errStr} = "Failed to open/create rsynd pw file $t->{pwFile }"; $t->{_errStr} = "Failed to open/create rsynd pw file $t->{pwFile }";
return; return;
} }
my $shareName = $shareNamePath; my $shareName = $shareNamePath;
#from_to($shareName, "utf8", $conf->{ClientCharset}) #from_to($shareName, "utf8", $conf->{ClientCharset})
# if ( $conf->{ClientCharset} ne "" ); # if ( $conf->{ClientCharset} ne "" );
push(@$rsyncArgs, @fileList) if ( @fileList ); push(@$rsyncArgs, @fileList) if ( @fileList );
push(@$rsyncArgs, push(@$rsyncArgs, "$conf->{RsyncdUserName}\@$t->{hostIP}::$shareName
"$conf->{RsyncdUserName}\@$t->{hostIP}::$shareName", ", "/");
"/");
} }
if ( $bpc->{PoolV3} ) { if ( $bpc->{PoolV3} ) {
unshift(@$rsyncArgs, unshift(@$rsyncArgs,
'--bpc-hardlink-max', $conf->{HardLinkMax} || 31999, '--bpc-hardlink-max', $conf->{HardLinkMax} || 31999,
'--bpc-v3pool-used', $conf->{PoolV3Enabled}, '--bpc-v3pool-used', $conf->{PoolV3Enabled},
); );
} }
my $inode0 = 1; my $inode0 = 1;
for ( my $i = 0 ; $i < @{$t->{backups}} ; $i++ ) { for ( my $i = 0 ; $i < @{$t->{backups}} ; $i++ ) {
$inode0 = $t->{backups}[$i]{inodeLast} + 1 if ( $inode0 <= $t->{back ups}[$i]{inodeLast} ); $inode0 = $t->{backups}[$i]{inodeLast} + 1 if ( $inode0 <= $t->{back ups}[$i]{inodeLast} );
} }
unshift(@$rsyncArgs, unshift(
'--bpc-top-dir', $conf->{TopDir}, @$rsyncArgs,
'--bpc-host-name', $t->{client}, '--bpc-top-dir', $conf->{TopDir}, # p
'--bpc-share-name', $t->{shareName}, erltidy protect
'--bpc-bkup-num', $t->{backups}[$t->{newBkupIdx}]{num}, '--bpc-host-name', $t->{client},
'--bpc-bkup-comp', $t->{backups}[$t->{newBkupIdx}]{compress}, '--bpc-share-name', $t->{shareName},
'--bpc-bkup-prevnum', defined($t->{lastBkupIdx}) ? $t->{backups}[$ '--bpc-bkup-num', $t->{backups}[$t->{newBkupIdx}]{num},
t->{lastBkupIdx}]{num} : -1, '--bpc-bkup-comp', $t->{backups}[$t->{newBkupIdx}]{compress},
'--bpc-bkup-prevcomp', defined($t->{lastBkupIdx}) ? $t->{backups}[$ '--bpc-bkup-prevnum', defined($t->{lastBkupIdx}) ? $t->{backups}[$t
t->{lastBkupIdx}]{compress} : -1, ->{lastBkupIdx}]{num} : -1,
'--bpc-bkup-inode0', $inode0, '--bpc-bkup-prevcomp', defined($t->{lastBkupIdx}) ? $t->{backups}[$t
->{lastBkupIdx}]{compress} : -1,
'--bpc-bkup-inode0', $inode0,
'--bpc-log-level', $conf->{XferLogLevel},
'--bpc-attrib-new', '--bpc-attrib-new',
'--bpc-log-level', $conf->{XferLogLevel},
); );
} }
$logMsg .= " (client path $shareNamePath)" if ( $t->{shareName} ne $shareNam ePath ); $logMsg .= " (client path $shareNamePath)" if ( $t->{shareName} ne $shareNam ePath );
#from_to($args->{shareName}, "utf8", $conf->{ClientCharset}) #from_to($args->{shareName}, "utf8", $conf->{ClientCharset})
# if ( $conf->{ClientCharset} ne "" ); # if ( $conf->{ClientCharset} ne "" );
if ( $conf->{RsyncBackupPCPath} eq "" || !-x $conf->{RsyncBackupPCPath} ) { if ( $conf->{RsyncBackupPCPath} eq "" || !-x $conf->{RsyncBackupPCPath} ) {
$t->{_errStr} = "\$Conf{RsyncBackupPCPath} is set to $conf->{RsyncBackup $t->{_errStr} =
PCPath}, which isn't a valid executable"; "\$Conf{RsyncBackupPCPath} is set to $conf->{RsyncBackupPCPath}, which
isn't a valid executable";
return; return;
} }
$rsyncCmd = [$conf->{RsyncBackupPCPath}, @$rsyncArgs]; $rsyncCmd = [$conf->{RsyncBackupPCPath}, @$rsyncArgs];
my $rsyncFd; my $rsyncFd;
if ( !defined($t->{xferPid} = open($rsyncFd, "-|")) ) { if ( !defined($t->{xferPid} = open($rsyncFd, "-|")) ) {
$t->{_errStr} = "Can't fork to run $conf->{RsyncBackupPCPath}"; $t->{_errStr} = "Can't fork to run $conf->{RsyncBackupPCPath}";
return; return;
} }
$t->{rsyncFd} = $rsyncFd; $t->{rsyncFd} = $rsyncFd;
if ( !$t->{xferPid} ) { if ( !$t->{xferPid} ) {
# #
# This is the rsync child. We capture both stdout # This is the rsync child. We capture both stdout
# and stderr to put into the XferLOG file. # and stderr to put into the XferLOG file.
# #
setpgrp 0,0; setpgrp 0, 0;
close(STDERR); close(STDERR);
open(STDERR, ">&STDOUT"); open(STDERR, ">&STDOUT");
# #
# Run the $conf->{RsyncBackupPCPath} command # Run the $conf->{RsyncBackupPCPath} command
# #
print("This is the rsync child about to exec $conf->{RsyncBackupPCPath}\ n"); print("This is the rsync child about to exec $conf->{RsyncBackupPCPath}\ n");
$bpc->cmdExecOrEval($rsyncCmd); $bpc->cmdExecOrEval($rsyncCmd);
print("cmdExecOrEval failed $?\n"); print("cmdExecOrEval failed $?\n");
# should not be reached, but just in case... # should not be reached, but just in case...
$t->{_errStr} = "Can't exec @$rsyncCmd)"; $t->{_errStr} = "Can't exec @$rsyncCmd)";
return; return;
} }
my $str = $bpc->execCmd2ShellCmd(@$rsyncCmd); my $str = $bpc->execCmd2ShellCmd(@$rsyncCmd);
#from_to($str, $conf->{ClientCharset}, "utf8") #from_to($str, $conf->{ClientCharset}, "utf8")
# if ( $conf->{ClientCharset} ne "" ); # if ( $conf->{ClientCharset} ne "" );
$t->{XferLOG}->write(\"Running: $str\n"); $t->{XferLOG}->write(\"Running: $str\n");
$t->{_errStr} = undef; $t->{_errStr} = undef;
return $logMsg; return $logMsg;
} }
sub run sub run
{ {
my($t) = @_; my($t) = @_;
my $conf = $t->{conf}; my $conf = $t->{conf};
my $bpc = $t->{bpc}; my $bpc = $t->{bpc};
alarm(0); alarm(0);
while ( 1 ) { while ( 1 ) {
my($mesg, $done); my($mesg, $done);
if ( sysread($t->{rsyncFd}, $mesg, 32768) <= 0 ) { if ( sysread($t->{rsyncFd}, $mesg, 32768) <= 0 ) {
next if ( $!{EINTR} ); next if ( $!{EINTR} );
if ( !close($t->{rsyncFd}) ) { if ( !close($t->{rsyncFd}) ) {
# #
# rsync exits with the RERR_* codes in errcode.h. Exit codes 23 , 24, 25 are minor (ie: some # rsync exits with the RERR_* codes in errcode.h. Exit codes 23 , 24, 25 are minor (ie: some
# error in transfer, but not fatal). Other non-zero exit codes are considered failures. # error in transfer, but not fatal). Other non-zero exit codes are considered failures.
# #
$t->{lastOutputLine} = $t->{lastErrorLine} if ( defined($t->{las tErrorLine}) ); $t->{lastOutputLine} = $t->{lastErrorLine} if ( defined($t->{las tErrorLine}) );
my $exitCode = $? >> 8; my $exitCode = $? >> 8;
if ( $exitCode == 23 || $exitCode == 24 || $exitCode == 25 ) { if ( $exitCode == 23 || $exitCode == 24 || $exitCode == 25 ) {
$t->{rsyncOut} .= "rsync_bpc exited with benign status $exit Code ($?)\n"; $t->{rsyncOut} .= "rsync_bpc exited with benign status $exit Code ($?)\n";
$t->{rsyncOut} .=
"That means the client rsync had errors on some files. Pl
ease check the XferLOG.\n";
$t->{rsyncOut} .=
"It likely means that rsync's delete cleanup (which delete
s files on the backup\n";
$t->{rsyncOut} .=
"server that are no longer on the client) was skipped. Yo
u should fix the error(s)\n";
$t->{rsyncOut} .= "that rsync can run cleanly. You can also
specify the --ignore-errors option\n";
$t->{rsyncOut} .=
"which will still do the delete even if there are rsync er
rors, but do that with caution.\n";
$t->{xferOK} = 1; $t->{xferOK} = 1;
$t->{stats}{xferErrs}++; $t->{stats}{xferErrs}++;
} else { } else {
$t->{rsyncOut} .= "rsync_bpc exited with fatal status $exitC ode ($?) ($t->{lastOutputLine})\n"; $t->{rsyncOut} .= "rsync_bpc exited with fatal status $exitC ode ($?) ($t->{lastOutputLine})\n";
$t->{xferOK} = 0; $t->{xferOK} = 0;
$t->{stats}{xferErrs}++; $t->{stats}{xferErrs}++;
} }
} else { } else {
$t->{xferOK} = 1; $t->{xferOK} = 1;
} }
$done = 1; $done = 1;
} else { } else {
$t->{rsyncOut} .= $mesg; $t->{rsyncOut} .= $mesg;
} }
while ( $t->{rsyncOut} =~ /(.*?)[\n\r]+(.*)/s ) { while ( $t->{rsyncOut} =~ /(.*?)[\n\r]+(.*)/s ) {
$_ = $1; $_ = $1;
$t->{rsyncOut} = $2; $t->{rsyncOut} = $2;
# #
# refresh our inactivity alarm # refresh our inactivity alarm
skipping to change at line 528 skipping to change at line 550
my $fileName = $4; my $fileName = $4;
if ( $changes =~ /^\./ ) { if ( $changes =~ /^\./ ) {
$t->{logInfo}{$fileName}{seqNum} = ++$t->{logInfoSeq}; $t->{logInfo}{$fileName}{seqNum} = ++$t->{logInfoSeq};
push(@{$t->{logInfo}{$fileName}{status}}, "same"); push(@{$t->{logInfo}{$fileName}{status}}, "same");
} }
if ( $type eq "del." ) { if ( $type eq "del." ) {
$t->{logInfo}{$fileName}{seqNum} = ++$t->{logInfoSeq}; $t->{logInfo}{$fileName}{seqNum} = ++$t->{logInfoSeq};
push(@{$t->{logInfo}{$fileName}{status}}, "del"); push(@{$t->{logInfo}{$fileName}{status}}, "del");
} }
s/^log: //; s/^log: //;
push(@{$t->{logSave}}, push(
{ @{$t->{logSave}},
mesg => $_, {
type => $type, mesg => $_,
fileName => $fileName, type => $type,
}); fileName => $fileName,
}
);
$t->logSaveFlush(); $t->logSaveFlush();
next; next;
} }
if ( /^IOdone:\s(\S*)\s(.*)/ ) { if ( /^IOdone:\s(\S*)\s(.*)/ ) {
my $status = $1; my $status = $1;
my $fileName = $2; my $fileName = $2;
$t->{logInfo}{$fileName}{seqNum} = ++$t->{logInfoSeq}; $t->{logInfo}{$fileName}{seqNum} = ++$t->{logInfoSeq};
push(@{$t->{logInfo}{$fileName}{status}}, $status); push(@{$t->{logInfo}{$fileName}{status}}, $status);
$t->{XferLOG}->write(\"$_\n") if ( $conf->{XferLogLevel} >= 6 ); $t->{XferLOG}->write(\"$_\n") if ( $conf->{XferLogLevel} >= 6 );
$t->logSaveFlush(); $t->logSaveFlush();
next; next;
} }
if ( /^__bpc_progress_fileCnt__ \d+/ ) { if ( /^__bpc_progress_fileCnt__ \d+/ ) {
print("$_\n") if ( !$t->{noProgressPrint} ); print("$_\n") if ( !$t->{noProgressPrint} );
$t->{XferLOG}->write(\"$_\n") if ( $conf->{XferLogLevel} >= 6 ); $t->{XferLOG}->write(\"$_\n") if ( $conf->{XferLogLevel} >= 6 );
next; next;
} }
if ( /^ERROR: / ) { if ( /^ERROR: / ) {
if ( /failed verification -- update discarded./ ) { if ( /failed verification -- update discarded./ ) {
$t->{xferBadFileCnt}++; $t->{xferBadFileCnt}++;
} }
$t->{stats}{xferErrs}++; $t->{stats}{xferErrs}++;
} }
if ( /^rsync error: / || /^rsync warning: / ) { if ( /^rsync error: / || /^rsync warning: / ) {
$t->{stats}{xferErrs}++; $t->{stats}{xferErrs}++;
} }
if ( /^IO error encountered -- skipping file deletion/ ) {
$t->{stats}{xferErrs}++;
}
if ( /^rsync: send_files failed to open / || /^file has vanished: / ) { if ( /^rsync: send_files failed to open / || /^file has vanished: / ) {
$t->{stats}{xferErrs}++; $t->{stats}{xferErrs}++;
} }
if ( /^IOrename:\s(\d+)\s(.*)/ ) { if ( /^IOrename:\s(\d+)\s(.*)/ ) {
my $oldName = substr($2, 0, $1); my $oldName = substr($2, 0, $1);
my $newName = substr($2, $1); my $newName = substr($2, $1);
$t->{logInfo}{$newName} = $t->{logInfo}{$oldName}; $t->{logInfo}{$newName} = $t->{logInfo}{$oldName};
delete($t->{logInfo}{$oldName}); delete($t->{logInfo}{$oldName});
$t->{XferLOG}->write(\"$_\n") if ( $conf->{XferLogLevel} >= 6 ); $t->{XferLOG}->write(\"$_\n") if ( $conf->{XferLogLevel} >= 6 );
$t->logSaveFlush(); $t->logSaveFlush();
next; next;
} }
if ( /^xferPids (\d+),(\d+)/ ) { if ( /^xferPids (\d+),(\d+)/ ) {
my $pidHandler = $t->{pidHandler}; my $pidHandler = $t->{pidHandler};
if ( ref($pidHandler) eq 'CODE' ) { if ( ref($pidHandler) eq 'CODE' ) {
&$pidHandler($1, $2); &$pidHandler($1, $2);
} else { } else {
$t->{XferLOG}->write(\"$_\n") if ( $conf->{XferLogLevel} >= 4 ); $t->{XferLOG}->write(\"$_\n") if ( $conf->{XferLogLevel} >= 4 );
} }
} }
if ( /^Done(Gen)?: (\d+) errors, (\d+) filesExist, (\d+) sizeExist, if (
(\d+) sizeExistComp, (\d+) filesTotal, (\d+) sizeTotal, (\d+) filesNew, (\d+) si /^Done(Gen)?: (\d+) errors, (\d+) filesExist, (\d+) sizeExist, (
zeNew, (\d+) sizeNewComp, (\d+) inode/ ) { \d+) sizeExistComp, (\d+) filesTotal, (\d+) sizeTotal, (\d+) filesNew, (\d+) siz
eNew, (\d+) sizeNewComp, (\d+) inode/
) {
$t->{stats}{xferErrs} += $2; $t->{stats}{xferErrs} += $2;
$t->{stats}{nFilesExist} += $3; $t->{stats}{nFilesExist} += $3;
$t->{stats}{sizeExist} += $4; $t->{stats}{sizeExist} += $4;
$t->{stats}{sizeExistComp} += $5; $t->{stats}{sizeExistComp} += $5;
$t->{stats}{nFilesTotal} += $6; $t->{stats}{nFilesTotal} += $6;
$t->{stats}{sizeTotal} += $7; $t->{stats}{sizeTotal} += $7;
$t->{stats}{nFilesNew} += $8; $t->{stats}{nFilesNew} += $8;
$t->{stats}{sizeNew} += $9; $t->{stats}{sizeNew} += $9;
$t->{stats}{sizeNewComp} += $10; $t->{stats}{sizeNewComp} += $10;
$t->{stats}{inode} = $11 if ( $t->{stats}{inode} < $11 ); $t->{stats}{inode} = $11 if ( $t->{stats}{inode} < $11 );
$t->{XferLOG}->write(\"$_\n"); $t->{XferLOG}->write(\"$_\n");
$t->{XferLOG}->write(\"Parsing done: nFilesTotal = $t->{stats}{n FilesTotal}\n") $t->{XferLOG}->write(\"Parsing done: nFilesTotal = $t->{stats}{n FilesTotal}\n")
if ( $conf->{XferLogLevel} >= 3 ); if ( $conf->{XferLogLevel} >= 3 );
$t->{fileCnt} = $t->{stats}{nFilesTotal}; $t->{fileCnt} = $t->{stats}{nFilesTotal};
$t->{byteCnt} = $t->{stats}{sizeTotal}; $t->{byteCnt} = $t->{stats}{sizeTotal};
next; next;
} }
# if ( /: \.\/(.*): Read error at byte / ) { # if ( /: \.\/(.*): Read error at byte / ) {
# my $badFile = $1; # my $badFile = $1;
# push(@{$t->{badFiles}}, { # push(@{$t->{badFiles}}, {
# share => $t->{shareName}, # share => $t->{shareName},
# file => $badFile # file => $badFile
# }); # });
# } # }
# from_to($_, $conf->{ClientCharset}, "utf8") # from_to($_, $conf->{ClientCharset}, "utf8")
# if ( $conf->{ClientCharset} ne "" ); # if ( $conf->{ClientCharset} ne "" )
;
$t->{lastOutputLine} = $_ if ( !/^\s+$/ && length($_) ); $t->{lastOutputLine} = $_ if ( !/^\s+$/ && length($_) );
$t->{lastErrorLine} = $_ if ( /^rsync_bpc: / || /^rsync error: / ); $t->{lastErrorLine} = $_ if ( /^rsync_bpc: / || /^rsync error: / );
$t->{XferLOG}->write(\"$_\n"); $t->{XferLOG}->write(\"$_\n");
} }
last if ( $done ); last if ( $done );
} }
unlink($t->{pwFile}) if ( length($t->{pwFile}) && -f $t->{pwFile} ); unlink($t->{pwFile}) if ( length($t->{pwFile}) && -f $t->{pwFile} );
unlink($t->{filesFrom}) if ( length($t->{filesFrom}) && -f $t->{filesFrom} ) ; unlink($t->{filesFrom}) if ( length($t->{filesFrom}) && -f $t->{filesFrom} ) ;
$t->logSaveFlush(1); $t->logSaveFlush(1);
$t->{lastOutputLine} = $t->{lastErrorLine} if ( defined($t->{lastErrorLine}) ); $t->{lastOutputLine} = $t->{lastErrorLine} if ( defined($t->{lastErrorLine}) );
# #
# Remove any rsyncTmp files in the backup directory # Remove any rsyncTmp files in the backup directory
# #
my $bkupDir = $t->{type} eq "restore" ? "$conf->{TopDir}/pc/$t->{bkupSrcHost my $bkupDir =
}/$t->{bkupSrcNum}" $t->{type} eq "restore"
: "$conf->{TopDir}/pc/$t->{client}/$t-> ? "$conf->{TopDir}/pc/$t->{bkupSrcHost}/$t->{bkupSrcNum}"
{backups}[$t->{newBkupIdx}]{num}"; : "$conf->{TopDir}/pc/$t->{client}/$t->{backups}[$t->{newBkupIdx}]{num}";
my $bkupDirEntries = BackupPC::DirOps::dirRead($bpc, $bkupDir); my $bkupDirEntries = BackupPC::DirOps::dirRead($bpc, $bkupDir);
my $pidRunning = {}; my $pidRunning = {};
if ( ref($bkupDirEntries) eq 'ARRAY' ) { if ( ref($bkupDirEntries) eq 'ARRAY' ) {
foreach my $e ( @$bkupDirEntries ) { foreach my $e ( @$bkupDirEntries ) {
next if ( $e->{name} !~ /^rsyncTmp\.(\d+)\.\d+\.\d+$/ ); next if ( $e->{name} !~ /^rsyncTmp\.(\d+)\.\d+\.\d+$/ );
my $pid = $1; my $pid = $1;
$pidRunning->{$pid} = kill(0, $pid) ? 1 : 0 if ( !defined($pidRunnin g->{$pid} ) ); $pidRunning->{$pid} = kill(0, $pid) ? 1 : 0 if ( !defined($pidRunnin g->{$pid}) );
next if ( $pidRunning->{$pid} ); next if ( $pidRunning->{$pid} );
$t->{XferLOG}->write(\"Removing rsync temporary file $bkupDir/$e->{na $t->{XferLOG}->write(\"Removing rsync temporary file $bkupDir/$e->{n
me}\n"); ame}\n");
unlink("$bkupDir/$e->{name}"); unlink("$bkupDir/$e->{name}");
} }
} }
if ( $t->{type} eq "restore" ) { if ( $t->{type} eq "restore" ) {
if ( $t->{xferOK} ) { if ( $t->{xferOK} ) {
return ( return ($t->{fileCnt}, $t->{byteCnt}, 0, undef,);
$t->{fileCnt},
$t->{byteCnt},
0,
undef,
);
} else { } else {
return ( return ($t->{fileCnt}, $t->{byteCnt}, $t->{stats}{xferErrs}, $t->{la
$t->{fileCnt}, stOutputLine},);
$t->{byteCnt},
$t->{stats}{xferErrs},
$t->{lastOutputLine},
);
} }
} else { } else {
$t->{xferErrCnt} = $t->{stats}{xferErrs}; $t->{xferErrCnt} = $t->{stats}{xferErrs};
return ( return (
$t->{stats}{xferErrs}, $t->{stats}{xferErrs}, $t->{stats}{nFilesExist}, $t->{stats}{si
$t->{stats}{nFilesExist}, zeExist},
$t->{stats}{sizeExist}, $t->{stats}{sizeExistComp}, $t->{stats}{nFilesTotal}, $t->{stats}{si
$t->{stats}{sizeExistComp}, zeTotal},
$t->{stats}{nFilesTotal}, $t->{stats}{nFilesNew}, $t->{stats}{sizeNew}, $t->{stats}{si
$t->{stats}{sizeTotal}, zeNewComp},
$t->{stats}{nFilesNew},
$t->{stats}{sizeNew},
$t->{stats}{sizeNewComp},
$t->{stats}{inode}, $t->{stats}{inode},
); );
} }
} }
sub errStr sub errStr
{ {
my($t) = @_; my($t) = @_;
return $t->{_errStr}; return $t->{_errStr};
} }
skipping to change at line 707 skipping to change at line 722
$t->{abortReason} = $reason; $t->{abortReason} = $reason;
if ( @xferPid ) { if ( @xferPid ) {
kill($t->{bpc}->sigName2num("INT"), $xferPid[0]); kill($t->{bpc}->sigName2num("INT"), $xferPid[0]);
} }
} }
sub logSaveFlush sub logSaveFlush
{ {
my($t, $all) = @_; my($t, $all) = @_;
my $change = 1; my $change = 1;
my $conf = $t->{conf}; my $conf = $t->{conf};
$all = 1 if ( $t->{type} eq "restore" ); $all = 1 if ( $t->{type} eq "restore" );
while ( $change && @{$t->{logSave}} ) { while ( $change && @{$t->{logSave}} ) {
$change = 0; $change = 0;
my $fileName = $t->{logSave}[0]{fileName}; my $fileName = $t->{logSave}[0]{fileName};
if ( defined($t->{logInfo}{$fileName}) || $all || @{$t->{logSave}} > 200 ) { if ( defined($t->{logInfo}{$fileName}) || $all || @{$t->{logSave}} > 200 ) {
my $mesg = sprintf(" %-6s %s", my $mesg = sprintf(" %-6s %s", shift(@{$t->{logInfo}{$fileName}{s
shift(@{$t->{logInfo}{$fileName}{status}}), tatus}}), $t->{logSave}[0]{mesg});
$t->{logSave}[0]{mesg});
delete($t->{logInfo}{$fileName}) if ( !@{$t->{logInfo}{$fileName}{st atus}} ); delete($t->{logInfo}{$fileName}) if ( !@{$t->{logInfo}{$fileName}{st atus}} );
shift(@{$t->{logSave}}); shift(@{$t->{logSave}});
#from_to($mesg, $conf->{ClientCharset}, "utf8") #from_to($mesg, $conf->{ClientCharset}, "utf8")
# if ( $conf->{ClientCharset} ne "" ); # if ( $conf->{ClientCharset} ne "" );
$t->{lastOutputLine} = $mesg if ( !/^\s+$/ && length($mesg) ); $t->{lastOutputLine} = $mesg if ( !/^\s+$/ && length($mesg) );
$t->{XferLOG}->write(\"$mesg\n"); $t->{XferLOG}->write(\"$mesg\n");
$change = 1; $change = 1;
} }
} }
if ( %{$t->{logInfo}} > 2000 ) { if ( %{$t->{logInfo}} > 2000 ) {
# #
# prune the fileName logInfo array if it gets too big # prune the fileName logInfo array if it gets too big
# #
my @info = sort { $t->{logInfo}{$a}{seqNum} <=> $t->{logInfo}{$b}{seqNum } } my @info = sort { $t->{logInfo}{$a}{seqNum} <=> $t->{logInfo}{$b}{seqNum } }
keys(%{$t->{logInfo}}); keys(%{$t->{logInfo}});
while ( @info > 500 ) { while ( @info > 500 ) {
my $fileName = shift(@info); my $fileName = shift(@info);
delete($t->{logInfo}{$fileName}); delete($t->{logInfo}{$fileName});
} }
} }
} }
1; 1;
 End of changes. 61 change blocks. 
147 lines changed or deleted 176 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)