* Changes in preparation for 3.2.0beta1...
authorcbarratt <cbarratt>
Mon, 11 Jan 2010 05:32:46 +0000 (05:32 +0000)
committercbarratt <cbarratt>
Mon, 11 Jan 2010 05:32:46 +0000 (05:32 +0000)
* Fixed FTP xfer method, with help from Holger Parplies and
  Mirco Piccin.  FTP restores are still not supported.

* Fixed bug in BackupPC_sendEmail where a user only receives
  email about one host.

* Fixed bug where top-level attrib file was linked into the pool with
  the wrong digest, caused by it being updated multiple times with
  multiple shares.  Reported by Jeff Kosowsky who also supplied a
  patch.

* Fixed bug in blackout calculation when multiple periods span midnight.
  Report and patch from Joachim Falk.

* Wrapped eval {} around attribute unpacking to make it more robust
  to data corruption.  Path submitted by Tim Connors.

* Ignore fileType 8 and 9 in BackupPC_tarCreate rather than consider then
  errors.  These are sockets and unknown (eg: solaris door) files that
  are created dynamicaly by applications - there is no meaningful restore
  for these file types.

* Changed lib/BackupPC/Lib.pm and lib/BackupPC/Storage/Text.pm based on
  patches from Davide Brini and Holger Parplies so that main config
  %Conf values are available in the host config file, allowing more
  flexibility in perl expressions in the config files.  Use beware,
  since the CGI editor won't work correctly if the config file have
  perl expressions.

* Obscure password values in LOG file when CGI editor is used to change
  values.  Proposed by Steve Ling.

* Added favicon.ico from Axel Beckert.  Thanks to Tyler Wagner for submitting
  another version and reminding me about the first.

* Replace "sort(HostSortCompare keys(%$Hosts))" with "sort HostSortCompare keys(%$Hosts)"
  in bin/BackupPC to avoid an error with certain versions of perl.

* Fixed $Conf{XX} links in the BackupPC.html and the CGI editor so they
  correctly reference the definition.

* Support ${VAR} style variable substitution in commands, in addition to
  existing $VAR style.  Suggested by Jeffrey Kosowsky.

* Clarified usage of -b and -w options to BackupPC_tarCreate.  Submitted by
  Michael Selway.

* Repaired Unable_to_connect_to_BackupPC_server Lang string and added new
  string Unable_to_connect_to_BackupPC_server_error_message.  Proposed and
  explained by Holger Parplies.

* Added 'use utf8' to lib/BackupPC/Lang/pl.pm.  Reported by Michal Sawicz.

* Minor updates to lib/BackupPC/Lang/fr.pm from Hubert Tournier.

* Minor update to lib/BackupPC/Lang/en.pm from David Relson.

30 files changed:
ChangeLog
bin/BackupPC
bin/BackupPC_dump
bin/BackupPC_link
bin/BackupPC_sendEmail
bin/BackupPC_tarCreate
conf/config.pl
images/favicon.ico [new file with mode: 0644]
lib/BackupPC/Attrib.pm
lib/BackupPC/CGI/EditConfig.pm
lib/BackupPC/CGI/EmailSummary.pm
lib/BackupPC/CGI/HostInfo.pm
lib/BackupPC/CGI/Lib.pm
lib/BackupPC/Config/Meta.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/Lang/nl.pm
lib/BackupPC/Lang/pl.pm
lib/BackupPC/Lang/pt_br.pm
lib/BackupPC/Lang/zh_CN.pm
lib/BackupPC/Lib.pm
lib/BackupPC/PoolWrite.pm
lib/BackupPC/Storage/Text.pm
lib/BackupPC/Xfer.pm
lib/BackupPC/Xfer/Ftp.pm
lib/BackupPC/Xfer/Protocol.pm
makeDist

index a0e2838..6f85277 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 # Version __VERSION__, __RELEASEDATE__
 #------------------------------------------------------------------------
 
+* Fixed FTP xfer method, with help from Holger Parplies and
+  Mirco Piccin.  FTP restores are still not supported.
+
+* Fixed bug in BackupPC_sendEmail where a user only receives
+  email about one host.
+
+* Fixed bug where top-level attrib file was linked into the pool with
+  the wrong digest, caused by it being updated multiple times with
+  multiple shares.  Reported by Jeff Kosowsky who also supplied a
+  patch.
+
+* Fixed bug in blackout calculation when multiple periods span midnight.
+  Report and patch from Joachim Falk.
+
+* Wrapped eval {} around attribute unpacking to make it more robust
+  to data corruption.  Path submitted by Tim Connors.
+
+* Ignore fileType 8 and 9 in BackupPC_tarCreate rather than consider then
+  errors.  These are sockets and unknown (eg: solaris door) files that
+  are created dynamicaly by applications - there is no meaningful restore
+  for these file types.
+
+* Changed lib/BackupPC/Lib.pm and lib/BackupPC/Storage/Text.pm based on
+  patches from Davide Brini and Holger Parplies so that main config
+  %Conf values are available in the host config file, allowing more
+  flexibility in perl expressions in the config files.  Use beware,
+  since the CGI editor won't work correctly if the config file have
+  perl expressions.
+
+* Obscure password values in LOG file when CGI editor is used to change
+  values.  Proposed by Steve Ling.
+
+* Added favicon.ico from Axel Beckert.  Thanks to Tyler Wagner for submitting
+  another version and reminding me about the first.
+
+* Replace "sort(HostSortCompare keys(%$Hosts))" with "sort HostSortCompare keys(%$Hosts)"
+  in bin/BackupPC to avoid an error with certain versions of perl.
+
+* Fixed $Conf{XX} links in the BackupPC.html and the CGI editor so they
+  correctly reference the definition.
+
+* Support ${VAR} style variable substitution in commands, in addition to
+  existing $VAR style.  Suggested by Jeffrey Kosowsky.
+
+* Clarified usage of -b and -w options to BackupPC_tarCreate.  Submitted by
+  Michael Selway.
+
+* Repaired Unable_to_connect_to_BackupPC_server Lang string and added new
+  string Unable_to_connect_to_BackupPC_server_error_message.  Proposed and
+  explained by Holger Parplies.
+
+* Added 'use utf8' to lib/BackupPC/Lang/pl.pm.  Reported by Michal Sawicz.
+
+* Minor updates to lib/BackupPC/Lang/fr.pm from Hubert Tournier.
+
+* Minor update to lib/BackupPC/Lang/en.pm from David Relson.
+
+#------------------------------------------------------------------------
+# Version 3.2.0beta0, 5 April 2009
+#------------------------------------------------------------------------
+
 * Added BackupPC::Xfer::Protocol as a common class for each Xfer
   method.  This simplifies some of the xfer specific code.
   Implemented by Paul Mantz.
   takes more than 24 hours (ie: when the next one is meant to
   start).  Reported by Tony Schreiner.
 
+* Fixed IO::Dirent run-time check.  Reported by Bernhard Ott and Tino Schwarze
+  debugged it.
+
 * Added more options to server backup command: rather than just forcing
   an incremental or full backup, a regular (auto) backup can be queued
   (ie: do nothing/incr/full based on schedule), as well as doing just
   Marko Tukiainen, who both helped debugging the problem.
 
 * Fixed bug in lib/BackupPC/Xfer/RsyncFileIO.pm that caused
-  incorrected deleted attributes to be set in directories
+  incorrectly deleted attributes to be set in directories
   where one of the files had an rsync phase 1 retry during
   an incremental.  Reported by Tony Nelson.
 
   processing by BackupPC_link, embedded newlines in the file's path
   will cause problems which are avoided by mangling.
 
-  The CGI script undoes the mangling, so it is invisibe to the user.
+  The CGI script undoes the mangling, so it is invisible to the user.
   Of course, old (unmangled) backups are still supported by the CGI
   interface.
 
index d9b58fb..d3eb8aa 100755 (executable)
@@ -1749,7 +1749,7 @@ sub QueueAllPCs
 {
     my $nSkip = 0;
 
-    foreach my $host ( sort(HostSortCompare keys(%$Hosts)) ) {
+    foreach my $host ( sort HostSortCompare keys(%$Hosts) ) {
         $nSkip++ if ( QueueOnePC($host, $host, 'BackupPC', 'bg', 'auto') == 2 );
     }
     foreach my $dhcp ( @{$Conf{DHCPAddressRanges}} ) {
index d1e8384..9dfd6c1 100755 (executable)
@@ -327,6 +327,7 @@ if ( !$opts{i} && !$opts{f} && $Conf{BlackoutGoodCnt} >= 0
                     || !defined($p->{hourBegin})
                     || !defined($p->{hourEnd})
                 );
+        my $matchWday = $wday;
         if ( $p->{hourBegin} > $p->{hourEnd} ) {
             $blackout = $p->{hourBegin} <= $currHours
                           || $currHours <= $p->{hourEnd};
@@ -336,14 +337,14 @@ if ( !$opts{i} && !$opts{f} && $Conf{BlackoutGoodCnt} >= 0
                 # weekday check (eg: Monday 11pm-1am means Monday 2300 to
                 # Tuesday 0100, not Monday 2300-2400 plus Monday 0000-0100).
                 #
-                $wday--;
-                $wday += 7 if ( $wday < 0 );
+                $matchWday--;
+                $matchWday += 7 if ( $matchWday < 0 );
             }
         } else {
             $blackout = $p->{hourBegin} <= $currHours
                           && $currHours <= $p->{hourEnd};
         }
-        if ( $blackout && grep($_ == $wday, @{$p->{weekDays}}) ) {
+        if ( $blackout && grep($_ == $matchWday, @{$p->{weekDays}}) ) {
 #           print(LOG $bpc->timeStamp, "skipping because of blackout"
 #                      . " (alive $StatusHost{aliveCnt} times)\n");
             print(STDERR "Skipping $client because of blackout\n")
index 32bab7f..c1a5604 100755 (executable)
@@ -39,7 +39,7 @@
 #
 #========================================================================
 #
-# Version 3.2.0beta0, released 5 April 2009.
+# Version 3.2.0beta1, released 10 Jan 2010.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -108,12 +108,23 @@ while ( 1 ) {
     $CurrDumpDir = "$Dir/$Backups[$num]{num}";
     $Compress = $Backups[$num]{compress};
     if ( open(NEW, "<", "$Dir/NewFileList.$Backups[$num]{num}") ) {
+        my(@shareAttribArgs);
        binmode(NEW);
         while ( <NEW> ) {
             chomp;
             next if ( !/(\w+) (\d+) (.*)/ );
-            LinkNewFile($1, $2, "$CurrDumpDir/$3");
+            if ( $3 eq "attrib" ) {
+                #
+                # Defer linking top-level attrib file until the end
+                # since it can appear multiple times when multiple shares
+                # are dumped.
+                #
+                @shareAttribArgs = ($1, $2, "$CurrDumpDir/$3");
+            } else {
+                LinkNewFile($1, $2, "$CurrDumpDir/$3");
+            }
         }
+        LinkNewFile(@shareAttribArgs) if ( @shareAttribArgs );
         close(NEW);
     }
     unlink("$Dir/NewFileList.$Backups[$num]{num}")
index f4845f3..6ac3773 100755 (executable)
@@ -31,7 +31,7 @@
 #
 #========================================================================
 #
-# Version 3.2.0beta0, released 5 April 2009.
+# Version 3.2.0beta1, released 10 Jan 2010.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -47,7 +47,7 @@ use Encode;
 use Data::Dumper;
 use Getopt::Std;
 use DirHandle ();
-use vars qw($Lang $TopDir $BinDir $LogDir %Conf);
+use vars qw($Lang $TopDir $BinDir $LogDir %Conf $Hosts);
 
 die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) );
 $TopDir = $bpc->TopDir();
@@ -55,6 +55,7 @@ $LogDir = $bpc->LogDir();
 $BinDir = $bpc->BinDir();
 %Conf   = $bpc->Conf();
 $Lang   = $bpc->Lang();
+$Hosts  = $bpc->HostInfoRead();
 
 $bpc->ChildInit();
 
@@ -76,6 +77,57 @@ EOF
     exit(1);
 }
 
+#
+# Upgrade legacy version of %UserEmailInfo
+#
+# Prior to 3.2.0, it was a hash with entries:
+#
+#    $UserEmailInfo{$user}{lastTime}
+#    $UserEmailInfo{$user}{lastSubj}
+#    $UserEmailInfo{$user}{lastHost}
+#
+# However, if a user had multiple hosts, then an email about one
+# host prevents mail delivery about other hosts.  Starting in 3.2.0
+# the hash is:
+#
+#    $UserEmailInfo{$user}{$host}{lastTime}
+#    $UserEmailInfo{$user}{$host}{lastSubj}
+#
+my $oldFormat = 0;
+foreach my $user ( keys(%UserEmailInfo) ) {
+    if ( defined($UserEmailInfo{$user}{lastTime})
+            && ref($UserEmailInfo{$user}{lastTime}) ne 'HASH' ) {
+        $oldFormat = 1;
+        last;
+    }
+}
+if ( $oldFormat ) {
+    #
+    # Convert to the new format
+    #
+    my %UserEmailInfoOld = %UserEmailInfo;
+    %UserEmailInfo = ();
+    foreach my $user ( keys(%UserEmailInfoOld) ) {
+        next if ( $user eq "" );
+        my $host = $UserEmailInfoOld{$user}{lastHost};
+        next if ( !defined($host) );
+        $UserEmailInfo{$user}{$host}{lastTime} = $UserEmailInfoOld{$user}{lastTime};
+        $UserEmailInfo{$user}{$host}{lastSubj} = $UserEmailInfoOld{$user}{lastSubj};
+    }
+}
+
+#
+# Prune hosts that no longer exist
+#
+foreach my $user ( keys(%UserEmailInfo) ) {
+    foreach my $host ( keys(%{$UserEmailInfo{$user}}) ) {
+        next if ( defined($Hosts->{$host}) );
+        delete($UserEmailInfo{$user}{$host});
+    }
+    next if ( $UserEmailInfo{$user} );
+    delete($UserEmailInfo{$user});
+}
+
 my $err = $bpc->ServerConnect($Conf{ServerHost}, $Conf{ServerPort});
 if ( $err ) {
     if ( $opts{c} && $Conf{EMailAdminUserName} ne "" ) {
@@ -124,7 +176,6 @@ EOF
 ###########################################################################
 # Generate per-host warning messages sent to each user
 ###########################################################################
-my $Hosts = $bpc->HostInfoRead();
 my @AdminBadHosts = ();
 
 foreach my $host ( sort(keys(%Status)) ) {
@@ -135,6 +186,8 @@ foreach my $host ( sort(keys(%Status)) ) {
     %Conf = $bpc->Conf();
     my $user = $Hosts->{$host}{user};
 
+    next if ( $user eq "" );
+
     #
     # Accumulate host errors for the admin email below
     #
@@ -146,7 +199,7 @@ foreach my $host ( sort(keys(%Status)) ) {
         push(@AdminBadHosts, "$host ($Status{$host}{error})");
     }
 
-    next if ( time - $UserEmailInfo{$user}{lastTime}
+    next if ( time - $UserEmailInfo{$user}{$host}{lastTime}
                         < $Conf{EMailNotifyMinDays} * 24*3600
               || $Conf{XferMethod} eq "archive"
               || $Conf{BackupsDisable}
@@ -376,9 +429,8 @@ sub sendUserEmail
     $vars->{subj}     = encode('MIME-Header', $subj);
     $mesg =~ s/\$(\w+)/defined($vars->{$1}) ? $vars->{$1} : "\$$1"/eg;
     SendMail($mesg);
-    $UserEmailInfo{$user}{lastTime} = time;
-    $UserEmailInfo{$user}{lastSubj} = $subj;
-    $UserEmailInfo{$user}{lastHost} = $host;
+    $UserEmailInfo{$user}{$host}{lastTime} = time;
+    $UserEmailInfo{$user}{$host}{lastSubj} = $subj;
 }
 
 sub SendMail
index 7185958..970b2d0 100755 (executable)
@@ -21,8 +21,8 @@
 #       -t              print summary totals
 #       -r pathRemove   path prefix that will be replaced with pathAdd
 #       -p pathAdd      new path prefix
-#       -b BLOCKS       BLOCKS x 512 bytes per record (default 20; same as tar)
-#       -w writeBufSz   write buffer size (default 1MB)
+#       -b BLOCKS       output write buffer size in 512-byte blocks (default 20; same as tar)
+#       -w readBufSz    buffer size for reading files (default 1048576 = 1MB)
 #       -e charset      charset for encoding file names (default: value of
 #                       $Conf{ClientCharset} when backup was done)
 #       -l              just print a file listing; don't generate an archive
@@ -90,8 +90,8 @@ usage: $0 [options] files/directories...
      -t              print summary totals
      -r pathRemove   path prefix that will be replaced with pathAdd
      -p pathAdd      new path prefix
-     -b BLOCKS       BLOCKS x 512 bytes per record (default 20; same as tar)
-     -w writeBufSz   write buffer size (default 1048576 = 1MB)
+     -b BLOCKS       output write buffer size in 512-byte blocks (default 20; same as tar)
+     -w readBufSz    buffer size for reading files (default 1048576 = 1MB)
      -e charset      charset for encoding file names (default: value of
                      \$Conf{ClientCharset} when backup was done)
      -l              just print a file listing; don't generate an archive
@@ -601,6 +601,12 @@ sub TarWriteFile
         $hdr->{size} = 0;
         TarWriteFileInfo($fh, $hdr);
        $SpecialCnt++;
+    } elsif ( $hdr->{type} == BPC_FTYPE_SOCKET
+           || $hdr->{type} == BPC_FTYPE_UNKNOWN ) {
+        #
+        # ignore these two file types - these are dynamic file types created
+        # by applications as needed
+        #
     } else {
         print(STDERR "Got unknown type $hdr->{type} for $hdr->{name}\n");
        $ErrorCnt++;
index 440f597..de759d6 100644 (file)
@@ -1437,6 +1437,16 @@ $Conf{FtpUserName} = '';
 $Conf{FtpPasswd} = '';
 
 #
+# Whether passive mode is used.  The correct setting depends upon
+# whether local or remote ports are accessible from the other machine,
+# which is affected by any firewall or routers between the FTP server
+# on the client and the BackupPC server.
+#
+# This setting is used only if $Conf{XferMethod} = 'ftp'.
+#
+$Conf{FtpPassive} = 1;
+
+#
 # Transfer block size. This sets the size of the amounts of data in
 # each frame. While undefined, this value takes the default value.
 #
@@ -1468,13 +1478,6 @@ $Conf{FtpTimeout} = 120;
 #
 $Conf{FtpFollowSymlinks} = 0;
 
-#
-# Direct restore enabling for FTP.
-#
-# Currently set to 0 since restore functionality is incomplete.
-#
-$Conf{FtpRestoreEnabled} = 0;
-
 ###########################################################################
 # Archive Configuration
 # (can be overwritten in the per-PC log file)
diff --git a/images/favicon.ico b/images/favicon.ico
new file mode 100644 (file)
index 0000000..624f012
Binary files /dev/null and b/images/favicon.ico differ
index ad2bfdc..2b4b36a 100644 (file)
@@ -252,11 +252,18 @@ sub read
            $fd->read(\$newData, 65536);
            $data .= $newData;
        }
-       (
-            @{$a->{files}{$fileName}}{@FldsUnixW},
-            @{$a->{files}{$fileName}}{@FldsUnixN},
-            $data
-        ) = unpack("w$nFldsW N$nFldsN a*", $data);
+        eval {
+           (
+               @{$a->{files}{$fileName}}{@FldsUnixW},
+               @{$a->{files}{$fileName}}{@FldsUnixN},
+               $data
+            ) = unpack("w$nFldsW N$nFldsN a*", $data);
+        };
+        if ( $@ ) {
+            $a->{_errStr} = "unpack: Can't read attributes for $fileName from $file ($@)";
+            $fd->close;
+            return;
+        }
         if ( $a->{files}{$fileName}{$FldsUnixN[-1]} eq "" ) {
             $a->{_errStr} = "Can't read attributes for $fileName"
                           . " from $file";
index 952ab96..8309192 100644 (file)
@@ -28,7 +28,7 @@
 #
 #========================================================================
 #
-# Version 3.2.0beta0, released 5 April 2009.
+# Version 3.2.0beta1, released 5 Jan 2010.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -215,6 +215,8 @@ our %ConfigMenu = (
              visible => sub { return $_[0]->{XferMethod} eq "ftp"; } },
             {name    => "FtpPasswd",
              visible => sub { return $_[0]->{XferMethod} eq "ftp"; } },
+            {name    => "FtpPassive",
+             visible => sub { return $_[0]->{XferMethod} eq "ftp"; } },
             {name    => "FtpBlockSize",
              visible => sub { return $_[0]->{XferMethod} eq "ftp"; } },
             {name    => "FtpPort",
@@ -223,8 +225,6 @@ our %ConfigMenu = (
              visible => sub { return $_[0]->{XferMethod} eq "ftp"; } },
             {name    => "FtpFollowSymlinks",
              visible => sub { return $_[0]->{XferMethod} eq "ftp"; } },
-            {name    => "FtpRestoreEnabled",
-             visible => sub { return $_[0]->{XferMethod} eq "ftp"; } },
 
 
             ### Archive Settings
@@ -1028,7 +1028,7 @@ sub fieldEditBuild
     if ( $level == 0 ) {
         my $lcVarName = lc($varName);
        $content .= <<EOF;
-<tr><td class="border"><a href="?action=view&type=docs#item__conf_${lcVarName}_">$varName</a>
+<tr><td class="border"><a href="?action=view&type=docs#_conf_${lcVarName}_">$varName</a>
 EOF
        if ( defined($overrideVar) ) {
            my $override_checked = "";
@@ -1541,6 +1541,10 @@ sub configDiffMesg
             my $value = $dump->Dump;
             $value =~ s/\n/\\n/g;
             $value =~ s/\r/\\r/g;
+            if ( $p =~ /Passwd/ || $p =~ /Secret/ ) {
+                $value = "'*'";
+            }
+
             $mesg .= eval("qq($Lang->{CfgEdit_Log_Add_param_value})");
         } else {
             my $dump = Data::Dumper->new([$newConf->{$p}]);
@@ -1568,6 +1572,10 @@ sub configDiffMesg
             $valueOld =~ s/\n/\\n/g;
             $valueNew =~ s/\r/\\r/g;
             $valueOld =~ s/\r/\\r/g;
+            if ( $p =~ /Passwd/ || $p =~ /Secret/ ) {
+                $valueNew = "'*'";
+                $valueOld = "'*'";
+            }
 
             $mesg .= eval("qq($Lang->{CfgEdit_Log_Change_param_value})");
         }
index a647c46..70736f7 100644 (file)
@@ -28,7 +28,7 @@
 #
 #========================================================================
 #
-# Version 3.2.0beta0, released 5 April 2009.
+# Version 3.2.0beta1, released 10 Jan 2010.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -50,14 +50,32 @@ sub action
     ReadUserEmailInfo();
     my(%EmailStr, $str);
     foreach my $u ( keys(%UserEmailInfo) ) {
-        next if ( !defined($UserEmailInfo{$u}{lastTime}) );
-        my $emailTimeStr = timeStamp2($UserEmailInfo{$u}{lastTime});
-        $EmailStr{$UserEmailInfo{$u}{lastTime}} .= <<EOF;
+        my $info;
+        if ( defined($UserEmailInfo{$u}{lastTime})
+                && ref($UserEmailInfo{$u}{lastTime}) ne 'HASH' ) {
+            #
+            # old format $UserEmailInfo - pre 3.2.0.
+            #
+            my $host = $UserEmailInfo{$u}{lastHost};
+            $info = {
+                $host => {
+                    lastTime => $UserEmailInfo{$u}{lastTime},
+                    lastSubj => $UserEmailInfo{$u}{lastSubj},
+                },
+            };
+        } else {
+            $info = $UserEmailInfo{$u};
+        }
+        foreach my $host ( keys(%$info) ) {
+            next if ( !defined($info->{$host}{lastTime}) );
+            my $emailTimeStr = timeStamp2($info->{$host}{lastTime});
+            $EmailStr{$info->{$host}{lastTime}} .= <<EOF;
 <tr><td>${UserLink($u)} </td>
-    <td>${HostLink($UserEmailInfo{$u}{lastHost})} </td>
+    <td>${HostLink($host)} </td>
     <td>$emailTimeStr </td>
-    <td>$UserEmailInfo{$u}{lastSubj} </td></tr>
+    <td>$info->{$host}{lastSubj} </td></tr>
 EOF
+        }
     }
     foreach my $t ( sort({$b <=> $a} keys(%EmailStr)) ) {
         $str .= $EmailStr{$t};
index 0805ab9..c4813c8 100644 (file)
@@ -28,7 +28,7 @@
 #
 #========================================================================
 #
-# Version 3.2.0beta0, released 5 April 2009.
+# Version 3.2.0beta1, released 5 Jan 2010.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -248,8 +248,15 @@ EOF
         if ( $user ne "" ) {
             $statusStr .= eval("qq{$Lang->{This_PC_is_used_by}$moreUserStr}");
         }
-        if ( defined($UserEmailInfo{$user})
+        if ( defined($UserEmailInfo{$user}) && defined($UserEmailInfo{$user}{$host}) ) {
+            my $mailTime = timeStamp2($UserEmailInfo{$user}{$host}{lastTime});
+            my $subj     = $UserEmailInfo{$user}{$host}{lastSubj};
+            $statusStr  .= eval("qq{$Lang->{Last_email_sent_to__was_at___subject}}");
+        } elsif ( defined($UserEmailInfo{$user})
                 && $UserEmailInfo{$user}{lastHost} eq $host ) {
+            #
+            # Old format %UserEmailInfo - pre 3.2.0.
+            #
             my $mailTime = timeStamp2($UserEmailInfo{$user}{lastTime});
             my $subj     = $UserEmailInfo{$user}{lastSubj};
             $statusStr  .= eval("qq{$Lang->{Last_email_sent_to__was_at___subject}}");
index e683fdf..44afe9d 100644 (file)
@@ -294,7 +294,8 @@ sub ServerConnect
             Trailer();
             exit(1);
         } else {
-            ErrorExit(eval("qq{$Lang->{Unable_to_connect_to_BackupPC_server}}"));
+            ErrorExit(eval("qq{$Lang->{Unable_to_connect_to_BackupPC_server}}"),
+                      eval("qq{$Lang->{Unable_to_connect_to_BackupPC_server_error_message}}"));
         }
     }
 }
@@ -447,6 +448,7 @@ sub Header
 <html><head>
 <title>$title</title>
 <link rel=stylesheet type="text/css" href="$Conf{CgiImageDirURL}/$Conf{CgiCSSFile}" title="CSSFile">
+<link rel=icon href="$Conf{CgiImageDirURL}/favicon.ico" type="image/x-icon">
 $Conf{CgiHeaders}
 <script src="$Conf{CgiImageDirURL}/sorttable.js"></script>
 </head><body onLoad="document.getElementById('NavMenu').style.height=document.body.scrollHeight">
index 6c35656..a887b8e 100644 (file)
@@ -28,7 +28,7 @@
 #
 #========================================================================
 #
-# Version 3.2.0beta0, released 5 April 2009.
+# Version 3.2.0beta1, released 5 Jan 2010.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -278,11 +278,11 @@ use vars qw(%ConfigMeta);
     },
     FtpUserName         => "string",
     FtpPasswd           => "string",
+    FtpPassive          => "boolean",
     FtpBlockSize        => "integer",
     FtpPort             => "integer",
     FtpTimeout          => "integer",
     FtpFollowSymlinks   => "boolean",
-    FtpRestoreEnabled   => "boolean",
 
     ######################################################################
     # Archive Configuration
index 31fa54c..2fa147c 100644 (file)
@@ -49,12 +49,16 @@ $Lang{Admin_Options_Page} = <<EOF;
 </ul>
 -->
 EOF
-$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"
-          . " Konfigurationsfehler. Bitte teilen Sie diese Fehlermeldung dem Systemadministrator mit.";
+
+$Lang{Unable_to_connect_to_BackupPC_server} = "Kann keine Verbindung zu dem BackupPC Server herstellen!";
+$Lang{Unable_to_connect_to_BackupPC_server_error_message} = <<EOF;
+Dieses CGI Script (\$MyURL) kann keine Verbindung zu dem BackupPC Server
+auf \$Conf{ServerHost} Port \$Conf{ServerPort} herstellen.<br>
+Der Fehler war: \$err.<br>
+Möglicherweise ist der BackupPC Server Prozess nicht gestartet oder es besteht ein
+Konfigurationsfehler. Bitte teilen Sie diese Fehlermeldung dem Systemadministrator mit.
+EOF
+
 $Lang{Admin_Start_Server} = <<EOF;
 \${h1(qq{$Lang{Unable_to_connect_to_BackupPC_server}})}
 <form action="\$MyURL" method="get">
index e4fe19e..9f1b3bc 100644 (file)
@@ -40,12 +40,16 @@ $Lang{Admin_Options_Page} = <<EOF;
 </ul>
 -->
 EOF
-$Lang{Unable_to_connect_to_BackupPC_server} = "Unable to connect to BackupPC server",
-            "This CGI script (\$MyURL) is unable to connect to the BackupPC"
-          . " server on \$Conf{ServerHost} port \$Conf{ServerPort}.  The error"
-          . " was: \$err.",
-            "Perhaps the BackupPC server is not running or there is a "
-          . " configuration error.  Please report this to your Sys Admin.";
+
+$Lang{Unable_to_connect_to_BackupPC_server} = "Unable to connect to BackupPC server";
+$Lang{Unable_to_connect_to_BackupPC_server_error_message} = <<EOF;
+This CGI script (\$MyURL) is unable to connect to the BackupPC
+server on \$Conf{ServerHost} port \$Conf{ServerPort}.<br>
+The error was: \$err.<br>
+Perhaps the BackupPC server is not running or there is a configuration error.
+Please report this to your Sys Admin.
+EOF
+
 $Lang{Admin_Start_Server} = <<EOF;
 \${h1(qq{$Lang{Unable_to_connect_to_BackupPC_server}})}
 <form action="\$MyURL" method="get">
@@ -1284,7 +1288,7 @@ $headers
 Dear $userName,
 
 Your PC ($host) has not been successfully backed up for $days days.
-Your PC has been correctly backed up $numBackups times from $firstTime to $days
+Your PC has been correctly backed up $numBackups times from $firstTime to $days days
 ago.  PC backups should occur automatically when your PC is connected
 to the network.
 
index 0f5f982..eb990dd 100644 (file)
@@ -41,12 +41,16 @@ $Lang{Admin_Options_Page} = <<EOF;
 </ul>
 -->
 EOF
-$Lang{Unable_to_connect_to_BackupPC_server} = "Imposible conectar al servidor BackupPC",
-            "Este script CGI (\$MyURL) no puede conectar al servidor BackupPC"
-          . " en \$Conf{ServerHost} puerto \$Conf{ServerPort}.  El error"
-          . " fué: \$err.",
-            "Quizá el servidor BackupPC no está activo o hay un "
-          . " error de configuración. Por favor informe a su administrador de sistemas.";
+
+$Lang{Unable_to_connect_to_BackupPC_server} = "Imposible conectar al servidor BackupPC";
+$Lang{Unable_to_connect_to_BackupPC_server_error_message} = <<EOF;
+Este script CGI (\$MyURL) no puede conectar al servidor BackupPC
+en \$Conf{ServerHost} puerto \$Conf{ServerPort}.<br>
+El error fué: \$err.<br>
+Quizá el servidor BackupPC no está activo o hay un
+error de configuración. Por favor informe a su administrador de sistemas.
+EOF
+
 $Lang{Admin_Start_Server} = <<EOF;
 \${h1(qq{$Lang{Unable_to_connect_to_BackupPC_server}})}
 <form action="\$MyURL" method="get">
index 7cbfc3d..f72c193 100644 (file)
@@ -40,12 +40,16 @@ $Lang{Admin_Options_Page} = <<EOF;
 </ul>
 -->
 EOF
-$Lang{Unable_to_connect_to_BackupPC_server} = "Impossible de se connecter au serveur BackupPC",
-            "Ce script CGI (\$MyURL) est incapable de se connecter au serveur BackupPC"
-          . " sur \$Conf{ServerHost} au port \$Conf{ServerPort}. L'erreur"
-          . " est: \$err."
-          . " Il est possible que le serveur BackupPC ne fonctionne pas actuellement ou qu'il"
-          . " y ait une erreur de configuration. Veuillez contacter votre administrateur système.";
+
+$Lang{Unable_to_connect_to_BackupPC_server} = "Impossible de se connecter au serveur BackupPC";
+$Lang{Unable_to_connect_to_BackupPC_server_error_message} = <<EOF;
+Ce script CGI (\$MyURL) est incapable de se connecter au serveur BackupPC
+sur \$Conf{ServerHost} au port \$Conf{ServerPort}.<br>
+L'erreur est: \$err.<br>
+Il est possible que le serveur BackupPC ne fonctionne pas actuellement ou qu'il
+y ait une erreur de configuration. Veuillez contacter votre administrateur système.
+EOF
+
 $Lang{Admin_Start_Server} = <<EOF;
 \${h1(qq{$Lang{Unable_to_connect_to_BackupPC_server}})}
 <form action="\$MyURL" method="get">
@@ -67,7 +71,7 @@ $Lang{BackupPC_Server_Status_General_Info}= <<EOF;
 <ul>
 <li> Le PID du serveur est \$Info{pid}, sur l\'hôte \$Conf{ServerHost},
      version \$Info{Version}, démarré le \$serverStartTime.
-<li> Ce rapport à été généré le \$now.
+<li> Ce rapport a été généré le \$now.
 <li> La configuration a été chargée pour la dernière fois à \$configLoadTime.
 <li> La prochaine file d\'attente sera remplie à \$nextWakeupTime.
 <li> Autres infos:
@@ -78,7 +82,7 @@ $Lang{BackupPC_Server_Status_General_Info}= <<EOF;
         \$poolInfo
         <li>L\'espace de stockage a été récemment rempli à \$Info{DUlastValue}%
             (\$DUlastTime), le maximum aujourd\'hui a été de \$Info{DUDailyMax}% (\$DUmaxTime)
-            et hier le maximum était \$Info{DUDailyMaxPrev}%.
+            et hier le maximum était de \$Info{DUDailyMaxPrev}%.
     </ul>
 </ul>
 EOF
@@ -129,7 +133,7 @@ $Lang{BackupPC_Summary}=<<EOF;
 <li>Ce statut a été généré le \$now.
 <li>L\'espace de stockage a été récemment rempli à \$Info{DUlastValue}%
     (\$DUlastTime), le maximum aujourd\'hui a été de \$Info{DUDailyMax}% (\$DUmaxTime)
-    et hier le maximum était \$Info{DUDailyMaxPrev}%.
+    et hier le maximum était de \$Info{DUDailyMaxPrev}%.
 </ul>
 </p>
 
@@ -305,7 +309,7 @@ EOF
 $Lang{BackupPC__Start_Backup_Confirm_on__host} = "BackupPC: Confirmation du démarrage de la sauvegarde de \$host";
 # --------------------------------
 $Lang{Are_you_sure_start} = <<EOF;
-\${h1("Êtes vous certain ?")}
+\${h1("Êtes-vous certain ?")}
 <p>
 Vous allez bientôt démarrer une sauvegarde \$type depuis \$host.
 
@@ -326,7 +330,7 @@ $Lang{BackupPC__Stop_Backup_Confirm_on__host} = "BackupPC: Confirmer l\'arr
 # --------------------------------
 $Lang{Are_you_sure_stop} = <<EOF;
 
-\${h1("Êtes vous certain ?")}
+\${h1("Êtes-vous certain ?")}
 
 <p>
 Vous êtes sur le point d\'arrêter/supprimer de la file les sauvegardes de \$host;
@@ -578,7 +582,7 @@ EOF
 $Lang{Restore_Confirm_on__host} = "BackupPC: Confirmation de restauration sur \$host";
 
 $Lang{Are_you_sure} = <<EOF;
-\${h1("Êtes-vous sur ?")}
+\${h1("Êtes-vous sûr ?")}
 <p>
 Vous êtes sur le point de démarrer une restauration directement sur 
 la machine \$In{hostDest}. Les fichiers suivants vont être restaurés 
index 380a50c..1e14296 100644 (file)
@@ -46,12 +46,16 @@ $Lang{Admin_Options_Page} = <<EOF;
 </ul>
 -->
 EOF
-$Lang{Unable_to_connect_to_BackupPC_server} = "Impossibile connettersi al server BackupPC",
-            "Questo script CGI (\$MyURL) non &egrave; in grado di connettersi al server"
-          . " BackupPC su \$Conf{ServerHost} alla porta \$Conf{ServerPort}.  L'errore &egrave;:"
-          . " \$err.",
-            "Forse il server BackupPC non &egrave; in esecuzione o c'&egrave; un errore"
-          . " nella configurazione.  Contattare l'amministratore di sistema.";
+
+$Lang{Unable_to_connect_to_BackupPC_server} = "Impossibile connettersi al server BackupPC";
+$Lang{Unable_to_connect_to_BackupPC_server_error_message} = <<EOF;
+Questo script CGI (\$MyURL) non &egrave; in grado di connettersi al server
+BackupPC su \$Conf{ServerHost} alla porta \$Conf{ServerPort}.<br>
+L'errore &egrave;: \$err.<br>
+Forse il server BackupPC non &egrave; in esecuzione o c'&egrave; un errore
+nella configurazione.  Contattare l'amministratore di sistema.
+EOF
+
 $Lang{Admin_Start_Server} = <<EOF;
 \${h1(qq{$Lang{Unable_to_connect_to_BackupPC_server}})}
 <form action="\$MyURL" method="get">
index d712812..b9a4262 100644 (file)
@@ -40,12 +40,16 @@ $Lang{Admin_Options_Page} = <<EOF;
 </ul>
 -->
 EOF
-$Lang{Unable_to_connect_to_BackupPC_server} = "Verbinding met de BackupPC server is mislukt",
-            "Dit CGI script (\$MyURL) kon geen verbinding maken met de BackupPC-server"
-          . " op \$Conf{ServerHost} poort \$Conf{ServerPort}."
-          . " De foutmelding was: \$err.",
-            "Mogelijk draait de BackupPC server niet of is er een "
-          . " configuratiefout.  Gelieve dit te melden aan uw systeembeheerder.";
+
+$Lang{Unable_to_connect_to_BackupPC_server} = "Verbinding met de BackupPC server is mislukt";
+$Lang{Unable_to_connect_to_BackupPC_server_error_message} = <<EOF;
+Dit CGI script (\$MyURL) kon geen verbinding maken met de BackupPC-server
+op \$Conf{ServerHost} poort \$Conf{ServerPort}.<br>
+De foutmelding was: \$err.<br>
+Mogelijk draait de BackupPC server niet of is er een
+configuratiefout.  Gelieve dit te melden aan uw systeembeheerder.
+EOF
+
 $Lang{Admin_Start_Server} = <<EOF;
 \${h1(qq{$Lang{Unable_to_connect_to_BackupPC_server}})}
 <form action="\$MyURL" method="get">
index da01f95..07519cb 100644 (file)
@@ -2,6 +2,7 @@
 
 #my %lang;
 #use strict;
+use utf8;
 
 # --------------------------------
 
@@ -40,12 +41,16 @@ $Lang{Admin_Options_Page} = <<EOF;
 </ul>
 -->
 EOF
-$Lang{Unable_to_connect_to_BackupPC_server} = "Nie można połączyć się z serwerem BackupPC",
-            "Ten skrypt CGI (\$MyURL) nie może połączyć się z BackupPC"
-          . " serwer na \$Conf{ServerHost} porcie \$Conf{ServerPort}.  Błąd"
-          . " to: \$err.",
-            "Możliwe ,że serwer BackupPC nie jest uruchomiony albo że występuje "
-          . " błąd w konfiguracji.  Proszę powiadomić o tym swojego Administratora.";
+
+$Lang{Unable_to_connect_to_BackupPC_server} = "Nie można połączyć się z serwerem BackupPC";
+$Lang{Unable_to_connect_to_BackupPC_server_error_message} = <<EOF;
+Ten skrypt CGI (\$MyURL) nie może połączyć się z BackupPC
+serwer na \$Conf{ServerHost} porcie \$Conf{ServerPort}.<br>
+Błąd to: \$err.<br>
+Możliwe ,że serwer BackupPC nie jest uruchomiony albo że występuje
+błąd w konfiguracji.  Proszę powiadomić o tym swojego Administratora.
+EOF
+
 $Lang{Admin_Start_Server} = <<EOF;
 \${h1(qq{$Lang{Unable_to_connect_to_BackupPC_server}})}
 <form action="\$MyURL" method="get">
index 33c357e..ef14035 100644 (file)
@@ -45,12 +45,16 @@ $Lang{Admin_Options_Page} = <<EOF;
 </ul>
 -->
 EOF
-$Lang{Unable_to_connect_to_BackupPC_server} = "Impossível conectar ao servidor BackupPC",
-            "Este script CGI (\$MyURL) não pode conectar-se ao servidor BackupPC"
-          . " em \$Conf{ServerHost} porta \$Conf{ServerPort}.  O erro"
-          . " foi: \$err.",
-            "Talvez o servidor BackupPC não esteja ativo ou há um "
-          . " erro de configuração. Por favor informe o administrador do sistema.";
+
+$Lang{Unable_to_connect_to_BackupPC_server} = "Impossível conectar ao servidor BackupPC";
+$Lang{Unable_to_connect_to_BackupPC_server_error_message} = <<EOF;
+Este script CGI (\$MyURL) não pode conectar-se ao servidor BackupPC
+em \$Conf{ServerHost} porta \$Conf{ServerPort}.<br>
+O erro foi: \$err.<br>
+Talvez o servidor BackupPC não esteja ativo ou há um
+erro de configuração. Por favor informe o administrador do sistema.
+EOF
+
 $Lang{Admin_Start_Server} = <<EOF;
 \${h1(qq{$Lang{Unable_to_connect_to_BackupPC_server}})}
 <form action="\$MyURL" method="get">
index c6a5d0a..e45ffeb 100644 (file)
@@ -41,9 +41,14 @@ $Lang{Admin_Options_Page} = <<EOF;
 </ul>
 -->
 EOF
-$Lang{Unable_to_connect_to_BackupPC_server} = "无法连接到 BackupPC 服务器",
-            "CGI 脚本程序 (\$MyURL) 无法连接到 BackupPC 服务器 \$Conf{ServerHost} 端口 \$Conf{ServerPort}。错误信息:\$err。",
-            "可能 BackupPC 服务器没有运行,或者服务器配置不正确。请通知网络系统管理员。";
+
+$Lang{Unable_to_connect_to_BackupPC_server} = "无法连接到 BackupPC 服务器";
+$Lang{Unable_to_connect_to_BackupPC_server_error_message} = <<EOF;
+CGI 脚本程序 (\$MyURL) 无法连接到 BackupPC 服务器 \$Conf{ServerHost} 端口 \$Conf{ServerPort}。错误信息:\$err。
+可能 BackupPC 服务器没有运行,或者服务器配置不正确。请通知网络系统管理员。
+<br><br>
+EOF
+
 $Lang{Admin_Start_Server} = <<EOF;
 \${h1(qq{$Lang{Unable_to_connect_to_BackupPC_server}})}
 <form action="\$MyURL" method="get">
index dafa09b..cb66a10 100644 (file)
@@ -364,9 +364,9 @@ sub ConfigRead
     # Read host config file
     #
     if ( $host ne "" ) {
-       ($mesg, $config) = $bpc->{storage}->ConfigDataRead($host);
+       ($mesg, $config) = $bpc->{storage}->ConfigDataRead($host, $config);
        return $mesg if ( defined($mesg) );
-       $bpc->{Conf} = { %{$bpc->{Conf}}, %$config };
+       $bpc->{Conf} = $config;
     }
 
     #
@@ -1237,18 +1237,23 @@ sub cmdVarSubstitute
     #
     foreach my $arg ( @$template ) {
         #
+        # Replace $VAR with ${VAR} so that both types of variable
+        # substitution are supported
+        #
+        $arg =~ s[\$(\w+)]{\${$1}}g;
+        #
         # Replace scalar variables first
         #
-        $arg =~ s{\$(\w+)(\+?)}{
+        $arg =~ s[\${(\w+)}(\+?)]{
             exists($vars->{$1}) && ref($vars->{$1}) ne "ARRAY"
                 ? ($2 eq "+" ? $bpc->shellEscape($vars->{$1}) : $vars->{$1})
-                : "\$$1$2"
+                : "\${$1}$2"
         }eg;
         #
         # Now replicate any array arguments; this just works for just one
         # array var in each argument.
         #
-        if ( $arg =~ m{(.*)\$(\w+)(\+?)(.*)} && ref($vars->{$2}) eq "ARRAY" ) {
+        if ( $arg =~ m[(.*)\${(\w+)}(\+?)(.*)] && ref($vars->{$2}) eq "ARRAY" ) {
             my $pre  = $1;
             my $var  = $2;
             my $esc  = $3;
index 63f6451..f11452e 100644 (file)
@@ -96,9 +96,10 @@ sub new
     #
     unlink($fileName) if ( -f $fileName );
     if ( $fileName =~ m{(.*)/.+} && !-d $1 ) {
-        eval { mkpath($1, 0, 0777) };
+        my $newDir = $1;
+        eval { mkpath($newDir, 0, 0777) };
         if ( $@ ) {
-            push(@{$self->{errors}}, "Unable to create directory $1 for $self->{fileName}");
+            push(@{$self->{errors}}, "Unable to create directory $newDir for $self->{fileName}");
         }
     }
     return $self;
index d9be3c3..0f22932 100644 (file)
@@ -274,25 +274,25 @@ sub ConfigPath
 
 sub ConfigDataRead
 {
-    my($s, $host) = @_;
+    my($s, $host, $prevConfig) = @_;
     my($ret, $mesg, $config, @configs);
 
     #
     # TODO: add lock
     #
-    my $conf = {};
+    my $conf = $prevConfig || {};
     my $configPath = $s->ConfigPath($host);
 
     push(@configs, $configPath) if ( -f $configPath );
     foreach $config ( @configs ) {
-        %Conf = ();
+        %Conf = %$conf;
         if ( !defined($ret = do $config) && ($! || $@) ) {
             $mesg = "Couldn't open $config: $!" if ( $! );
             $mesg = "Couldn't execute $config: $@" if ( $@ );
             $mesg =~ s/[\n\r]+//;
             return ($mesg, $conf);
         }
-        %$conf = ( %$conf, %Conf );
+        %$conf = %Conf;
     }
 
     #
index d61d3d2..45c8b54 100644 (file)
@@ -176,7 +176,7 @@ sub restoreEnabled
         return;
 
     } elsif ( $conf->{XferMethod} eq "ftp" ) {
-        return !!( $conf->{FtpRestoreEnabled} );
+        return;
 
     } elsif ( $conf->{XferMethod} eq "rsync"
            || $conf->{XferMethod} eq "rsyncd"
index 91f1881..d6e1955 100644 (file)
 #
 #========================================================================
 #
-# Version 3.2.0beta0, released 5 April 2009.
+# Version 3.2.0beta1, released 5 Jan 2010.
 #
 # See http://backuppc.sourceforge.net.
 #
 #========================================================================
 
-
 package BackupPC::Xfer::Ftp;
 
 use strict;
@@ -187,10 +186,11 @@ sub start
                                 : Net::FTP->new(%$args);
     };
     if ($@) {
-        $t->{_errStr} = "Can't open connection to $args->{host}: $!";
+        $t->{_errStr} = "Can't open connection to $args->{Host}: $!";
         $t->{xferErrCnt}++;
         return;
     }
+    $t->logWrite("Connected to $args->{Host}\n", 2);
 
     #
     # Log in to the ftp server and set appropriate path information.
@@ -198,19 +198,21 @@ sub start
     undef $@;
     eval { $t->{ftp}->login( $conf->{FtpUserName}, $conf->{FtpPasswd} ); };
     if ( $@ ) {
-        $t->{_errStr} = "Can't login to $args->{host}: $!";
+        $t->{_errStr} = "Can't login to $args->{Host}: $!";
         $t->{xferErrCnt}++;
         return;
     }
+    $t->logWrite("Login successful to $conf->{FtpUserName}\@$args->{Host}\n", 2);
 
     undef $@;
     eval { $t->{ftp}->binary(); };
     if ($@) {
         $t->{_errStr} =
-          "Can't enable binary transfer mode to $args->{host}: $!";
+          "Can't enable binary transfer mode to $args->{Host}: $!";
         $t->{xferErrCnt}++;
         return;
     }
+    $t->logWrite("Binary command successful\n", 2);
 
     undef $@;
     eval { $t->{shareName} =~ m/^\.?$/ || $t->{ftp}->cwd( $t->{shareName} ); };
@@ -220,6 +222,7 @@ sub start
         $t->{xferErrCnt}++;
         return;
     }
+    $t->logWrite("Set cwd to $t->{shareName}\n", 2);
 
     undef $@;
     eval { $t->{sharePath} = $t->{ftp}->pwd(); };
@@ -229,6 +232,7 @@ sub start
         $t->{xferErrCnt}++;
         return;
     }
+    $t->logWrite("Pwd returned as $t->{sharePath}\n", 2);
 
     #
     # log the beginning of action based on type
@@ -255,17 +259,20 @@ sub start
     if ( $t->{type} eq 'restore' ) {
 
         $t->restore();
-        $logMsg = "Restore of $t->{host} complete";
+        $logMsg = "Restore of $t->{host} "
+                . ($t->{xferOK} ? "complete" : "failed");
 
     } elsif ( $t->{type} eq 'incr' ) {
 
         $t->backup();
-        $logMsg = "Incremental backup of $t->{host} complete";
+        $logMsg = "Incremental backup of $t->{host} "
+                . ($t->{xferOK} ? "complete" : "failed");
 
     } elsif ( $t->{type} eq 'full' ) {
 
         $t->backup();
-        $logMsg = "Full backup of $t->{host} complete";
+        $logMsg = "Full backup of $t->{host} "
+                . ($t->{xferOK} ? "complete" : "failed");
     }
 
     delete $t->{_errStr};
@@ -490,6 +497,7 @@ sub backup
         $t->{xferErrCnt}++;
         return;
     }
+    $t->logWrite("Created output directory $OutDir\n", 3);
 
     #
     # determine the filetype of the shareName and back it up
@@ -537,15 +545,13 @@ sub getFTPArgs
         FirewallType => undef,                            # not used
         BlockSize    => $conf->{FtpBlockSize} || 10240,
         Port         => $conf->{FtpPort}      || 21,
-        Timeout      => $conf->{FtpTimeout}   || 120,
-        Debug        => 0,                                # do not touch
-        Passive      => 1,                                # do not touch
+        Timeout      => defined($conf->{FtpTimeout}) ? $conf->{FtpTimeout} : 120,
+        Debug        => $t->{logLevel} >= 10 ? 1 : 0,
+        Passive      => defined($conf->{FtpPassive}) ? $conf->{FtpPassive} : 1,          
         Hash         => undef,                            # do not touch
-        LocalAddr    => "localhost",                      # do not touch
     };
 }
 
-
 #
 #   usage:
 #     $dirList = $t->remotels($path);
@@ -568,15 +574,22 @@ sub remotels
 
     my ( $dirContents, $remoteDir, $f );
 
+    $remoteDir = [];
     undef $@;
+    $t->logWrite("remotels: about to list $path\n", 4);
     eval {
         $dirContents = ( $path =~ /^\.?$/ ) ? $ftp->dir()
                                             : $ftp->dir("$path/");
     };
     if ($@) {
         $t->{xferErrCnt}++;
+        $t->logWrite("remotels: can't retrieve remote directory contents of $path: $!\n", 1);
         return "can't retrieve remote directory contents of $path: $!";
     }
+    if ( $t->{logLevel} >= 4 ) {
+        my $str = join("\n", @$dirContents);
+        $t->logWrite("remotels: got dir() result:\n$str\n", 4);
+    }
 
     foreach my $info ( @{parse_dir($dirContents)} ) {
 
@@ -588,6 +601,8 @@ sub remotels
             mode  => $info->[4],
         };
 
+        $t->logWrite("remotels: adding name $f->{name}, type $f->{type}, size $f->{size}, mode $f->{mode}\n", 4);
+
         $f->{utf8name} = $f->{name};
         from_to( $f->{utf8name}, $conf->{ClientCharset}, "utf8" )
                                 if ( $conf->{ClientCharset} ne "" );
@@ -759,9 +774,17 @@ sub handleDir
         }
     }
 
+    $t->logWrite("handleDir: dir->relPath = $dir->{relPath}, OutDir = $OutDir\n", 4);
+
     $attrib    = BackupPC::Attrib->new( { compress => $t->{compress} } );
     $remoteDir = $t->remotels( $dir->{relPath} );
 
+    if ( ref($remoteDir) ne 'ARRAY' ) {
+        $t->logWrite("handleDir failed: $remoteDir\n", 1);
+        $t->logFileAction( "fail", $dir->{utf8name}, $dir );
+        return;
+    }
+
     if ( $t->{type} eq "incr" ) {
         $localDir  = $view->dirAttrib( $t->{incrBaseBkupNum},
                                        $t->{shareName}, $dir->{relPath} );
@@ -894,7 +917,6 @@ sub handleFile
     $poolFile    = $OutDir . "/" .  $bpc->fileNameMangle( $f->{name} );
     $poolWrite   = BackupPC::PoolWrite->new( $bpc, $poolFile, $f->{size},
                                            $t->{compress} );
-
     $localSize = 0;
 
     undef $@;
@@ -908,6 +930,7 @@ sub handleFile
     if ( !*FTP || $@ || @$errs ) {
 
         $t->logFileAction( "fail", $f->{utf8name}, $attribInfo );
+        $t->logWrite("Unlinking($poolFile) because of error on close\n", 3);
         unlink($poolFile);
         $t->{xferBadFileCnt}++;
         $stats->{errCnt} += scalar @$errs;
@@ -919,6 +942,7 @@ sub handleFile
     #
     if ( $localSize != $f->{size} ) {
         $t->logFileAction( "fail", $f->{utf8name}, $attribInfo );
+        $t->logWrite("Unlinking($poolFile) because of size mismatch ($localSize vs $f->{size})\n", 3);
         unlink($poolFile);
         $stats->{xferBadFileCnt}++;
         $stats->{errCnt}++;
index 6b1f903..3072870 100644 (file)
@@ -29,7 +29,7 @@
 #
 #========================================================================
 #
-# Version 3.2.0beta0, released 5 April 2009.
+# Version 3.2.0beta1, released 5 Jan 2010.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -63,6 +63,7 @@ sub new
         pipeRH    => undef,
         pipeWH    => undef,
         badFiles  => [],
+        logLevel  => $bpc->{Conf}{XferLogLevel},
 
         #
         # Various stats
index 5005498..21bca1f 100755 (executable)
--- a/makeDist
+++ b/makeDist
@@ -243,6 +243,7 @@ foreach my $dir ( qw(bin doc conf images init.d/src cgi-bin httpd/src
 
 my %ConfName;
 my $ConfPod = config2pod();
+
 rmtree("doc", 0, 0);
 mkpath("doc", 0, 0777);
 InstallFile("doc-src/BackupPC.pod", "doc/BackupPC.pod");
@@ -257,6 +258,7 @@ pod2html("doc/BackupPC.pod",
 foreach my $file ( (@PerlSrc,
            <images/*.gif>,
            <images/*.png>,
+           <images/*.ico>,
            qw(
                conf/config.pl
                conf/hosts
@@ -300,7 +302,7 @@ sub InstallFile
     my($file, $dest) = @_;
 
     unlink($dest) if ( -d $dest );
-    if ( $file =~ /\.gif/ || $file =~ /\.png/ ) {
+    if ( $file =~ /\.gif/ || $file =~ /\.png/ || $file =~ /\.ico/ ) {
         die("can't copy($file, $dest)\n") unless copy($file, $dest);
     } else {
        open(FILE, $file)   || die("can't open $file for reading\n");
@@ -315,10 +317,10 @@ sub InstallFile
                #
                # fixup for conf links
                #
-               if ( !/A NAME="item_(%|_)conf/i ) {
+               if ( !/a name="_conf/i ) {
                    s/\$Conf{([^}]*)}/
                        defined($ConfName{$1})
-                           ? "\L<a href=\"#$ConfName{$1}\">\E\$Conf{$1}<\/A>"
+                           ? "\L<a href=\"#$ConfName{$1}\">\E\$Conf{$1}<\/a>"
                            : "\$Conf{$1}"/eg;
                }
                s/^<DD>/<DD><P>/;
@@ -394,7 +396,7 @@ sub config2pod
             push(@conf, $_);
             my $text = "_conf_${var}_";
             $text =~ s{[\W\s]}{_}g;
-            $ConfName{$var} = "item_$text";
+            $ConfName{$var} = "$text";
         } elsif ( /^$/ ) {
             if ( $str ne "" && @conf ) {
                 $out .= "=item " . join("\n\n=item ", @conf) . "\n\n";