cd somewhere/BackupPC
cvs -z3 -d:pserver:anonymous@backuppc.cvs.sourceforge.net:/cvsroot/backuppc co BackupPC
-* To fetch the CVS code tagged at a particular release (eg: v2.1.2):
+* To fetch the CVS code tagged at a particular release (eg: v3.2.0):
- cvs -z3 -d:pserver:anonymous@backuppc.cvs.sourceforge.net:/cvsroot/backuppc co -r v2_1_2 BackupPC
+ cvs -z3 -d:pserver:anonymous@backuppc.cvs.sourceforge.net:/cvsroot/backuppc co -r v3_2_0 BackupPC
Building an installable release from the CVS source:
---------------------------------------------------
-* Edit makeDist and set the version number and release date
-
* Update makeDist and configure.pl if you add any new files to the release.
-* Run makeDist. makeDist merges the version number, release date and turns
- all the library paths etc back into the symbolic form (eg: __INSTALLDIR__)
+* Run makeDist, using arguments to specify the release date and version:
+
+ makeDist --releasedate '29 Mar 2009' --version 3.2.0beta0
+
+ makeDist merges the version number, release date and turns all the
+ library paths etc back into the symbolic form (eg: __INSTALLDIR__)
so that configure.pl will do the right thing.
- Often the language files are not up to date, and makeDist exits after
- complaining about the lang files being inconsistent. Use the -l option
- to turn off that checking.
+ Sometime the language files are not up to date, and makeDist exits
+ after complaining about the lang files being inconsistent. Use
+ the --nolangCheck option to turn off that checking.
+
+ By default makeDist does a syntax check on all the source files.
+ If you want to skip that you can use tune --nosyntaxCheck option, eg:
+
+ makeDist --nolangCheck --nosyntaxCheck --releasedate '29 Mar 2009' --version 3.2.0beta0
-* You should now have a sub-directory dist/BackupPC-version containing
- the release and a tar ball dist/BackupPC-VERSION.tar.gz. The tar
- ball can be copied, extracted and installed using configure.pl
+* You should now have a sub-directory dist/BackupPC-VERSION containing
+ the release and a tar ball dist/BackupPC-VERSION.tar.gz. You can
+ cd to dist/BackupPC-VERSION and run configure.pl from there, or
+ the tar ball can be copied, extracted and installed using configure.pl
like any BackupPC release.
takes more than 24 hours (ie: when the next one is meant to
start). Reported by Tony Schreiner.
-* Added server message for queuing a single host based on patch
- submitted by Joe Digilio.
+* Added more options to server backup command: rather than just forcing
+ an incremental or full backup, a regular (auto) backup can be queued
+ (ie: do nothing/incr/full based on schedule), as well as doing just
+ an incremental or full or nothing based on the client schedule.
+ Based on patches submitted by Joe Digilio.
* Modified lib/BackupPC/CGI/RSS.pm to replace \n with \r\n in the RSS
http response headers. Patch submitted by Thomas Eckhardt.
* Changed bin/BackupPC_dump to not ping or lookup the host if
$Conf{BackupsDisable} is set. Requested by John Rouillard.
+* Changed BackupPC_tarCreate to disable output of final nulls in
+ tar archive when -l or -L option is used. Reported by John
+ Rouillard.
+
* Added error check in BackupPC::Xfer::RsyncFileIO after call to
BackupPC::Xfer::RsyncDigest->digestStart(), reported by Jeff
Kosowsky.
+* Added variable substitution for host, confDir, client in
+ RsyncArgs, and also added option RsyncArgsExtra to allow
+ more easy customization of RsyncArgs on a per-client basis.
+ Proposed (with patch) by Raman Gupta.
+
+* Added Xfer error column to the host summary table in the CGI
+ interface. Based on patch submitted by Jan Kratochvíl.
+
* Minor fix to sprintf arguments in BackupPC::Attrib, reported by
Jonathan Kamens.
* Updated BackupPC.pod for $Conf{BackupsDisable}, reported by
Nils Breunese.
+* Added alternate freebsd-backuppc2 init.d script that is
+ more compact. Submitted by Dan Niles.
+
* Minor updates to lib/BackupPC/Lang/fr.pm from Nicolas STRANSKY
applied by GFK, and also from Vincent Fleuranceau.
#
my $pid;
defined($pid = fork) or die("Can't fork: $!");
- exit if( $pid ); # parent exits
+ exit if ( $pid ); # parent exits
POSIX::setsid();
defined($pid = fork) or die("Can't fork: $!");
push(@deferUserQueue, $req);
next;
}
- push(@args, $req->{doFull} ? "-f" : "-i")
- if (( !$req->{restore} ) && ( !$req->{archive} ));
$UserQueueOn{$req->{host}} = 0;
} elsif ( $nJobs < $Conf{MaxBackups}
&& (@CmdQueue + $nJobs)
} else {
$progName = "BackupPC_dump";
$type = "backup";
- push(@args, "-d") if ( $req->{dhcp} );
+ push(@args, "-I") if ( $req->{backupType} eq "autoIncr" );
+ push(@args, "-F") if ( $req->{backupType} eq "autoFull" );
+ push(@args, "-i") if ( $req->{backupType} eq "doIncr" );
+ push(@args, "-f") if ( $req->{backupType} eq "doFull" );
+ push(@args, "-d") if ( $req->{backupType} eq "dhcpPoll" );
push(@args, "-e") if ( $req->{dumpExpire} );
push(@args, $host);
}
QueueAllPCs();
} elsif ( $cmd =~ /^BackupPC_nightly run$/ ) {
$RunNightlyWhenIdle = 1;
- } elsif ( $cmd =~ /^queue (\S+)$/ ) {
- $host = $1;
- $host = $bpc->uriUnesc($host);
- if ( !defined($Hosts->{$host}) ) {
- print(LOG $bpc->timeStamp,
- "User requested backup of unknown host $host\n");
- $reply = "error: unknown host $host";
- } else {
- if ( QueueOnePC($host) ) {
- print(LOG $bpc->timeStamp,
- "Disk too full ($Info{DUlastValue}%); skipped 1 host\n");
- $Info{DUDailySkipHostCnt}++;
- $reply = "error: disk too full to queue $host";
- } else {
- print(LOG $bpc->timeStamp, "Host $host queued by user.\n");
- $reply = "ok: $host queued";
- }
- }
} elsif ( $cmd =~ /^backup (\S+)\s+(\S+)\s+(\S+)\s+(\S+)/ ) {
- my $hostIP = $1;
- $host = $2;
- my $user = $3;
- my $doFull = $4;
- $host = $bpc->uriUnesc($host);
- $hostIP = $bpc->uriUnesc($hostIP);
+ my $hostIP = $1;
+ $host = $2;
+ my $user = $3;
+ my $backupType = $4;
+ $host = $bpc->uriUnesc($host);
+ $hostIP = $bpc->uriUnesc($hostIP);
if ( !defined($Hosts->{$host}) ) {
print(LOG $bpc->timeStamp,
"User $user requested backup of unknown host"
. " $host\n");
$reply = "error: unknown host $host";
} else {
- print(LOG $bpc->timeStamp,
- "User $user requested backup of $host"
- . " ($hostIP)\n");
- if ( $BgQueueOn{$hostIP} ) {
- @BgQueue = grep($_->{host} ne $hostIP, @BgQueue);
- $BgQueueOn{$hostIP} = 0;
- }
- if ( $UserQueueOn{$hostIP} ) {
- @UserQueue = grep($_->{host} ne $hostIP, @UserQueue);
- $UserQueueOn{$hostIP} = 0;
+ #
+ # Handle numeric backupType for backward compatibility
+ # (technically -1 is a new feature for auto)
+ #
+ $backupType = 'auto' if ( $backupType eq '-1' );
+ $backupType = 'doIncr' if ( $backupType eq '0' );
+ $backupType = 'doFull' if ( $backupType eq '1' );
+ if ( $backupType !~ /^doIncr|doFull|autoIncr|autoFull|auto$/i ) {
+ $reply = "error: unknown backup type $backupType";
+ } else {
+ print(LOG $bpc->timeStamp,
+ "User $user requested backup of $host"
+ . " ($hostIP)\n");
+ if ( $BgQueueOn{$hostIP} ) {
+ @BgQueue = grep($_->{host} ne $hostIP, @BgQueue);
+ $BgQueueOn{$hostIP} = 0;
+ }
+ if ( $UserQueueOn{$hostIP} ) {
+ @UserQueue = grep($_->{host} ne $hostIP, @UserQueue);
+ $UserQueueOn{$hostIP} = 0;
+ }
+ my $status = QueueOnePC($host, $hostIP, $user, 'user', $backupType);
+ if ( $status == 0 ) {
+ $reply = "ok: requested backup of $host ($backupType)";
+ } elsif ( $status == 1 ) {
+ #should never see this we just dequeued it
+ $reply = "warning: $host was already queued."
+ . " Ignoring this request";
+ } elsif ( $status == 2 ) {
+ print(LOG $bpc->timeStamp,
+ "Disk too full ($Info{DUlastValue}%)."
+ . " Not queueing backup of $host\n");
+ $reply = "error: disk too full ($Info{DUlastValue}%)";
+ $Info{DUDailySkipHostCnt}++;
+ } elsif ( $status == 3 ) {
+ # should never reach this because
+ # it's set to "user" above
+ $reply = "error: unknown queue name";
+ } else {
+ $reply = "error: unknown queue status $status";
+ if ( $BgQueueOn{$hostIP} || $UserQueueOn{$hostIP} ) {
+ $reply .= ". Host is queued.";
+ } else {
+ $reply .= ". Host is not queued.";
+ }
+ }
}
- unshift(@UserQueue, {
- host => $hostIP,
- user => $user,
- reqTime => time,
- doFull => $doFull,
- userReq => 1,
- dhcp => $hostIP eq $host ? 0 : 1,
- });
- $UserQueueOn{$hostIP} = 1;
- $reply = "ok: requested backup of $host";
}
} elsif ( $cmd =~ /^archive (\S+)\s+(\S+)\s+(\S+)/ ) {
my $user = $1;
} else {
unshift(@UserQueue, {
host => $host,
- hostIP => $user,
+ user => $user,
reqFileName => $reqFileName,
reqTime => time,
dhcp => 0,
return $a cmp $b;
}
+#
+# Attempt to queue a host.
+# Returns 0 on success; 1 if host is already queued;
+# 2 if host was skipped; 3 on invalid queue name
+#
+# $host is the client's host name
+# $hostIP is usually the client's host name too, or IP address
+# if the user specified it in the manual backup command
+# $user is the user name, or BackupPC by default
+# $queue is which queue to use ("bg" by default)
+# $backupType is the backup type (doIncr|doFull|autoIncr|autoFull|auto|dhcpPoll)
+#
+# Note: starting in 3.2.0, the PC is queued even if it has a current
+# job running
+#
sub QueueOnePC
{
- my($host) = @_;
- my $skipped = 0;
+ my($host, $hostIP, $user, $queue, $backupType) = @_;
+ my $retVal = 0;
+ $user = "BackupPC" if ( $user eq '' );
+ $queue = "bg" if ( $queue eq '' && $user eq 'BackupPC' );
+ $backupType = "auto" if ( $backupType eq '' );
delete($Status{$host}{backoffTime})
if ( defined($Status{$host}{backoffTime})
- && $Status{$host}{backoffTime} < time );
- return if ( defined($Jobs{$host})
- || $BgQueueOn{$host}
- || $UserQueueOn{$host}
- || $CmdQueueOn{$host} );
+ && $Status{$host}{backoffTime} < time );
+ return 1 if ( $BgQueueOn{$host} || $UserQueueOn{$host} );
if ( $Hosts->{$host}{dhcp} ) {
$Status{$host}{dhcpCheckCnt}++;
if ( $RunNightlyWhenIdle ) {
# after the DHCP hosts has been detected on the network.
#
unshift(@BgQueue,
- {host => $host, user => "BackupPC", reqTime => time,
+ {host => $hostIP, user => $user, reqTime => time,
dhcp => 0, dumpExpire => 1});
$BgQueueOn{$host} = 1;
}
} else {
#
- # this is a fixed ip host: queue it
+ # this is a fixed ip host or DHCP ip address: queue it
#
if ( $Info{DUlastValue} > $Conf{DfMaxUsagePct} ) {
#
# BackupPC_dump will never run since we have exceeded
# the limit.
#
- $skipped = 1;
+ $retVal = 2;
unshift(@BgQueue,
- {host => $host, user => "BackupPC", reqTime => time,
- dhcp => $Hosts->{$host}{dhcp}, dumpExpire => 1});
- } else {
+ {host => $hostIP, user => $user, reqTime => time, dumpExpire => 1});
+ $BgQueueOn{$host} = 1;
+ } elsif( $queue eq 'bg' ) {
#
# Queue regular background backup
#
unshift(@BgQueue,
- {host => $host, user => "BackupPC", reqTime => time,
- dhcp => $Hosts->{$host}{dhcp}});
+ {host => $hostIP, user => $user, reqTime => time, backupType => $backupType});
+ $BgQueueOn{$host} = 1;
+ } elsif( $queue eq 'user' ) {
+ #
+ # Queue user backup
+ #
+ unshift(@UserQueue,
+ {host => $hostIP, user => $user, reqTime => time, backupType => $backupType});
+ $UserQueueOn{$host} = 1;
+ } else {
+ # unknown $queue type
+ $retVal = 3;
}
- $BgQueueOn{$host} = 1;
}
- return $skipped;
+ return $retVal;
}
#
my $nSkip = 0;
foreach my $host ( sort(HostSortCompare keys(%$Hosts)) ) {
- $nSkip += QueueOnePC($host);
- }
- if ( $nSkip ) {
- print(LOG $bpc->timeStamp,
- "Disk too full ($Info{DUlastValue}%); skipped $nSkip hosts\n");
- $Info{DUDailySkipHostCnt} += $nSkip;
+ $nSkip++ if ( QueueOnePC($host, $host, 'BackupPC', 'bg', 'auto') == 2 );
}
foreach my $dhcp ( @{$Conf{DHCPAddressRanges}} ) {
for ( my $i = $dhcp->{first} ; $i <= $dhcp->{last} ; $i++ ) {
my $ipAddr = "$dhcp->{ipAddrBase}.$i";
- next if ( defined($Jobs{$ipAddr})
- || $BgQueueOn{$ipAddr}
- || $UserQueueOn{$ipAddr}
- || $CmdQueueOn{$ipAddr} );
- #
- # this is a potential dhcp ip address (we don't know the
- # host name yet): queue it
- #
- unshift(@BgQueue,
- {host => $ipAddr, user => "BackupPC", reqTime => time,
- dhcp => 1});
- $BgQueueOn{$ipAddr} = 1;
+ $nSkip++ if ( QueueOnePC($ipAddr, $ipAddr, 'BackupPC', 'bg', 'dhcpPoll') == 2 );
}
}
+ if ( $nSkip ) {
+ print(LOG $bpc->timeStamp,
+ "Disk too full ($Info{DUlastValue}%); skipped $nSkip hosts\n");
+ $Info{DUDailySkipHostCnt} += $nSkip;
+ }
}
#
#
# DESCRIPTION
#
-# Usage: BackupPC_dump [-i] [-f] [-d] [-e] [-v] <client>
+# Usage: BackupPC_dump [-i] [-f] [-F] [-I] [-d] [-e] [-v] <client>
#
# Flags:
#
#
# -f Do a full dump, overriding any scheduling.
#
+# -I Do an increment dump if the regular schedule requires a
+# full or incremental, otherwise do nothing (a full is done
+# if no dumps have yet succeeded)
+#
+# -F Do a full dump if the regular schedule requires a
+# full or incremental, otherwise do nothing
+#
# -d Host is a DHCP pool address, and the client argument
# just an IP address. We lookup the NetBios name from
# the IP address.
$bpc->ChildInit();
my %opts;
-if ( !getopts("defiv", \%opts) || @ARGV != 1 ) {
- print("usage: $0 [-d] [-e] [-f] [-i] [-v] <client>\n");
+if ( !getopts("defivFI", \%opts) || @ARGV != 1 ) {
+ print("usage: $0 [-d] [-e] [-f] [-i] [-F] [-I] [-v] <client>\n");
exit(1);
}
if ( $ARGV[0] !~ /^([\w\.\s-]+)$/ ) {
print("$0: bad client name '$ARGV[0]'\n");
exit(1);
}
+if ( (defined($opts{f}) + defined($opts{i}) + defined($opts{F}) + defined($opts{I})) > 1 ) {
+ print("$0: exiting because you can only use one of -f, -i, -F, and -I\n");
+ exit(1);
+}
+
my $client = $1; # BackupPC's client name (might not be real host name)
my $hostIP; # this is the IP address
my $host; # this is the real host name
#
# Decide whether we do nothing, or a full or incremental backup.
#
+my $needs_full = (time - $lastFullTime > $Conf{FullPeriod} * 24 * 3600
+ && time - $lastIncrTime > $Conf{IncrPeriod} * 24 * 3600);
+my $needs_incr = (time - $lastIncrTime > $Conf{IncrPeriod} * 24 * 3600
+ && time - $lastFullTime > $Conf{IncrPeriod} * 24 * 3600);
+
if ( $lastFullTime == 0
|| $opts{f}
- || (!$opts{i} && (time - $lastFullTime > $Conf{FullPeriod} * 24*3600
- && time - $lastIncrTime > $Conf{IncrPeriod} * 24*3600)) ) {
+ || (!$opts{i} && !$opts{I} && $needs_full)
+ || ( $opts{F} && $needs_incr) ) {
$type = "full";
$incrLevel = 0;
$incrBaseBkupNum = $lastBkupNum;
-} elsif ( $opts{i} || (time - $lastIncrTime > $Conf{IncrPeriod} * 24*3600
- && time - $lastFullTime > $Conf{IncrPeriod} * 24*3600) ) {
+} elsif ( $opts{i}
+ || $needs_incr
+ || ($opts{I} && $needs_full) ) {
$type = "incr";
#
# For an incremental backup, figure out which level we should
#
#========================================================================
#
-# Version 3.1.0, released 25 Nov 2007.
+# Version 3.2.0beta0, released 17 Jan 2009.
#
# See http://backuppc.sourceforge.net.
#
archiveWriteHardLinks($fh);
}
-#
-# Finish with two null 512 byte headers, and then round out a full
-# block.
-#
-my $data = "\0" x ($tar_header_length * 2);
-TarWrite($fh, \$data);
-TarWrite($fh, undef);
+if ( !$opts{l} && !$opts{L} ) {
+ #
+ # Finish with two null 512 byte headers, and then round out a full
+ # block.
+ #
+ my $data = "\0" x ($tar_header_length * 2);
+ TarWrite($fh, \$data);
+ TarWrite($fh, undef);
+}
#
# print out totals if requested
# Arguments to rsync for backup. Do not edit the first set unless you
# have a thorough understanding of how File::RsyncP works.
#
-# Examples of additional arguments that should work are --exclude/--include,
-# eg:
-#
-# $Conf{RsyncArgs} = [
-# # original arguments here
-# '-v',
-# '--exclude', '/proc',
-# '--exclude', '*.tmp',
-# ];
-#
$Conf{RsyncArgs} = [
#
# Do not edit these!
# to enable checksum caching.
#
#'--checksum-seed=32761',
-
- #
- # Add additional arguments here
- #
];
+#
+# Additional arguments added to RsyncArgs. This can be used in
+# conbination with $Conf{RsyncArgs} to allow customization of
+# the rsync arguments on a part-client basis. The standard
+# arguments go in $Conf{RsyncArgs} and $Conf{RsyncArgsExtra}
+# can be set on a per-client basis.
+#
+# Examples of additional arguments that should work are --exclude/--include,
+# eg:
+#
+# $Conf{RsyncArgsExtra} = [
+# '--exclude', '/proc',
+# '--exclude', '*.tmp',
+# ];
+#
+# Both $Conf{RsyncArgs} and $Conf{RsyncArgsExtra} are subject
+# to the following variable substitutions:
+#
+# $client client name being backed up
+# $host host name (could be different from client name if
+# $Conf{ClientNameAlias} is set)
+# $hostIP IP address of host
+# $confDir configuration directory path
+#
+# This allows settings of the form:
+#
+# $Conf{RsyncArgsExtra} = [
+# '--exclude-from=$confDir/pc/$host.exclude',
+# ];
+#
+$Conf{RsyncArgsExtra} = [];
+
#
# Arguments to rsync for restore. Do not edit the first set unless you
# have a thorough understanding of how File::RsyncP works.
# is read-only), you should set $Conf{RsyncRestoreArgs} to undef and
# the corresponding CGI restore option will be removed.
#
+# $Conf{RsyncRestoreArgs} is subject to the following variable
+# substitutions:
+#
+# $client client name being backed up
+# $host host name (could be different from client name if
+# $Conf{ClientNameAlias} is set)
+# $hostIP IP address of host
+# $confDir configuration directory path
+#
+# Note: $Conf{RsyncArgsExtra} doesn't apply to $Conf{RsyncRestoreArgs}.
+#
$Conf{RsyncRestoreArgs} = [
#
# Do not edit these!
#
$Conf{FtpFollowSymlinks} = 0;
+#
+# Direct restore enabling for FTP.
+#
+# Currently set to 0 since restore functionality is incomplete.
+#
+$Conf{FtpRestoreEnabled} = 0;
+
###########################################################################
# Archive Configuration
# (can be overwritten in the per-PC log file)
RsyncdAuthRequired => 1,
RsyncCsumCacheVerifyProb => 1,
RsyncArgs => 1,
+ RsyncArgsExtra => 1,
RsyncRestoreArgs => 1,
RsyncClientCmd => 0,
RsyncClientRestoreCmd => 0,
FtpBlockSize => 1,
FtpPort => 1,
FtpTimeout => 1,
+ FtpFollowSymlinks => 1,
+ FtpRestoreEnabled => 1,
ArchiveDest => 1,
ArchiveComp => 1,
ArchivePar => 1,
printf("Making init.d scripts\n");
foreach my $init ( qw(gentoo-backuppc gentoo-backuppc.conf linux-backuppc
solaris-backuppc debian-backuppc freebsd-backuppc
- suse-backuppc slackware-backuppc ) ) {
+ freebsd-backuppc2 suse-backuppc slackware-backuppc ) ) {
InstallFile("init.d/src/$init", "init.d/$init", 0444);
}
=======
When configure.pl is run, the script freebsd-backuppc is created.
+An alternative more compact script is freebsd-backuppc2, submitted
+by Dan Niles.
-Copy this script to /usr/local/etc/rc.d/backuppc and make execuatble.
+Copy one of these scripts to /usr/local/etc/rc.d/backuppc and make
+execuatble.
Add the following line to /etc/rc.conf to enable BackupPC:
#
#========================================================================
#
-# Version 3.2.0, released 31 Dec 2008.
+# Version 3.2.0beta0, released 17 Jan 2009.
#
# See http://backuppc.sourceforge.net.
#
visible => sub { return $_[0]->{XferMethod} eq "ftp"; } },
{name => "FtpFollowSymlinks",
visible => sub { return $_[0]->{XferMethod} eq "ftp"; } },
-
+ {name => "FtpRestoreEnabled",
+ visible => sub { return $_[0]->{XferMethod} eq "ftp"; } },
+
+
### Archive Settings
{text => "CfgEdit_Title_Archive_Settings",
visible => sub { return $_[0]->{XferMethod} eq "archive"; } },
visible => sub { return $_[0]->{XferMethod} eq "rsyncd"; } },
{name => "RsyncArgs",
visible => sub { return $_[0]->{XferMethod} =~ /rsync/; } },
+ {name => "RsyncArgsExtra",
+ visible => sub { return $_[0]->{XferMethod} =~ /rsync/; } },
{name => "RsyncRestoreArgs",
visible => sub { return $_[0]->{XferMethod} =~ /rsync/; } },
#
#========================================================================
#
-# Version 3.2.0, released 31 Dec 2008.
+# Version 3.2.0beta0, released 17 Jan 2009.
#
# See http://backuppc.sourceforge.net.
#
use strict;
use BackupPC::CGI::Lib qw(:all);
+use BackupPC::Xfer;
use Data::Dumper;
use File::Path;
use Encode qw/decode_utf8/;
#
$bpc->ConfigRead($h);
%Conf = $bpc->Conf();
- my $cmd = $Conf{XferMethod} eq "smb" ? $Conf{SmbClientRestoreCmd}
- : $Conf{XferMethod} eq "tar" ? $Conf{TarClientRestoreCmd}
- : $Conf{XferMethod} eq "archive" ? undef
- : $Conf{RsyncRestoreArgs};
- if ( ref($cmd) eq "ARRAY" ? @$cmd : $cmd ne "" ) {
+ if ( BackupPC::Xfer::restoreEnabled( \%Conf ) ) {
#
# Direct restore is enabled
#
# Decide if option 1 (direct restore) is available based
# on whether the restore command is set.
#
- my $cmd = $Conf{XferMethod} eq "smb" ? $Conf{SmbClientRestoreCmd}
- : $Conf{XferMethod} eq "tar" ? $Conf{TarClientRestoreCmd}
- : $Conf{XferMethod} eq "archive" ? undef
- : $Conf{RsyncRestoreArgs};
- if ( !defined($cmd) ) {
+ unless ( BackupPC::Xfer::restoreEnabled( \%Conf ) ) {
ErrorExit(eval("qq{$Lang->{Restore_Options_for__host_Option1_disabled}}"));
}
#
#========================================================================
#
-# Version 3.1.0, released 25 Nov 2007.
+# Version 3.2.0beta0, released 29 Mar 2009.
#
# See http://backuppc.sourceforge.net.
#
foreach my $host ( GetUserHosts(1) ) {
my($fullDur, $incrCnt, $incrAge, $fullSize, $fullRate, $reasonHilite,
- $lastAge, $tempState, $tempReason);
+ $lastAge, $tempState, $tempReason, $lastXferErrors);
my($shortErr);
my @Backups = $bpc->BackupInfoRead($host);
my $fullCnt = $incrCnt = 0;
$incrTot += $incrCnt;
$fullSize = sprintf("%.2f", $fullSize / 1000);
$incrAge = " " if ( $incrAge eq "" );
+ $lastXferErrors = $Backups[@Backups-1]{xferErrs} if ( @Backups );
$reasonHilite = $Conf{CgiStatusHilightColor}{$Status{$host}{reason}}
|| $Conf{CgiStatusHilightColor}{$Status{$host}{state}};
if ( $Conf{BackupsDisable} == 1 ) {
<td align="center" class="border">$incrAge</td>
<td align="center" class="border">$lastAge</td>
<td align="center" class="border">$Lang->{$tempState}</td>
+ <td align="center" class="border">$lastXferErrors</td>
<td class="border">$Lang->{$tempReason}$shortErr</td></tr>
EOF
if ( @Backups == 0 ) {
#
#========================================================================
#
-# Version 3.2.0, released 31 Dec 2008.
+# Version 3.2.0beta0, released 17 Jan 2009.
#
# See http://backuppc.sourceforge.net.
#
emptyOk => 1,
child => "string",
},
+ RsyncArgsExtra => {
+ type => "list",
+ emptyOk => 1,
+ child => "string",
+ },
RsyncRestoreArgs => {
type => "list",
emptyOk => 1,
FtpPort => "integer",
FtpTimeout => "integer",
FtpFollowSymlinks => "boolean",
-
+ FtpRestoreEnabled => "boolean",
+
######################################################################
# Archive Configuration
######################################################################
RsyncdAuthRequired => "boolean",
RsyncCsumCacheVerifyProb => "boolean",
RsyncArgs => "boolean",
+ RsyncArgsExtra => "boolean",
RsyncRestoreArgs => "boolean",
RsyncClientCmd => "boolean",
RsyncClientPath => "boolean",
FtpBlockSize => "boolean",
FtpPort => "boolean",
FtpTimeout => "boolean",
+ FtpFollowSymlinks => "boolean",
+ FtpRestoreEnabled => "boolean",
ArchiveDest => "boolean",
ArchiveComp => "boolean",
ArchivePar => "boolean",
-#!/bin/perl
+#!/usr/bin/perl
#
# by Ralph Passgang <ralph@debianbase.de> (13.11.2006 for V3.0.0)
# by Ralph Passgang <ralph@debianbase.de> (30.06.2006 for V3.0.0)
<td align="center"> Alter (Tage) </td>
<td align="center"> Letzes Backup (Tage) </td>
<td align="center"> Status </td>
+ <td align="center"> #Xfer Fehler </td>
<td align="center"> Letzte Aktion </td></tr>
\$strGood
</table>
<td align="center"> Alter (Tage) </td>
<td align="center"> Letztes Backup (Tage) </td>
<td align="center"> Status </td>
+ <td align="center"> #Xfer Fehler </td>
<td align="center"> Letzter Versuch </td></tr>
\$strNone
</table>
$Lang{CfgEdit_Title_User_Config_Editing} = "Benutzerkonfiguration ändern";
$Lang{CfgEdit_Title_Xfer} = "Xfer";
$Lang{CfgEdit_Title_Xfer_Settings} = "Xfer Einstellungen";
+$Lang{CfgEdit_Title_Ftp_Settings} = "FTP Einstellungen";
$Lang{CfgEdit_Title_Smb_Settings} = "Smb Einstellungen";
$Lang{CfgEdit_Title_Tar_Settings} = "Tar Einstellungen";
$Lang{CfgEdit_Title_Rsync_Settings} = "Rsync Einstellungen";
$Lang{CfgEdit_Title_Rsyncd_Settings} = "Rsyncd Einstellungen";
-$Lang{CfgEdit_Title_Ftp_Settings} = "FTP Einstellungen";
$Lang{CfgEdit_Title_Archive_Settings} = "Archive Einstellungen";
$Lang{CfgEdit_Title_Include_Exclude} = "Include/Exclude";
$Lang{CfgEdit_Title_Smb_Paths_Commands} = "Smb Pfade/Kommandos";
-#!/bin/perl
+#!/usr/bin/perl
#my %lang;
#use strict;
<td align="center"> Incr Age (days) </td>
<td align="center"> Last Backup (days) </td>
<td align="center"> State </td>
+ <td align="center"> #Xfer errs </td>
<td align="center"> Last attempt </td></tr>
\$strGood
</table>
<td align="center"> Incr Age/days </td>
<td align="center"> Last Backup (days) </td>
<td align="center"> State </td>
+ <td align="center"> #Xfer errs </td>
<td align="center"> Last attempt </td></tr>
\$strNone
</table>
$Lang{CfgEdit_Title_User_Config_Editing} = "User Config Editing";
$Lang{CfgEdit_Title_Xfer} = "Xfer";
$Lang{CfgEdit_Title_Xfer_Settings} = "Xfer Settings";
+$Lang{CfgEdit_Title_Ftp_Settings} = "FTP Settings";
$Lang{CfgEdit_Title_Smb_Settings} = "Smb Settings";
$Lang{CfgEdit_Title_Tar_Settings} = "Tar Settings";
$Lang{CfgEdit_Title_Rsync_Settings} = "Rsync Settings";
$Lang{CfgEdit_Title_Rsyncd_Settings} = "Rsyncd Settings";
-$Lang{CfgEdit_Title_Ftp_Settings} = "FTP Settings";
$Lang{CfgEdit_Title_Archive_Settings} = "Archive Settings";
$Lang{CfgEdit_Title_Include_Exclude} = "Include/Exclude";
$Lang{CfgEdit_Title_Smb_Paths_Commands} = "Smb Paths/Commands";
-#!/bin/perl
+#!/usr/bin/perl
#my %lang;
<td align="center"> Incrementales Antig (Días) </td>
<td align="center"> ENG Last Backup (days) </td>
<td align="center"> Estado </td>
+ <td align="center"> Nº Xfer errs </td>
<td align="center"> Ultimo Intento </td></tr>
\$strGood
</table>
<td align="center"> Incrementales Antig (Días) </td>
<td align="center"> ENG Last Backup (days) </td>
<td align="center"> Estado </td>
+ <td align="center"> Nº Xfer errs </td>
<td align="center"> Ultimo Intento </td></tr>
\$strNone
</table>
$Lang{CfgEdit_Title_User_Config_Editing} = "User Config Editing";
$Lang{CfgEdit_Title_Xfer} = "Xfer";
$Lang{CfgEdit_Title_Xfer_Settings} = "Xfer Settings";
+$Lang{CfgEdit_Title_Ftp_Settings} = "FTP Settings";
$Lang{CfgEdit_Title_Smb_Settings} = "Smb Settings";
$Lang{CfgEdit_Title_Tar_Settings} = "Tar Settings";
$Lang{CfgEdit_Title_Rsync_Settings} = "Rsync Settings";
$Lang{CfgEdit_Title_Rsyncd_Settings} = "Rsyncd Settings";
-$Lang{CfgEdit_Title_Ftp_Settings} = "FTP Settings";
$Lang{CfgEdit_Title_Archive_Settings} = "Archive Settings";
$Lang{CfgEdit_Title_Include_Exclude} = "Include/Exclude";
$Lang{CfgEdit_Title_Smb_Paths_Commands} = "Smb Paths/Commands";
-#!/bin/perl
+#!/usr/bin/perl
#my %Lang;
#use strict;
<td align="center"> Incrémentielles Âge (jours) </td>
<td align="center"> Dernière sauvegarde (jours) </td>
<td align="center"> État actuel </td>
+ <td align="center"> Nb erreurs transfert </td>
<td align="center"> Dernière tentative </td></tr>
\$strGood
</table>
<td align="center"> Incrémentielles Âge (jours) </td>
<td align="center"> Dernière sauvegarde (jours) </td>
<td align="center"> État actuel </td>
+ <td align="center"> Nb erreurs transfert </td>
<td align="center"> Dernière tentative </td></tr>
\$strNone
</table>
$Lang{CfgEdit_Title_User_Config_Editing} = "Modifications des configurations des usagers";
$Lang{CfgEdit_Title_Xfer} = "Xfer";
$Lang{CfgEdit_Title_Xfer_Settings} = "Paramètres des transfers";
+$Lang{CfgEdit_Title_Ftp_Settings} = "Paramètres de FTP";
$Lang{CfgEdit_Title_Smb_Settings} = "Paramètres de Smb";
$Lang{CfgEdit_Title_Tar_Settings} = "Paramètres de Tar";
$Lang{CfgEdit_Title_Rsync_Settings} = "Paramètres de Rsync";
$Lang{CfgEdit_Title_Rsyncd_Settings} = "Paramètres de Rsyncd";
-$Lang{CfgEdit_Title_Ftp_Settings} = "Paramètres de FTP";
$Lang{CfgEdit_Title_Archive_Settings} = "Paramètres d'archivage";
$Lang{CfgEdit_Title_Include_Exclude} = "Inclure/Exclure";
$Lang{CfgEdit_Title_Smb_Paths_Commands} = "Chemins/Commandes Smb";
-#!/bin/perl
+#!/usr/bin/perl
#
# Italian i18n file
#
<td align="center"> Età incrementali (giorni) </td>
<td align="center"> Ultimo Backup (giorni) </td>
<td align="center"> Stato </td>
+ <td align="center"> Numero errori trasferimento </td>
<td align="center"> Ultimo tentativo </td></tr>
\$strGood
</table>
<td align="center"> Età incrementali (giorni) </td>
<td align="center"> Ultimo Backup (giorni) </td>
<td align="center"> Stato </td>
+ <td align="center"> Numero errori trasferimento </td>
<td align="center"> Ultimo tentativo </td></tr>
\$strNone
</table>
$Lang{CfgEdit_Title_User_Config_Editing} = "Modifica Configurazione Utenti";
$Lang{CfgEdit_Title_Xfer} = "Xfer";
$Lang{CfgEdit_Title_Xfer_Settings} = "Configurazione Xfer";
+$Lang{CfgEdit_Title_Ftp_Settings} = "Configurazione FTP";
$Lang{CfgEdit_Title_Smb_Settings} = "Configurazione Smb";
$Lang{CfgEdit_Title_Tar_Settings} = "Configurazione Tar";
$Lang{CfgEdit_Title_Rsync_Settings} = "Configurazione Rsync";
$Lang{CfgEdit_Title_Rsyncd_Settings} = "Configurazione Rsyncd";
-$Lang{CfgEdit_Title_Ftp_Settings} = "Configurazione FTP";
$Lang{CfgEdit_Title_Archive_Settings} = "Configurazione Archivi";
$Lang{CfgEdit_Title_Include_Exclude} = "Includi/Escludi";
$Lang{CfgEdit_Title_Smb_Paths_Commands} = "Smb Percorsi/Comandi";
-#!/bin/perl
+#!/usr/bin/perl
#my %lang;
#use strict;
<td align="center"> Incr.Lftd (dagen) </td>
<td align="center"> Vorige Backup (dagen) </td>
<td align="center"> Status </td>
+ <td align="center"> Aantal fouten </td>
<td align="center"> Laatste poging</td></tr>
\$strGood
</table>
<td align="center"> Incr.Lftd (dagen) </td>
<td align="center"> Vorige Backup (dagen) </td>
<td align="center"> Status </td>
+ <td align="center"> Aantal fouten </td>
<td align="center"> Laatste poging </td></tr>
\$strNone
</table>
$Lang{CfgEdit_Title_User_Config_Editing} = "Wijzigen gebruikersconfiguratie";
$Lang{CfgEdit_Title_Xfer} = "Overdracht";
$Lang{CfgEdit_Title_Xfer_Settings} = "Overdracht instellingen";
+$Lang{CfgEdit_Title_Ftp_Settings} = "FTP instellingen";
$Lang{CfgEdit_Title_Smb_Settings} = "Smb instellingen";
$Lang{CfgEdit_Title_Tar_Settings} = "Tar instellingen";
$Lang{CfgEdit_Title_Rsync_Settings} = "Rsync instellingen";
$Lang{CfgEdit_Title_Rsyncd_Settings} = "Rsyncd instellingen";
-$Lang{CfgEdit_Title_Ftp_Settings} = "FTP instellingen";
$Lang{CfgEdit_Title_Archive_Settings} = "Archivering instellingen";
$Lang{CfgEdit_Title_Include_Exclude} = "Inclusief/Exclusief";
$Lang{CfgEdit_Title_Smb_Paths_Commands} = "Smb Pad/Opdrachten";
-#!/bin/perl
+#!/usr/bin/perl
#my %lang;
#use strict;
<td align="center"> Wiek Inkr (dni) </td>
<td align="center"> Ostatnia kopia bezpieczeństwa (dni) </td>
<td align="center"> Status </td>
+ <td align="center"> #Xfer błędó</td>
<td align="center"> Ostatnia próba </td></tr>
\$strGood
</table>
<td align="center"> Wiek Inkr (dni) </td>
<td align="center"> Ostatnia kopia bezpieczeństwa (dni) </td>
<td align="center"> Status </td>
+ <td align="center"> #Xfer błędó</td>
<td align="center"> Ostatnia próba </td></tr>
\$strNone
</table>
$Lang{CfgEdit_Title_User_Config_Editing} = "Edytowanie konfiguracji użytkownika";
$Lang{CfgEdit_Title_Xfer} = "Xfer";
$Lang{CfgEdit_Title_Xfer_Settings} = "Ustawienia Xfer";
+$Lang{CfgEdit_Title_Ftp_Settings} = "Ustawienia FTP";
$Lang{CfgEdit_Title_Smb_Settings} = "Ustawienia Smb";
$Lang{CfgEdit_Title_Tar_Settings} = "Ustawienia Tar";
$Lang{CfgEdit_Title_Rsync_Settings} = "Ustawienia Rsync";
$Lang{CfgEdit_Title_Rsyncd_Settings} = "Ustawienia Rsyncd";
-$Lang{CfgEdit_Title_Ftp_Settings} = "Ustawienia FTP";
$Lang{CfgEdit_Title_Archive_Settings} = "Ustawienia Archiwizacji";
$Lang{CfgEdit_Title_Include_Exclude} = "Dodaj/Usuń";
$Lang{CfgEdit_Title_Smb_Paths_Commands} = "Ściezki/Polecenia Smb";
-#!/bin/perl
+#!/usr/bin/perl
#
# By Reginaldo Ferreira <reginaldo@lepper.com.br> (23.07.2004 for V2.1.10)
#
<td align="center"> Incrementais Antig (Dias) </td>
<td align="center"> ENG Last Backup (days) </td>
<td align="center"> Estado </td>
+ <td align="center"> Nº Xfer errs </td>
<td align="center"> Última Tentativa </td></tr>
\$strGood
</table>
<td align="center"> Incrementais Antig (Dias) </td>
<td align="center"> ENG Last Backup (days) </td>
<td align="center"> Estado </td>
+ <td align="center"> Nº Xfer errs </td>
<td align="center"> Última tentativa </td></tr>
\$strNone
</table>
$Lang{CfgEdit_Title_User_Config_Editing} = "Edição de Configurações do Usuário";
$Lang{CfgEdit_Title_Xfer} = "Transferência";
$Lang{CfgEdit_Title_Xfer_Settings} = "Configurações de transferência";
+$Lang{CfgEdit_Title_Ftp_Settings} = "Configurações do FTP";
$Lang{CfgEdit_Title_Smb_Settings} = "Configurações do Smb";
$Lang{CfgEdit_Title_Tar_Settings} = "Configurações do Tar";
$Lang{CfgEdit_Title_Rsync_Settings} = "Configurações do Rsync";
$Lang{CfgEdit_Title_Rsyncd_Settings} = "Configurações do Rsyncd";
-$Lang{CfgEdit_Title_Ftp_Settings} = "Configurações do FTP";
$Lang{CfgEdit_Title_Archive_Settings} = "Configurações do Archive";
$Lang{CfgEdit_Title_Include_Exclude} = "Inclui/Exclui";
$Lang{CfgEdit_Title_Smb_Paths_Commands} = "Caminhos/Comandos do Smb";
-#!/bin/perl
+#!/usr/bin/perl
#my %lang;
#use strict;
<td align="center"> 最后一次增量备份 (天前) </td>
<td align="center"> 最后一次备份 (天前) </td>
<td align="center"> 当前状态 </td>
+ <td align="center"> 传输错误数目 </td>
<td align="center"> 最后一次备份结果 </td></tr>
\$strGood
</table>
<td align="center"> 最后一次增量备份 (天前) </td>
<td align="center"> 最后一次备份 (天前) </td>
<td align="center"> 当前状态 </td>
+ <td align="center"> 传输错误数目 </td>
<td align="center"> 最后一次备份结果 </td></tr>
\$strNone
</table>
$Lang{CfgEdit_Title_User_Config_Editing} = "用户配置编辑";
$Lang{CfgEdit_Title_Xfer} = "传输";
$Lang{CfgEdit_Title_Xfer_Settings} = "传输设置";
+$Lang{CfgEdit_Title_Ftp_Settings} = "FTP 设置";
$Lang{CfgEdit_Title_Smb_Settings} = "Smb 设置";
$Lang{CfgEdit_Title_Tar_Settings} = "Tar 设置";
$Lang{CfgEdit_Title_Rsync_Settings} = "Rsync 设置";
$Lang{CfgEdit_Title_Rsyncd_Settings} = "Rsyncd 设置";
-$Lang{CfgEdit_Title_Ftp_Settings} = "FTP 设置";
$Lang{CfgEdit_Title_Archive_Settings} = "备档设置";
$Lang{CfgEdit_Title_Include_Exclude} = "包含/排除";
$Lang{CfgEdit_Title_Smb_Paths_Commands} = "Smb 路径/命令";
return $ShareNames;
}
+
+sub getRestoreCmd
+{
+ my($conf) = @_;
+ my $restoreCmd;
+
+ if ( $conf->{XferMethod} eq "archive" ) {
+ $restoreCmd = undef;
+
+ } elsif ( $conf->{XferMethod} eq "ftp" ) {
+ $restoreCmd = undef;
+
+ } elsif ( $conf->{XferMethod} eq "rsync"
+ || $conf->{XferMethod} eq "rsyncd" ) {
+ $restoreCmd = $conf->{RsyncRestoreArgs};
+
+ } elsif ( $conf->{XferMethod} eq "tar" ) {
+ $restoreCmd = $conf->{TarClientRestoreCmd};
+
+ } elsif ( $conf->{XferMethod} eq "smb" ) {
+ $restoreCmd = $conf->{SmbClientRestoreCmd};
+
+ } else {
+
+ #
+ # protocol unrecognized
+ #
+ $restoreCmd = undef;
+ }
+ return $restoreCmd;
+}
+
+
+sub restoreEnabled
+{
+ my($conf) = @_;
+ my $restoreCmd;
+
+ if ( $conf->{XferMethod} eq "archive" ) {
+ return;
+
+ } elsif ( $conf->{XferMethod} eq "ftp" ) {
+ return !!( $conf->{FtpRestoreEnabled} );
+
+ } elsif ( $conf->{XferMethod} eq "rsync"
+ || $conf->{XferMethod} eq "rsyncd"
+ || $conf->{XferMethod} eq "tar"
+ || $conf->{XferMethod} eq "smb" ) {
+ $restoreCmd = getRestoreCmd( $conf );
+ return !!(
+ ref $restoreCmd eq "ARRAY"
+ ? @$restoreCmd
+ : $restoreCmd ne ""
+ );
+
+ } else {
+ return;
+ }
+}
+
+
sub errStr
{
return $errStr;
# Collect FTP configuration arguments and translate them for
# passing to the FTP module.
#
- $args = $t->getFTPArgs();
+ unless ( $args = $t->getFTPArgs() ) {
+ return;
+ }
#
# Create the Net::FTP::AutoReconnect or Net::FTP object.
#
- unless ( $t->{ftp} = ($ARCLibOK) ? Net::FTP::AutoReconnect->new(%$args)
- : Net::FTP->new(%$args) )
- {
- $t->{_errStr} = "Can't open connection to $args->{Host}";
+ undef $@;
+ eval {
+ $t->{ftp} = ($ARCLibOK) ? Net::FTP::AutoReconnect->new(%$args)
+ : Net::FTP->new(%$args);
+ };
+ if ($@) {
+ $t->{_errStr} = "Can't open connection to $args->{Host}: $!";
$t->{xferErrCnt}++;
return;
}
#
# Log in to the ftp server and set appropriate path information.
#
- unless ( $t->{ftp}->login( $conf->{FtpUserName}, $conf->{FtpPasswd} ) ) {
- $t->{_errStr} = "Can't login to $args->{Host}";
+ undef $@;
+ eval { $t->{ftp}->login( $conf->{FtpUserName}, $conf->{FtpPasswd} ); };
+ if ( $@ ) {
+ $t->{_errStr} = "Can't login to $args->{Host}: $!";
$t->{xferErrCnt}++;
return;
}
- unless ( $t->{ftp}->binary() ) {
- $t->{_errStr} = "Can't enable binary transfer mode to $args->{Host}";
+ undef $@;
+ eval { $t->{ftp}->binary(); };
+ if ($@) {
+ $t->{_errStr} =
+ "Can't enable binary transfer mode to $args->{Host}: $!";
$t->{xferErrCnt}++;
return;
}
- unless ( ( $t->{shareName} =~ m/^\.?$/ )
- || ( $t->{ftp}->cwd( $t->{shareName} ) ) )
- {
- $t->{_errStr} = "Can't change working directory to $t->{shareName}";
+ undef $@;
+ eval { $t->{shareName} =~ m/^\.?$/ || $t->{ftp}->cwd( $t->{shareName} ); };
+ if ($@) {
+ $t->{_errStr} =
+ "Can't change working directory to $t->{shareName}: $!";
$t->{xferErrCnt}++;
return;
}
- unless ( $t->{sharePath} = $t->{ftp}->pwd() ) {
- $t->{_errStr} = "Can't retrieve full working directory of $t->{shareName}";
+ undef $@;
+ eval { $t->{sharePath} = $t->{ftp}->pwd(); };
+ if ($@) {
+ $t->{_errStr} =
+ "Can't retrieve full working directory of $t->{shareName}: $!";
$t->{xferErrCnt}++;
return;
}
#
# Create the remote directory
#
- unless ( $ftp->mkdir( $path, 1 ) ) {
-
+ undef $@;
+ eval { $ftp->mkdir( $path, 1 ); };
+ if ($@) {
$t->logFileAction( "fail", $dirName, $dirAttr );
return;
}
#print STDERR "BackupPC::Xfer::Ftp->restoreFile($fileName)\n";
- #
- # Note: is logging necessary here?
- #
- if ( $ftp->put( $poolFile, $fileDest ) ) {
- $t->logFileAction("restore", $fileName, $fileAttr);
-
- } else {
- $t->logFileAction("fail", $fileName, $fileAttr);
+ undef $@;
+ eval {
+ if ( $ftp->put( $poolFile, $fileDest ) ) {
+ $t->logFileAction( "restore", $fileName, $fileAttr );
+ } else {
+ $t->logFileAction( "fail", $fileName, $fileAttr );
+ }
+ };
+ if ($@) {
+ $t->logFileAction( "fail", $fileName, $fileAttr );
}
}
#
# Prepare backup folder
#
- unless ( mkpath( $OutDir, 0, 0755 ) ) {
+ unless ( eval { mkpath( $OutDir, 0, 0755 ); } ) {
$t->{_errStr} = "can't create OutDir: $OutDir";
$t->{xferErrCnt}++;
return;
sub getFTPArgs
{
my ($t) = @_;
- my $bpc = $t->{bpc};
my $conf = $t->{conf};
- #
- # accepted default key => value pairs to Net::FTP
- #
- my $args = {
- Host => undef,
- Firewall => undef, # not used
- FirewallType => undef, # not used
- BlockSize => 10240,
- Port => 21,
- Timeout => 120,
- Debug => 0, # do not touch
- Passive => 1, # do not touch
- Hash => undef, # do not touch
- LocalAddr => "localhost", # do not touch
- };
-
- #
- # This is mostly to fool makeDist
- #
- exists( $conf->{ClientNameAlias} ) && exists( $conf->{FtpBlockSize} ) &&
- exists( $conf->{FtpPort} ) && exists( $conf->{FtpTimeout} )
- or die "Configuration variables for FTP not present in config.pl";
-
- #
- # map of options from %Conf in the config.pl scripts to options
- # the Net::FTP::AutoReconnect object.
- #
- my $argMap = {
- "Host" => "ClientNameAlias",
- "BlockSize" => "FtpBlockSize",
- "Port" => "FtpPort",
- "Timeout" => "FtpTimeout",
- };
-
- foreach my $key ( keys(%$args) ) {
- $args->{$key} = $conf->{ $argMap->{$key} } || $args->{$key};
- }
-
- #
- # Fix for $args->{Host} since it can be in more than one location.
- # Note the precedence here, this may need to be fixed. Order of
- # precedence:
- # $conf->{ClientNameAlias}
- # $t->{hostIP}
- # $t->{host}
- #
- $args->{Host} ||= $t->{hostIP};
- $args->{Host} ||= $t->{host};
-
- #
- # return the reference to the hash of items
- #
- return $args;
+ return {
+ Host => $conf->{ClientNameAlias}
+ || $t->{hostIP}
+ || $t->{host},
+ Firewall => undef, # not used
+ FirewallType => undef, # not used
+ BlockSize => $conf->{FtpBlockSize} || 10240,
+ Port => $conf->{FtpPort} || 21,
+ Timeout => $conf->{FtpTimeout} || 120,
+ Debug => 0, # do not touch
+ Passive => 1, # do not touch
+ Hash => undef, # do not touch
+ LocalAddr => "localhost", # do not touch
+ };
}
my ( $dirContents, $remoteDir, $f );
- unless ( $dirContents = ($path =~ /^\.?$/ ) ? $ftp->dir() :
- $ftp->dir("$path/") )
- {
+ undef $@;
+ eval {
+ $dirContents = ( $path =~ /^\.?$/ ) ? $ftp->dir()
+ : $ftp->dir("$path/");
+ };
+ if ($@) {
$t->{xferErrCnt}++;
- return "can't retrieve remote directory contents of $path";
+ return "can't retrieve remote directory contents of $path: $!";
}
foreach my $info ( @{parse_dir($dirContents)} ) {
$f = {
- name => $info->[0],
- type => $info->[1],
- size => $info->[2],
- mtime => $info->[3],
- mode => $info->[4],
- };
-
- #
- # convert & store utf8 version of filename
- #
+ name => $info->[0],
+ type => $info->[1],
+ size => $info->[2],
+ mtime => $info->[3],
+ mode => $info->[4],
+ };
+
$f->{utf8name} = $f->{name};
from_to( $f->{utf8name}, $conf->{ClientCharset}, "utf8" );
- #
- # construct the full name
- #
$f->{fullName} = "$t->{sharePath}/$path/$f->{name}";
$f->{fullName} =~ s/\/+/\//g;
push( @$remoteDir, $f );
}
-
return $remoteDir;
}
{
my ( $t, $f, $attrib ) = @_;
- #
- # case for ignoring the files '.' & '..'
- #
if ( $f->{name} =~ /^\.\.?$/ ) {
return 1;
}
- #
- # Check the include/exclude lists. the function returns true if
- # the file should be backed up, so return the opposite.
- #
return ( !$t->checkIncludeExclude( $f->{fullName} ) );
}
$f->{type} =~ /^l (.*)/;
$target = $1;
- if ( $targetDesc = $ftp->dir("$target/") ) {
- $t->handleSymDir( $f, $OutDir, $attrib, $targetDesc );
-
- } elsif ( $targetDesc = $ftp->dir($target) ) {
- if ( $targetDesc->[4] eq 'file' ) {
- $t->handleSymFile( $f, $OutDir, $attrib );
-
- } elsif ( $targetDesc->[4] =~ /l (.*)/) {
-
- $t->logFileAction("fail", $f->{utf8name}, $attribInfo);
+ undef $@;
+ eval {
+ if ( $targetDesc = $ftp->dir("$target/") ) {
+ $t->handleSymDir( $f, $OutDir, $attrib, $targetDesc );
+
+ } elsif ( $targetDesc = $ftp->dir($target) ) {
+ if ( $targetDesc->[4] eq 'file' ) {
+ $t->handleSymFile( $f, $OutDir, $attrib );
+
+ } elsif ( $targetDesc->[4] =~ /l (.*)/ ) {
+ $t->logFileAction( "fail", $f->{utf8name}, $attribInfo );
+ return;
+ }
+ } else {
+ $t->( "fail", $f );
return;
}
- } else {
-
- $t->("fail", $f);
+ };
+ if ($@) {
+ $t->logFileAction( "fail", $f->{utf8name}, $attribInfo );
return;
}
} else {
-
#
# If we are not following symlinks, record them normally.
#
my $conf = $t->{conf};
my $f = {
- name => $fSym->{name},
- type => $targetDesc->[1],
- size => $targetDesc->[2],
- mtime => $targetDesc->[3],
- mode => $targetDesc->[4]
- };
+ name => $fSym->{name},
+ type => $targetDesc->[1],
+ size => $targetDesc->[2],
+ mtime => $targetDesc->[3],
+ mode => $targetDesc->[4]
+ };
$f->{utf8name} = $fSym->{name};
from_to( $f->{utf8name}, $conf->{ClientCharset}, "utf8" );
- $f->{relPath} = $fSym->{relPath};
-
+ $f->{relPath} = $fSym->{relPath};
$f->{fullName} = "$t->{shareName}/$fSym->{relPath}/$fSym->{name}";
$f->{fullName} =~ s/\/+/\//g;
#
- # since FTP servers follow symlinks, we can jsut do this:
+ # since FTP servers follow symlinks, we can just do this:
#
return $t->handleFile( $f, $OutDir, $attrib );
}
unless ( -d $OutDir ) {
- mkpath( $OutDir, 0, 0755 );
- $t->logFileAction( "create", $dir->{utf8name}, $dir );
+ eval { mkpath( $OutDir, 0, 0755 ) };
+ if ( $@ ) {
+ $t->logFileAction( "fail", $dir->{utf8name}, $dir );
+ return;
+ } else {
+ $t->logFileAction( "create", $dir->{utf8name}, $dir );
+ }
}
$attrib = BackupPC::Attrib->new( { compress => $t->{Compress} } );
# If this is a full backup or the file has changed on the host,
# back it up.
#
- unless ( tie( *FTP, 'Net::FTP::RetrHandle', $ftp, $f->{fullName} ) ) {
-
+ undef $@;
+ eval { tie ( *FTP, 'Net::FTP::RetrHandle', $ftp, $f->{fullName} ); };
+ if ( !*FTP || $@ ) {
$t->handleFileAction( "fail", $attribInfo );
$t->{xferBadFileCnt}++;
$stats->{errCnt}++;
$bpc->{xfer}{compress} );
$localSize = 0;
- while (<FTP>) {
- $localSize += length($_);
- $poolWrite->write( \$_ );
- }
+ undef $@;
+ eval {
+ while (<FTP>) {
+ $localSize += length($_);
+ $poolWrite->write( \$_ );
+ }
+ };
( $exists, $digest, $outSize, $errs ) = $poolWrite->close();
-
- #
- # calculate the file statistics
- #
- if (@$errs) {
+ if ( !*FTP || $@ || @$errs ) {
$t->logFileAction( "fail", $f->{utf8name}, $attribInfo );
unlink($poolFile);
$t->{xferBadFileCnt}++;
- $t->{errCnt} += scalar(@$errs);
+ $stats->{errCnt} += scalar @$errs;
return;
}
# this should never happen
#
if ( $localSize != $f->{size} ) {
-
$t->logFileAction( "fail", $f->{utf8name}, $attribInfo );
unklink($poolFile);
$stats->{xferBadFileCnt}++;
# Perform logging
#
$attrib->set( $f->{utf8name}, $attribInfo );
- $t->logFileAction( $exists ? "pool" : "create", $f->{utf8name}, $attribInfo );
+ $t->logFileAction( $exists ? "pool" : "create",
+ $f->{utf8name}, $attribInfo );
print $newFilesFH "$digest $f->{size} $poolFile\n" unless $exists;
#
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})
# 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" );
if ( $conf->{ClientCharset} ne "" );
}
- my $str = "RsyncArgsBefore: " . join(" ", @{$rs->{rsyncArgs}}) . "\n";
- $t->{XferLOG}->write(\$str);
+ ##my $str = "RsyncArgsBefore: " . join(" ", @{$rs->{rsyncArgs}}) . "\n";
+ ##$t->{XferLOG}->write(\$str);
$rs->serverStart($remoteSend, $remoteDirDaemon);
- my $str = "RsyncArgsAfter: " . join(" ", @{$rs->{rsyncArgs}}) . "\n";
- $t->{XferLOG}->write(\$str);
+ ##$str = "RsyncArgsAfter: " . join(" ", @{$rs->{rsyncArgs}}) . "\n";
+ ##$t->{XferLOG}->write(\$str);
}
my $shareNameSlash = $t->{shareNameSlash};
from_to($shareNameSlash, "utf8", $conf->{ClientCharset})
$opts{syntaxCheck} = 1;
if ( !GetOptions(
\%opts,
- "l",
"langCheck!",
"syntaxCheck!",
"version=s",
init.d/README
init.d/src/debian-backuppc
init.d/src/freebsd-backuppc
+ init.d/src/freebsd-backuppc2
init.d/src/gentoo-backuppc
init.d/src/gentoo-backuppc.conf
init.d/src/linux-backuppc