From: cbarratt Date: Mon, 30 Mar 2009 07:09:19 +0000 (+0000) Subject: * Added more options to server backup command: rather than just forcing X-Git-Tag: v3_2_0beta1~8 X-Git-Url: http://git.rot13.org/?p=BackupPC.git;a=commitdiff_plain;h=1015740e2b58fc43d7cf49881f190a9612e73fff;ds=sidebyside * 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. * Changed BackupPC_tarCreate to disable output of final nulls in tar archive when -l or -L option is used. Reported by John Rouillard. * 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. * Added alternate freebsd-backuppc2 init.d script that is more compact. Submitted by Dan Niles. --- diff --git a/CVS_README b/CVS_README index 782d4b7..c7aab1f 100644 --- a/CVS_README +++ b/CVS_README @@ -23,26 +23,34 @@ Fetching CVS: 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. diff --git a/ChangeLog b/ChangeLog index f604831..fa5e62a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -58,8 +58,11 @@ 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. @@ -93,10 +96,22 @@ * 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. @@ -120,6 +135,9 @@ * 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. diff --git a/bin/BackupPC b/bin/BackupPC index 79d89c7..67a31d8 100755 --- a/bin/BackupPC +++ b/bin/BackupPC @@ -285,7 +285,7 @@ sub Main_Initialize # 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: $!"); @@ -655,8 +655,6 @@ sub Main_TryToRun_Bg_or_User_Queue 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) @@ -692,7 +690,11 @@ sub Main_TryToRun_Bg_or_User_Queue } 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); } @@ -1347,58 +1349,66 @@ sub Main_Check_Client_Messages 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; @@ -1419,7 +1429,7 @@ sub Main_Check_Client_Messages } else { unshift(@UserQueue, { host => $host, - hostIP => $user, + user => $user, reqFileName => $reqFileName, reqTime => time, dhcp => 0, @@ -1647,18 +1657,33 @@ sub HostSortCompare 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 ) { @@ -1671,13 +1696,13 @@ sub QueueOnePC # 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} ) { # @@ -1688,22 +1713,31 @@ sub QueueOnePC # 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; } # @@ -1716,30 +1750,19 @@ sub QueueAllPCs 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; + } } # diff --git a/bin/BackupPC_dump b/bin/BackupPC_dump index 89e4bfe..243be55 100755 --- a/bin/BackupPC_dump +++ b/bin/BackupPC_dump @@ -5,7 +5,7 @@ # # DESCRIPTION # -# Usage: BackupPC_dump [-i] [-f] [-d] [-e] [-v] +# Usage: BackupPC_dump [-i] [-f] [-F] [-I] [-d] [-e] [-v] # # Flags: # @@ -14,6 +14,13 @@ # # -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. @@ -105,14 +112,19 @@ my $Abort; $bpc->ChildInit(); my %opts; -if ( !getopts("defiv", \%opts) || @ARGV != 1 ) { - print("usage: $0 [-d] [-e] [-f] [-i] [-v] \n"); +if ( !getopts("defivFI", \%opts) || @ARGV != 1 ) { + print("usage: $0 [-d] [-e] [-f] [-i] [-F] [-I] [-v] \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 @@ -387,15 +399,21 @@ for ( my $i = 0 ; $i < @Backups ; $i++ ) { # # 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 diff --git a/bin/BackupPC_tarCreate b/bin/BackupPC_tarCreate index 4366a27..9ce81f7 100755 --- a/bin/BackupPC_tarCreate +++ b/bin/BackupPC_tarCreate @@ -55,7 +55,7 @@ # #======================================================================== # -# Version 3.1.0, released 25 Nov 2007. +# Version 3.2.0beta0, released 17 Jan 2009. # # See http://backuppc.sourceforge.net. # @@ -186,13 +186,15 @@ if ( $ShareName eq "*" ) { 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 diff --git a/conf/config.pl b/conf/config.pl index feed6bf..0c73cbb 100644 --- a/conf/config.pl +++ b/conf/config.pl @@ -1272,16 +1272,6 @@ $Conf{RsyncCsumCacheVerifyProb} = 0.01; # 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! @@ -1305,12 +1295,40 @@ $Conf{RsyncArgs} = [ # 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. @@ -1319,6 +1337,17 @@ $Conf{RsyncArgs} = [ # 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! @@ -1412,6 +1441,13 @@ $Conf{FtpTimeout} = 120; # $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) @@ -2154,6 +2190,7 @@ $Conf{CgiUserConfigEdit} = { RsyncdAuthRequired => 1, RsyncCsumCacheVerifyProb => 1, RsyncArgs => 1, + RsyncArgsExtra => 1, RsyncRestoreArgs => 1, RsyncClientCmd => 0, RsyncClientRestoreCmd => 0, @@ -2164,6 +2201,8 @@ $Conf{CgiUserConfigEdit} = { FtpBlockSize => 1, FtpPort => 1, FtpTimeout => 1, + FtpFollowSymlinks => 1, + FtpRestoreEnabled => 1, ArchiveDest => 1, ArchiveComp => 1, ArchivePar => 1, diff --git a/configure.pl b/configure.pl index a879807..c62787a 100755 --- a/configure.pl +++ b/configure.pl @@ -613,7 +613,7 @@ if ( $Conf{CgiImageDir} ne "" ) { 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); } diff --git a/init.d/README b/init.d/README index afa4a61..3d0aeaa 100644 --- a/init.d/README +++ b/init.d/README @@ -83,8 +83,11 @@ FreeBSD: ======= 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: diff --git a/lib/BackupPC/CGI/EditConfig.pm b/lib/BackupPC/CGI/EditConfig.pm index 466ab13..4590229 100644 --- a/lib/BackupPC/CGI/EditConfig.pm +++ b/lib/BackupPC/CGI/EditConfig.pm @@ -28,7 +28,7 @@ # #======================================================================== # -# Version 3.2.0, released 31 Dec 2008. +# Version 3.2.0beta0, released 17 Jan 2009. # # See http://backuppc.sourceforge.net. # @@ -223,7 +223,10 @@ our %ConfigMenu = ( 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"; } }, @@ -285,6 +288,8 @@ our %ConfigMenu = ( 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/; } }, diff --git a/lib/BackupPC/CGI/Restore.pm b/lib/BackupPC/CGI/Restore.pm index 1892a95..a1ee5c6 100644 --- a/lib/BackupPC/CGI/Restore.pm +++ b/lib/BackupPC/CGI/Restore.pm @@ -28,7 +28,7 @@ # #======================================================================== # -# Version 3.2.0, released 31 Dec 2008. +# Version 3.2.0beta0, released 17 Jan 2009. # # See http://backuppc.sourceforge.net. # @@ -38,6 +38,7 @@ package BackupPC::CGI::Restore; use strict; use BackupPC::CGI::Lib qw(:all); +use BackupPC::Xfer; use Data::Dumper; use File::Path; use Encode qw/decode_utf8/; @@ -116,11 +117,7 @@ EOF # $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 # @@ -263,11 +260,7 @@ EOF # 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}}")); } diff --git a/lib/BackupPC/CGI/Summary.pm b/lib/BackupPC/CGI/Summary.pm index 4406081..012ae0e 100644 --- a/lib/BackupPC/CGI/Summary.pm +++ b/lib/BackupPC/CGI/Summary.pm @@ -28,7 +28,7 @@ # #======================================================================== # -# Version 3.1.0, released 25 Nov 2007. +# Version 3.2.0beta0, released 29 Mar 2009. # # See http://backuppc.sourceforge.net. # @@ -50,7 +50,7 @@ sub action 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; @@ -106,6 +106,7 @@ sub action $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 ) { @@ -147,6 +148,7 @@ sub action $incrAge $lastAge $Lang->{$tempState} + $lastXferErrors $Lang->{$tempReason}$shortErr EOF if ( @Backups == 0 ) { diff --git a/lib/BackupPC/Config/Meta.pm b/lib/BackupPC/Config/Meta.pm index 76b8b49..2fb3f65 100644 --- a/lib/BackupPC/Config/Meta.pm +++ b/lib/BackupPC/Config/Meta.pm @@ -28,7 +28,7 @@ # #======================================================================== # -# Version 3.2.0, released 31 Dec 2008. +# Version 3.2.0beta0, released 17 Jan 2009. # # See http://backuppc.sourceforge.net. # @@ -257,6 +257,11 @@ use vars qw(%ConfigMeta); emptyOk => 1, child => "string", }, + RsyncArgsExtra => { + type => "list", + emptyOk => 1, + child => "string", + }, RsyncRestoreArgs => { type => "list", emptyOk => 1, @@ -277,7 +282,8 @@ use vars qw(%ConfigMeta); FtpPort => "integer", FtpTimeout => "integer", FtpFollowSymlinks => "boolean", - + FtpRestoreEnabled => "boolean", + ###################################################################### # Archive Configuration ###################################################################### @@ -435,6 +441,7 @@ use vars qw(%ConfigMeta); RsyncdAuthRequired => "boolean", RsyncCsumCacheVerifyProb => "boolean", RsyncArgs => "boolean", + RsyncArgsExtra => "boolean", RsyncRestoreArgs => "boolean", RsyncClientCmd => "boolean", RsyncClientPath => "boolean", @@ -445,6 +452,8 @@ use vars qw(%ConfigMeta); FtpBlockSize => "boolean", FtpPort => "boolean", FtpTimeout => "boolean", + FtpFollowSymlinks => "boolean", + FtpRestoreEnabled => "boolean", ArchiveDest => "boolean", ArchiveComp => "boolean", ArchivePar => "boolean", diff --git a/lib/BackupPC/Lang/de.pm b/lib/BackupPC/Lang/de.pm index cf3d436..31fa54c 100644 --- a/lib/BackupPC/Lang/de.pm +++ b/lib/BackupPC/Lang/de.pm @@ -1,4 +1,4 @@ -#!/bin/perl +#!/usr/bin/perl # # by Ralph Passgang (13.11.2006 for V3.0.0) # by Ralph Passgang (30.06.2006 for V3.0.0) @@ -167,6 +167,7 @@ Es gibt \$hostCntGood Computer die erfolgreich gesichert wurden, mit insgesamt: Alter (Tage) Letzes Backup (Tage) Status + #Xfer Fehler Letzte Aktion \$strGood @@ -186,6 +187,7 @@ Es gibt \$hostCntNone Computer ohne Backups !!! Alter (Tage) Letztes Backup (Tage) Status + #Xfer Fehler Letzter Versuch \$strNone @@ -1387,11 +1389,11 @@ $Lang{CfgEdit_Title_User_URLs} = "Benutzer URLs"; $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"; diff --git a/lib/BackupPC/Lang/en.pm b/lib/BackupPC/Lang/en.pm index 7b75881..e4fe19e 100644 --- a/lib/BackupPC/Lang/en.pm +++ b/lib/BackupPC/Lang/en.pm @@ -1,4 +1,4 @@ -#!/bin/perl +#!/usr/bin/perl #my %lang; #use strict; @@ -154,6 +154,7 @@ There are \$hostCntGood hosts that have been backed up, for a total of: Incr Age (days) Last Backup (days) State + #Xfer errs Last attempt \$strGood @@ -173,6 +174,7 @@ There are \$hostCntNone hosts with no backups. Incr Age/days Last Backup (days) State + #Xfer errs Last attempt \$strNone @@ -1379,11 +1381,11 @@ $Lang{CfgEdit_Title_User_URLs} = "User URLs"; $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"; diff --git a/lib/BackupPC/Lang/es.pm b/lib/BackupPC/Lang/es.pm index 34d933f..0f5f982 100644 --- a/lib/BackupPC/Lang/es.pm +++ b/lib/BackupPC/Lang/es.pm @@ -1,4 +1,4 @@ -#!/bin/perl +#!/usr/bin/perl #my %lang; @@ -155,6 +155,7 @@ Il y a \$hostCntGood hosts tienen copia de seguridad, de un total de : Incrementales Antig (Días) ENG Last Backup (days) Estado + Nº Xfer errs Ultimo Intento \$strGood @@ -174,6 +175,7 @@ Hay \$hostCntNone hosts sin copias de seguridad. Incrementales Antig (Días) ENG Last Backup (days) Estado + Nº Xfer errs Ultimo Intento \$strNone @@ -1383,11 +1385,11 @@ $Lang{CfgEdit_Title_User_URLs} = "User URLs"; $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"; diff --git a/lib/BackupPC/Lang/fr.pm b/lib/BackupPC/Lang/fr.pm index 1f709fc..7cbfc3d 100644 --- a/lib/BackupPC/Lang/fr.pm +++ b/lib/BackupPC/Lang/fr.pm @@ -1,4 +1,4 @@ -#!/bin/perl +#!/usr/bin/perl #my %Lang; #use strict; @@ -154,6 +154,7 @@ Il y a \$hostCntGood h Incrémentielles Âge (jours) Dernière sauvegarde (jours) État actuel + Nb erreurs transfert Dernière tentative \$strGood @@ -173,6 +174,7 @@ Il y a \$hostCntNone h Incrémentielles Âge (jours) Dernière sauvegarde (jours) État actuel + Nb erreurs transfert Dernière tentative \$strNone @@ -1380,11 +1382,11 @@ $Lang{CfgEdit_Title_User_URLs} = "URL des usagers"; $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"; diff --git a/lib/BackupPC/Lang/it.pm b/lib/BackupPC/Lang/it.pm index 78c5974..380a50c 100644 --- a/lib/BackupPC/Lang/it.pm +++ b/lib/BackupPC/Lang/it.pm @@ -1,4 +1,4 @@ -#!/bin/perl +#!/usr/bin/perl # # Italian i18n file # @@ -163,6 +163,7 @@ Ci sono \$hostCntGood host sottoposti a backup per un totale di: Età incrementali (giorni) Ultimo Backup (giorni) Stato + Numero errori trasferimento Ultimo tentativo \$strGood @@ -182,6 +183,7 @@ Ci sono \$hostCntNone host senza alcun backup. Età incrementali (giorni) Ultimo Backup (giorni) Stato + Numero errori trasferimento Ultimo tentativo \$strNone @@ -1394,11 +1396,11 @@ $Lang{CfgEdit_Title_User_URLs} = "URL Utenti"; $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"; diff --git a/lib/BackupPC/Lang/nl.pm b/lib/BackupPC/Lang/nl.pm index 291a7be..d712812 100644 --- a/lib/BackupPC/Lang/nl.pm +++ b/lib/BackupPC/Lang/nl.pm @@ -1,4 +1,4 @@ -#!/bin/perl +#!/usr/bin/perl #my %lang; #use strict; @@ -154,6 +154,7 @@ Er zijn \$hostCntGood hosts gebackupt, wat een totaal geeft van: Incr.Lftd (dagen) Vorige Backup (dagen) Status + Aantal fouten Laatste poging \$strGood @@ -173,6 +174,7 @@ Er zijn \$hostCntNone hosts zonder backup. Incr.Lftd (dagen) Vorige Backup (dagen) Status + Aantal fouten Laatste poging \$strNone @@ -1392,11 +1394,11 @@ $Lang{CfgEdit_Title_User_URLs} = "Gebruiker URLs"; $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"; diff --git a/lib/BackupPC/Lang/pl.pm b/lib/BackupPC/Lang/pl.pm index 55425c5..da01f95 100644 --- a/lib/BackupPC/Lang/pl.pm +++ b/lib/BackupPC/Lang/pl.pm @@ -1,4 +1,4 @@ -#!/bin/perl +#!/usr/bin/perl #my %lang; #use strict; @@ -154,6 +154,7 @@ Jest \$hostCntGood hostów które zostaly zabezpieczone, na całkowita liczbę: Wiek Inkr (dni) Ostatnia kopia bezpieczeństwa (dni) Status + #Xfer błędó Ostatnia próba \$strGood @@ -173,6 +174,7 @@ Jest \$hostCntNone hostów bez kopii bezpieczeństwa. Wiek Inkr (dni) Ostatnia kopia bezpieczeństwa (dni) Status + #Xfer błędó Ostatnia próba \$strNone @@ -1373,11 +1375,11 @@ $Lang{CfgEdit_Title_User_URLs} = "URLe użytkownika"; $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"; diff --git a/lib/BackupPC/Lang/pt_br.pm b/lib/BackupPC/Lang/pt_br.pm index b698044..33c357e 100644 --- a/lib/BackupPC/Lang/pt_br.pm +++ b/lib/BackupPC/Lang/pt_br.pm @@ -1,4 +1,4 @@ -#!/bin/perl +#!/usr/bin/perl # # By Reginaldo Ferreira (23.07.2004 for V2.1.10) # @@ -159,6 +159,7 @@ Existem \$hostCntGood hosts com backup, de um total de : Incrementais Antig (Dias) ENG Last Backup (days) Estado + Nº Xfer errs Última Tentativa \$strGood @@ -178,6 +179,7 @@ Existem \$hostCntNone hosts sem backups. Incrementais Antig (Dias) ENG Last Backup (days) Estado + Nº Xfer errs Última tentativa \$strNone @@ -1383,11 +1385,11 @@ $Lang{CfgEdit_Title_User_URLs} = "URLs do Usu $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"; diff --git a/lib/BackupPC/Lang/zh_CN.pm b/lib/BackupPC/Lang/zh_CN.pm index 5bce4d0..c6a5d0a 100644 --- a/lib/BackupPC/Lang/zh_CN.pm +++ b/lib/BackupPC/Lang/zh_CN.pm @@ -1,4 +1,4 @@ -#!/bin/perl +#!/usr/bin/perl #my %lang; #use strict; @@ -152,6 +152,7 @@ $Lang{BackupPC_Summary} = < 最后一次增量备份 (天前) 最后一次备份 (天前) 当前状态 + 传输错误数目 最后一次备份结果 \$strGood @@ -171,6 +172,7 @@ $Lang{BackupPC_Summary} = < 最后一次增量备份 (天前) 最后一次备份 (天前) 当前状态 + 传输错误数目 最后一次备份结果 \$strNone @@ -1347,11 +1349,11 @@ $Lang{CfgEdit_Title_User_URLs} = "用户 URLs"; $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 路径/命令"; diff --git a/lib/BackupPC/Xfer.pm b/lib/BackupPC/Xfer.pm index 2977015..af20a75 100644 --- a/lib/BackupPC/Xfer.pm +++ b/lib/BackupPC/Xfer.pm @@ -134,6 +134,67 @@ sub getShareNames 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; diff --git a/lib/BackupPC/Xfer/Ftp.pm b/lib/BackupPC/Xfer/Ftp.pm index 2b3c001..26f8510 100644 --- a/lib/BackupPC/Xfer/Ftp.pm +++ b/lib/BackupPC/Xfer/Ftp.pm @@ -174,15 +174,20 @@ sub start # 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; } @@ -190,28 +195,37 @@ sub start # # 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; } @@ -366,8 +380,9 @@ sub restoreDir # # Create the remote directory # - unless ( $ftp->mkdir( $path, 1 ) ) { - + undef $@; + eval { $ftp->mkdir( $path, 1 ); }; + if ($@) { $t->logFileAction( "fail", $dirName, $dirAttr ); return; } @@ -426,14 +441,16 @@ sub restoreFile #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 ); } } @@ -466,7 +483,7 @@ sub backup # # Prepare backup folder # - unless ( mkpath( $OutDir, 0, 0755 ) ) { + unless ( eval { mkpath( $OutDir, 0, 0755 ); } ) { $t->{_errStr} = "can't create OutDir: $OutDir"; $t->{xferErrCnt}++; return; @@ -508,62 +525,22 @@ sub backup 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 + }; } @@ -589,32 +566,29 @@ sub remotels 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; @@ -623,7 +597,6 @@ sub remotels push( @$remoteDir, $f ); } - return $remoteDir; } @@ -637,17 +610,10 @@ sub ignoreFileCheck { 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} ) ); } @@ -685,26 +651,30 @@ sub handleSymlink $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. # @@ -731,23 +701,22 @@ sub handleSymFile 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 ); } @@ -777,8 +746,13 @@ sub handleDir 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} } ); @@ -905,8 +879,9 @@ sub handleFile # 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}++; @@ -918,22 +893,21 @@ sub handleFile $bpc->{xfer}{compress} ); $localSize = 0; - while () { - $localSize += length($_); - $poolWrite->write( \$_ ); - } + undef $@; + eval { + while () { + $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; } @@ -941,7 +915,6 @@ sub handleFile # this should never happen # if ( $localSize != $f->{size} ) { - $t->logFileAction( "fail", $f->{utf8name}, $attribInfo ); unklink($poolFile); $stats->{xferBadFileCnt}++; @@ -953,7 +926,8 @@ sub handleFile # 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; # diff --git a/lib/BackupPC/Xfer/Rsync.pm b/lib/BackupPC/Xfer/Rsync.pm index 0c1c336..934ce48 100644 --- a/lib/BackupPC/Xfer/Rsync.pm +++ b/lib/BackupPC/Xfer/Rsync.pm @@ -92,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}) @@ -209,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" ); @@ -392,13 +420,13 @@ sub run 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}) diff --git a/makeDist b/makeDist index 39f6f43..2e9e884 100755 --- a/makeDist +++ b/makeDist @@ -133,7 +133,6 @@ $opts{langCheck} = 1; $opts{syntaxCheck} = 1; if ( !GetOptions( \%opts, - "l", "langCheck!", "syntaxCheck!", "version=s", @@ -267,6 +266,7 @@ foreach my $file ( (@PerlSrc, 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