* Added more options to server backup command: rather than just forcing
[BackupPC.git] / lib / BackupPC / Xfer / Rsync.pm
index 67e5296..934ce48 100644 (file)
@@ -11,7 +11,7 @@
 #   Craig Barratt  <cbarratt@users.sourceforge.net>
 #
 # COPYRIGHT
-#   Copyright (C) 2002-2003  Craig Barratt
+#   Copyright (C) 2002-2007  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 3.0.0, released 28 Jan 2007.
+# Version 3.2.0beta0, released 17 Jan 2009.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -41,6 +41,7 @@ use strict;
 use BackupPC::View;
 use BackupPC::Xfer::RsyncFileIO;
 use Encode qw/from_to encode/;
+use base qw(BackupPC::Xfer::Protocol);
 
 use vars qw( $RsyncLibOK $RsyncLibErr );
 
@@ -59,7 +60,7 @@ BEGIN {
         if ( $File::RsyncP::VERSION < 0.68 ) {
             $RsyncLibOK = 0;
             $RsyncLibErr = "File::RsyncP module version"
-                         . " ($File::RsyncP::VERSION) too old: need 0.68";
+                         . " ($File::RsyncP::VERSION) too old: need >= 0.68";
         } else {
             $RsyncLibOK = 1;
         }
@@ -71,46 +72,8 @@ sub new
     my($class, $bpc, $args) = @_;
 
     return if ( !$RsyncLibOK );
-    $args ||= {};
-    my $t = bless {
-        bpc       => $bpc,
-        conf      => { $bpc->Conf },
-        host      => "",
-        hostIP    => "",
-        shareName => "",
-        badFiles  => [],
-
-       #
-       # Various stats
-       #
-        byteCnt         => 0,
-       fileCnt         => 0,
-       xferErrCnt      => 0,
-       xferBadShareCnt => 0,
-       xferBadFileCnt  => 0,
-       xferOK          => 0,
-
-       #
-       # User's args
-       #
-        %$args,
-    }, $class;
-
-    return $t;
-}
-
-sub args
-{
-    my($t, $args) = @_;
-
-    foreach my $arg ( keys(%$args) ) {
-       $t->{$arg} = $args->{$arg};
-    }
-}
-
-sub useTar
-{
-    return 0;
+    my $t = BackupPC::Xfer::Protocol->new($bpc, $args);
+    return bless($t, $class);
 }
 
 sub start
@@ -129,6 +92,17 @@ sub start
     if ( $t->{type} eq "restore" ) {
         $rsyncClientCmd = $conf->{RsyncClientRestoreCmd};
        $rsyncArgs = $conf->{RsyncRestoreArgs};
+
+        #
+        # Merge variables into $rsyncArgs
+        #
+        $rsyncArgs = $bpc->cmdVarSubstitute($rsyncArgs, {
+                            host      => $t->{host},
+                            hostIP    => $t->{hostIP},
+                            client    => $t->{client},
+                            confDir   => $conf->{ConfDir},
+                        });
+
        my $remoteDir = "$t->{shareName}/$t->{pathHdrDest}";
        $remoteDir    =~ s{//+}{/}g;
         from_to($remoteDir, "utf8", $conf->{ClientCharset})
@@ -246,6 +220,23 @@ sub start
         # transferred, even though it is a full dump.
         #
        $rsyncArgs = $conf->{RsyncArgs};
+
+        #
+        # Add any additional rsync args
+        #
+       $rsyncArgs = [@$rsyncArgs, @{$conf->{RsyncArgsExtra}}]
+                        if ( ref($conf->{RsyncArgsExtra}) eq 'ARRAY' );
+
+        #
+        # Merge variables into $rsyncArgs
+        #
+        $rsyncArgs = $bpc->cmdVarSubstitute($rsyncArgs, {
+                            host      => $t->{host},
+                            hostIP    => $t->{hostIP},
+                            client    => $t->{client},
+                            confDir   => $conf->{ConfDir},
+                        });
+
        $rsyncArgs = [@$rsyncArgs, @fileList] if ( @fileList );
         $rsyncArgs = [@$rsyncArgs, "--ignore-times"]
                                     if ( $t->{type} eq "full" );
@@ -323,6 +314,9 @@ sub start
        pidHandler   => sub {
                            $t->{pidHandler}(@_);
                        },
+       completionPercent => sub {
+                           $t->{completionPercent}(@_);
+                       },
         clientCharset => $conf->{ClientCharset},
        fio          => BackupPC::Xfer::RsyncFileIO->new({
                            xfer       => $t,
@@ -413,7 +407,26 @@ sub run
            $t->{hostError} = $err;
            return;
        }
+        
+        #
+        # This is a hack.  To avoid wide chars we encode the arguments
+        # to utf8 byte streams, then to the client's local charset.
+        # The second conversion should really go in File::RsyncP, since
+        # it shouldn't be applied to in-line include/exclude arguments.
+        #
+        for ( my $i = 0 ; $i < @{$rs->{rsyncArgs}} ; $i++ ) {
+            $rs->{rsyncArgs}[$i] = encode('utf8', $rs->{rsyncArgs}[$i]);
+            from_to($rs->{rsyncArgs}[$i], 'utf8', $conf->{ClientCharset})
+                                    if ( $conf->{ClientCharset} ne "" );
+        }
+    
+       ##my $str = "RsyncArgsBefore: " . join(" ", @{$rs->{rsyncArgs}}) . "\n";
+        ##$t->{XferLOG}->write(\$str);
+
        $rs->serverStart($remoteSend, $remoteDirDaemon);
+
+       ##$str = "RsyncArgsAfter: " . join(" ", @{$rs->{rsyncArgs}}) . "\n";
+        ##$t->{XferLOG}->write(\$str);
     }
     my $shareNameSlash = $t->{shareNameSlash};
     from_to($shareNameSlash, "utf8", $conf->{ClientCharset})
@@ -480,11 +493,6 @@ sub abort
     return 1;
 }
 
-sub setSelectMask
-{
-    my($t, $FDreadRef) = @_;
-}
-
 sub errStr
 {
     my($t) = @_;
@@ -500,39 +508,4 @@ sub xferPid
     return ();
 }
 
-sub logMsg
-{
-    my($t, $msg) = @_;
-
-    push(@{$t->{_logMsg}}, $msg);
-}
-
-sub logMsgGet
-{
-    my($t) = @_;
-
-    return shift(@{$t->{_logMsg}});
-}
-
-#
-# Returns a hash ref giving various status information about
-# the transfer.
-#
-sub getStats
-{
-    my($t) = @_;
-
-    return { map { $_ => $t->{$_} }
-            qw(byteCnt fileCnt xferErrCnt xferBadShareCnt xferBadFileCnt
-               xferOK hostAbort hostError lastOutputLine)
-    };
-}
-
-sub getBadFiles
-{
-    my($t) = @_;
-
-    return @{$t->{badFiles}};
-}
-
 1;