X-Git-Url: http://git.rot13.org/?p=BackupPC.git;a=blobdiff_plain;f=lib%2FBackupPC%2FXfer%2FSmb.pm;h=3f88c3c01f928aa21798fd7f899ca0e28a33af4d;hp=5bf0619917cdbcdef69da8b57b43a28304a91a8e;hb=5729095faa3ef12dc5d4f02538c3650ac81912ef;hpb=1ce7d1541ea1279aaa0a75c16986a3fd40b608ec diff --git a/lib/BackupPC/Xfer/Smb.pm b/lib/BackupPC/Xfer/Smb.pm index 5bf0619..3f88c3c 100644 --- a/lib/BackupPC/Xfer/Smb.pm +++ b/lib/BackupPC/Xfer/Smb.pm @@ -11,7 +11,7 @@ # Craig Barratt # # COPYRIGHT -# Copyright (C) 2001 Craig Barratt +# Copyright (C) 2001-2003 Craig Barratt # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -29,7 +29,7 @@ # #======================================================================== # -# Version 1.5.0, released 2 Aug 2002. +# Version 2.1.0_CVS, released 3 Jul 2003. # # See http://backuppc.sourceforge.net. # @@ -43,6 +43,7 @@ sub new { my($class, $bpc, $args) = @_; + $args ||= {}; my $t = bless { bpc => $bpc, conf => { $bpc->Conf }, @@ -58,30 +59,46 @@ sub new return $t; } +sub args +{ + my($t, $args) = @_; + + foreach my $arg ( keys(%$args) ) { + $t->{$arg} = $args->{$arg}; + } +} + +sub useTar +{ + return 1; +} + sub start { my($t) = @_; my $bpc = $t->{bpc}; my $conf = $t->{conf}; - my $I_option = $t->{hostIP} eq $t->{host} ? "" : " -I $t->{hostIP}"; - my($fileList, $optX, $smbClientCmd, $logMsg); + my $I_option = $t->{hostIP} eq $t->{host} ? [] : ['-I', $t->{hostIP}]; + my(@fileList, $X_option, $smbClientCmd, $logMsg); + my($timeStampFile); local(*SMB); # # First propagate the PASSWD setting # + $ENV{PASSWD} = $ENV{BPC_SMB_PASSWD} if ( defined($ENV{BPC_SMB_PASSWD}) ); $ENV{PASSWD} = $conf->{SmbSharePasswd} if ( defined($conf->{SmbSharePasswd}) ); if ( !defined($ENV{PASSWD}) ) { $t->{_errStr} = "passwd not set for smbclient"; return; } + if ( !defined($conf->{SmbClientPath}) || !-x $conf->{SmbClientPath} ) { + $t->{_errStr} = '$Conf{SmbClientPath} is not a valid executable'; + return; + } if ( $t->{type} eq "restore" ) { - $smbClientCmd = - "$conf->{SmbClientPath} '\\\\$t->{host}\\$t->{shareName}'" - . "$I_option -U '$conf->{SmbShareUserName}' -E -N -d 1" - . " $conf->{SmbClientArgs}" - . " -c 'tarmode full' -Tx -"; + $smbClientCmd = $conf->{SmbClientRestoreCmd}; $logMsg = "restore started for share $t->{shareName}"; } else { # @@ -104,45 +121,49 @@ sub start }; } } + $t->{fileIncludeHash} = {}; if ( defined($conf->{BackupFilesOnly}{$t->{shareName}}) ) { foreach my $file ( @{$conf->{BackupFilesOnly}{$t->{shareName}}} ) { - $file =~ s/'/\\'/g; - $fileList .= "'$file' "; + push(@fileList, $file); + $t->{fileIncludeHash}{$file} = 1; } } elsif ( defined($conf->{BackupFilesExclude}{$t->{shareName}}) ) { foreach my $file ( @{$conf->{BackupFilesExclude}{$t->{shareName}}} ) { - $file =~ s/'/\\'/g; - $fileList .= "'$file' "; + push(@fileList, $file); } # # Allow simple wildcards in exclude list by specifying "r" option. # - $optX = "rX"; + $X_option = "rX"; } if ( $t->{type} eq "full" ) { - $smbClientCmd = - "$conf->{SmbClientPath} '\\\\$t->{host}\\$t->{shareName}'" - . "$I_option -U '$conf->{SmbShareUserName}' -E -N -d 1" - . " $conf->{SmbClientArgs}" - . " -c 'tarmode full'" - . " -Tc$optX - $fileList"; + $smbClientCmd = $conf->{SmbClientFullCmd}; $logMsg = "full backup started for share $t->{shareName}"; } else { - my $timeStampFile = "$t->{outDir}/timeStamp.level0"; - open(LEV0, ">$timeStampFile") && close(LEV0); + $timeStampFile = "$t->{outDir}/timeStamp.level0"; + open(LEV0, ">", $timeStampFile) && close(LEV0); utime($t->{lastFull} - 3600, $t->{lastFull} - 3600, $timeStampFile); - $smbClientCmd = - "$conf->{SmbClientPath} '\\\\$t->{host}\\$t->{shareName}'" - . "$I_option -U '$conf->{SmbShareUserName}' -E -N -d 1" - . " $conf->{SmbClientArgs}" - . " -c 'tarmode full'" - . " -TcN$optX $timeStampFile - $fileList"; + $smbClientCmd = $conf->{SmbClientIncrCmd}; $logMsg = "incr backup started back to " . $bpc->timeStamp($t->{lastFull} - 3600, 0) . "for share $t->{shareName}"; } } + my $args = { + smbClientPath => $conf->{SmbClientPath}, + host => $t->{host}, + hostIP => $t->{hostIP}, + client => $t->{client}, + shareName => $t->{shareName}, + userName => $conf->{SmbShareUserName}, + fileList => \@fileList, + I_option => $I_option, + X_option => $X_option, + timeStampFile => $timeStampFile, + }; + $smbClientCmd = $bpc->cmdVarSubstitute($smbClientCmd, $args); + if ( !defined($t->{xferPid} = open(SMB, "-|")) ) { $t->{_errStr} = "Can't fork to run smbclient"; return; @@ -174,15 +195,16 @@ sub start open(STDOUT, ">&$t->{pipeWH}"); } # - # exec smbclient. + # Run smbclient. # - exec($smbClientCmd); + $bpc->cmdExecOrEval($smbClientCmd, $args); # should not be reached, but just in case... $t->{_errStr} = "Can't exec $conf->{SmbClientPath}"; return; } - $t->{XferLOG}->write(\"Running: $smbClientCmd\n"); - alarm($conf->{SmbClientTimeout}); + my $str = "Running: " . $bpc->execCmd2ShellCmd(@$smbClientCmd) . "\n"; + $t->{XferLOG}->write(\$str); + alarm($conf->{ClientTimeout}); $t->{_errStr} = undef; return $logMsg; } @@ -208,7 +230,7 @@ sub readOutput # # refresh our inactivity alarm # - alarm($conf->{SmbClientTimeout}); + alarm($conf->{ClientTimeout}); $t->{lastOutputLine} = $_ if ( !/^$/ ); # # This section is highly dependent on the version of smbclient. @@ -234,8 +256,27 @@ sub readOutput } elsif ( /^code 0 listing / || /^code 0 opening / || /^abandoning restore/i - || /^Error: Looping in FIND_NEXT/i ) { - $t->{hostError} ||= $_; + || /^Error: Looping in FIND_NEXT/i + || /^SUCCESS - 0/i + || /^Call timed out: server did not respond/i + || /^tree connect failed: ERRDOS - ERRnoaccess \(Access denied\.\)/ + || /^tree connect failed: NT_STATUS_BAD_NETWORK_NAME/ + ) { + if ( $t->{hostError} eq "" ) { + $t->{XferLOG}->write(\"This backup will fail because: $_\n"); + $t->{hostError} = $_; + } + } elsif ( /^NT_STATUS_ACCESS_DENIED listing (.*)/ + || /^ERRDOS - ERRnoaccess \(Access denied\.\) listing (.*)/ ) { + my $badDir = $1; + $badDir =~ s{\\}{/}g; + $badDir =~ s{/+}{/}g; + $badDir =~ s{/\*$}{}; + if ( $t->{hostError} eq "" + && ($badDir eq "" || $t->{fileIncludeHash}{$badDir}) ) { + $t->{XferLOG}->write(\"This backup will fail because: $_\n"); + $t->{hostError} ||= $_; + } } elsif ( /smb: \\>/ || /^added interface/i || /^tarmode is now/i @@ -274,7 +315,10 @@ sub readOutput my $badFile = $1; $badFile =~ s{\\}{/}g; $badFile =~ s{^/}{}; - push(@{$t->{badFiles}}, "$t->{shareName}/$badFile"); + push(@{$t->{badFiles}}, { + share => $t->{shareName}, + file => $badFile + }); } } } @@ -299,7 +343,7 @@ sub xferPid { my($t) = @_; - return $t->{xferPid}; + return ($t->{xferPid}); } sub logMsg