--- /dev/null
+#============================================================= -*-perl-*-
+#
+# BackupPC::Xfer::BackupPCd package
+#
+# DESCRIPTION
+#
+# This library defines a BackupPC::Xfer::BackupPCd class for managing
+# the backuppcd-based transport of backup data from the client.
+#
+# AUTHOR
+# Craig Barratt <cbarratt@users.sourceforge.net>
+#
+# COPYRIGHT
+# Copyright (C) 2006 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+#========================================================================
+#
+# Version 3.0.0alpha, released 23 Jan 2006.
+#
+# See http://backuppc.sourceforge.net.
+#
+#========================================================================
+
+package BackupPC::Xfer::BackupPCd;
+
+use strict;
+
+sub new
+{
+ my($class, $bpc, $args) = @_;
+
+ $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;
+}
+
+sub start
+{
+ my($t) = @_;
+ my $bpc = $t->{bpc};
+ my $conf = $t->{conf};
+ my(@fileList, $bpcdCmd, $bpcdArgs, $logMsg, $incrDate,
+ $incrFlag, $restoreDir);
+
+ #
+ # We add a slash to the share name we pass to bpcd
+ #
+ ($t->{shareNameSlash} = "$t->{shareName}/") =~ s{//+$}{/};
+
+ if ( $t->{type} eq "restore" ) {
+ $bpcdCmd = $conf->{BackupPCdRestoreCmd};
+ $restoreDir = "$t->{shareName}/$t->{pathHdrDest}";
+ $restoreDir =~ s{//+}{/}g;
+ $logMsg = "restore started below directory $t->{shareName}"
+ . " to host $t->{host}";
+ } else {
+ if ( $t->{type} eq "full" ) {
+ if ( $t->{partialNum} ) {
+ $logMsg = "full backup started for directory $t->{shareName};"
+ . " updating partial $t->{partialNum}";
+ } else {
+ $logMsg = "full backup started for directory $t->{shareName}";
+ }
+ $incrFlag = 0;
+ } else {
+ #
+ # TODO: fix this message - just refer to the backup, not time?
+ #
+ $incrDate = $bpc->timeStamp($t->{lastFull} - 3600, 1);
+ $logMsg = "incr backup started back to $incrDate for directory"
+ . " $t->{shareName}";
+ $incrFlag = 1;
+ }
+ $bpcdCmd = $conf->{BackupPCdCmd};
+ }
+
+ #
+ # Merge variables into $bpcdCmd
+ #
+ my $args = {
+ host => $t->{host},
+ hostIP => $t->{hostIP},
+ client => $t->{client},
+ shareName => $t->{shareName},
+ shareNameSlash => $t->{shareNameSlash},
+ restoreDir => $restoreDir,
+ bpcdPath => $conf->{BackupPCdPath},
+ sshPath => $conf->{SshPath},
+ topDir => $bpc->TopDir(),
+ poolDir => $t->{compress} ? $bpc->{CPoolDir} : $bpc->{PoolDir},
+ poolCompress => $t->{compress} + 0,
+ incrFlag => $incrFlag,
+ };
+ $bpcdCmd = $bpc->cmdVarSubstitute($bpcdCmd, $args);
+
+ $t->{bpcdCmd} = $bpcdCmd;
+
+ delete($t->{_errStr});
+
+ return $logMsg;
+}
+
+sub run
+{
+ my($t) = @_;
+ my $bpc = $t->{bpc};
+ my $conf = $t->{conf};
+ my($remoteSend, $remoteDir, $remoteDirDaemon);
+ my $error;
+ my $stats;
+
+ # NO: alarm($conf->{ClientTimeout});
+
+ #
+ # Run backupcd command
+ #
+ my $str = "Running: "
+ . $t->{bpc}->execCmd2ShellCmd(@{$t->{bpcdCmd}})
+ . "\n";
+ $t->{XferLOG}->write(\$str);
+
+ #
+ #
+ #
+
+ $bpc->cmdSystemOrEvalLong($t->{bpcdCmd},
+ sub {
+ # write stdout to the XferLOG
+ my($str) = @_;
+ $t->{XferLOG}->write(\$str);
+ },
+ 0, # also catch stderr
+ $t->{pidHandler}
+ );
+
+ #
+ # TODO: generate sensible stats by parsing the output of
+ # backuppcd. Get error and fail status.
+ #
+ if ( !defined($error) && defined($stats) ) {
+ $t->{xferOK} = 1;
+ } else {
+ $t->{xferOK} = 0;
+ }
+ $t->{xferErrCnt} = $stats->{errorCnt};
+ $t->{byteCnt} = $stats->{TotalFileSize};
+ $t->{fileCnt} = $stats->{TotalFileCnt};
+ my $str = "Done: $t->{fileCnt} files, $t->{byteCnt} bytes\n";
+ $t->{XferLOG}->write(\$str);
+
+ $t->{hostError} = $error if ( defined($error) );
+
+ if ( $t->{type} eq "restore" ) {
+ return (
+ $t->{fileCnt},
+ $t->{byteCnt},
+ 0,
+ 0
+ );
+ } else {
+ return (
+ 0,
+ $stats->{ExistFileCnt},
+ $stats->{ExistFileSize},
+ $stats->{ExistFileCompSize},
+ $stats->{TotalFileCnt},
+ $stats->{TotalFileSize}
+ );
+ }
+}
+
+sub abort
+{
+ my($t, $reason) = @_;
+
+ # TODO
+ return 1;
+}
+
+sub errStr
+{
+ my($t) = @_;
+
+ return $t->{_errStr};
+}
+
+sub xferPid
+{
+ my($t) = @_;
+
+ return ();
+}
+
+#
+# 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;