-#!/bin/perl
+#!/usr/bin/perl
#============================================================= -*-perl-*-
#
# BackupPC_tarExtract: extract data from a dump
# Craig Barratt <cbarratt@users.sourceforge.net>
#
# COPYRIGHT
-# Copyright (C) 2001-2003 Craig Barratt
+# Copyright (C) 2001-2009 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
#
#========================================================================
#
-# Version 2.1.0, released 20 Jun 2004.
+# Version 3.2.0, released 31 Jul 2010.
#
# See http://backuppc.sourceforge.net.
#
use strict;
no utf8;
use lib "/usr/local/BackupPC/lib";
+use Encode qw/from_to/;
use BackupPC::Lib;
use BackupPC::Attrib qw(:all);
use BackupPC::FileZIO;
exit(1);
}
my $client = $1;
-if ( $ARGV[1] !~ /^([\w\s\.\/\$-]+)$/ ) {
+if ( $ARGV[1] =~ m{(^|/)\.\.(/|$)} ) {
print("$0: bad share name '$ARGV[1]'\n");
exit(1);
}
-my $ShareNameUM = $1;
+my $ShareNameUM = $1 if ( $ARGV[1] =~ /(.*)/ );
my $ShareName = $bpc->fileNameEltMangle($ShareNameUM);
if ( $ARGV[2] !~ /^(\d+)$/ ) {
print("$0: bad compress level '$ARGV[2]'\n");
# Copyright 1998 Stephen Zander. All rights reserved.
#
my $tar_unpack_header
- = 'Z100 A8 A8 A8 A12 A12 A8 A1 Z100 A6 A2 Z32 Z32 A8 A8 A155 x12';
+ = 'Z100 A8 A8 A8 a12 A12 A8 A1 Z100 A6 A2 Z32 Z32 A8 A8 A155 x12';
my $tar_header_length = 512;
my $BufSize = 1048576; # 1MB or 2^20
$name, $mode, $size, $type) if ( $Conf{XferLogLevel} >= 3 );
$name = $longName if ( defined($longName) );
$linkname = $longLink if ( defined($longLink) );
+
+ #
+ # Map client charset encodings to utf8
+ #
+ # printf("File $name (hex: %s)\n", unpack("H*", $name));
+ if ( $Conf{ClientCharset} ne "" ) {
+ from_to($name, $Conf{ClientCharset}, "utf8");
+ from_to($linkname, $Conf{ClientCharset}, "utf8");
+ }
+ # printf("File now $name (hex: %s)\n", unpack("H*", $name));
+
$name =~ s{^\./+}{};
- $name =~ s{/+$}{};
+ $name =~ s{/+\.?$}{};
$name =~ s{//+}{/}g;
return {
name => $name,
#
my($nRead);
#print("Reading $f->{name}, $f->{size} bytes, type $f->{type}\n");
+ pathCreate($dir, "$OutDir/$ShareName/$f->{mangleName}", $f);
my $poolWrite = BackupPC::PoolWrite->new($bpc,
"$OutDir/$ShareName/$f->{mangleName}",
$f->{size}, $Compress);
# a plain file.
#
$f->{size} = length($f->{linkname});
+ pathCreate($dir, "$OutDir/$ShareName/$f->{mangleName}", $f);
my $poolWrite = BackupPC::PoolWrite->new($bpc,
"$OutDir/$ShareName/$f->{mangleName}",
$f->{size}, $Compress);
# contents.
#
$f->{size} = length($f->{linkname});
+ pathCreate($dir, "$OutDir/$ShareName/$f->{mangleName}", $f);
my $poolWrite = BackupPC::PoolWrite->new($bpc,
"$OutDir/$ShareName/$f->{mangleName}",
$f->{size}, $Compress);
} else {
$data = "$f->{devmajor},$f->{devminor}";
}
+ pathCreate($dir, "$OutDir/$ShareName/$f->{mangleName}", $f);
my $poolWrite = BackupPC::PoolWrite->new($bpc,
"$OutDir/$ShareName/$f->{mangleName}",
length($data), $Compress);
$name);
}
+#
+# Create the parent directory of $file if necessary
+#
+sub pathCreate
+{
+ my($dir, $fullPath, $f) = @_;
+
+ #
+ # Get parent directory of each of $dir and $fullPath
+ #
+ # print("pathCreate: dir = $dir, fullPath = $fullPath\n");
+ $dir =~ s{/([^/]*)$}{};
+ my $file = $bpc->fileNameUnmangle($1);
+ $fullPath =~ s{/[^/]*$}{};
+ return if ( -d $fullPath || $file eq "" );
+ unlink($fullPath) if ( -e $fullPath );
+ mkpath($fullPath, 0, 0777);
+ $Attrib{$dir} = BackupPC::Attrib->new({ compress => $Compress })
+ if ( !defined($Attrib{$dir}) );
+ # print("pathCreate: adding file = $file to dir = $dir\n");
+ $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;