- added $Conf{ClientNameAlias}, which allows the host name to be
[BackupPC.git] / lib / BackupPC / Xfer / Smb.pm
index 5bf0619..bfd367a 100644 (file)
@@ -29,7 +29,7 @@
 #
 #========================================================================
 #
-# Version 1.5.0, released 2 Aug 2002.
+# Version 2.0.0_CVS, released 18 Jan 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(@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 {
        #
@@ -106,43 +123,45 @@ sub start
        }
         if ( defined($conf->{BackupFilesOnly}{$t->{shareName}}) ) {
             foreach my $file ( @{$conf->{BackupFilesOnly}{$t->{shareName}}} ) {
-                $file =~ s/'/\\'/g;
-                $fileList .= "'$file' ";
+               push(@fileList, $file);
             }
         } 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 +193,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 +228,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,7 +254,10 @@ sub readOutput
         } elsif ( /^code 0 listing /
                     || /^code 0 opening /
                     || /^abandoning restore/i
-                    || /^Error: Looping in FIND_NEXT/i ) {
+                    || /^Error: Looping in FIND_NEXT/i
+                    || /^SUCCESS - 0/i
+                    || /^Call timed out: server did not respond/i
+                 ) {
             $t->{hostError} ||= $_;
         } elsif ( /smb: \\>/
                 || /^added interface/i