Various changes, including changes in 2.1.1 and 2.1.2 releases.
[BackupPC.git] / bin / BackupPC_tarExtract
index fdef553..32044f6 100755 (executable)
@@ -27,7 +27,7 @@
 #
 #========================================================================
 #
-# Version 2.1.0beta1, released 9 Apr 2004.
+# Version 2.1.0, released 20 Jun 2004.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -58,7 +58,7 @@ if ( $ARGV[0] !~ /^([\w\.\s-]+)$/ ) {
     exit(1);
 }
 my $client = $1;
-if ( $ARGV[1] !~ /^([\w\s\.\/\$-]+)$/ ) {
+if ( $ARGV[1] !~ /^([\w\s.\/$(){}[\]-]+)$/ ) {
     print("$0: bad share name '$ARGV[1]'\n");
     exit(1);
 }
@@ -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;
 }
@@ -310,6 +313,7 @@ sub TarReadFile
         #
         my($nRead);
         #print("Reading $f->{name}, $f->{size} bytes, type $f->{type}\n");
+        pathCreate($dir, "$OutDir/$ShareName/$f->{mangleName}", $file, $f);
         my $poolWrite = BackupPC::PoolWrite->new($bpc,
                                          "$OutDir/$ShareName/$f->{mangleName}",
                                          $f->{size}, $Compress);
@@ -347,6 +351,7 @@ sub TarReadFile
        # a plain file.
         #
         $f->{size} = length($f->{linkname});
+        pathCreate($dir, "$OutDir/$ShareName/$f->{mangleName}", $file, $f);
         my $poolWrite = BackupPC::PoolWrite->new($bpc,
                                          "$OutDir/$ShareName/$f->{mangleName}",
                                          $f->{size}, $Compress);
@@ -364,6 +369,7 @@ sub TarReadFile
         # contents.
         #
         $f->{size} = length($f->{linkname});
+        pathCreate($dir, "$OutDir/$ShareName/$f->{mangleName}", $file, $f);
         my $poolWrite = BackupPC::PoolWrite->new($bpc,
                                          "$OutDir/$ShareName/$f->{mangleName}",
                                          $f->{size}, $Compress);
@@ -387,6 +393,7 @@ sub TarReadFile
         } else {
             $data = "$f->{devmajor},$f->{devminor}";
         }
+        pathCreate($dir, "$OutDir/$ShareName/$f->{mangleName}", $file, $f);
         my $poolWrite = BackupPC::PoolWrite->new($bpc,
                                          "$OutDir/$ShareName/$f->{mangleName}",
                                          length($data), $Compress);
@@ -423,26 +430,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");
     }
@@ -471,6 +482,32 @@ sub logFileAction
                                $name);
 }
 
+#
+# Create the parent directory of $file if necessary
+#
+sub pathCreate
+{
+    my($dir, $fullPath, $file, $f) = @_;
+
+    #
+    # Get parent directory of each of $dir and $fullPath
+    #
+    $dir      =~ s{/[^/]*$}{};
+    $fullPath =~ s{/[^/]*$}{};
+    return if ( -d $fullPath );
+    mkpath($fullPath, 0, 0777);
+    $Attrib{$dir} = BackupPC::Attrib->new({ compress => $Compress })
+                                if ( !defined($Attrib{$dir}) );
+    $Attrib{$dir}->set($file, {
+                            type  => BPC_FTYPE_DIR,
+                            mode  => 0755,
+                            uid   => $f->{uid},
+                            gid   => $f->{gid},
+                            size  => 0,
+                            mtime => 0,
+                       });
+}
+
 sub catch_signal
 {
     my $sigName = shift;