Add format support for efficient sparse file handling.
[cumulus.git] / contrib / restore.pl
index ad1f594..96cf4b4 100755 (executable)
@@ -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 ($2 + 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";
     }
@@ -243,7 +248,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 +258,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