* On the phase 2 retry pass with rsync, verify the cached checksums
authorcbarratt <cbarratt>
Fri, 21 May 2004 02:11:34 +0000 (02:11 +0000)
committercbarratt <cbarratt>
Fri, 21 May 2004 02:11:34 +0000 (02:11 +0000)
  if checksum caching is turned on.  This will catch the case of
  cached checksums being incorrectly appended to the compressed
  pool file.  Added new config parameter $Conf{RsyncCsumCacheVerifyProb}
  so that cached checksums are verified with a selectable probability.
  Also, increased File::RsyncP version number to 0.51.

* configure.pl now supports an optional batch mode.  Command-line
  options are used to specify all the information that configure.pl
  needs.  This is useful for buidling auto-install packages.
  Also, configure.pl now includes pod documentation, so you can do
  "perldoc configure.pl" to see all the command-line options.
  Suggested, tested and tweaked by Stuart Herbert for possible
  Gentoo inclusion.

* At each wakeup, clients are now queued based on how old the most
  recent backup is.  Clients with errors are queued first, with
  the oldest error times going first.  Clients with good backups
  are queued next, with the oldest backup going first.  Previously
  the clients were simply queued in alphabetic order.  Suggested
  by Tony Nelson.

* Added config parameter $Conf{PartialAgeMax} that controls whether
  partials are saved at all, and if so, whether the partial will be
  ignored at the next full backup if it is too old.

* BackupPC_tarExtract now allows empty archives without reporting
  an error.  Reported by Don Silvia.

* Removed Browse Backups link from Nav Bar in Archive Info display.
  Reported by Ralph Paßgang.

* Fixed documentation display for regular users.  Reported by Ralph Paßgang.

* Status and PC Summary now work for regular users and only show
  that user's hosts.  Server general status information only appears
  for admins.  Suggested by Ralph Paßgang.

* Moved the last three navigation-bar links (docs, FAQ and SF) to
  a new config parameter $Conf{CgiNavBarLinks}.  This allows
  these links to be locally configured.  Based on a patch
  submitted by Ralph Paßgang.

* Allow the navigation bar search box to be disabled by
  setting $Conf{CgiSearchBoxEnable} to 0.  Based on a patch
  submitted by Ralph Paßgang.

* Updates to de.pm from Ralph Paßgang.

* Made the BackupPC icon a link to the SF BackupPC project page.

24 files changed:
ChangeLog
bin/BackupPC
bin/BackupPC_dump
bin/BackupPC_tarExtract
cgi-bin/BackupPC_Admin
conf/config.pl
configure.pl
doc-src/BackupPC.pod
lib/BackupPC/CGI/ArchiveInfo.pm
lib/BackupPC/CGI/GeneralInfo.pm
lib/BackupPC/CGI/HostInfo.pm
lib/BackupPC/CGI/Lib.pm
lib/BackupPC/CGI/Summary.pm
lib/BackupPC/CGI/View.pm
lib/BackupPC/Lang/de.pm
lib/BackupPC/Lang/en.pm
lib/BackupPC/Lang/es.pm
lib/BackupPC/Lang/fr.pm
lib/BackupPC/Lang/it.pm
lib/BackupPC/Xfer/Rsync.pm
lib/BackupPC/Xfer/RsyncDigest.pm
lib/BackupPC/Xfer/RsyncFileIO.pm
lib/BackupPC/Xfer/Smb.pm
makeDist

index d372dba..ef5db9b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 # Version __VERSION__, __RELEASEDATE__
 #------------------------------------------------------------------------
 
+** Add checksum caching info and file format to the docs.
+
+* On the phase 2 retry pass with rsync, verify the cached checksums
+  if checksum caching is turned on.  This will catch the case of
+  cached checksums being incorrectly appended to the compressed
+  pool file.  Added new config parameter $Conf{RsyncCsumCacheVerifyProb}
+  so that cached checksums are verified with a selectable probability.
+  Also, increased File::RsyncP version number to 0.51.
+
+* configure.pl now supports an optional batch mode.  Command-line
+  options are used to specify all the information that configure.pl
+  needs.  This is useful for buidling auto-install packages.
+  Also, configure.pl now includes pod documentation, so you can do
+  "perldoc configure.pl" to see all the command-line options.
+  Suggested, tested and tweaked by Stuart Herbert for possible
+  Gentoo inclusion.
+
+* At each wakeup, clients are now queued based on how old the most
+  recent backup is.  Clients with errors are queued first, with
+  the oldest error times going first.  Clients with good backups
+  are queued next, with the oldest backup going first.  Previously
+  the clients were simply queued in alphabetic order.  Suggested
+  by Tony Nelson.
+
+* Added config parameter $Conf{PartialAgeMax} that controls whether
+  partials are saved at all, and if so, whether the partial will be
+  ignored at the next full backup if it is too old.
+
+* BackupPC_tarExtract now allows empty archives without reporting
+  an error.  Reported by Don Silvia.
+
+* Removed Browse Backups link from Nav Bar in Archive Info display.
+  Reported by Ralph Paßgang.
+
+* Fixed documentation display for regular users.  Reported by Ralph Paßgang.
+
+* Status and PC Summary now work for regular users and only show
+  that user's hosts.  Server general status information only appears
+  for admins.  Suggested by Ralph Paßgang.
+
+* Moved the last three navigation-bar links (docs, FAQ and SF) to
+  a new config parameter $Conf{CgiNavBarLinks}.  This allows
+  these links to be locally configured.  Based on a patch
+  submitted by Ralph Paßgang.
+
+* Allow the navigation bar search box to be disabled by
+  setting $Conf{CgiSearchBoxEnable} to 0.  Based on a patch
+  submitted by Ralph Paßgang.
+
+* Updates to de.pm from Ralph Paßgang.
+
+* Made the BackupPC icon a link to the SF BackupPC project page.
+
+#------------------------------------------------------------------------
+# Version 2.1.0beta1, 4 Apr 2004
+#------------------------------------------------------------------------
+
 * The CSS definition has been removed from the config.pl file and
   is now a separate file, BackupPC_stnd.css.  A new config variable,
   $Conf{CgiCSSFile}, gives the name of the CSS file to use.
@@ -41,7 +98,7 @@
   Wayne Scott.
 
 * Allow several BackupPC_nightly processes to run in parallel based
-  on new $Conf{MaxBackupPCNightlyJobs} setting.  This speeds up the
+  on new $Conf{BackupPCNightlyJobs} setting.  This speeds up the
   traversal of the pool, reducing the overall run time for
   BackupPC_nightly.
 
index 585eec1..3d86d96 100755 (executable)
@@ -1531,6 +1531,18 @@ sub StatusWrite
     }
 }
 
+#
+# Compare function for host sort.  Hosts with errors go first,
+# sorted with the oldest errors first.  The remaining hosts
+# are sorted so that those with the oldest backups go first.
+#
+sub HostSortCompare
+{
+    return -1 if ( $Status{$a}{error} ne "" && $Status{$b}{error} eq "" );
+    return  1 if ( $Status{$a}{error} eq "" && $Status{$b}{error} ne "" );
+    return $Status{$a}{endTime} <=> $Status{$b}{endTime};
+}
+
 #
 # Queue all the hosts for backup.  This means queuing all the fixed
 # ip hosts and all the dhcp address ranges.  We also additionally
@@ -1538,7 +1550,7 @@ sub StatusWrite
 #
 sub QueueAllPCs
 {
-    foreach my $host ( sort(keys(%$Hosts)) ) {
+    foreach my $host ( sort(HostSortCompare keys(%$Hosts)) ) {
         delete($Status{$host}{backoffTime})
                 if ( defined($Status{$host}{backoffTime})
                   && $Status{$host}{backoffTime} < time );
index 3ac9ebc..5ea4259 100755 (executable)
@@ -276,6 +276,7 @@ my $lastFull = 0;
 my $lastIncr = 0;
 my $partialIdx = -1;
 my $partialNum;
+my $lastPartial = 0;
 
 if ( $Conf{FullPeriod} == -1 && !$opts{f} && !$opts{i}
         || $Conf{FullPeriod} == -2 ) {
@@ -375,8 +376,9 @@ for ( my $i = 0 ; $i < @Backups ; $i++ ) {
         $lastIncr = $Backups[$i]{startTime}
                 if ( $lastIncr < $Backups[$i]{startTime} );
     } elsif ( $Backups[$i]{type} eq "partial" ) {
-        $partialIdx = $i;
-        $partialNum = $Backups[$i]{num};
+        $partialIdx  = $i;
+        $lastPartial = $Backups[$i]{startTime};
+        $partialNum  = $Backups[$i]{num};
     }
 }
 
@@ -444,10 +446,10 @@ if ( !defined($XferLOG) ) {
 }
 
 #
-# Ignore the partial dump in the case of an incremental.
-# A partial is a partial full.
+# Ignore the partial dump in the case of an incremental
+# or when the partial is too old.  A partial is a partial full.
 #
-if ( $type ne "full" ) {
+if ( $type ne "full" || time - $lastPartial > $Conf{PartialAgeMax} * 24*3600 ) {
     $partialNum = undef;
     $partialIdx = -1;
 }
@@ -1008,6 +1010,11 @@ sub BackupFailCleanup
        }
     }
 
+    #
+    # Don't keep partials if they are disabled
+    #
+    $keepPartial = 0 if ( $Conf{PartialAgeMax} < 0 );
+
     if ( !$keepPartial ) {
         #
         # No point in saving this dump; get rid of eveything.
index fdef553..c18dc95 100755 (executable)
@@ -115,6 +115,7 @@ my $ExistFileSize     = 0;
 my $ExistFileCompSize = 0;
 my $TotalFileCnt      = 0;
 my $TotalFileSize     = 0;
+my $TarReadHdrCnt     = 0;
 
 sub TarRead
 {
@@ -128,6 +129,7 @@ sub TarRead
                         substr($data, $numBytes, $totBytes - $numBytes),
                         $totBytes - $numBytes);
         if ( $newBytes <= 0 ) {
+           return if ( $TarReadHdrCnt == 1 );   # empty tar file ok
             print("Unexpected end of tar archive (tot = $totBytes,"
                    . " num = $numBytes, posn = " . sysseek($fh, 0, 1) . ")\n");
             $Abort = 1;
@@ -144,6 +146,7 @@ sub TarReadHeader
 {
     my($fh) = @_;
 
+    $TarReadHdrCnt++;
     return $1 if ( TarRead($fh, $tar_header_length) =~ /(.*)/s );
     return;
 }
@@ -423,26 +426,30 @@ sub attributeWrite
         my $poolWrite = BackupPC::PoolWrite->new($bpc, $fileName,
                                          length($data), $Compress);
         $poolWrite->write(\$data);
-        processClose($poolWrite, $Attrib{$d}->fileName($d), length($data));
+        processClose($poolWrite, $Attrib{$d}->fileName($d), length($data), 1);
     }
     delete($Attrib{$d});
 }
 
 sub processClose
 {
-    my($poolWrite, $fileName, $origSize) = @_;
+    my($poolWrite, $fileName, $origSize, $noStats) = @_;
     my($exists, $digest, $outSize, $errs) = $poolWrite->close;
 
     if ( @$errs ) {
         print(join("", @$errs));
         $Errors += @$errs;
     }
-    $TotalFileCnt++;
-    $TotalFileSize += $origSize;
+    if ( !$noStats ) {
+       $TotalFileCnt++;
+       $TotalFileSize += $origSize;
+    }
     if ( $exists ) {
-        $ExistFileCnt++;
-        $ExistFileSize     += $origSize;
-        $ExistFileCompSize += $outSize;
+       if ( !$noStats ) {
+           $ExistFileCnt++;
+           $ExistFileSize     += $origSize;
+           $ExistFileCompSize += $outSize;
+       }
     } elsif ( $outSize > 0 ) {
         print(NEW_FILES "$digest $origSize $fileName\n");
     }
index a3fbe87..81b85ad 100755 (executable)
@@ -86,8 +86,6 @@ my %ActionDispatch = (
 # Set default actions, then call sub handler
 #
 $In{action} ||= "hostInfo"    if ( defined($In{host}) );
-## rk default non admin users to pc summary for their hosts
-$In{action}   = "summary" if ( !defined($ActionDispatch{$In{action}}) && !CheckPermission());
 $In{action}   = "generalInfo" if ( !defined($ActionDispatch{$In{action}}) );
 my $action    = $ActionDispatch{$In{action}};
 
index d8bf145..47d7ac7 100644 (file)
@@ -504,6 +504,21 @@ $Conf{IncrKeepCnt} = 6;
 $Conf{IncrKeepCntMin} = 1;
 $Conf{IncrAgeMax}     = 30;
 
+#
+# A failed full backup is saved as a partial backup.  The rsync
+# XferMethod can take advantage of the partial full when the next
+# backup is run. This parameter sets the age of the partial full
+# in days: if the partial backup is older than this number of
+# days, then rsync will ignore (not use) the partial full when
+# the next backup is run.  If you set this to a negative value
+# then no partials will be saved.  If you set this to 0, partials
+# will be saved, but will not be used by the next backup.
+#
+# The default setting of 3 days means that a partial older than
+# 3 days is ignored when the next full backup is done.
+#
+$Conf{PartialAgeMax} = 3;
+
 #
 # Whether incremental backups are filled.  "Filling" means that the
 # most recent full (or filled) dump is merged into the new incremental
@@ -980,6 +995,29 @@ $Conf{RsyncdPasswd} = '';
 #
 $Conf{RsyncdAuthRequired} = 1;
 
+#
+# When rsync checksum caching is enabled (by adding the
+# --checksum-seed=32761 option to $Conf{RsyncArgs}), the cached
+# checksums can be occaisonally verified to make sure the file
+# contents matches the cached checksums.  This is to avoid the
+# risk that disk problems might cause the pool file contents to
+# get corrupted, but the cached checksums would make BackupPC
+# think that the file still matches the client.
+#
+# This setting is the probability (0 means never and 1 means always)
+# that a file will be rechecked.  Setting it to 0 means the checksums
+# will not be rechecked (unless there is a phase 0 failure).  Setting
+# it to 1 (ie: 100%) means all files will be checked, but that is
+# not a desirable setting since you are better off simply turning
+# caching off (ie: remove the --checksum-seed option).
+#   
+# The default of 0.01 means 1% (on average) of the files during a full
+# backup will have their cached checksum re-checked.
+#   
+# This setting has no effect unless checksum caching is turned on.
+#   
+$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.
@@ -1010,10 +1048,10 @@ $Conf{RsyncArgs} = [
 
            #
            # If you are using a patched client rsync that supports the
-           # --fixed-csumseed option (see http://backuppc.sourceforge.net),
+           # --checksum-seed option (see http://backuppc.sourceforge.net),
            # then uncomment this to enabled rsync checksum cachcing
            #
-           #'--fixed-csumseed',
+           #'--checksum-seed=32761',
 
            #
            # Add additional arguments here
@@ -1046,10 +1084,10 @@ $Conf{RsyncRestoreArgs} = [
 
            #
            # If you are using a patched client rsync that supports the
-           # --fixed-csumseed option (see http://backuppc.sourceforge.net),
+           # --checksum-seed option (see http://backuppc.sourceforge.net),
            # then uncomment this to enabled rsync checksum cachcing
            #
-           #'--fixed-csumseed',
+           #'--checksum-seed=32761',
 
            #
            # Add additional arguments here
@@ -1605,6 +1643,33 @@ $Conf{CgiDateFormatMMDD} = 1;
 #
 $Conf{CgiNavBarAdminAllHosts} = 1;
 
+#
+# Enable/disable the search box in the navigation bar.
+#
+$Conf{CgiSearchBoxEnable} = 1;
+
+#
+# Additional navigation bar links.  These appear for both regular users
+# and administrators.  This is a list of hashes giving the link (URL)
+# and the text (name) for the link.  Specifying lname instead of name
+# uses the language specific string (ie: $Lang->{lname}) instead of
+# just literally displaying name.
+#
+$Conf{CgiNavBarLinks} = [
+    {
+        link  => "?action=view&type=docs",
+        lname => "Documentation",    # actually displays $Lang->{Documentation}
+    },
+    {
+        link  => "http://backuppc.sourceforge.net/faq",
+        name  => "FAQ",              # displays literal "FAQ"
+    },
+    {
+        link  => "http://backuppc.sourceforge.net",
+        name  => "SourceForge",      # displays literal "SourceForge"
+    },
+];
+
 #
 # Hilight colors based on status that are used in the PC summary page.
 #
index 09d99b7..dfc9006 100755 (executable)
@@ -33,7 +33,7 @@
 #
 #========================================================================
 #
-# Version 2.0.0_CVS, released 18 Jan 2003.
+# Version 2.1.0beta1, released 9 Apr 2004.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -44,13 +44,27 @@ no  utf8;
 use vars qw(%Conf %OrigConf);
 use lib "./lib";
 
-my @Packages = qw(ExtUtils::MakeMaker File::Path File::Spec File::Copy
-                  DirHandle Digest::MD5 Data::Dumper Getopt::Std
-                 BackupPC::Lib BackupPC::FileZIO);
+my @Packages = qw(File::Path File::Spec File::Copy DirHandle Digest::MD5
+                  Data::Dumper Getopt::Std Getopt::Long Pod::Usage
+                  BackupPC::Lib BackupPC::FileZIO);
 
 foreach my $pkg ( @Packages ) {
     eval "use $pkg";
     next if ( !$@ );
+    if ( $pkg =~ /BackupPC/ ) {
+        die <<EOF;
+
+BackupPC cannot find the package $pkg, which is included in the
+BackupPC distribution.  This probably means you did not cd to the
+unpacked BackupPC distribution before running configure.pl, eg:
+
+    cd BackupPC-__VERSION__
+    ./configure.pl
+
+Please try again.
+
+EOF
+    }
     die <<EOF;
 
 BackupPC needs the package $pkg.  Please install $pkg
@@ -59,6 +73,30 @@ before installing BackupPC.
 EOF
 }
 
+my %opts;
+if ( !GetOptions(
+            \%opts,
+            "batch",
+            "bin-path=s%",
+            "config-path=s",
+            "cgi-dir=s",
+            "data-dir=s",
+            "dest-dir=s",
+            "help|?",
+            "hostname=s",
+            "html-dir=s",
+            "html-dir-url=s",
+            "install-dir=s",
+            "man",
+            "uid-ignore",
+        ) || @ARGV ) {
+    pod2usage(2);
+}
+pod2usage(1) if ( $opts{help} );
+pod2usage(-exitstatus => 0, -verbose => 2) if $opts{man};
+
+my $DestDir = $opts{"dest-dir"};
+
 if ( $< != 0 ) {
     print <<EOF;
 
@@ -68,7 +106,9 @@ install directories, then it should be ok to proceed.  Otherwise,
 please quit and restart as root.
 
 EOF
-    exit unless prompt("--> Do you want to continue?", "y") =~ /y/i;
+    exit(1) if ( prompt("--> Do you want to continue?",
+                       "y") !~ /y/i );
+    exit(1) if ( $opts{batch} && !$opts{"uid-ignore"} );
 }
 
 print <<EOF;
@@ -87,7 +127,8 @@ EOF
 my $ConfigPath = "";
 while ( 1 ) {
     $ConfigPath = prompt("--> Full path to existing conf/config.pl",
-                                    $ConfigPath);
+                         $ConfigPath,
+                         "config-path");
     last if ( $ConfigPath eq ""
             || ($ConfigPath =~ /^\// && -r $ConfigPath && -w $ConfigPath) );
     my $problem = "is not an absolute path";
@@ -95,6 +136,10 @@ while ( 1 ) {
     $problem = "is not readable" if ( !-r $ConfigPath );
     $problem = "doesn't exist"   if ( !-f $ConfigPath );
     print("The file '$ConfigPath' $problem.\n");
+    if ( $opts{batch} ) {
+        print("Need to specify a valid --config-path for upgrade\n");
+        exit(1);
+    }
 }
 my $bpc;
 if ( $ConfigPath ne "" && -r $ConfigPath ) {
@@ -141,10 +186,10 @@ my %Programs = (
 foreach my $prog ( sort(keys(%Programs)) ) {
     my $path;
     foreach my $subProg ( split(/\//, $prog) ) {
-        $path ||= FindProgram("$ENV{PATH}:/bin:/usr/bin:/sbin:/usr/sbin",
-                              $subProg);
+        $path = FindProgram("$ENV{PATH}:/bin:/usr/bin:/sbin:/usr/sbin",
+                            $subProg) if ( !length($path) );
     }
-    $Conf{$Programs{$prog}} ||= $path;
+    $Conf{$Programs{$prog}} = $path if ( !length($Conf{$Programs{$prog}}) );
 }
 
 while ( 1 ) {
@@ -185,7 +230,9 @@ Please tell me the hostname of the machine that BackupPC will run on.
 EOF
 chomp($Conf{ServerHost} = `$Conf{HostnamePath}`)
         if ( defined($Conf{HostnamePath}) && !defined($Conf{ServerHost}) );
-$Conf{ServerHost} = prompt("--> BackupPC will run on host", $Conf{ServerHost});
+$Conf{ServerHost} = prompt("--> BackupPC will run on host",
+                           $Conf{ServerHost},
+                           "hostname");
 
 print <<EOF;
 
@@ -203,7 +250,8 @@ EOF
 my($name, $passwd, $Uid, $Gid);
 while ( 1 ) {
     $Conf{BackupPCUser} = prompt("--> BackupPC should run as user",
-                                 $Conf{BackupPCUser} || "backuppc");
+                                 $Conf{BackupPCUser} || "backuppc",
+                                 "username");
     ($name, $passwd, $Uid, $Gid) = getpwnam($Conf{BackupPCUser});
     last if ( $name ne "" );
     print <<EOF;
@@ -212,6 +260,7 @@ getpwnam() says that user $Conf{BackupPCUser} doesn't exist.  Please check the
 name and verify that this user is in the passwd file.
 
 EOF
+    exit(1) if ( $opts{batch} );
 }
 
 print <<EOF;
@@ -223,8 +272,13 @@ EOF
 
 while ( 1 ) {
     $Conf{InstallDir} = prompt("--> Install directory (full path)",
-                               $Conf{InstallDir});
+                               $Conf{InstallDir},
+                               "install-dir");
     last if ( $Conf{InstallDir} =~ /^\// );
+    if ( $opts{batch} ) {
+        print("Need to specify --install-dir for new installation\n");
+        exit(1);
+    }
 }
 
 print <<EOF;
@@ -237,8 +291,14 @@ PCs you expect to backup (eg: at least 1-2GB per machine).
 EOF
 
 while ( 1 ) {
-    $Conf{TopDir} = prompt("--> Data directory (full path)", $Conf{TopDir});
+    $Conf{TopDir} = prompt("--> Data directory (full path)",
+                           $Conf{TopDir},
+                           "data-dir");
     last if ( $Conf{TopDir} =~ /^\// );
+    if ( $opts{batch} ) {
+        print("Need to specify --data-dir for new installation\n");
+        exit(1);
+    }
 }
 
 if ( !defined($Conf{CompressLevel}) ) {
@@ -318,8 +378,14 @@ Leave this path empty if you don't want to install the CGI interface.
 EOF
 
 while ( 1 ) {
-    $Conf{CgiDir} = prompt("--> CGI bin directory (full path)", $Conf{CgiDir});
+    $Conf{CgiDir} = prompt("--> CGI bin directory (full path)",
+                           $Conf{CgiDir},
+                           "cgi-dir");
     last if ( $Conf{CgiDir} =~ /^\// || $Conf{CgiDir} eq "" );
+    if ( $opts{batch} ) {
+        print("Need to specify --cgi-dir for new installation\n");
+        exit(1);
+    }
 }
 
 if ( $Conf{CgiDir} ne "" ) {
@@ -339,13 +405,23 @@ The URL for the image directory should start with a slash.
 EOF
     while ( 1 ) {
        $Conf{CgiImageDir} = prompt("--> Apache image directory (full path)",
-                                       $Conf{CgiImageDir});
+                                    $Conf{CgiImageDir},
+                                    "html-dir");
        last if ( $Conf{CgiImageDir} =~ /^\// );
+        if ( $opts{batch} ) {
+            print("Need to specify --html-dir for new installation\n");
+            exit(1);
+        }
     }
     while ( 1 ) {
        $Conf{CgiImageDirURL} = prompt("--> URL for image directory (omit http://host; starts with '/')",
-                                       $Conf{CgiImageDirURL});
+                                       $Conf{CgiImageDirURL},
+                                        "html-dir-url");
        last if ( $Conf{CgiImageDirURL} =~ /^\// );
+        if ( $opts{batch} ) {
+            print("Need to specify --html-dir-url for new installation\n");
+            exit(1);
+        }
     }
 }
 
@@ -371,13 +447,13 @@ foreach my $dir ( qw(bin doc
                     lib/BackupPC/Xfer
                     lib/BackupPC/Zip
                 ) ) {
-    next if ( -d "$Conf{InstallDir}/$dir" );
-    mkpath("$Conf{InstallDir}/$dir", 0, 0775);
-    if ( !-d "$Conf{InstallDir}/$dir"
-            || !chown($Uid, $Gid, "$Conf{InstallDir}/$dir") ) {
-        die("Failed to create or chown $Conf{InstallDir}/$dir\n");
+    next if ( -d "$DestDir$Conf{InstallDir}/$dir" );
+    mkpath("$DestDir$Conf{InstallDir}/$dir", 0, 0775);
+    if ( !-d "$DestDir$Conf{InstallDir}/$dir"
+            || !chown($Uid, $Gid, "$DestDir$Conf{InstallDir}/$dir") ) {
+        die("Failed to create or chown $DestDir$Conf{InstallDir}/$dir\n");
     } else {
-        print("Created $Conf{InstallDir}/$dir\n");
+        print("Created $DestDir$Conf{InstallDir}/$dir\n");
     }
 }
 
@@ -386,11 +462,11 @@ foreach my $dir ( qw(bin doc
 #
 foreach my $dir ( ($Conf{CgiImageDir}) ) {
     next if ( $dir eq "" || -d $dir );
-    mkpath($dir, 0, 0775);
-    if ( !-d $dir || !chown($Uid, $Gid, $dir) ) {
-        die("Failed to create or chown $dir");
+    mkpath("$DestDir$dir", 0, 0775);
+    if ( !-d "$DestDir$dir" || !chown($Uid, $Gid, "$DestDir$dir") ) {
+        die("Failed to create or chown $DestDir$dir");
     } else {
-        print("Created $dir\n");
+        print("Created $DestDir$dir\n");
     }
 }
 
@@ -398,30 +474,25 @@ foreach my $dir ( ($Conf{CgiImageDir}) ) {
 # Create $TopDir's top-level directories
 #
 foreach my $dir ( qw(. conf pool cpool pc trash log) ) {
-    mkpath("$Conf{TopDir}/$dir", 0, 0750) if ( !-d "$Conf{TopDir}/$dir" );
-    if ( !-d "$Conf{TopDir}/$dir"
-            || !chown($Uid, $Gid, "$Conf{TopDir}/$dir") ) {
-        die("Failed to create or chown $Conf{TopDir}/$dir\n");
+    mkpath("$DestDir$Conf{TopDir}/$dir", 0, 0750) if ( !-d "$DestDir$Conf{TopDir}/$dir" );
+    if ( !-d "$DestDir$Conf{TopDir}/$dir"
+            || !chown($Uid, $Gid, "$DestDir$Conf{TopDir}/$dir") ) {
+        die("Failed to create or chown $DestDir$Conf{TopDir}/$dir\n");
     } else {
-        print("Created $Conf{TopDir}/$dir\n");
+        print("Created $DestDir$Conf{TopDir}/$dir\n");
     }
 }
 
-printf("Installing binaries in $Conf{InstallDir}/bin\n");
+printf("Installing binaries in $DestDir$Conf{InstallDir}/bin\n");
 foreach my $prog ( qw(BackupPC BackupPC_dump BackupPC_link BackupPC_nightly
         BackupPC_sendEmail BackupPC_tarCreate BackupPC_trashClean
         BackupPC_tarExtract BackupPC_compressPool BackupPC_zcat
         BackupPC_archive BackupPC_archiveHost
         BackupPC_restore BackupPC_serverMesg BackupPC_zipCreate ) ) {
-    InstallFile("bin/$prog", "$Conf{InstallDir}/bin/$prog", 0555);
+    InstallFile("bin/$prog", "$DestDir$Conf{InstallDir}/bin/$prog", 0555);
 }
 
-#
-# Remove unused binaries from older versions
-#
-unlink("$Conf{InstallDir}/bin/BackupPC_queueAll");
-
-printf("Installing library in $Conf{InstallDir}/lib\n");
+printf("Installing library in $DestDir$Conf{InstallDir}/lib\n");
 foreach my $lib ( qw(
        BackupPC/Lib.pm
        BackupPC/FileZIO.pm
@@ -461,25 +532,25 @@ foreach my $lib ( qw(
        BackupPC/CGI/Summary.pm
        BackupPC/CGI/View.pm
     ) ) {
-    InstallFile("lib/$lib", "$Conf{InstallDir}/lib/$lib", 0444);
+    InstallFile("lib/$lib", "$DestDir$Conf{InstallDir}/lib/$lib", 0444);
 }
 
 if ( $Conf{CgiImageDir} ne "" ) {
-    printf("Installing images in $Conf{CgiImageDir}\n");
+    printf("Installing images in $DestDir$Conf{CgiImageDir}\n");
     foreach my $img ( <images/*> ) {
        (my $destImg = $img) =~ s{^images/}{};
-       InstallFile($img, "$Conf{CgiImageDir}/$destImg", 0444, 1);
+       InstallFile($img, "$DestDir$Conf{CgiImageDir}/$destImg", 0444, 1);
     }
 
     #
     # Install new CSS file, making a backup copy if necessary
     #
-    my $cssBackup = "$Conf{CgiImageDir}/BackupPC_stnd.css.pre-__VERSION__";
-    if ( -f "$Conf{CgiImageDir}/BackupPC_stnd.css" && !-f $cssBackup ) {
-       rename("$Conf{CgiImageDir}/BackupPC_stnd.css", $cssBackup);
+    my $cssBackup = "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css.pre-__VERSION__";
+    if ( -f "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css" && !-f $cssBackup ) {
+       rename("$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css", $cssBackup);
     }
     InstallFile("conf/BackupPC_stnd.css",
-               "$Conf{CgiImageDir}/BackupPC_stnd.css", 0444, 0);
+               "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css", 0444, 0);
 }
 
 printf("Making init.d scripts\n");
@@ -488,21 +559,21 @@ foreach my $init ( qw(gentoo-backuppc gentoo-backuppc.conf linux-backuppc
     InstallFile("init.d/src/$init", "init.d/$init", 0444);
 }
 
-printf("Installing docs in $Conf{InstallDir}/doc\n");
+printf("Installing docs in $DestDir$Conf{InstallDir}/doc\n");
 foreach my $doc ( qw(BackupPC.pod BackupPC.html) ) {
-    InstallFile("doc/$doc", "$Conf{InstallDir}/doc/$doc", 0444);
+    InstallFile("doc/$doc", "$DestDir$Conf{InstallDir}/doc/$doc", 0444);
 }
 
-printf("Installing config.pl and hosts in $Conf{TopDir}/conf\n");
-InstallFile("conf/hosts", "$Conf{TopDir}/conf/hosts", 0644)
-                    if ( !-f "$Conf{TopDir}/conf/hosts" );
+printf("Installing config.pl and hosts in $DestDir$Conf{TopDir}/conf\n");
+InstallFile("conf/hosts", "$DestDir$Conf{TopDir}/conf/hosts", 0644)
+                    if ( !-f "$DestDir$Conf{TopDir}/conf/hosts" );
 
 #
 # Now do the config file.  If there is an existing config file we
 # merge in the new config file, adding any new configuration
 # parameters and deleting ones that are no longer needed.
 #
-my $dest = "$Conf{TopDir}/conf/config.pl";
+my $dest = "$DestDir$Conf{TopDir}/conf/config.pl";
 my ($newConf, $newVars) = ConfigParse("conf/config.pl");
 my ($oldConf, $oldVars);
 if ( -f $dest ) {
@@ -656,9 +727,9 @@ if ( !defined($oldConf) ) {
 }
 
 if ( $Conf{CgiDir} ne "" ) {
-    printf("Installing cgi script BackupPC_Admin in $Conf{CgiDir}\n");
-    mkpath("$Conf{CgiDir}", 0, 0755);
-    InstallFile("cgi-bin/BackupPC_Admin", "$Conf{CgiDir}/BackupPC_Admin",
+    printf("Installing cgi script BackupPC_Admin in $DestDir$Conf{CgiDir}\n");
+    mkpath("$DestDir$Conf{CgiDir}", 0, 0755);
+    InstallFile("cgi-bin/BackupPC_Admin", "$DestDir$Conf{CgiDir}/BackupPC_Admin",
                 04554);
 }
 
@@ -705,9 +776,9 @@ EOF
 }
 
 eval "use File::RsyncP;";
-if ( !$@ && $File::RsyncP::VERSION < 0.50 ) {
+if ( !$@ && $File::RsyncP::VERSION < 0.51 ) {
     print("\nWarning: you need to upgrade File::RsyncP;"
-        . " I found $File::RsyncP::VERSION and BackupPC needs 0.50\n");
+        . " I found $File::RsyncP::VERSION and BackupPC needs 0.51\n");
 }
 
 exit(0);
@@ -764,10 +835,15 @@ sub InstallFile
 sub FindProgram
 {
     my($path, $prog) = @_;
+
+    if ( defined($opts{"bin-path"}{$prog}) ) {
+        return $opts{"bin-path"}{$prog};
+    }
     foreach my $dir ( split(/:/, $path) ) {
         my $file = File::Spec->catfile($dir, $prog);
         return $file if ( -x $file );
     }
+    return;
 }
 
 sub ConfigParse
@@ -864,3 +940,189 @@ sub ConfigMerge
     }
     return $res;
 }
+
+sub prompt
+{
+    my($question, $default, $option) = @_;
+
+    $default = $opts{$option} if ( defined($opts{$option}) );
+    if ( $opts{batch} ) {
+        print("$question [$default]\n");
+        return $default;
+    }
+    print("$question [$default]? ");
+    my $reply = <STDIN>;
+    $reply =~ s/[\n\r]*//g;
+    return $reply if ( $reply !~ /^$/ );
+    return $default;
+}
+
+__END__
+
+=head1 SYNOPSIS
+
+configure.pl [options]
+
+=head1 DESCRIPTION
+
+configure.pl is a script that is used to install or upgrade a BackupPC
+installation.  It is usually run interactively without arguments.  It
+also supports a batch mode where all the options can be specified
+via the command-line.
+
+For upgrading BackupPC you need to make sure that BackupPC is not
+running prior to running BackupPC.
+
+Typically configure.pl needs to run as the super user (root).
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<--batch>
+
+Run configure.pl in batch mode.  configure.pl will run without
+prompting the user.  The other command-line options are used
+to specify the settings that the user is usually prompted for.
+
+=item B<--bin-path PROG=PATH>
+
+Specify the path for various external programs that BackupPC
+uses.  Several --bin-path options may be specified.  configure.pl
+usually finds sensible defaults based on searching the PATH.
+The format is:
+
+    --bin-path PROG=PATH
+
+where PROG is one of perl, tar, smbclient, nmblookup, rsync, ping,
+df, ssh, sendmail, hostname, split, par2, cat, gzip, bzip2 and
+PATH is that full path to that program.
+
+Examples
+
+    --bin-path cat=/bin/cat --bin-path bzip2=/home/user/bzip2
+
+=item B<--config-path CONFIG_PATH>
+
+Path to the existing config.pl configuration file for BackupPC.
+This option should be specified for batch upgrades to an
+existing installation.  The option should be omitted when
+doing a batch new install.
+
+=item B<--cgi-dir CGI_DIR>
+
+Path to Apache's cgi-bin directory where the BackupPC_Admin
+script will be installed.  This option only needs to be
+specified for a batch new install.
+
+=item B<--data-dir DATA_DIR>
+
+Path to the BackupPC data directory.  This is where all the backup
+data is stored, and it should be on a large file system. This option
+only needs to be specified for a batch new install.
+
+Example:
+
+    --data-dir /data/BackupPC
+
+=item B<--dest-dir DEST_DIR>
+
+An optional prefix to apply to all installation directories.
+Usually this is not needed, but certain auto-installers like
+to stage an install in a temporary directory, and then copy
+the files to their real destination.  This option can be used
+to specify the temporary directory prefix.  Note that if you
+specify this option, BackupPC won't run correctly if you try
+to run it from below the --dest-dir directory, since all the
+paths are set assuming BackupPC is installed in the intended
+final locations.
+
+=item B<--help|?>
+
+Print a brief help message and exits.
+
+=item B<--hostname HOSTNAME>
+
+Host name (this machine's name) on which BackupPC is being installed.
+This option only needs to be specified for a batch new install.
+
+=item B<--html-dir HTML_DIR>
+
+Path to an Apache html directory where various BackupPC image files
+and the CSS files will be installed.  This is typically a directory
+below Apache's DocumentRoot directory.  This option only needs to be
+specified for a batch new install.
+
+Example:
+
+    --html-dir /usr/local/apache/htdocs/BackupPC
+
+=item B<--html-dir-url URL>
+
+The URL (without http://hostname) required to access the BackupPC html
+directory specified with the --html-dir option.  This option only needs
+to be specified for a batch new install.
+
+Example:
+
+    --html-dir-url /BackupPC
+
+=item B<--install-dir INSTALL_DIR>
+
+Installation directory for BackupPC scripts, libraries, and
+documentation.  This option only needs to be specified for a
+batch new install.
+
+Example:
+
+    --install-dir /usr/local/BackupPC
+
+=item B<--man>
+
+Prints the manual page and exits.
+
+=item B<--uid-ignore>
+
+configure.pl verifies that the script is being run as the super user
+(root).  Without the --uid-ignore option, in batch mode the script will
+exit with an error if not run as the super user, and in interactive mode
+the user will be prompted.  Specifying this option will cause the script
+to continue even if the user id is not root.
+
+=head1 EXAMPLES
+
+For a standard interactive install, run without arguments:
+
+    configure.pl
+
+For a batch new install you need to specify answers to all the
+questions that are normally prompted:
+
+    configure.pl                                   \
+        --batch                                    \
+        --cgi-dir /var/www/cgi-bin/BackupPC        \
+        --data-dir /data/BackupPC                  \
+        --hostname myHost                          \
+        --html-dir /var/www/html/BackupPC          \
+        --html-dir-url /BackupPC                   \
+        --install-dir /usr/local/BackupPC
+
+For a batch upgrade, you only need to specify the path to the
+configuration file:
+        
+    configure.pl --batch --config-path /data/BackupPC/conf/config.pl
+
+=head1 AUTHOR
+
+Craig Barratt <cbarratt@users.sourceforge.net>
+
+=head1 COPYRIGHT
+
+Copyright (C) 2001-2004  Craig Barratt.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+=cut
index 75bcc63..1362a97 100644 (file)
@@ -204,6 +204,13 @@ Three BackupPC mailing lists exist for announcements (backuppc-announce),
 developers (backuppc-devel), and a general user list for support, asking
 questions or any other topic relevant to BackupPC (backuppc-users).
 
+The lists are archived on SourceForge and Gmane.  The SourceForge lists
+are not always up to date and the searching is limited, so Gmane is
+a good alternative.  See:
+
+    http://news.gmane.org/index.php?prefix=gmane.comp.sysutils.backup.backuppc
+    http://sourceforge.net/mailarchive/forum.php?forum_id=503
+
 You can subscribe to these lists by visiting:
 
     http://lists.sourceforge.net/lists/listinfo/backuppc-announce
@@ -267,12 +274,30 @@ releases of BackupPC:
 
 =item *
 
-Develop a FAQ and move some significant parts of this document
-to the FAQ (eg: ssh setup, this roadmap etc).  Volunteers?
+Adding hardlink support to rsync.  Currently the tar XferMethod
+correctly saves/restores hardlinks, but rsync does not.  Rsync
+2.6.2 has greatly improved the efficiency of saving hardlink
+information, so File::RsyncP and BackupPC::Xfer::RsyncFileIO need
+the corresponding changes.  Hardlink support is necessary for
+doing a bare-metal restore of a *nix system.
 
 =item *
 
-Adding hardlink support to rsync.
+Adding more complete utf8 support.  BackupPC should use utf8 as the
+native charset for storing file names, and the CGI script should emit
+utf8 so that the file names can be rendered correctly.  Additional
+configuration parameters should allow you to specify the client Xfer
+charset (ie: the filcharset delivered by the XferMethod).  BackupPC
+should encode/decode between this charset and utf8 when doing a
+backup/restore. That way BackupPC can store all files in utf8 no
+matter what charset is used by the XferMethod to deliver the file
+names.  Secondly, the CGI charset should be configurable (default
+utf8) and the CGI script BackupPC_Admin should encode the utf8 file
+names in the desired output charset.  Finally, the charset used to
+deliver file names when restoring individual file names should also
+be configurable, and again BackupPC_Admin should encode the file
+names in this charset (again, utf8 default).  That should allow the
+"Save As" IE dialog to default to the correct file name.
 
 =item *
 
@@ -297,6 +322,17 @@ be specified (eg: MySQL, ascii text etc).
 
 =item *
 
+Because of file name mangling (adding "f" to start of each file
+name) and with pending utf8 changes, BackupPC is not able to
+store files whose file name length is 255 bytes or greater. The
+format of the attrib file should be extended so that very long
+file names (ie: >= 255) are abbreviated on the file system, but
+the full name is stored in the attrib file.  This could also be
+used to eliminate the leading "f", since that is there to avoid
+collisions with the attrib file.
+
+=item *
+
 Replacing smbclient with the perl module FileSys::SmbClient.  This
 gives much more direct control of the smb transfer, allowing
 incrementals to depend on any attribute change (eg: exist, mtime,
@@ -304,71 +340,42 @@ file size, uid, gid), and better support for include and exclude.
 Currently smbclient incrementals only depend upon mtime, so
 deleted files or renamed files are not detected.  FileSys::SmbClient
 would also allow resuming of incomplete full backups in the
-same manner as rsync will.  (I'm not sure if FileSys::SmbClient
-has been updated for samba 3.x.)
+same manner as rsync will.
 
 =item *
 
-Possibly support --listed-incremental or --incremental for tar, so that
-incrementals will depend upon any attribute change (eg: exist, mtime,
-file size, uid, gid), rather than just mtime.  This will allow tar to
-be to as capable as FileSys::SmbClient and rsync.
+Support --listed-incremental or --incremental for tar,
+so that incrementals will depend upon any attribute change (eg: exist,
+mtime, file size, uid, gid), rather than just mtime.  This will allow
+tar to be to as capable as FileSys::SmbClient and rsync.  This is
+low priority since rsync is really the preferred method.
+
+=item *
+
+In addition to allowing a specific backup (incremental or full) to
+be started from the CGI interface, also allow a "regular" backup
+to be started.  This would behave just like a regular background
+backup and determine whether a full, incremental or nothing
+should be done.
 
 =item *
 
 For rysnc (and smb when FileSys::SmbClient is supported, and tar when
 --listed-incremental is supported) support multi-level incrementals.
 In fact, since incrementals will now be more "accurate", you could
-choose to never to full dumps (except the first time), or at a
+choose to never do full backups (except the first time), or at a
 minimum do them infrequently: each incremental would depend upon
-the last, giving a continuous chain of differential dumps.
-
-=item *
-
-Improve the warning messages about locked files on WinXX machines,
-so that more file types than just outlook pst files will produce
-warning emails (and configuration settings for specifying the
-file extensions that produce email warngings).
-
-=item *
-
-Long term, support bare metal restore.  For *nix machines there's
-not a lot to do (althought rsync needs hardlink support).  For
-WinXX machines the file locking problem has to get resolved.
-Plus ACL save/restore would need to be supported.  This is
-really long term.
+the last, giving a continuous chain of differential backups.
 
 =item *
 
-Support client pull for restores.  For example, BackupPC could
-emulate an rsync server.  That way you could boot a knoppix cd,
-and you wouldn't need perl, BackupPC, ssh setup or anything on
-the client to restore.  You would just run an rsync command like:
-
-    rsync -aH BackupPCServer::moduleName /path/to/emtpy/disk
-
-ModuleName could contain the client name, share name and backup number.
-There would have to be some way of specifying the password; perhaps
-the CGI could be used to "turn on" rsynd for a specific client and
-a specific time period (eg: only listens for X minutes, only serves
-up a specific client backup, accepts connections from a specific IP).
-BackupPC listens for and serves the request; it's not a real rsyncd on
-the server.
-
-=item *
-
-Add support for wget as an XferMethod.  This would allow ftp and http
-files to be backed up.  This might be useful, for example, for backing
-up the configuration of a router (via http), so that you have a
-backup copy of all the router setup screens in case the router
-fails.
-
-=item *
-
-Possibly support client push for backups, in addition to the
-existing server pull.  This would be helpful for clients behind
-firewalls who can connect to the server, but the server cannot
-see the client.
+Allow diffs between two different backed up files to be displayed.
+The history feature in 2.1.0 does show files that are the same
+between backups.  Most often we would like to just take the diff of
+the same host, path and file between different backups, but it would
+be nice to generalize it to any pair of files (ie: different hosts,
+backups, paths etc).  But I'm not sure how the user interface would
+look.
 
 =item *
 
@@ -381,7 +388,7 @@ around 15-20%, which isn't spectacular, and likely not worth the
 implementation effort. The program xdelta (v1) on SourceForge (see
 L<http://sourceforge.net/projects/xdelta>) uses an rsync algorithm for
 doing efficient binary file deltas.  Rather than using an external
-program, File::RsyncP will eventually get the necessary delta
+program, File::RsyncP would eventually get the necessary delta
 generation code from rsync.
 
 =back
@@ -407,7 +414,7 @@ time and money) for marketing, PR and advertising, so it's up to
 all of you!
 
 Also, everyone is encouraged to contribute patches, bug reports, feature
-and design suggestions, code, and documentation corrections or
+and design suggestions, new code, and documentation corrections or
 improvements.
 
 =head1 Installing BackupPC
@@ -443,8 +450,8 @@ compression is on.
 =item *
 
 Perl version 5.6.0 or later. BackupPC has been tested with
-version 5.6.0, 5.6.1 and 5.8.0. If you don't have perl, please
-see L<http://www.cpan.org>.
+version 5.6.0, 5.6.1, 5.8.0, 5.8.1 and 5.8.2. If you don't
+have perl, please see L<http://www.cpan.org>.
 
 =item *
 
@@ -465,6 +472,7 @@ you are backing up linux/unix DHCP machines.  See L<http://www.samba.org>.
 Version 2.2.0 or later of Samba is required (smbclient's tar feature in
 2.0.8 and prior has bugs for file path lengths around 100 characters
 and generates bad output when file lengths change during the backup).
+Samba versions 3.x are stable and recommended instead of 2.x.
 
 See L<http://www.samba.org> for source and binaries.  It's pretty easy to
 fetch and compile samba, and just grab smbclient and nmblookup, without
@@ -488,7 +496,8 @@ version.
 
 For BackupPC to use Rsync you will also need to install the perl
 File::RsyncP module, which is available from
-L<http://perlrsync.sourceforge.net>.  Version 0.44 or later is required.
+L<http://perlrsync.sourceforge.net>.
+Version 0.51 or later is required.
 
 =item *
 
@@ -600,8 +609,16 @@ BackupPC-__VERSION__.tar.gz, run these commands as root:
     cd BackupPC-__VERSION__
     perl configure.pl
 
-You will be prompted for the full paths of various executables, and
-you will be prompted for the following information:
+The configure.pl also accepts command-line options if you wish
+to run it in a non-interactive manner.  It has self-contained
+documentation for all the command-line options, which you can
+read with perldoc:
+
+    perldoc configure.pl
+
+When you run configure.pl you will be prompted for the full paths
+of various executables, and you will be prompted for the following
+information:
 
 =over 4
 
@@ -2309,15 +2326,6 @@ are using that file).  Again, to avoid race conditions, BackupPC_nightly
 is only run when there are no BackupPC_dump or BackupPC_link processes
 running.
 
-To improve the running time for BackupPC_nightly, several
-BackupPC_nightly processes can be run concurrently, based on
-the $Conf{MaxBackupPCNightlyJobs} setting.
-
-If BackupPC_nightly still takes too long to run,
-$Conf{BackupPCNightlyPeriod} can be used to split
-BackupPC_nightly's pool traversal across multiple nights,
-proportionally reducing its runtime each night.
-
 =back
 
 BackupPC also listens for TCP connections on $Conf{ServerPort}, which
index 4de942b..2ee5836 100644 (file)
@@ -80,7 +80,7 @@ EOF
     }
 
     my $content = eval("qq{$Lang->{Archive___num_details_for__host2 }}");
-    Header(eval("qq{$Lang->{Archive___num_details_for__host}}"),$content);
+    Header(eval("qq{$Lang->{Archive___num_details_for__host}}"), $content, 1);
     Trailer();
 }
 
index 0323d5e..8e1968a 100644 (file)
@@ -49,6 +49,7 @@ sub action
         my $startTime = timeStamp2($Jobs{$host}{startTime});
         next if ( $host eq $bpc->trashJob
                     && $Jobs{$host}{processState} ne "running" );
+        next if ( !$Privileged && !CheckPermission($host) );
         $Jobs{$host}{type} = $Status{$host}{type}
                     if ( $Jobs{$host}{type} eq "" && defined($Status{$host}));
         (my $cmd = $Jobs{$host}{cmd}) =~ s/$BinDir\///g;
@@ -70,6 +71,7 @@ EOF
                    && $Status{$host}{reason} ne "Reason_restore_failed"
                    && (!$Status{$host}{userReq}
                        || $Status{$host}{reason} ne "Reason_no_ping") );
+        next if ( !$Privileged && !CheckPermission($host) );
         my $startTime = timeStamp2($Status{$host}{startTime});
         my($errorTime, $XferViewStr);
         if ( $Status{$host}{errorTime} > 0 ) {
@@ -124,7 +126,9 @@ EOF
     } elsif ( $Info{cpoolFileCnt} > 0 ) {
         $poolInfo = $cpoolInfo;
     }
-    my $content = eval ("qq{$Lang->{BackupPC_Server_Status}}");
+    my $generalInfo = eval("qq{$Lang->{BackupPC_Server_Status_General_Info}}")
+                                if ( $Privileged );
+    my $content = eval("qq{$Lang->{BackupPC_Server_Status}}");
     Header($Lang->{H_BackupPC_Server_Status}, $content);
     Trailer();
 }
index 7af47e9..109e21b 100644 (file)
@@ -46,14 +46,16 @@ sub action
 
     $host =~ s/^\s+//;
     $host =~ s/\s+$//;
-    return Action_GeneralInfo() if ( $host eq "" );
+    if ( $host eq "" ) {
+       ErrorExit(eval("qq{$Lang->{Unknown_host_or_user}}"));
+    }
     $host = lc($host)
-                if ( !-d "$TopDir/pc/$host" && -d "$TopDir/pc/" . lc($host) );
+               if ( !-d "$TopDir/pc/$host" && -d "$TopDir/pc/" . lc($host) );
     if ( $host =~ /\.\./ || !-d "$TopDir/pc/$host" ) {
         #
         # try to lookup by user name
         #
-        if ( !defined($Hosts->{$host}) ) {
+        if ( $host eq "" || !defined($Hosts->{$host}) ) {
             foreach my $h ( keys(%$Hosts) ) {
                 if ( $Hosts->{$h}{user} eq $host
                         || lc($Hosts->{$h}{user}) eq lc($host) ) {
@@ -63,7 +65,7 @@ sub action
             }
             CheckPermission();
             ErrorExit(eval("qq{$Lang->{Unknown_host_or_user}}"))
-                                if ( !defined($Hosts->{$host}) );
+                               if ( !defined($Hosts->{$host}) );
         }
         $In{host} = $host;
     }
@@ -286,7 +288,8 @@ EOF
     if ( $StatusHost{aliveCnt} > 0 ) {
         $statusStr .= eval("qq{$Lang->{priorStr_to_host_have_succeeded_StatusHostaliveCnt_consecutive_times}}");
 
-        if ( $StatusHost{aliveCnt} >= $Conf{BlackoutGoodCnt}
+        if ( (@{$Conf{BlackoutPeriods}} || defined($Conf{BlackoutHourBegin}))
+               && $StatusHost{aliveCnt} >= $Conf{BlackoutGoodCnt}
                 && $Conf{BlackoutGoodCnt} >= 0 ) {
             #
             # Handle backward compatibility with original separate scalar
index 1133b3a..307e441 100644 (file)
@@ -392,23 +392,23 @@ sub Header
 {
     my($title, $content, $noBrowse, $contentSub, $contentPost) = @_;
     my @adminLinks = (
-        { link => "",                         name => $Lang->{Status},
+        { link => "",                         name => $Lang->{Status}},
+        { link => "?action=adminOpts",        name => $Lang->{Admin_Options},
                                               priv => 1},
-        { link => "?action=adminOpts",        name => $Lang->{Admin_Options} },
-        { link => "?action=summary",          name => $Lang->{PC_Summary},
+        { link => "?action=summary",          name => $Lang->{PC_Summary}},
+        { link => "?action=view&type=LOG",    name => $Lang->{LOG_file},
                                               priv => 1},
-        { link => "?action=view&type=LOG",    name => $Lang->{LOG_file} },
-        { link => "?action=LOGlist",          name => $Lang->{Old_LOGs} },
-        { link => "?action=emailSummary",     name => $Lang->{Email_summary} },
-        { link => "?action=view&type=config", name => $Lang->{Config_file} },
-        { link => "?action=view&type=hosts",  name => $Lang->{Hosts_file} },
-        { link => "?action=queue",            name => $Lang->{Current_queues} },
-        { link => "?action=view&type=docs",   name => $Lang->{Documentation},
+        { link => "?action=LOGlist",          name => $Lang->{Old_LOGs},
                                               priv => 1},
-        { link => "http://backuppc.sourceforge.net/faq", name => "FAQ",
+        { link => "?action=emailSummary",     name => $Lang->{Email_summary},
                                               priv => 1},
-        { link => "http://backuppc.sourceforge.net", name => "SourceForge",
+        { link => "?action=view&type=config", name => $Lang->{Config_file},
                                               priv => 1},
+        { link => "?action=view&type=hosts",  name => $Lang->{Hosts_file},
+                                              priv => 1},
+        { link => "?action=queue",            name => $Lang->{Current_queues},
+                                              priv => 1},
+        @{$Conf{CgiNavBarLinks}},
     );
     my $host = $In{host};
 
@@ -420,12 +420,12 @@ sub Header
 <link rel=stylesheet type="text/css" href="$Conf{CgiImageDirURL}/$Conf{CgiCSSFile}" title="CSSFile">
 $Conf{CgiHeaders}
 </head><body onLoad="document.getElementById('NavMenu').style.height=document.body.scrollHeight">
-<img src="$Conf{CgiImageDirURL}/logo.gif" hspace="5" vspace="7"><br>
+<a href="http://backuppc.sourceforge.net"><img src="$Conf{CgiImageDirURL}/logo.gif" hspace="5" vspace="7" border="0"></a><br>
 EOF
 
     if ( defined($Hosts) && defined($host) && defined($Hosts->{$host}) ) {
        print "<div class=\"NavMenu\">";
-       NavSectionTitle("${EscURI($host)}");
+       NavSectionTitle("${EscHTML($host)}");
        print <<EOF;
 </div>
 <div class="NavMenu">
@@ -487,20 +487,23 @@ $hostSelectbox
 <br><br>
 EOF
     }
-    print <<EOF;
+    if ( $Conf{CgiSearchBoxEnable} ) {
+        print <<EOF;
 <form action="$MyURL" method="get">
     <input type="text" name="host" size="14" maxlength="64">
     <input type="hidden" name="action" value="hostInfo"><input type="submit" value="$Lang->{Go}" name="ignore">
     </form>
 EOF
+    }
     NavSectionTitle($Lang->{NavSectionTitle_});
     foreach my $l ( @adminLinks ) {
-        if ( $PrivAdmin || $l->{priv} ) {
-            NavLink($l->{link}, $l->{name});
+        if ( $PrivAdmin || !$l->{priv} ) {
+            my $txt = defined($l->{lname}) ? $Lang->{$l->{lname}} : $l->{name};
+            NavLink($l->{link}, $txt);
+        }
     }
-}
 
-print <<EOF;
+    print <<EOF;
 <br><br><br>
 </div>
 EOF
index 6c7459e..a485cd3 100644 (file)
@@ -58,9 +58,8 @@ sub action
         $bpc->ConfigRead($host);
         %Conf = $bpc->Conf();
 
-        if ( $Conf{XferMethod} eq "archive" ) {
-            next;
-        }
+        next if ( $Conf{XferMethod} eq "archive" );
+        next if ( !$Privileged && !CheckPermission($host) );
 
         for ( my $i = 0 ; $i < @Backups ; $i++ ) {
             if ( $Backups[$i]{type} eq "full" ) {
index fc99fee..7fc95a0 100644 (file)
@@ -28,7 +28,7 @@
 #
 #========================================================================
 #
-# Version 2.1.0beta1, released 9 Apr 2004.
+# Version 2.1.0beta2, released 9 May 2004.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -97,7 +97,7 @@ sub action
         $file = "$TopDir/log/LOG$ext";
         $linkHosts = 1;
     }
-    if ( !$Privileged ) {
+    if ( $type ne "docs" && !$Privileged ) {
         ErrorExit($Lang->{Only_privileged_users_can_view_log_or_config_files});
     }
     if ( !-f $file && -f "$file.z" ) {
@@ -186,16 +186,16 @@ sub action
                    last if ( $s eq "" );
                    $s =~ s/[\n\r]+//g;
                    # remove any passwords and user names
-                   $s =~ s/(SmbSharePasswd.*=.*['"]).*(['"])/$1$2/ig;
-                   $s =~ s/(SmbShareUserName.*=.*['"]).*(['"])/$1$2/ig;
-                   $s =~ s/(RsyncdPasswd.*=.*['"]).*(['"])/$1$2/ig;
-                   $s =~ s/(ServerMesgSecret.*=.*['"]).*(['"])/$1$2/ig;
+                   $s =~ s/(SmbSharePasswd.*=.*['"]).*(['"])/$1****$2/ig;
+                   $s =~ s/(SmbShareUserName.*=.*['"]).*(['"])/$1****$2/ig;
+                   $s =~ s/(RsyncdPasswd.*=.*['"]).*(['"])/$1****$2/ig;
+                   $s =~ s/(ServerMesgSecret.*=.*['"]).*(['"])/$1****$2/ig;
                    $s = ${EscHTML($s)};
                    $s =~ s[(\$Conf\{.*?\})][
                        my $c = $1;
                        my $s = lc($c);
                        $s =~ s{(\W)}{sprintf("%%%02x", ord($1) )}gxe;
-                       "<a href=\"?action=view&type=docs#item_$s\">$c</a>"
+                       "<a href=\"?action=view&type=docs#item_$s\"><tt>$c</tt></a>"
                    ]eg;
                    $c .= $s . "\n";
                }
index 1e487fc..b799ac6 100644 (file)
@@ -1,5 +1,6 @@
 #!/bin/perl
 #
+# by Ralph Passgang <ralph@debianbase.de> (06.05.2004 for V2.1.0beta2)
 # by Manfred Herrmann (11.03.2004 for V2.1.0beta0)
 # by Manfred Herrmann (V1.1) (some typo errors + 3 new strings)
 # CVS-> Revision ???
 
 $Lang{Start_Archive} = "Archivierung starten";
 $Lang{Stop_Dequeue_Archive} = "Archivierung stoppen";
-$Lang{Start_Full_Backup} = "Starte Backup vollständig";
-$Lang{Start_Incr_Backup} = "Starte Backup incrementell";
-$Lang{Stop_Dequeue_Backup} = "Stoppen/Aussetzen Backup";
-$Lang{Restore} = "Wiederherstellung";
+$Lang{Start_Full_Backup} = "Starte vollständiges Backup";
+$Lang{Start_Incr_Backup} = "Starte inkrementelles Backup";
+$Lang{Stop_Dequeue_Backup} = "Backup Stoppen/Aussetzen";
+$Lang{Restore} = "Wiederherstellen";
 
 $Lang{Type_full} = "voll";
 $Lang{Type_incr} = "inkrementell";
 
 # -----
 
-$Lang{Only_privileged_users_can_view_admin_options} = "Nur privilegierte Nutzer können Admin Optionen einsehen.";
-$Lang{H_Admin_Options} = "BackupPC Server: Admin Optionen";
+$Lang{Only_privileged_users_can_view_admin_options} = "Nur privilegierte Nutzer können die Administrator Optionen einsehen.";
+$Lang{H_Admin_Options} = "BackupPC Server: Administrations Optionen";
 $Lang{Admin_Options} = "Admin Optionen";
 $Lang{Admin_Options_Page} = <<EOF;
 \${h1(qq{$Lang{Admin_Options}})}
@@ -43,16 +44,16 @@ $Lang{Admin_Options_Page} = <<EOF;
 </ul>
 -->
 EOF
-$Lang{Unable_to_connect_to_BackupPC_server} = "Kann keine Verbindung zu BackupPC server herstellen",
-            "Dieses CGI script (\$MyURL) kann keine Verbindung zu BackupPC"
-          . " server auf \$Conf{ServerHost} port \$Conf{ServerPort} herstellen.  Der Fehler"
+$Lang{Unable_to_connect_to_BackupPC_server} = "Kann keine Verbindung zu dem BackupPC Server herstellen!",
+            "Dieses CGI Script (\$MyURL) kann keine Verbindung zu dem BackupPC"
+          . " Server auf \$Conf{ServerHost} Port \$Conf{ServerPort} herstellen.  Der Fehler"
           . " war: \$err.",
-            "Möglicherweise ist der BackupPC server Prozess nicht gestartet oder es besteht ein"
+            "Möglicherweise ist der BackupPC Server Prozess nicht gestartet oder es besteht ein"
           . " Konfigurationsfehler.  Bitte teilen Sie diese Fehlermeldung dem Systemadministrator mit.";
 $Lang{Admin_Start_Server} = <<EOF;
 \${h1(qq{$Lang{Unable_to_connect_to_BackupPC_server}})}
 <form action="\$MyURL" method="get">
-Der BackupPC Server auf <tt>\$Conf{ServerHost}</tt> port <tt>\$Conf{ServerPort}</tt>
+Der BackupPC Server auf <tt>\$Conf{ServerHost}</tt> Port <tt>\$Conf{ServerPort}</tt>
 ist momentan nicht aktiv (möglicherweise wurde er gestoppt, oder noch nicht gestartet).<br>
 Möchten Sie den Server starten?
 <input type="hidden" name="action" value="startServer">
@@ -62,39 +63,45 @@ EOF
 
 # -----
 
-$Lang{H_BackupPC_Server_Status} = "BackupServer Server Status";
+$Lang{H_BackupPC_Server_Status} = "BackupPC Server Status";
 
-$Lang{BackupPC_Server_Status}= <<EOF;
-\${h1(qq{$Lang{H_BackupPC_Server_Status}})}
+$Lang{BackupPC_Server_Status_General_Info}= <<EOF;
 
-<p>
-\${h2(\"Allgemeine Server Information\")}
+\${h2(\"Allgemeine Server Informationen\")}
 
 <ul>
-<li> Die Server Prozess ID (PID) ist \$Info{pid},  auf Computer \$Conf{ServerHost},
+<li>Die Server Prozess ID (PID) ist \$Info{pid}, auf Computer \$Conf{ServerHost},
      Version \$Info{Version}, gestartet am \$serverStartTime.
 <li> Dieser Status wurde am \$now generiert.
-<li> Die Konfiguration wurde neu geladen am \$configLoadTime.
+<li> Die Konfiguration wurde am \$configLoadTime neu geladen.
 <li> Computer werden am \$nextWakeupTime auf neue Aufträge geprüft.
 <li> Weitere Informationen:
     <ul>
-        <li>\$numBgQueue wartende backup Aufträge der letzten Prüfung,
+        <li>\$numBgQueue wartende Backup Aufträge der letzten Prüfung,
         <li>\$numUserQueue wartende Aufträge von Benutzern,
         <li>\$numCmdQueue wartende Kommando Aufträge.
         \$poolInfo
         <li>Das Pool Filesystem (Backup-Speicherplatz) ist zu \$Info{DUlastValue}%
-            (\$DUlastTime) gefüllt, das Maximum-Heute ist \$Info{DUDailyMax}% (\$DUmaxTime)
-            und Maximum-Gestern war \$Info{DUDailyMaxPrev}%. (Hinweis: sollten ca. 70% überschritten werden, so
-           ist evtl. bald eine Erweiterung des Backup-Speichers erforderlich. Planung erforderlich?)
+            (\$DUlastTime) voll, das Maximum heute ist \$Info{DUDailyMax}% (\$DUmaxTime)
+            und das Maximum gestern war \$Info{DUDailyMaxPrev}%. (Hinweis: Sollten ca. 70% überschritten werden, so
+           ist evtl. bald eine Erweiterung des Backupspeichers erforderlich. Weitere Planung nötig?)
     </ul>
 </ul>
+EOF
+
+$Lang{BackupPC_Server_Status} = <<EOF;
+
+\${h1(qq{$Lang{H_BackupPC_Server_Status}})}
+
+<p>
+\$generalInfo
 
 \${h2("Aktuell laufende Aufträge")}
 <p>
 <table class="tableStnd" border cellspacing="1" cellpadding="3">
 <tr class="tableheader"><td> Computer </td>
     <td> Typ </td>
-    <td> User </td>
+    <td> Benutzer </td>
     <td> Startzeit </td>
     <td> Kommando </td>
     <td align="center"> PID </td>
@@ -109,43 +116,43 @@ $Lang{BackupPC_Server_Status}= <<EOF;
 <table class="tableStnd" border cellspacing="1" cellpadding="3">
 <tr class="tableheader"><td align="center"> Computer </td>
     <td align="center"> Typ </td>
-    <td align="center"> User </td>
+    <td align="center"> Benutzer </td>
     <td align="center"> letzter Versuch </td>
     <td align="center"> Details </td>
     <td align="center"> Fehlerzeit </td>
-    <td> Letzter Fehler (außer "kein ping") </td></tr>
+    <td> Letzter Fehler (ausser "kein ping") </td></tr>
 \$statusStr
 </table>
 EOF
 
 # --------------------------------
-$Lang{BackupPC__Server_Summary} = "BackupServer: Übersicht";
+$Lang{BackupPC__Server_Summary} = "BackupPC: Übersicht";
 $Lang{BackupPC__Archive} = "BackupPC: Archivierung";
 $Lang{BackupPC_Summary}=<<EOF;
 
 \${h1(qq{$Lang{BackupPC__Server_Summary}})}
 <p>
-Dieser Status wurde generiert am \$now.
+Dieser Status wurde am \$now generiert.
 </p>
 
 \${h2("Computer mit erfolgreichen Backups")}
 <p>
 Es gibt \$hostCntGood Computer die erfolgreich gesichert wurden, mit insgesamt:
 <ul>
-<li> \$fullTot Voll Backups, Gesamtgröße \${fullSizeTot}GB
-     (vor pooling und Komprimierung),
-<li> \$incrTot Incrementelle Backups, Gesamtgröße \${incrSizeTot}GB
-     (vor pooling und Komprimierung).
+<li> \$fullTot Volle Backups, Gesamtgröße \${fullSizeTot}GB
+     (vor Pooling und Komprimierung),
+<li> \$incrTot Inkrementelle Backups, Gesamtgröße \${incrSizeTot}GB
+     (vor Pooling und Komprimierung).
 </ul>
 </p>
 <table class="tableStnd" border cellpadding="3" cellspacing="1">
 <tr class="tableheader"><td> Computer </td>
-    <td align="center"> User </td>
+    <td align="center"> Benutzer </td>
     <td align="center"> #Voll </td>
-    <td align="center"> Alter/Tage </td>
+    <td align="center"> Alter/Tagen </td>
     <td align="center"> Größe/GB </td>
-    <td align="center"> MB/sec </td>
-    <td align="center"> #Incr </td>
+    <td align="center"> MB/Sek </td>
+    <td align="center"> #Inkr </td>
     <td align="center"> Alter/Tage </td>
     <td align="center"> Status </td>
     <td align="center"> Letzte Aktion </td></tr>
@@ -154,16 +161,16 @@ Es gibt \$hostCntGood Computer die erfolgreich gesichert wurden, mit insgesamt:
 <br><br>
 \${h2("Computer ohne Backups")}
 <p>
-Es gibt \$hostCntNone Computer ohne Backups !!!.
+Es gibt \$hostCntNone Computer ohne Backups !!!
 <p>
 <table class="tableStnd" border cellpadding="3" cellspacing="1">
 <tr class="tableheader"><td> Computer </td>
-    <td align="center"> User </td>
+    <td align="center"> Benutzer </td>
     <td align="center"> #Voll </td>
     <td align="center"> Alter/Tage </td>
     <td align="center"> Größe/GB </td>
     <td align="center"> MB/sec </td>
-    <td align="center"> #Incr </td>
+    <td align="center"> #Inkr </td>
     <td align="center"> Alter/Tage </td>
     <td align="center"> Status </td>
     <td align="center"> Letzter Versuch </td></tr>
@@ -267,7 +274,7 @@ EOF
 $Lang{BackupPC_Archive2_split} = <<EOF;
 <tr>
     <td>Aufteilen in</td>
-    <td><input type="numeric" value="\$ArchiveSplit" name="splitsize">Megabytes</td>
+    <td><input type="numeric" value="\$ArchiveSplit" name="splitsize"> Megabytes</td>
 </tr>
 EOF
 
@@ -330,23 +337,23 @@ M
 
 EOF
 # --------------------------------
-$Lang{Only_privileged_users_can_view_queues_} = "Nur berechtigte User können die Warteschlangen einsehen.";
+$Lang{Only_privileged_users_can_view_queues_} = "Nur berechtigte Benutzer können die Warteschlangen einsehen.";
 # --------------------------------
-$Lang{Only_privileged_users_can_archive} = "Nur berechtigte Personen könnnen archivieren.";
+$Lang{Only_privileged_users_can_archive} = "Nur berechtigte Benutzer könnnen archivieren.";
 # --------------------------------
 $Lang{BackupPC__Queue_Summary} = "BackupServer: Warteschlangen Übersicht";
 # --------------------------------
 $Lang{Backup_Queue_Summary} = <<EOF;
 \${h1("Backup Warteschlangen Übersicht")}
 <br><br>
-\${h2("User Warteschlange Übersicht")}
+\${h2("Benutzer Warteschlange Übersicht")}
 <p>
-Die folgenden User Aufträge sind eingereiht:
+Die folgenden Benutzer Aufträge sind eingereiht:
 </p>
 <table class="tableStnd" border cellspacing="1" cellpadding="3" width="80%">
 <tr class="tableheader"><td> Computer </td>
     <td> Uhrzeit </td>
-    <td> User </td></tr>
+    <td> Benutzer </td></tr>
 \$strUser
 </table>
 <br><br>
@@ -358,7 +365,7 @@ Die folgenden Hintergrund Auftr
 <table class="tableStnd" border cellspacing="1" cellpadding="3" width="80%">
 <tr class="tableheader"><td> Computer </td>
     <td> Uhrzeit </td>
-    <td> User </td></tr>
+    <td> Benutzer </td></tr>
 \$strBg
 </table>
 <br><br>
@@ -369,7 +376,7 @@ Die folgenden Kommando Auftr
 <table class="tableStnd" border cellspacing="1" cellpadding="3" width="80%">
 <tr class="tableheader"><td> Computer </td>
     <td> Uhrzeit </td>
-    <td> User </td>
+    <td> Benutzer </td>
     <td> Kommando </td></tr>
 \$strCmd
 </table>
@@ -406,7 +413,7 @@ EOF
 
 # -------------------------------
 $Lang{Recent_Email_Summary} = <<EOF;
-\${h1("Letzte e-mail Übersicht (Sortierung nach Zeitpunkt)")}
+\${h1("Letzte eMail Übersicht (Sortierung nach Zeitpunkt)")}
 <p>
 <table class="tableStnd" border cellspacing="1" cellpadding="3" width="80%">
 <tr class="tableheader"><td align="center"> Empfänger </td>
@@ -426,7 +433,7 @@ $Lang{Restore_Options_for__host} = "BackupServer: Restore Optionen f
 $Lang{Restore_Options_for__host2} = <<EOF;
 \${h1("Restore Optionen für \$host")}
 <p>
-Sie haben die folgenden Dateien/Verzeichnisse von Freigabe \$share selektiert, von Backup Nummer #\$num:
+Sie haben die folgenden Dateien/Verzeichnisse von der Freigabe \$share aus der Backup Nummer #\$num selektiert:
 <ul>
 \$fileListStr
 </ul>
@@ -434,7 +441,7 @@ Sie haben die folgenden Dateien/Verzeichnisse von Freigabe \$share selektiert, v
 Sie haben drei verschiedene Möglichkeiten zur Wiederherstellung (Restore) der Dateien/Verzeichnisse.
 Bitte wählen Sie eine der folgenden Möglichkeiten:.
 </p>
-\${h2("Möglichkeit 1: Direct Restore")}
+\${h2("Möglichkeit 1: Direkte Wiederherstellung")}
 <p>
 EOF
 
@@ -443,9 +450,9 @@ Sie k
 \$host wiederherzustellen. Alternativ können Sie einen anderen Computer und/oder Freigabe als Ziel angeben.
 </p><p>
 <b>Warnung:</b> alle aktuell existierenden Dateien/Verzeichnisse die bereits vorhanden sind
-werden überschrieben! (Tip: alternativ eine spezielle Freigabe erstellen mit schreibrecht für den
-Backup-User und die wiederhergestellten Dateien/Verzeichnisse durch Stichproben prüfen, ob die beabsichtigte
-Wiederherstellung korrekt ist) 
+werden überschrieben! (Tip: alternativ eine spezielle Freigabe erstellen mit Schreibrecht für den
+Backup-Benutzer und die wiederhergestellten Dateien/Verzeichnisse durch Stichproben prüfen, ob die beabsichtigte
+Wiederherstellung korrekt ist.
 </p>
 <form action="\$MyURL" method="post" name="direct">
 <input type="hidden" name="host" value="\${EscHTML(\$host)}">
@@ -476,7 +483,7 @@ Wiederherstellung korrekt ist)
     <td valign="top"><input type="text" size="40" maxlength="256"
        value="\${EscHTML(\$pathHdr)}" name="pathHdr"></td>
 </tr><tr>
-    <td><input type="submit" value="Start Restore" name=""></td>
+    <td><input type="submit" value="Wiederherstellung starten" name=""></td>
 </table>
 </form>
 EOF
@@ -489,9 +496,9 @@ EOF
 # ------------------------------
 $Lang{Option_2__Download_Zip_archive} = <<EOF;
 <p>
-\${h2("Möglichkeit 2: Download als Zip Archiv Datei")}
+\${h2("Möglichkeit 2: Download als Zip Archiv")}
 <p>
-Sie können eine ZIP Archiv Datei downloaden, die alle selektierten Dateien/Verzeichnisse
+Sie können eine ZIP Archivdatei downloaden, die alle selektierten Dateien/Verzeichnisse
 enthält. Mit einer lokalen Anwendung (z.B. WinZIP, WinXP-ZIP-Ordner...) können Sie dann
 beliebige Dateien entpacken. 
 </p><p>
@@ -513,7 +520,7 @@ evtl. die Dateien/Verzeichnisse erneut und lassen sehr gro
 Kompression (0=aus, 1=schnelle,...,9=höchste)
 <input type="text" size="6" value="5" name="compressLevel">
 <br>
-<input type="submit" value="Download Zip Datei" name="">
+<input type="submit" value="Zip Datei downloaden" name="">
 </form>
 EOF
 
@@ -521,20 +528,20 @@ EOF
 
 $Lang{Option_2__Download_Zip_archive2} = <<EOF;
 <p>
-\${h2("Möglichkeit 2: Download als Zip Archiv Datei")}
+\${h2("Möglichkeit 2: Download als Zip Archiv")}
 <p>
 Archive::Zip ist nicht installiert. Der Download als Zip Archiv Datei ist daher nicht möglich.
 Bitte lassen Sie bei Bedarf von Ihrem Administrator die Perl-Erweiterung Archive::Zip von 
-<a href="http://www.cpan.org">www.cpan.org</a> installieren.
+<a href="http://www.cpan.org">www.cpan.org</a> installieren. Vielen Dank!
 </p>
 EOF
 
 
 # ------------------------------
 $Lang{Option_3__Download_Zip_archive} = <<EOF;
-\${h2("Möglichkeit 3: Download als Tar Archiv Datei")}
+\${h2("Möglichkeit 3: Download als Tar Archiv")}
 <p>
-Sie können eine Tar Archiv Datei downloaden, die alle selektierten Dateien/Verzeichnisse
+Sie können eine Tar Archivdatei downloaden, die alle selektierten Dateien/Verzeichnisse
 enthält. Mit einer lokalen Anwendung (z.B. tar, WinZIP...) können Sie dann
 beliebige Dateien entpacken.
 </p><p>
@@ -553,7 +560,7 @@ evtl. die Dateien/Verzeichnisse erneut und lassen sehr gro
  \${EscHTML(\$pathHdr eq "" ? "/" : \$pathHdr)}
 (andernfalls enthält die Archiv Datei vollständige Pfade).
 <br>
-<input type="submit" value="Download Tar Datei" name="">
+<input type="submit" value="Tar Datei downloaden" name="">
 </form>
 EOF
 
@@ -565,11 +572,11 @@ $Lang{Are_you_sure} = <<EOF;
 \${h1("Sind Sie sicher?")}
 <p>
 Sie starten eine direkte Wiederherstellung auf den Computer \$In{hostDest}.
-Die folgenden Dateien werden auf die Freigabe \$In{shareDest} wiederhergestellt, vom
-Backup Nummer \$num:
+Die folgenden Dateien werden auf die Freigabe \$In{shareDest} wiederhergestellt, von
+der Backup Nummer \$num:
 <p>
 <table border>
-<tr><td>Original Datei/Verzeichnis</td><td>Wird wiederhergestellt nach</td></tr>
+<tr><td>Original Datei/Verzeichnis:</td><td>Wird wiederhergestellt nach:</td></tr>
 \$fileListStr
 </table>
 
@@ -615,7 +622,7 @@ $Lang{Host__host_Backup_Summary2} = <<EOF;
 \$statusStr
 </ul>
 </p>
-\${h2("User Aktionen")}
+\${h2("Benutzer Aktionen")}
 <p>
 <form action="\$MyURL" method="get">
 <input type="hidden" name="host" value="\$host">
@@ -626,14 +633,14 @@ $Lang{Host__host_Backup_Summary2} = <<EOF;
 </p>
 \${h2("Backup Übersicht")}
 <p>
-Klicken Sie auf die Backup-Nummer um Dateien zu browsen und bei Bedarf wiederherzustellen.
+Klicken Sie auf die Backup Nummer um durch Dateien zu browsen und bei Bedarf wiederherzustellen.
 </p>
 <table class="tableStnd" border cellspacing="1" cellpadding="3">
 <tr class="tableheader"><td align="center"> Backup# </td>
     <td align="center"> Typ </td>
     <td align="center"> Filled </td>
     <td align="center"> Start Zeitpunkt </td>
-    <td align="center"> Dauer/mins </td>
+    <td align="center"> Dauer/min </td>
     <td align="center"> Alter/Tage </td>
     <td align="center"> Server Backup Pfad </td>
 </tr>
@@ -663,7 +670,7 @@ Klicken Sie auf die Backup-Nummer um Dateien zu browsen und bei Bedarf wiederher
 <p>
 "Bestehende Dateien" bedeutet bereits im Pool vorhanden.
 "Neue Dateien" bedeutet neu zum Pool hinzugefügt.
-Leere Dateien und Datei-Fehler sind nicht in den Summen enthalten.
+Leere Dateien und eventuelle Datei Fehler sind nicht in den Summen enthalten.
 </p>
 <table class="tableStnd" border cellspacing="1" cellpadding="3" width="80%">
 <tr class="tableheader"><td colspan="2" bgcolor="#ffffff"></td>
@@ -686,7 +693,7 @@ Leere Dateien und Datei-Fehler sind nicht in den Summen enthalten.
 </table>
 <br><br>
 
-\${h2("Kompression Übersicht")}
+\${h2("Kompressions Übersicht")}
 <p>
 Kompressionsergebnisse für bereits im Backup-Pool vorhandene und für neu komprimierte Dateien.
 </p>
@@ -697,7 +704,7 @@ Kompressionsergebnisse f
 </tr>
 <tr class="tableheader"><td align="center"> Backup# </td>
     <td align="center"> Typ </td>
-    <td align="center"> Comp Level </td>
+    <td align="center"> Komp Level </td>
     <td align="center"> Größe/MB </td>
     <td align="center"> Comp/MB </td>
     <td align="center"> Comp </td>
@@ -719,7 +726,7 @@ $Lang{Host__host_Archive_Summary2} = <<EOF;
 \$statusStr
 </ul>
 
-\${h2("User Aktionen")}
+\${h2("Benutzer Aktionen")}
 <p>
 <form action="\$MyURL" method="get">
 <input type="hidden" name="archivehost" value="\$host">
@@ -744,7 +751,7 @@ $Lang{NavSectionTitle_} = "Server";
 
 # -------------------------
 $Lang{Backup_browse_for__host} = <<EOF;
-\${h1("Backup browsen von Computer \$host")}
+\${h1("Backup durchsuchen für den Computer \$host")}
 
 <script language="javascript" type="text/javascript">
 <!--
@@ -779,12 +786,12 @@ $Lang{Backup_browse_for__host} = <<EOF;
 <input type="hidden" name="share" value="\${EscHTML(\$share)}">
 <input type="hidden" name="action" value="browse">
 <ul>
-<li> Sie browsen das Backup #\$num, erstellt am \$backupTime
+<li>Sie browsen das Backup #\$num, erstellt am \$backupTime
         (vor \$backupAge Tagen),
 \$filledBackup
 <li> Verzeichnis eingeben: <input type="text" name="dir" size="50" maxlength="4096" value="\${EscHTML(\$dir)}"> <input type="submit" value="\$Lang->{Go}" name="Submit">
 <li> Klicken Sie auf ein Verzeichnis um dieses zu durchsuchen,
-<li> Klicken Sie auf eine Datei um diese per download wiederherzustellen,
+<li> Klicken Sie auf eine Datei um diese per Download wiederherzustellen,
 <li> Einsehen der Backup <a href="\$MyURL?action=dirHistory&host=\${EscURI(\$host)}&share=\$shareURI&dir=\$pathURI">Historie</a> des aktuellen Verzeichnisses.
 </ul>
 </form>
@@ -815,7 +822,7 @@ $Lang{Backup_browse_for__host} = <<EOF;
 <br>
 <!--
 This is now in the checkAll row
-<input type="submit" name="Submit" value="Restore der Selektion">
+<input type="submit" name="Submit" value="Selektion wiederherstellen">
 -->
 </form>
 EOF
@@ -898,7 +905,7 @@ $Lang{Archive___num_details_for__host} = "BackupPC: Archiv #\$num Details f
 $Lang{Archive___num_details_for__host2 } = <<EOF;
 \${h1("Archiv #\$num Details für \$host")}
 <p>
-<table class="tableStnd" border cellspacing="1" cellpadding="3" width="50%">
+<table class="tableStnd" border cellspacing="1" cellpadding="3" width="80%">
 <tr><td class="tableheader"> Nummer </td><td class="border"> \$Archives[\$i]{num} </td></tr>
 <tr><td class="tableheader"> beauftragt von </td><td class="border"> \$ArchiveReq{user} </td></tr>
 <tr><td class="tableheader"> Auftrag Zeitpunkt</td><td class="border"> \$reqTime </td></tr>
@@ -921,37 +928,37 @@ $Lang{Archive___num_details_for__host2 } = <<EOF;
 EOF
 
 # -----------------------------------
-$Lang{Email_Summary} = "BackupServer: e-mail Übersicht";
+$Lang{Email_Summary} = "BackupServer: eMail Übersicht";
 
 # -----------------------------------
 #  !! ERROR messages !!
 # -----------------------------------
-$Lang{BackupPC__Lib__new_failed__check_apache_error_log} = "BackupPC::Lib->new failed: überprüfen Sie die apache error_log\n";
+$Lang{BackupPC__Lib__new_failed__check_apache_error_log} = "BackupPC::Lib->new failed: Überprüfen Sie die Apache error_log\n";
 $Lang{Wrong_user__my_userid_is___} =  
-              "Falscher User: meine userid ist \$>, anstatt \$uid"
+              "Falscher Benutzer: Meine userid ist \$>, anstelle \$uid"
             . "(\$Conf{BackupPCUser})\n";
-# $Lang{Only_privileged_users_can_view_PC_summaries} = "Nur berechtigte User können die Computer Übersicht einsehen.";
+# $Lang{Only_privileged_users_can_view_PC_summaries} = "Nur berechtigte Benutzer können die Computer Übersicht einsehen.";
 $Lang{Only_privileged_users_can_stop_or_start_backups} = 
-                  "Nur berechtigte User können Backups starten und stoppen für"
+                  "Nur berechtigte Benutzer können Backups starten und stoppen für"
                . " \${EscHTML(\$host)}.";
 $Lang{Invalid_number__num} = "ungültige Nummer \$num";
 $Lang{Unable_to_open__file__configuration_problem} = "kann Datei nicht öffnen \$file: Konfigurationsproblem?";
-$Lang{Only_privileged_users_can_view_log_or_config_files} = "Nur berechtigte User können LOG oder config Dateien einsehen.";
-$Lang{Only_privileged_users_can_view_log_files} = "Nur berechtigte User können LOG Dateien einsehen.";
-$Lang{Only_privileged_users_can_view_email_summaries} = "Nur berechtigte User können die Email Übersicht einsehen.";
-$Lang{Only_privileged_users_can_browse_backup_files} = "Nur berechtigte User können Backup Dateien browsen"
+$Lang{Only_privileged_users_can_view_log_or_config_files} = "Nur berechtigte Benutzer können Log oder Config Dateien einsehen.";
+$Lang{Only_privileged_users_can_view_log_files} = "Nur berechtigte Benutzer können LOG Dateien einsehen.";
+$Lang{Only_privileged_users_can_view_email_summaries} = "Nur berechtigte Benutzer können die Email Übersicht einsehen.";
+$Lang{Only_privileged_users_can_browse_backup_files} = "Nur berechtigte Benutzer können Backup Dateien browsen"
                 . " für computer \${EscHTML(\$In{host})}.";
-$Lang{Empty_host_name} = "Empty host name.";
+$Lang{Empty_host_name} = "Kein Hostname.";
 $Lang{Directory___EscHTML} = "Verzeichnis \${EscHTML(\"\$TopDir/pc/\$host/\$num\")}"
                    . " ist leer";
-$Lang{Can_t_browse_bad_directory_name2} = "Kann fehlerhaften Verzeichnisnamen nicht browsen"
+$Lang{Can_t_browse_bad_directory_name2} = "Kann fehlerhaften Verzeichnisnamen nicht durchsuchen"
                    . " \${EscHTML(\$relDir)}";
-$Lang{Only_privileged_users_can_restore_backup_files} = "Nur berechtigte User können Dateien wiederherstellen"
+$Lang{Only_privileged_users_can_restore_backup_files} = "Nur berechtigte Benutzer können Dateien wiederherstellen"
                 . " für Computer \${EscHTML(\$In{host})}.";
 $Lang{Bad_host_name} = "Falscher Computer Name \${EscHTML(\$host)}";
 $Lang{You_haven_t_selected_any_files__please_go_Back_to} = "Sie haben keine Dateien selektiert; bitte gehen Sie zurück um"
                 . " Dateien zu selektieren.";
-$Lang{You_haven_t_selected_any_hosts} = "Sie haben keinen Computer gewählt, bitte zurückgehen um einen auszuwählen.";
+$Lang{You_haven_t_selected_any_hosts} = "Sie haben keinen Computer gewählt, bitte zurück gehen um einen auszuwählen.";
 $Lang{Nice_try__but_you_can_t_put} = "Sie dürfen \'..\' nicht in Dateinamen verwenden";
 $Lang{Host__doesn_t_exist} = "Computer \${EscHTML(\$In{hostDest})} existiert nicht";
 $Lang{You_don_t_have_permission_to_restore_onto_host} = "Sie haben keine Berechtigung zum Restore auf Computer"
@@ -961,11 +968,11 @@ $Lang{Can_t_open_create} = "Kann Datei nicht 
 $Lang{Only_privileged_users_can_restore_backup_files2} = "Nur berechtigte Benutzer dürfen Backup und Restore von Dateien"
                 . " für Computer \${EscHTML(\$host)} durchführen.";
 $Lang{Empty_host_name} = "leerer Computer Name";
-$Lang{Unknown_host_or_user} = "Unbekannter Computer oder User \${EscHTML(\$host)}";
-$Lang{Only_privileged_users_can_view_information_about} = "Nur berechtigte User können Informationen sehen über"
+$Lang{Unknown_host_or_user} = "Unbekannter Computer oder Benutzer \${EscHTML(\$host)}";
+$Lang{Only_privileged_users_can_view_information_about} = "Nur berechtigte Benutzer können Informationen sehen über"
                 . " Computer \${EscHTML(\$host)}." ;
-$Lang{Only_privileged_users_can_view_archive_information} = "Nur berechtigte User können Archiv Informationen einsehen.";
-$Lang{Only_privileged_users_can_view_restore_information} = "Nur berechtigte User können Restore Informationen einsehen.";
+$Lang{Only_privileged_users_can_view_archive_information} = "Nur berechtigte Benutzer können Archiv Informationen einsehen.";
+$Lang{Only_privileged_users_can_view_restore_information} = "Nur berechtigte Benutzer können Restore Informationen einsehen.";
 $Lang{Restore_number__num_for_host__does_not_exist} = "Restore Nummer \$num für Computer \${EscHTML(\$host)} existiert"
                . " nicht.";
 $Lang{Archive_number__num_for_host__does_not_exist} = "Archiv Nummer \$num für Computer \${EscHTML(\$host)} existiert"
@@ -999,20 +1006,20 @@ $Lang{Status} = "Status";
 $Lang{PC_Summary} = "Computer Übersicht";
 $Lang{LOG_file} = "LOG Datei";
 $Lang{LOG_files} = "LOG Dateien";
-$Lang{Old_LOGs} = "Alte LOGs";
-$Lang{Email_summary} = "Email Übersicht";
+$Lang{Old_LOGs} = "Alte LOG Dateien";
+$Lang{Email_summary} = "eMail Übersicht";
 $Lang{Config_file} = "Config Datei";
 $Lang{Hosts_file} = "Hosts Datei";
 $Lang{Current_queues} = "Warteschlangen";
 $Lang{Documentation} = "Dokumentation";
 
-#$Lang{Host_or_User_name} = "<small>Computer oder User Name:</small>";
+#$Lang{Host_or_User_name} = "<small>Computer oder Benutzer Name:</small>";
 $Lang{Go} = "gehe zu";
 $Lang{Hosts} = "Computer";
 $Lang{Select_a_host} = "Computer auswählen...";
 
 $Lang{There_have_been_no_archives} = "<h2> Es existieren keine Archive </h2>\n";
-$Lang{This_PC_has_never_been_backed_up} = "<h2> Dieser Computer wurde nie gesichert!! </h2>\n";
+$Lang{This_PC_has_never_been_backed_up} = "<h2> Dieser Computer wurde nie gesichert! </h2>\n";
 $Lang{This_PC_is_used_by} = "<li>Dieser Computer wird betreut von \${UserLink(\$user)}";
 
 $Lang{Extracting_only_Errors} = "(nur Fehler anzeigen)";
@@ -1021,7 +1028,7 @@ $Lang{Errors}  = "Fehler";
 
 # ------------
 $Lang{Last_email_sent_to__was_at___subject} = <<EOF;
-<li>Letzte e-mail gesendet an \${UserLink(\$user)} am  \$mailTime, Titel "\$subj".
+<li>Letzte eMail gesendet an \${UserLink(\$user)} am  \$mailTime, Titel "\$subj".
 EOF
 # ------------
 $Lang{The_command_cmd_is_currently_running_for_started} = <<EOF;
@@ -1035,7 +1042,7 @@ EOF
 
 # ----------
 $Lang{Host_host_is_queued_on_the_user_queue__will_be_backed_up_soon} = <<EOF;
-<li>Computer \$host ist in die User-Warteschlange eingereiht (Backup wird bald gestartet).
+<li>Computer \$host ist in die Benutzer-Warteschlange eingereiht (Backup wird bald gestartet).
 EOF
 
 # ---------
@@ -1088,7 +1095,7 @@ $Lang{checkAll} = <<EOF;
 <tr><td class="fviewborder">
 <input type="checkbox" name="allFiles" onClick="return checkAll('allFiles');">&nbsp;alles auswählen
 </td><td colspan="5" align="center" class="fviewborder">
-<input type="submit" name="Submit" value="Restore der Selektion">
+<input type="submit" name="Submit" value="Selektion wiederherstellen">
 </td></tr>
 EOF
 
@@ -1112,8 +1119,8 @@ EOF
 
 $Lang{Home} = "Home";
 $Lang{Browse} = "Datensicherungen anzeigen";
-$Lang{Last_bad_XferLOG} = "Letzte bad XferLOG";
-$Lang{Last_bad_XferLOG_errors_only} = "Letzte bad XferLOG (nur&nbsp;Fehler)";
+$Lang{Last_bad_XferLOG} = "Letztes fehlerhafte XferLOG";
+$Lang{Last_bad_XferLOG_errors_only} = "Letztes fehlerhafte XferLOG (nur&nbsp;Fehler)";
 
 $Lang{This_display_is_merged_with_backup} = <<EOF;
 <li> Diese Liste ist mit Backup #\$numF verbunden.
@@ -1131,7 +1138,7 @@ Klicken Sie auf die Restore Nummer (Restore#) f
 <tr class="tableheader"><td align="center"> Restore# </td>
     <td align="center"> Ergebnis </td>
     <td align="right"> Start Zeitpunkt</td>
-    <td align="right"> Dauer/mins</td>
+    <td align="right"> Dauer/min </td>
     <td align="right"> #Dateien </td>
     <td align="right"> Größe/MB </td>
     <td align="right"> #tar Fehler </td>
@@ -1172,7 +1179,7 @@ $Lang{off} = "aus";
 
 $Lang{backupType_full}    = "voll";
 $Lang{backupType_incr}    = "inkrementell";
-$Lang{backupType_partial} = "partiell";
+$Lang{backupType_partial} = "unvollständig";
 
 $Lang{failed} = "fehler";
 $Lang{success} = "erfolgreich";
@@ -1196,9 +1203,9 @@ $Lang{Reason_backup_failed} = "Backup Fehler";
 $Lang{Reason_restore_failed} = "Restore Fehler";
 $Lang{Reason_archive_failed} = "Archivierung Fehler";
 $Lang{Reason_no_ping} = "nicht erreichbar";
-$Lang{Reason_backup_canceled_by_user} = "Abbruch durch User";
-$Lang{Reason_restore_canceled_by_user} = "Abbruch durch User";
-$Lang{Reason_archive_canceled_by_user} = "Archivierung abgebrochen durch User";
+$Lang{Reason_backup_canceled_by_user} = "Abbruch durch Benutzer";
+$Lang{Reason_restore_canceled_by_user} = "Abbruch durch Benutzer";
+$Lang{Reason_archive_canceled_by_user} = "Archivierung abgebrochen durch Benutzer";
 
 # ---------
 # Email messages
index eb629f1..1276dd0 100644 (file)
@@ -59,10 +59,7 @@ EOF
 
 $Lang{H_BackupPC_Server_Status} = "BackupPC Server Status";
 
-$Lang{BackupPC_Server_Status}= <<EOF;
-\${h1(qq{$Lang{H_BackupPC_Server_Status}})}
-
-<p>
+$Lang{BackupPC_Server_Status_General_Info}= <<EOF;
 \${h2(\"General Server Information\")}
 
 <ul>
@@ -82,6 +79,13 @@ $Lang{BackupPC_Server_Status}= <<EOF;
             and yesterday\'s max was \$Info{DUDailyMaxPrev}%.
     </ul>
 </ul>
+EOF
+
+$Lang{BackupPC_Server_Status} = <<EOF;
+\${h1(qq{$Lang{H_BackupPC_Server_Status}})}
+
+<p>
+\$generalInfo
 
 \${h2("Currently Running Jobs")}
 <p>
@@ -901,7 +905,7 @@ $Lang{Archive___num_details_for__host} = "BackupPC: Archive #\$num details for \
 $Lang{Archive___num_details_for__host2 } = <<EOF;
 \${h1("Archive #\$num Details for \$host")}
 <p>
-<table class="tableStnd" border cellspacing="1" cellpadding="3" width="50%">
+<table class="tableStnd" border cellspacing="1" cellpadding="3" width="80%">
 <tr><td class="tableheader"> Number </td><td class="border"> \$Archives[\$i]{num} </td></tr>
 <tr><td class="tableheader"> Requested by </td><td class="border"> \$ArchiveReq{user} </td></tr>
 <tr><td class="tableheader"> Request time </td><td class="border"> \$reqTime </td></tr>
index a595948..30dade2 100644 (file)
@@ -6,37 +6,36 @@
 
 # --------------------------------
 
-$Lang{Start_Archive} = "ENG Start Archive";
-$Lang{Stop_Dequeue_Archive} = "ENG Stop/Dequeue Archive";
+$Lang{Start_Archive} = "Comenzar archivado";
+$Lang{Stop_Dequeue_Archive} = "Parar/anular archivado";
 $Lang{Start_Full_Backup} = "Comenzar copia de seguridad completa";
 $Lang{Start_Incr_Backup} = "Comenzar copia de seguridad incremental";
 $Lang{Stop_Dequeue_Backup} = "Parar/anular copia de seguridad";
 $Lang{Restore} = "Restaurar";
 
-$Lang{Type_full} = "ENG full";
-$Lang{Type_incr} = "ENG incremental";
+$Lang{Type_full} = "completo";
+$Lang{Type_incr} = "incremental";
 
 # -----
 
-$Lang{Only_privileged_users_can_view_admin_options} = "ENG Only privileged users can view admin options.";
-$Lang{H_Admin_Options} = "ENG BackupPC Server: Admin Options";
-$Lang{Admin_Options} = "ENG Admin Options";
+$Lang{Only_privileged_users_can_view_admin_options} = "Sólo los superusuarios pueden ver las opciones de administración.";
+$Lang{H_Admin_Options} = "Servidor BackupPC: Opciones de administración";
+$Lang{Admin_Options} = "Opciones de administración";
 $Lang{Admin_Options_Page} = <<EOF;
-ENG
 \${h1(qq{$Lang{Admin_Options}})}
 <br>
-\${h2("Server Control")}
+\${h2("Control del Servidor")}
 <form action="\$MyURL" method="get">
 <table>
-<!--<tr><td>Stop the server:<td><input type="submit" name="action" value="Stop">-->
-  <tr><td>Reload the server configuration:<td><input type="submit" name="action" value="Reload">
+<!--<tr><td>Para el servidor:<td><input type="submit" name="action" value="Stop">-->
+  <tr><td>Actualizar configuración del servidor:<td><input type="submit" name="action" value="Reload">
 </table>
 </form>
 <!--
 \${h2("Server Configuration")}
 <ul> 
-  <li><i>Other options can go here... e.g.,</i>
-  <li>Edit server configuration
+  <li><i>Espacio para otras opciones... e.j.,</i>
+  <li>Editar configuración del servidor
 </ul>
 -->
 EOF
@@ -47,11 +46,11 @@ $Lang{Unable_to_connect_to_BackupPC_server} = "Imposible conectar al servidor Ba
             "Quizá el servidor BackupPC no está activo o hay un "
           . " error de configuración. Por favor informe a su administrador de sistemas.";
 $Lang{Admin_Start_Server} = <<EOF;
-ENG\${h1(qq{$Lang{Unable_to_connect_to_BackupPC_server}})}
+\${h1(qq{$Lang{Unable_to_connect_to_BackupPC_server}})}
 <form action="\$MyURL" method="get">
-The BackupPC server at <tt>\$Conf{ServerHost}</tt> port <tt>\$Conf{ServerPort}</tt>
-is not currently running (maybe you just stopped it, or haven't yet started it).<br>
-Do you want to start it?
+El servidor BackupPC en <tt>\$Conf{ServerHost}</tt> port <tt>\$Conf{ServerPort}</tt>
+no está en funcionamiento ahora (puede haberlo detenido o no haberlo arrancado aún).<br>
+¿Quiere inicializarlo?
 <input type="hidden" name="action" value="startServer">
 <input type="submit" value="Start Server" name="ignore">
 </form>
@@ -61,17 +60,14 @@ EOF
 
 $Lang{H_BackupPC_Server_Status} = "Estado del Servidor BackupPC";
 
-$Lang{BackupPC_Server_Status}= <<EOF;
-\${h1(qq{$Lang{H_BackupPC_Server_Status}})}
-
-<p>
+$Lang{BackupPC_Server_Status_General_Info}= <<EOF;
 \${h2(\"Información General del servidor\")}
 
 <ul>
 <li> El PID del servidor es \$Info{pid}, en el host \$Conf{ServerHost},
      version \$Info{Version}, iniciado el \$serverStartTime.
 <li> Esta información de estado se ha generado el \$now.
-<li> ENG The configuration was last loaded at \$configLoadTime
+<li> La última configuración ha sido cargada a las \$configLoadTime
 <li> La cola de PC´s se activará de nuevo el \$nextWakeupTime.
 <li> Información adicional:
     <ul>
@@ -84,6 +80,13 @@ $Lang{BackupPC_Server_Status}= <<EOF;
             y el máximo de ayer era \$Info{DUDailyMaxPrev}%.
     </ul>
 </ul>
+EOF
+
+$Lang{BackupPC_Server_Status} = <<EOF;
+\${h1(qq{$Lang{H_BackupPC_Server_Status}})}
+
+<p>
+\$generalInfo
 
 \${h2("Trabajos en Ejecución")}
 <p>
@@ -116,7 +119,7 @@ EOF
 
 # --------------------------------
 $Lang{BackupPC__Server_Summary} = "BackupPC: Resumen del Servidor";
-$Lang{BackupPC__Archive} = "ENG BackupPC: Archive";
+$Lang{BackupPC__Archive} = "BackupPC: Archivo";
 $Lang{BackupPC_Summary}=<<EOF;
 
 \${h1(qq{$Lang{BackupPC__Server_Summary}})}
@@ -168,7 +171,7 @@ Hay \$hostCntNone hosts sin copias de seguridad.
 EOF
 
 $Lang{BackupPC_Archive} = <<EOF;
-ENG\${h1(qq{$Lang{BackupPC__Archive}})}
+\${h1(qq{$Lang{BackupPC__Archive}})}
 <script language="javascript" type="text/javascript">
 <!--
 
@@ -196,7 +199,7 @@ ENG\${h1(qq{$Lang{BackupPC__Archive}})}
 //-->
 </script>
 
-There are \$hostCntGood hosts that have been backed up for a total size of \${fullSizeTot}GB
+Hay \$hostCntGood hosts que tienen copia de seguridad con un tamaño total de \${fullSizeTot}GB
 <p>
 <form name="form1" method="post" action="\$MyURL">
 <input type="hidden" name="fcbMax" value="\$checkBoxCnt">
@@ -216,8 +219,8 @@ There are \$hostCntGood hosts that have been backed up for a total size of \${fu
 EOF
 
 $Lang{BackupPC_Archive2} = <<EOF;
-ENG\${h1(qq{$Lang{BackupPC__Archive}})}
-About to archive the following hosts
+\${h1(qq{$Lang{BackupPC__Archive}})}
+Se va a hacer copia de seguridad de los siguientes hosts
 <ul>
 \$HostListStr
 </ul>
@@ -237,14 +240,14 @@ About to archive the following hosts
 EOF
 
 $Lang{BackupPC_Archive2_location} = <<EOF;
-ENG<tr>
-    <td>Archive Location/Device</td>
+<tr>
+    <td>Ubicación de archivo/Dispositivo</td>
     <td><input type="text" value="\$ArchiveDest" name="archive_device"></td>
 </tr>
 EOF
 
 $Lang{BackupPC_Archive2_compression} = <<EOF;
-ENG<tr>
+<tr>
     <td>Compression</td>
     <td>
     <input type="radio" value="0" name="compression" \$ArchiveCompNone>None<br>
@@ -255,15 +258,15 @@ ENG<tr>
 EOF
 
 $Lang{BackupPC_Archive2_parity} = <<EOF;
-ENG<tr>
-    <td>Number of Parity Files</td>
+<tr>
+    <td>Porcentaje de datos de paridad (0 = deshabilitado, 5 = normal)</td>
     <td><input type="numeric" value="\$ArchivePar" name="par"></td>
 </tr>
 EOF
 
 $Lang{BackupPC_Archive2_split} = <<EOF;
-ENG<tr>
-    <td>Split output into</td>
+<tr>
+    <td>Dividir resultado en</td>
     <td><input type="numeric" value="\$ArchiveSplit" name="splitsize">Megabytes</td>
 </tr>
 EOF
@@ -330,7 +333,7 @@ EOF
 # --------------------------------
 $Lang{Only_privileged_users_can_view_queues_} = "Sólo los administradores pueden ver las colas.";
 # --------------------------------
-$Lang{Only_privileged_users_can_archive} = "ENG Only privileged users can Archive.";
+$Lang{Only_privileged_users_can_archive} = "Sólo los administradores pueden archivar.";
 # --------------------------------
 $Lang{BackupPC__Queue_Summary} = "BackupPC: Resumen de la Cola";
 # --------------------------------
@@ -479,8 +482,8 @@ seleccionado ser
 EOF
 
 $Lang{Restore_Options_for__host_Option1_disabled} = <<EOF;
-ENG Direct restore has been disabled for host \${EscHTML(\$hostDest)}.
-Please select one of the other restore options.
+Se ha deshabilitado la restauración directa para el host \${EscHTML(\$hostDest)}.
+Por favor seleccione una de las otras opciones de restauración.
 EOF
 
 # ------------------------------
@@ -493,7 +496,7 @@ ha seleccionado.  Despu
 para ver o extraer cualquiera de los archivos.
 </p><p>
 <b>¡Atención!:</b> Dependiendo de que archivos/carpetas haya seleccionado,
-este archivo puede ser muy grande. Podría tardar muchos minutos
+este archivo puede ser muy grande. Podría tardar muchos minutos en
 crear y transferir el archivo. Además necesitará suficiente espacio el el disco
 local para almacenarlo.
 </p>
@@ -557,7 +560,7 @@ EOF
 
 
 # ------------------------------
-$Lang{Restore_Confirm_on__host} = "BackupPC: Restore Confirm on \$host";
+$Lang{Restore_Confirm_on__host} = "BackupPC: Confirme restauración en \$host";
 
 $Lang{Are_you_sure} = <<EOF;
 \${h1("¿Está seguro?")}
@@ -579,7 +582,7 @@ la copia de seguridad n
 <input type="hidden" name="num" value="\$num">
 <input type="hidden" name="type" value="4">
 \$hiddenStr
-Do you really want to do this?
+¿Realmente quiere hacer esto?
 <input type="submit" value="\$In{action}" name="action">
 <input type="submit" value="No" name="">
 </form>
@@ -593,13 +596,13 @@ $Lang{Reply_from_server_was___reply} = <<EOF;
 <p>
 La respuesta del servidor fué: \$reply
 <p>
-ENG Go back to <a href="\$MyURL?host=\$hostDest">\$hostDest home page</a>.
+volver a <a href="\$MyURL?host=\$hostDest">\$hostDest home page</a>.
 EOF
 
 $Lang{BackupPC_Archive_Reply_from_server} = <<EOF;
-ENG\${h1(\$str)}
+\${h1(\$str)}
 <p>
-Reply from server was: \$reply
+La respuesta del servidor fué: \$reply
 EOF
 
 # -------------------------
@@ -712,14 +715,14 @@ EOF
 
 $Lang{Host__host_Archive_Summary} = "BackupPC: Host \$host Archive Summary";
 $Lang{Host__host_Archive_Summary2} = <<EOF;
-ENG\${h1("Host \$host Archive Summary")}
+${h1("Resumen de archivo del Host \$host")}
 <p>
 \$warnStr
 <ul>
 \$statusStr
 </ul>
 
-\${h2("User Actions")}
+\${h2("Acciones de usuario")}
 <p>
 <form action="\$MyURL" method="get">
 <input type="hidden" name="archivehost" value="\$host">
@@ -782,10 +785,10 @@ $Lang{Backup_browse_for__host} = <<EOF;
 <li> Está revisando la copia de seguridad Nº\$num, que comenzó hacia las \$backupTime
         (hace \$backupAge dias),
 \$filledBackup
-<li> ENG Enter directory: <input type="text" name="dir" size="50" maxlength="4096" value="\${EscHTML(\$dir)}"> <input type="submit" value="\$Lang->{Go}" name="Submit">
+<li> Introduzca el directorio: <input type="text" name="dir" size="50" maxlength="4096" value="\${EscHTML(\$dir)}"> <input type="submit" value="\$Lang->{Go}" name="Submit">
 <li> Haga click en uno de los directorios de abajo para revisar sus contenidos,
 <li> Haga click en un archivo para restaurarlo,
-<li> ENG You can view the backup <a href="\$MyURL?action=dirHistory&host=\${EscURI(\$host)}&share=\$shareURI&dir=\$pathURI">history</a> of the current directory.
+<li> Puede ver la copia de seguridad <a href="\$MyURL?action=dirHistory&host=\${EscURI(\$host)}&share=\$shareURI&dir=\$pathURI">history</a> del directorio actual.
 </ul>
 </form>
 
@@ -821,32 +824,32 @@ This is now in the checkAll row
 EOF
 
 # ------------------------------
-$Lang{DirHistory_backup_for__host} = "(ENGLISH) BackupPC: Directory backup history for \$host";
+$Lang{DirHistory_backup_for__host} = "BackupPC: Histórico de copia de seguridad del directorio en \$host";
 
 #
 # These two strings are used to build the links for directories and
 # file versions.  Files are appended with a version number.
 #
-$Lang{DirHistory_dirLink}  = "ENG dir";
-$Lang{DirHistory_fileLink} = "ENG v";
+$Lang{DirHistory_dirLink}  = "dir";
+$Lang{DirHistory_fileLink} = "v";
 
 $Lang{DirHistory_for__host} = <<EOF;
-ENG\${h1("Directory backup history for \$host")}
+${h1("Histórico de copia de seguridad del directorio en \$host")}
 <p>
-This display shows each unique version of files across all
-the backups:
+Esta pantalla muestra cada versión única de archivos de entre todas
+las copias de seguridad:
 <ul>
-<li> Click on a backup number to return to the backup browser,
-<li> Click on a directory link (\$Lang->{DirHistory_dirLink}) to navigate
-     into that directory,
-<li> Click on a file version link (\$Lang->{DirHistory_fileLink}0,
-     \$Lang->{DirHistory_fileLink}1, ...) to download that file,
-<li> Files with the same contents between different backups have the same
-     version number,
-<li> Files or directories not present in a particular backup have an
-     empty box.
-<li> Files shown with the same version might have different attributes.
-     Select the backup number to see the file attributes.
+<li> Haga click en un número de copia de seguridad para volver al explorador de copias de seguridad,
+<li> Haga click en un vínculo de directorio (\$Lang->{DirHistory_dirLink}) para navegar
+     en ese directorio,
+<li> Haga click en un vínculo de versión de archivo (\$Lang->{DirHistory_fileLink}0,
+     \$Lang->{DirHistory_fileLink}1, ...) para descargar ese archivo,
+<li> Los archivos con diferentes contenidos entre distintas copias de seguridad tienen el mismo
+     número de versión,
+<li> Los archivos o directorios que no existen en una copia concreta tienen una
+     celda vacía.
+<li> Los archivos mostrados con la misma versión pueden tener diferentes atributos.
+     Seleccione el número de copia de seguridad para ver los atributos del archivo.
 </ul>
 
 \${h2("History of \${EscHTML(\$dirDisplay)}")}
@@ -898,20 +901,20 @@ $Lang{Restore___num_details_for__host2} = <<EOF;
 EOF
 
 # ------------------------------
-$Lang{Archive___num_details_for__host} = "ENG BackupPC: Archive #\$num details for \$host";
+$Lang{Archive___num_details_for__host} = "BackupPC: Copia de seguridad #\$num .Detalles de \$host";
 
 $Lang{Archive___num_details_for__host2 } = <<EOF;
-ENG\${h1("Archive #\$num Details for \$host")}
+\${h1("Copia de seguridad #\$num Detalles de \$host")}
 <p>
-<table class="tableStnd" border cellspacing="1" cellpadding="3" width="50%">
-<tr><td class="tableheader"> Number </td><td class="border"> \$Archives[\$i]{num} </td></tr>
-<tr><td class="tableheader"> Requested by </td><td class="border"> \$ArchiveReq{user} </td></tr>
-<tr><td class="tableheader"> Request time </td><td class="border"> \$reqTime </td></tr>
-<tr><td class="tableheader"> Result </td><td class="border"> \$Archives[\$i]{result} </td></tr>
-<tr><td class="tableheader"> Error Message </td><td class="border"> \$Archives[\$i]{errorMsg} </td></tr>
-<tr><td class="tableheader"> Start time </td><td class="border"> \$startTime </td></tr>
-<tr><td class="tableheader"> Duration </td><td class="border"> \$duration min </td></tr>
-<tr><td class="tableheader"> Xfer log file </td><td class="border">
+<table class="tableStnd" border cellspacing="1" cellpadding="3" width="80%">
+<tr><td class="tableheader"> Número </td><td class="border"> \$Archives[\$i]{num} </td></tr>
+<tr><td class="tableheader"> Solicitado por </td><td class="border"> \$ArchiveReq{user} </td></tr>
+<tr><td class="tableheader"> Hora petición </td><td class="border"> \$reqTime </td></tr>
+<tr><td class="tableheader"> Resultado </td><td class="border"> \$Archives[\$i]{result} </td></tr>
+<tr><td class="tableheader"> Mensaje de error </td><td class="border"> \$Archives[\$i]{errorMsg} </td></tr>
+<tr><td class="tableheader"> Hora comienzo </td><td class="border"> \$startTime </td></tr>
+<tr><td class="tableheader"> Duración </td><td class="border"> \$duration min </td></tr>
+<tr><td class="tableheader"> Archivo registro Xfer </td><td class="border">
 <a href="\$MyURL?action=view&type=ArchiveLOG&num=\$Archives[\$i]{num}&host=\$host">View</a>,
 <a href="\$MyURL?action=view&type=ArchiveErr&num=\$Archives[\$i]{num}&host=\$host">Errors</a>
 </tr></tr>
@@ -920,7 +923,7 @@ ENG\${h1("Archive #\$num Details for \$host")}
 \${h1("Host list")}
 <p>
 <table class="tableStnd" border cellspacing="1" cellpadding="3" width="80%">
-<tr class="tableheader"><td>Host</td><td>Backup Number</td></tr>
+<tr class="tableheader"><td>Host</td><td>Copia de seguridad número</td></tr>
 \$HostListStr
 </table>
 EOF
@@ -956,7 +959,7 @@ $Lang{Only_privileged_users_can_restore_backup_files} = "S
 $Lang{Bad_host_name} = "Nombre de host erróneo \${EscHTML(\$host)}";
 $Lang{You_haven_t_selected_any_files__please_go_Back_to} = "No ha seleccionado nigún archivo; por favor, vuelva a"
                 . " seleccione algunos archivos.";
-$Lang{You_haven_t_selected_any_hosts} = "ENG You haven\'t selected any hosts; please go Back to"
+$Lang{You_haven_t_selected_any_hosts} = "No ha seleccionado ningún host; por favor vuelva a"
                 . " select some hosts.";
 $Lang{Nice_try__but_you_can_t_put} = "Buen intento, pero no puede usar \'..\' en los nombres de archivo";
 $Lang{Host__doesn_t_exist} = "El Host \${EscHTML(\$In{hostDest})} no existe";
@@ -970,12 +973,12 @@ $Lang{Empty_host_name} = "Nombre de host vac
 $Lang{Unknown_host_or_user} = "Unknown host or user \${EscHTML(\$host)}";
 $Lang{Only_privileged_users_can_view_information_about} = "Sólo los usuarios autorizados pueden ver información del"
                 . " host \${EscHTML(\$host)}." ;
-$Lang{Only_privileged_users_can_view_archive_information} = "ENG Only privileged users can view archive information.";
+$Lang{Only_privileged_users_can_view_archive_information} = "Sólo los administradores pueden ver información de archivo.";
 $Lang{Only_privileged_users_can_view_restore_information} = "Sólo los usuarios autorizados pueden ver información de restauración.";
 $Lang{Restore_number__num_for_host__does_not_exist} = "El número de restauración \$num del host \${EscHTML(\$host)} "
                . " no existe.";
-$Lang{Archive_number__num_for_host__does_not_exist} = "ENG Archive number \$num for host \${EscHTML(\$host)} does"
-                . " not exist.";
+$Lang{Archive_number__num_for_host__does_not_exist} = "La copia de seguridad \$num del host \${EscHTML(\$host)} "
+                . " no existe.";
 $Lang{Can_t_find_IP_address_for} = "No puedo encontrar la dirección IP de \${EscHTML(\$host)}";
 $Lang{host_is_a_DHCP_host} = <<EOF;
 \$host es un host DHCP y yo no conozco su dirección IP. He comprobado el
@@ -996,7 +999,7 @@ $Lang{Backup_requested_on__host_by__User} = "Copia de seguridad solicitada en \$
 $Lang{Backup_stopped_dequeued_on__host_by__User} = "Copia de seguridad detenida/desprogramada en \$host por \$User";
 $Lang{Restore_requested_to_host__hostDest__backup___num} = "Restauración solicitada para el host \$hostDest, copia de seguridad #\$num,"
             . " por \$User desde \$ENV{REMOTE_ADDR}";
-$Lang{Archive_requested} = "ENG Archive requested by \$User from \$ENV{REMOTE_ADDR}";
+$Lang{Archive_requested} = "Archivo solicitado por \$User desde \$ENV{REMOTE_ADDR}";
 
 # -------------------------------------------------
 # ------- Stuff that was forgotten ----------------
@@ -1005,7 +1008,7 @@ $Lang{Archive_requested} = "ENG Archive requested by \$User from \$ENV{REMOTE_AD
 $Lang{Status} = "Estado";
 $Lang{PC_Summary} = "Resumen PC";
 $Lang{LOG_file} = "Archivo Registro";
-$Lang{LOG_files} = "ENG LOG files";
+$Lang{LOG_files} = "Archivos de registro";
 $Lang{Old_LOGs} = "Registros antiguos";
 $Lang{Email_summary} = "Resumen correo";
 $Lang{Config_file} = "Archivo configuración";
@@ -1016,9 +1019,9 @@ $Lang{Documentation} = "Documentaci
 #$Lang{Host_or_User_name} = "<small>Host o usuario:</small>";
 $Lang{Go} = "Aceptar";
 $Lang{Hosts} = "Hosts";
-$Lang{Select_a_host} = "ENGLISH Select a host...";
+$Lang{Select_a_host} = "Seleccione un host...";
 
-$Lang{There_have_been_no_archives} = "<h2> ENG There have been no archives </h2>\n";
+$Lang{There_have_been_no_archives} = "<h2> No ha habido archivos </h2>\n";
 $Lang{This_PC_has_never_been_backed_up} = "<h2> !Nunca se ha hecho copia de seguridad de este PC! </h2>\n";
 $Lang{This_PC_is_used_by} = "<li>This PC es utilizado por \${UserLink(\$user)}";
 
@@ -1100,9 +1103,9 @@ EOF
 
 $Lang{checkAllHosts} = <<EOF;
 <tr><td class="fviewborder">
-<input type="checkbox" name="allFiles" onClick="return checkAll('allFiles');">&nbsp;ENG Select all
+<input type="checkbox" name="allFiles" onClick="return checkAll('allFiles');">&nbsp;Seleccionar todo
 </td><td colspan="2" align="center" class="fviewborder">
-<input type="submit" name="Submit" value="ENG Archive selected hosts">
+<input type="submit" name="Submit" value="Archivar los hosts seleccionados">
 </td></tr>
 EOF
 
@@ -1117,7 +1120,7 @@ $Lang{fileHeader} = <<EOF;
 EOF
 
 $Lang{Home} = "Principal";
-$Lang{Browse} = "ENG Browse backups";
+$Lang{Browse} = "Explorar copias de seguridad";
 $Lang{Last_bad_XferLOG} = "Ultimo error en registro de transferencia";
 $Lang{Last_bad_XferLOG_errors_only} = "Ultimo error en registro de transferencia (errores&nbsp;sólo)";
 
@@ -1126,7 +1129,7 @@ $Lang{This_display_is_merged_with_backup} = <<EOF;
 EOF
 
 $Lang{Visit_this_directory_in_backup} = <<EOF;
-<li> ENG Select the backup you wish to view: <select onChange="window.location=this.value">\$otherDirs </select>
+<li> Seleccione la copia de seguridad que desea ver: <select onChange="window.location=this.value">\$otherDirs </select>
 EOF
 
 $Lang{Restore_Summary} = <<EOF;
@@ -1149,13 +1152,13 @@ Haga click en el n
 EOF
 
 $Lang{Archive_Summary} = <<EOF;
-ENG\${h2("Archive Summary")}
+\${h2("Archive Summary")}
 <p>
 Click on the archive number for more details.
 <table class="tableStnd" border cellspacing="1" cellpadding="3" width="80%">
 <tr class="tableheader"><td align="center"> Archive# </td>
-    <td align="center"> Result </td>
-    <td align="right"> Start Date</td>
+    <td align="center"> Resultado </td>
+    <td align="right"> Hora comienzo</td>
     <td align="right"> Dur/mins</td>
 </tr>
 \$ArchiveStr
@@ -1178,7 +1181,7 @@ $Lang{off} = "inactivo";
 
 $Lang{backupType_full}    = "completo";
 $Lang{backupType_incr}    = "incremental";
-$Lang{backupType_partial} = "ENG partial";
+$Lang{backupType_partial} = "parcial";
 
 $Lang{failed} = "fallido";
 $Lang{success} = "éxito";
@@ -1196,15 +1199,15 @@ $Lang{Status_link_running} = "conexi
 
 $Lang{Reason_backup_done} = "copia de seguridad realizada";
 $Lang{Reason_restore_done} = "restauración realizada";
-$Lang{Reason_archive_done}   = "ENG archive done";
+$Lang{Reason_archive_done}   = "archivado realizado";
 $Lang{Reason_nothing_to_do} = "nada por hacer";
 $Lang{Reason_backup_failed} = "copia de seguridad fallida";
 $Lang{Reason_restore_failed} = "restauración fallida";
-$Lang{Reason_archive_failed} = "ENG archive failed";
+$Lang{Reason_archive_failed} = "ha fallado el archivado";
 $Lang{Reason_no_ping} = "no hay ping";
 $Lang{Reason_backup_canceled_by_user} = "copia cancelada por el usuario";
 $Lang{Reason_restore_canceled_by_user} = "restauración cancelada por el usuario";
-$Lang{Reason_archive_canceled_by_user} = "ENG archive canceled by user";
+$Lang{Reason_archive_canceled_by_user} = "archivado cancelado por el usuario";
 
 # ---------
 # Email messages
@@ -1306,3 +1309,4 @@ $Lang{howLong_not_been_backed_up} = "no se le ha realizado una copia de segurida
 $Lang{howLong_not_been_backed_up_for_days_days} = "no se le ha realizado una copia de seguridad durante \$days días";
 
 #end of lang_en.pm
+
index 279d32d..240c009 100644 (file)
@@ -59,10 +59,7 @@ EOF
 
 $Lang{H_BackupPC_Server_Status} = "État du serveur BackupPC";
 
-$Lang{BackupPC_Server_Status}= <<EOF;
-\${h1(qq{$Lang{H_BackupPC_Server_Status}})}
-
-<p>
+$Lang{BackupPC_Server_Status_General_Info}= <<EOF;
 \${h2(\"Informations générales du serveur\")}
 
 <ul>
@@ -82,6 +79,13 @@ $Lang{BackupPC_Server_Status}= <<EOF;
             et hier le maximum était \$Info{DUDailyMaxPrev}%.
     </ul>
 </ul>
+EOF
+
+$Lang{BackupPC_Server_Status} = <<EOF;
+\${h1(qq{$Lang{H_BackupPC_Server_Status}})}
+
+<p>
+\$generalInfo
 
 \${h2("Travaux en cours d'exécution")}
 <p>
@@ -899,7 +903,7 @@ $Lang{Archive___num_details_for__host} = "BackupPC: D
 $Lang{Archive___num_details_for__host2 } = <<EOF;
 \${h1("Archive #\$num Details for \$host")}
 <p>
-<table class="tableStnd" border cellspacing="1" cellpadding="3" width="50%">
+<table class="tableStnd" border cellspacing="1" cellpadding="3" width="80%">
 <tr><td class="tableheader"> Numéro </td><td class="border"> \$Archives[\$i]{num} </td></tr>
 <tr><td class="tableheader"> Demandé par </td><td class="border"> \$ArchiveReq{user} </td></tr>
 <tr><td class="tableheader"> Heure de demande </td><td class="border"> \$reqTime </td></tr>
index b821a80..d662030 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/perl
 #
-# $Id: it.pm,v 1.6 2004/04/10 06:52:47 cbarratt Exp $
+# $Id: it.pm,v 1.7 2004/05/21 02:11:35 cbarratt Exp $
 #
 # Italian i18n file
 #
@@ -64,10 +64,7 @@ EOF
 
 $Lang{H_BackupPC_Server_Status} = "Stato server BackupPC";
 
-$Lang{BackupPC_Server_Status}= <<EOF;
-\${h1(qq{$Lang{H_BackupPC_Server_Status}})}
-
-<p>
+$Lang{BackupPC_Server_Status_General_Info}= <<EOF;
 \${h2("Informazioni generali server")}
 
 <ul>
@@ -89,6 +86,13 @@ $Lang{BackupPC_Server_Status}= <<EOF;
             di ieri era del \$Info{DUDailyMaxPrev}%.
     </ul>
 </ul>
+EOF
+
+$Lang{BackupPC_Server_Status} = <<EOF;
+\${h1(qq{$Lang{H_BackupPC_Server_Status}})}
+
+<p>
+\$generalInfo
 
 \${h2("Processi attualmente in esecuzione")}
 <p>
@@ -262,7 +266,7 @@ EOF
 
 $Lang{BackupPC_Archive2_parity} = <<EOF;
 <tr>
-    <td>ENG Percentage of Parity Data (0 = disable, 5 = typical)</td>
+    <td>Percentuale di dati di parità (0 = disabiltata, 5 = valori tipici)</td>
     <td><input type="numeric" value="\$ArchivePar" name="par"></td>
 </tr>
 EOF
@@ -910,7 +914,7 @@ $Lang{Archive___num_details_for__host} = "BackupPC: Dettagli archivio n. \$num p
 $Lang{Archive___num_details_for__host2 } = <<EOF;
 \${h1("Dettagli archivio n. \$num per \$host")}
 <p>
-<table class="tableStnd" border cellspacing="1" cellpadding="3" width="50%">
+<table class="tableStnd" border cellspacing="1" cellpadding="3" width="80%">
 <tr><td class="tableheader"> Number </td><td class="border"> \$Archives[\$i]{num} </td></tr>
 <tr><td class="tableheader"> Requested by </td><td class="border"> \$ArchiveReq{user} </td></tr>
 <tr><td class="tableheader"> Request time </td><td class="border"> \$reqTime </td></tr>
index 338ca56..d3358c9 100644 (file)
@@ -29,7 +29,7 @@
 #
 #========================================================================
 #
-# Version 2.1.0beta1, released 9 Apr 2004.
+# Version 2.1.0beta2, released 9 May 2004.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -55,7 +55,7 @@ BEGIN {
        #
        # Note: also update configure.pl when this version number is changed!
        #
-        if ( $File::RsyncP::VERSION < 0.50 ) {
+        if ( $File::RsyncP::VERSION < 0.51 ) {
             $RsyncLibOK = 0;
             $RsyncLibErr = "File::RsyncP module version too old: need 0.50";
         } else {
@@ -324,6 +324,7 @@ sub start
                                              $str .= "\n";
                                              $t->{XferLOG}->write(\$str);
                                          },
+                           cacheCheckProb => $conf->{RsyncCsumCacheVerifyProb},
                            %$fioArgs,
                      }),
     });
index be0b24b..07d5a10 100644 (file)
@@ -29,7 +29,7 @@
 #
 #========================================================================
 #
-# Version 2.1.0beta1, released 9 Apr 2004.
+# Version 2.1.0beta2, released 9 May 2004.
 #
 # See http://backuppc.sourceforge.net.
 #
 package BackupPC::Xfer::RsyncDigest;
 
 use strict;
+use BackupPC::FileZIO;
 
 use vars qw( $RsyncLibOK );
 use Carp;
+require Exporter;
+use vars qw( @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS );
+
+my $Log = \&logHandler;
+
+#
+# Magic value for checksum seed.  We only cache block and file digests
+# when the checksum seed matches this value.
+#
+use constant RSYNC_CSUMSEED_CACHE     => 32761;
+
+@ISA = qw(Exporter);
+
+@EXPORT    = qw( );
+
+@EXPORT_OK = qw(
+                  RSYNC_CSUMSEED_CACHE
+             );
+
+%EXPORT_TAGS = (
+    'all'    => [ @EXPORT_OK ],
+);
 
 BEGIN {
     eval "use File::RsyncP;";
@@ -72,25 +95,53 @@ sub blockSize
     return $blkSize;
 }
 
+sub fileDigestIsCached
+{
+    my($class, $file) = @_;
+    my $data;
+
+    open(my $fh, "<", $file) || return -1;
+    binmode($fh);
+    return -2 if ( sysread($fh, $data, 1) != 1 );
+    close($fh);
+    return $data eq chr(0xd6) ? 1 : 0;
+}
+
 #
 # Compute and add rsync block and file digests to the given file.
 #
+# Empty files don't get cached checksums.
+#
+# If verify is set then existing cached checksums are checked.
+# 
+# Returns 0 on success.  Returns 1 on good verify and 2 on bad verify.
+# Returns a variety of negative values on error.
+#
 sub digestAdd
 {
-    my($class, $file, $blockSize, $checksumSeed) = @_;
+    my($class, $file, $blockSize, $checksumSeed, $verify) = @_;
+    my $retValue = 0;
+
+    #
+    # Don't cache checksums if the checksumSeed is not RSYNC_CSUMSEED_CACHE
+    # or if the file is empty.
+    #
+    return -100 if ( $checksumSeed != RSYNC_CSUMSEED_CACHE || !-s $file );
+
     if ( $blockSize == 0 ) {
-       print("bogus digestAdd($file, $blockSize, $checksumSeed)\n");
+       &$Log("digestAdd: bad blockSize ($file, $blockSize, $checksumSeed)");
        $blockSize = 2048;
     }
     my $nBlks = int(65536 * 16 / $blockSize) + 1;
     my($data, $blockDigest, $fileDigest);
 
-    return if ( !$RsyncLibOK );
+    return -101 if ( !$RsyncLibOK );
 
     my $digest = File::RsyncP::Digest->new;
     $digest->add(pack("V", $checksumSeed)) if ( $checksumSeed );
 
-    return -1 if ( !defined(my $fh = BackupPC::FileZIO->open($file, 0, 1)) );
+    return -102 if ( !defined(my $fh = BackupPC::FileZIO->open($file, 0, 1)) );
+
     while ( 1 ) {
         $fh->read(\$data, $nBlks * $blockSize);
         last if ( $data eq "" );
@@ -113,18 +164,56 @@ sub digestAdd
 #                                            length($metaData),
 #                                            $file,
 #                                            $eofPosn);
-    open(my $fh2, "+<", $file) || return -2;
+    open(my $fh2, "+<", $file) || return -103;
     binmode($fh2);
-    return -3 if ( sysread($fh2, $data, 1) != 1 );
+    return -104 if ( sysread($fh2, $data, 1) != 1 );
     if ( $data ne chr(0x78) && $data ne chr(0xd6) ) {
-        printf("Unexpected first char 0x%x\n", ord($data));
-        return -4;
+        &$Log(sprintf("digestAdd: $file has unexpected first char 0x%x",
+                             ord($data)));
+        return -105;
+    }
+    return -106 if ( sysseek($fh2, $eofPosn, 0) != $eofPosn );
+    if ( $verify ) {
+        my $data3;
+
+        #
+        # Verify the cached checksums
+        #
+        return -107 if ( $data ne chr(0xd6) );
+        return -108 if ( sysread($fh2, $data3, length($data2) + 1) < 0 );
+        if ( $data2 eq $data3 ) {
+            return 1;
+        }
+        #
+        # Checksums don't agree - fall through so we rewrite the data
+        #
+        &$Log("digestAdd: $file verify failed; redoing checksums");
+        return -109 if ( sysseek($fh2, $eofPosn, 0) != $eofPosn );
+        $retValue = 2;
     }
-    return -5 if ( sysseek($fh2, $eofPosn, 0) != $eofPosn );
-    return -6 if ( syswrite($fh2, $data2) != length($data2) );
-    return -7 if ( !defined(sysseek($fh2, 0, 0)) );
-    return -8 if ( syswrite($fh2, chr(0xd6)) != 1 );
+    return -110 if ( syswrite($fh2, $data2) != length($data2) );
+    if ( $verify ) {
+        #
+        # Make sure there is no extraneous data on the end of
+        # the file.  Seek to the end and truncate if it doesn't
+        # match our expected length.
+        #
+        return -111 if ( !defined(sysseek($fh2, 0, 2)) );
+        if ( tell($fh2) != $eofPosn + length($data2) ) {
+            if ( !truncate($fh2, $eofPosn + length($data2)) ) {
+                &$Log(sprintf("digestAdd: $file truncate from %d to %d failed",
+                                tell($fh2), $eofPosn + length($data2)));
+                return -112;
+            } else {
+                &$Log(sprintf("digestAdd: $file truncated from %d to %d",
+                                tell($fh2), $eofPosn + length($data2)));
+            }
+        }
+    }
+    return -113 if ( !defined(sysseek($fh2, 0, 0)) );
+    return -114 if ( syswrite($fh2, chr(0xd6)) != 1 );
     close($fh2);
+    return $retValue;
 }
 
 #
@@ -132,6 +221,17 @@ sub digestAdd
 # if they exist and the block size and checksum seed match.  Otherwise
 # we compute the checksums from the file contents.
 #
+# The doCache flag can take three ranges:
+#
+#  - doCache <  0: don't generate/use cached checksums
+#  - doCache == 0: don't generate, but do use cached checksums if available
+#  - doCache >  0: generate (if necessary) and use cached checksums
+#
+# Note: caching is only enabled when compression is on and the
+# checksum seed is RSYNC_CSUMSEED_CACHE (32761).
+#
+# Returns 0 on success.  Returns a variety of negative values on error.
+#
 sub digestStart
 {
     my($class, $fileName, $fileSize, $blockSize, $defBlkSize,
@@ -141,20 +241,23 @@ sub digestStart
 
     my $data;
 
-    my $fio = bless {
+    my $dg = bless {
         name     => $fileName,
         needMD4  => $needMD4,
         digest   => File::RsyncP::Digest->new,
     }, $class;
 
-    if ( $fileSize > 0 && $compress ) {
+    if ( $fileSize > 0 && $compress && $doCache >= 0 ) {
         open(my $fh, "<", $fileName) || return -2;
         binmode($fh);
         return -3 if ( read($fh, $data, 1) != 1 );
-        if ( $data eq chr(0x78) && $doCache && $checksumSeed == 32761 ) {
+        my $ret;
+
+        if ( $data eq chr(0x78) && $doCache > 0
+                     && $checksumSeed == RSYNC_CSUMSEED_CACHE ) {
             #
-            # 32761 is the magic number that rsync uses for checksumSeed
-            # with the --fixed-csum option.
+            # RSYNC_CSUMSEED_CACHE (32761) is the magic number that
+            # rsync uses for checksumSeed with the --fixed-csum option.
             #
             # We now add the cached checksum data to the file.  There
             # is a possible race condition here since two BackupPC_dump
@@ -164,48 +267,57 @@ sub digestStart
             # in which they write it doesn't matter.
             #
             close($fh);
-            $fio->digestAdd($fileName,
-                    $blockSize
-                       || BackupPC::Xfer::RsyncDigest->blockSize($fileSize,
-                                                           $defBlkSize),
-                    $checksumSeed);
+            $ret = $dg->digestAdd($fileName,
+                            $blockSize
+                                || BackupPC::Xfer::RsyncDigest->blockSize(
+                                                    $fileSize, $defBlkSize),
+                                $checksumSeed);
+            if ( $ret < 0 ) {
+                &$Log("digestAdd($fileName) failed ($ret)");
+            }
             #
             # now re-open the file and re-read the first byte
             #
-            open($fh, "<", $fileName) || return -2;
+            open($fh, "<", $fileName) || return -4;
             binmode($fh);
-            return -3 if ( read($fh, $data, 1) != 1 );
+            return -5 if ( read($fh, $data, 1) != 1 );
         }
-        if ( $data eq chr(0xd6) ) {
+        if ( $ret >= 0 && $data eq chr(0xd6) ) {
             #
             # Looks like this file has cached checksums
             # Read the last 48 bytes: that's 2 file MD4s (32 bytes)
             # plus 4 words of meta data
             #
-            return -4 if ( !defined(seek($fh, -48, 2)) ); 
-            return -5 if ( read($fh, $data, 48) != 48 );
-            ($fio->{md4DigestOld},
-             $fio->{md4Digest},
-             $fio->{blockSize},
-             $fio->{checksumSeed},
-             $fio->{nBlocks},
-             $fio->{magic}) = unpack("a16 a16 V V V V", $data);
-            if ( $fio->{magic} == 0x5fe3c289
-                    && $fio->{checksumSeed} == $checksumSeed
-                    && ($blockSize == 0 || $fio->{blockSize} == $blockSize) ) {
-                $fio->{fh}     = $fh;
-                $fio->{cached} = 1;
+            return -6 if ( !defined(seek($fh, -48, 2)) ); 
+            return -7 if ( read($fh, $data, 48) != 48 );
+            ($dg->{md4DigestOld},
+             $dg->{md4Digest},
+             $dg->{blockSize},
+             $dg->{checksumSeed},
+             $dg->{nBlocks},
+             $dg->{magic}) = unpack("a16 a16 V V V V", $data);
+            if ( $dg->{magic} == 0x5fe3c289
+                    && $dg->{checksumSeed} == $checksumSeed
+                    && ($blockSize == 0 || $dg->{blockSize} == $blockSize) ) {
+                $dg->{fh}     = $fh;
+                $dg->{cached} = 1;
+                #
+                # position the file at the start of the rsync block checksums
+                # (4 (adler) + 16 (md4) bytes each)
+                #
+                return -8
+                    if ( !defined(seek($fh, -$dg->{nBlocks}*20 - 48, 2)) );
             } else {
+                #
+                # cached checksums are not valid, so we close the
+                # file and treat it as uncached.
+                #
+                $dg->{cachedInvalid} = 1;
                 close($fh);
             }
-            #
-            # position the file at the start of the rsync block checksums
-            # (4 (adler) + 16 (md4) bytes each)
-            #
-            return -6 if ( !defined(seek($fh, -$fio->{nBlocks}*20 - 48, 2)) );
         }
     }
-    if ( !$fio->{cached} ) {
+    if ( !$dg->{cached} ) {
         #
         # This file doesn't have cached checksums, or the checksumSeed
         # or blocksize doesn't match.  Open the file and prepare to
@@ -214,70 +326,104 @@ sub digestStart
         $blockSize
            = BackupPC::Xfer::RsyncDigest->blockSize($fileSize, $defBlkSize)
                                    if ( $blockSize == 0 );
-        $fio->{checksumSeed} = $checksumSeed;
-        $fio->{blockSize}    = $blockSize;
-        $fio->{fh} = BackupPC::FileZIO->open($fileName, 0, $compress);
-        return -7 if ( !defined($fio->{fh}) );
+        $dg->{checksumSeed} = $checksumSeed;
+        $dg->{blockSize}    = $blockSize;
+        $dg->{fh} = BackupPC::FileZIO->open($fileName, 0, $compress);
+        return -9 if ( !defined($dg->{fh}) );
         if ( $needMD4) {
-            $fio->{csumDigest} = File::RsyncP::Digest->new;
-            $fio->{csumDigest}->add(pack("V", $fio->{checksumSeed}));
+            $dg->{csumDigest} = File::RsyncP::Digest->new;
+            $dg->{csumDigest}->add(pack("V", $dg->{checksumSeed}));
         }
     }
-    return (undef, $fio, $fio->{blockSize});
+    return (undef, $dg, $dg->{blockSize});
 }
 
 sub digestGet
 {
-    my($fio, $num, $csumLen) = @_;
+    my($dg, $num, $csumLen, $noPad) = @_;
     my($fileData);
-    my $blockSize = $fio->{blockSize};
+    my $blockSize = $dg->{blockSize};
 
-    if ( $fio->{cached} ) {
+    if ( $dg->{cached} ) {
         my $thisNum = $num;
-        $thisNum = $fio->{nBlocks} if ( $thisNum > $fio->{nBlocks} );
-        read($fio->{fh}, $fileData, 20 * $thisNum);
-        $fio->{nBlocks} -= $thisNum;
-        if ( $thisNum < $num ) {
+        $thisNum = $dg->{nBlocks} if ( $thisNum > $dg->{nBlocks} );
+        read($dg->{fh}, $fileData, 20 * $thisNum);
+        $dg->{nBlocks} -= $thisNum;
+        if ( $thisNum < $num && !$noPad) {
             #
             # unexpected shortfall of data; pad with zero digest
             #
             $fileData .= pack("c", 0) x (20 * ($num - $thisNum));
         }
-        return $fio->{digest}->blockDigestExtract($fileData, $csumLen);
+        return $dg->{digest}->blockDigestExtract($fileData, $csumLen);
     } else {
-        if ( $fio->{fh}->read(\$fileData, $blockSize * $num) <= 0 ) {
+        if ( $dg->{fh}->read(\$fileData, $blockSize * $num) <= 0 ) {
             #
             # unexpected shortfall of data; pad with zeros
             #
-            $fileData = pack("c", 0) x ($blockSize * $num);
+            $fileData = pack("c", 0) x ($blockSize * $num) if ( !$noPad );
         }
-        $fio->{csumDigest}->add($fileData) if ( $fio->{needMD4} );
-        return $fio->{digest}->blockDigest($fileData, $blockSize,
-                                           $csumLen, $fio->{checksumSeed});
+        $dg->{csumDigest}->add($fileData) if ( $dg->{needMD4} );
+        return $dg->{digest}->blockDigest($fileData, $blockSize,
+                                           $csumLen, $dg->{checksumSeed});
     }
 }
 
 sub digestEnd
 {
-    my($fio) = @_;
+    my($dg, $skipMD4) = @_;
     my($fileData);
 
-    if ( $fio->{cached} ) {
-        close($fio->{fh});
-        return $fio->{md4DigestOld} if ( $fio->{needMD4} );
+    if ( $dg->{cached} ) {
+        close($dg->{fh});
+        return $dg->{md4DigestOld} if ( $dg->{needMD4} );
     } else {
         #
         # make sure we read the entire file for the file MD4 digest
         #
-        if ( $fio->{needMD4} ) {
+        if ( $dg->{needMD4} && !$skipMD4 ) {
             my $fileData;
-            while ( $fio->{fh}->read(\$fileData, 65536) > 0 ) {
-                $fio->{csumDigest}->add($fileData);
+            while ( $dg->{fh}->read(\$fileData, 65536) > 0 ) {
+                $dg->{csumDigest}->add($fileData);
             }
         }
-        $fio->{fh}->close();
-        return $fio->{csumDigest}->digest if ( $fio->{needMD4} );
+        $dg->{fh}->close();
+        return $dg->{csumDigest}->digest if ( $dg->{needMD4} );
     }
 }
 
+sub isCached
+{
+    my($dg) = @_;
+    return wantarray ? ($dg->{cached}, $dg->{cachedInvalid}) : $dg->{cached};
+}
+
+sub blockSizeCurr
+{
+    my($dg) = @_;
+    return $dg->{blockSize};
+}
+
+#
+# Default log handler
+#
+sub logHandler
+{
+    my($str) = @_;
+
+    print(STDERR $str, "\n");
+}
+
+#
+# Set log handler to a new subroutine.
+#
+sub logHandlerSet
+{
+    my($sub) = @_;
+
+    $Log = $sub;
+}
+
 1;
index b028b65..4d2dcb8 100644 (file)
@@ -12,7 +12,7 @@
 #
 #========================================================================
 #
-# Version 2.1.0beta1, released 9 Apr 2004.
+# Version 2.1.0beta2, released 9 May 2004.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -24,7 +24,7 @@ use strict;
 use File::Path;
 use BackupPC::Attrib qw(:all);
 use BackupPC::View;
-use BackupPC::Xfer::RsyncDigest;
+use BackupPC::Xfer::RsyncDigest qw(:all);
 use BackupPC::PoolWrite;
 
 use constant S_IFMT       => 0170000;  # type of file
@@ -97,6 +97,7 @@ sub logHandlerSet
 {
     my($fio, $sub) = @_;
     $fio->{logHandler} = $sub;
+    BackupPC::Xfer::RsyncDigest->logHandlerSet($sub);
 }
 
 #
@@ -104,17 +105,55 @@ sub logHandlerSet
 #
 sub csumStart
 {
-    my($fio, $f, $needMD4, $defBlkSize) = @_;
+    my($fio, $f, $needMD4, $defBlkSize, $phase) = @_;
 
     $defBlkSize ||= $fio->{blockSize};
     my $attr = $fio->attribGet($f);
     $fio->{file} = $f;
     $fio->csumEnd if ( defined($fio->{csum}) );
     return -1 if ( $attr->{type} != BPC_FTYPE_FILE );
+    #
+    # Rsync uses short checksums on the first phase.  If the whole-file
+    # checksum fails, then the file is repeated with full checksums.
+    # So on phase 2 we verify the checksums if they are cached.
+    #
+    if ( ($phase > 0 || rand(1) < $fio->{cacheCheckProb})
+            && $attr->{compress}
+            && $fio->{checksumSeed} == RSYNC_CSUMSEED_CACHE ) {
+        my($err, $d, $blkSize) = BackupPC::Xfer::RsyncDigest->digestStart(
+                                     $attr->{fullPath}, $attr->{size}, 0,
+                                     $defBlkSize, $fio->{checksumSeed},
+                                     0, $attr->{compress}, 0);
+        my($isCached, $isInvalid) = $d->isCached;
+        if ( $fio->{logLevel} >= 5 ) {
+            $fio->log("$attr->{fullPath} verify; cached = $isCached,"
+                    . " invalid = $isInvalid, phase = $phase");
+        }
+        if ( $isCached || $isInvalid ) {
+            my $ret = BackupPC::Xfer::RsyncDigest->digestAdd(
+                            $attr->{fullPath}, $blkSize,
+                            $fio->{checksumSeed}, 1        # verify
+                        );
+            if ( $ret != 1 ) {
+                $fio->log("Bad cached digest for $attr->{fullPath} ($ret);"
+                        . " fixed");
+                $fio->{stats}{errorCnt}++;
+            } else {
+                $fio->log("$f->{name}: verified cached digest")
+                                    if ( $fio->{logLevel} >= 2 );
+            }
+        }
+        $d->digestEnd;
+    }
     (my $err, $fio->{csum}, my $blkSize)
          = BackupPC::Xfer::RsyncDigest->digestStart($attr->{fullPath},
                         $attr->{size}, 0, $defBlkSize, $fio->{checksumSeed},
                         $needMD4, $attr->{compress}, 1);
+    if ( $fio->{logLevel} >= 5 ) {
+        my($isCached, $invalid) = $fio->{csum}->isCached;
+        $fio->log("$attr->{fullPath} cache = $isCached,"
+                . " invalid = $invalid, phase = $phase");
+    }
     if ( $err ) {
         $fio->log("Can't get rsync digests from $attr->{fullPath}"
                 . " (err=$err, name=$f->{name})");
@@ -192,9 +231,9 @@ sub checksumSeed
 
     $fio->{checksumSeed} = $checksumSeed;
     $fio->log("Checksum caching enabled (checksumSeed = $checksumSeed)")
-                   if ( $fio->{logLevel} >= 1 && $checksumSeed == 32761 );
+        if ( $fio->{logLevel} >= 1 && $checksumSeed == RSYNC_CSUMSEED_CACHE );
     $fio->log("Checksum seed is $checksumSeed")
-                   if ( $fio->{logLevel} >= 2 && $checksumSeed != 32761 );
+        if ( $fio->{logLevel} >= 2 && $checksumSeed != RSYNC_CSUMSEED_CACHE );
 }
 
 sub dirs
@@ -876,7 +915,7 @@ sub fileDeltaRxNext
 #
 sub fileDeltaRxDone
 {
-    my($fio, $md4) = @_;
+    my($fio, $md4, $phase) = @_;
     my $name = $1 if ( $fio->{rxFile}{name} =~ /(.*)/ );
     my $ret;
 
@@ -903,12 +942,17 @@ sub fileDeltaRxDone
                          = BackupPC::Xfer::RsyncDigest->digestStart(
                                  $attr->{fullPath}, $attr->{size},
                                  0, 2048, $fio->{checksumSeed}, 1,
-                                 $attr->{compress});
+                                 $attr->{compress}, 1);
                 if ( $err ) {
                     $fio->log("Can't open $attr->{fullPath} for MD4"
                             . " check (err=$err, $name)");
                     $fio->{stats}{errorCnt}++;
                 } else {
+                    if ( $fio->{logLevel} >= 5 ) {
+                        my($isCached, $invalid) = $csum->isCached;
+                        $fio->log("MD4 $attr->{fullPath} cache = $isCached,"
+                                . " invalid = $invalid");
+                    }
                     $newDigest = $csum->digestEnd;
                 }
                 $fio->{rxSize} = $attr->{size};
@@ -930,7 +974,13 @@ sub fileDeltaRxDone
             $fio->log("$name got digests $md4Str vs $newStr")
         }
         if ( $md4 ne $newDigest ) {
-            $fio->log("$name: fatal error: md4 doesn't match");
+            if ( $phase > 0 ) {
+                $fio->log("$name: fatal error: md4 doesn't match on retry;"
+                        . " file removed");
+            } else {
+                $fio->log("$name: md4 doesn't match: will retry in phase 1;"
+                        . " file removed");
+            }
             $fio->{stats}{errorCnt}++;
             if ( defined($fio->{rxOutFd}) ) {
                 $fio->{rxOutFd}->close;
index ebdff99..6886397 100644 (file)
@@ -304,6 +304,7 @@ sub readOutput
                || /^\s*restore directory \\/i
                 || /^\s*Output is \/dev\/null/i
                 || /^\s*Timezone is/i
+                || /^\s*tar_re_search set/i
                 || /^\s*creating lame (up|low)case table/i
            ) {
             # ignore these messages
index ebddca8..2ed1a08 100755 (executable)
--- a/makeDist
+++ b/makeDist
@@ -42,8 +42,8 @@ use Getopt::Std;
 
 umask(0022);
 
-my $Version     = "2.1.0beta1";
-my $ReleaseDate = "9 Apr 2004";
+my $Version     = "2.1.0beta2";
+my $ReleaseDate = "20 May 2004";
 my $DistDir     = "dist/BackupPC-$Version";
 
 my @PerlSrc = qw(
@@ -235,13 +235,13 @@ sub InstallFile
                #
                # fixup for perl 5.6.x
                #
-               if ( !/A NAME="item_%24Conf/i ) {
+               if ( !/A NAME="item_(%|_)24Conf/i ) {
                    s/\$Conf{([^}]*)}/
                        defined($ConfName{$1})
                            ? "\L<A HREF=\"#$ConfName{$1}\">\E\$Conf{$1}<\/A>"
                            : "\$Conf{$1}"/eg;
                }
-               s/<(A NAME="item_%24Conf%7B.*?%7D).*?">/\L<$1">/ig;
+               s/<(A NAME="item_(%|_)24Conf(%|_)7B(.*?)(%|_)7D).*?">/\L<A NAME="item_%24Conf%7b$4%7d">/ig;
                s/^<DD>/<DD><P>/;
                #
                # fixup for perl 5.8.x
@@ -407,6 +407,7 @@ sub CheckLangUsage
             s/\$Lang{([^}]*)}/
                    my $var = $1;
                    next if ( $var =~ m{^(Reason_|Status_|backupType_)} );
+                   next if ( $var eq "Documentation" );
                     if ( !defined($vars->{$var}) ) {
                         print("Unexpected Lang var $var in $f\n");
                         $errors++;