X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=contrib%2Frestore.pl;h=40ac46909da1efb9549acd51fb1a9ebe1cf6f263;hb=f38dd9bcb0caffd3fc9126b05788c936690e8288;hp=ad1f5949840fc1ef9caa20e7a4816d6b6fff1e36;hpb=ff89c9e6f03239f5a671352a29dc647cd284823f;p=cumulus.git diff --git a/contrib/restore.pl b/contrib/restore.pl index ad1f594..40ac469 100755 --- a/contrib/restore.pl +++ b/contrib/restore.pl @@ -85,11 +85,16 @@ sub verifier_check { # necessary integrity checks (if a checksum is included), and return the object # data. sub load_ref { - # First, try to parse the object reference string into constituent pieces. - # The format is segment/object(checksum)[range]. Both the checksum and - # range are optional. my $ref_str = shift; + # Check for special objects before attempting general parsing. + if ($ref_str =~ m/^zero\[((\d+)\+)?(\d+)\]$/) { + return "\0" x ($3 + 0); + } + + # Try to parse the object reference string into constituent pieces. The + # format is segment/object(checksum)[range]. Both the checksum and range + # are optional. if ($ref_str !~ m/^([-0-9a-f]+)\/([0-9a-f]+)(\(\S+\))?(\[\S+\])?$/) { die "Malformed object reference: $ref_str"; } @@ -117,12 +122,21 @@ sub load_ref { # If a range was specified, then only a subset of the bytes of the object # are desired. Extract just the desired bytes. if ($range) { - if ($range !~ m/^\[(\d+)\+(\d+)\]$/) { + my $object_size = length $contents; + my ($start, $length); + + if ($range =~ m/^\[=(\d+)\]$/) { + die "Object size incorrect (ref $ref_str, actual size $object_size" + if $object_size != $1; + ($start, $length) = (0, $1 + 0); + } elsif ($range =~ m/^\[(\d+)\]$/) { + ($start, $length) = (0, $1 + 0); + } elsif ($range =~ m/^\[(\d+)\+(\d+)\]$/) { + ($start, $length) = ($1 + 0, $2 + 0); + } else { die "Malformed object range: $range"; } - my $object_size = length $contents; - my ($start, $length) = ($1 + 0, $2 + 0); if ($start >= $object_size || $start + $length > $object_size) { die "Object range $range falls outside object bounds " . "(actual size $object_size)"; @@ -243,7 +257,7 @@ sub process_file { # Restore the specified file. How to do so depends upon the file type, so # dispatch based on that. my $dest = "$DEST_DIR/$filename"; - if ($type eq '-') { + if ($type eq '-' || $type eq 'f') { # Regular file unpack_file($filename, %info); } elsif ($type eq 'd') { @@ -253,11 +267,12 @@ sub process_file { } } elsif ($type eq 'l') { # Symlink - if (!defined($info{contents})) { + my $target = $info{target} || $info{contents}; + if (!defined($target)) { die "Symlink $filename has no value specified"; } - my $contents = uri_decode($info{contents}); - symlink $contents, $dest + $target = uri_decode($target); + symlink $target, $dest or die "Cannot create symlink $filename: $!"; # TODO: We can't properly restore all metadata for symbolic links @@ -348,7 +363,7 @@ sub process_metadata { # Try to parse the data as "key: value" pairs of file metadata. Also # handle continuation lines, which start with whitespace and continue # the previous "key: value" pair. - if ($line =~ m/^(\w+):\s*(.*)$/) { + if ($line =~ m/^([-\w]+):\s*(.*)$/) { $info{$1} = $2; $last_key = $1; } elsif ($line =~/^\s/ && defined $last_key) { @@ -398,7 +413,7 @@ while (defined($line = )) { # lines. chomp $line; - if ($line =~ m/^(\w+):\s*(.*)$/) { + if ($line =~ m/^([-\w]+):\s*(.*)$/) { $descriptor{$1} = $2; $last_key = $1; } elsif ($line =~/^\s/ && defined $last_key) {