|         |      1 #! /usr/bin/perl | 
|         |      2 # Eigentlich geht das selbe mit: | 
|         |      3 # grep '^[[:space:]]*[[:digit:]]' IDX-file | tr -d | cut -f4 -d' ' | while read f; do | 
|         |      4 #	cat DATA/$f || zcat DATA/$f.gz | 
|         |      5 # done | 
|         |      6 # ODER | 
|         |      7 # perl -ne '/^\s*\d/ and print "DATA/" . (split)[2] . "\n"' IDX-File | while read f; do | 
|         |      8 #	cat DATA/$f || zcat DATA/$f.gz | 
|         |      9 # done | 
|         |     10  | 
|         |     11 use 5.010; | 
|         |     12 use strict; | 
|         |     13 use warnings; | 
|         |     14 use File::Basename; | 
|         |     15 use Cwd qw(abs_path); | 
|         |     16 use autodie qw(:all); | 
|         |     17 use Pod::Usage; | 
|         |     18 use Getopt::Long; | 
|         |     19 use IO::Uncompress::Gunzip qw(gunzip $GunzipError); | 
|         |     20  | 
|         |     21 use constant KiB => 1024; | 
|         |     22 use constant MiB => 1024 * KiB; | 
|         |     23 use constant GiB => 1024 * MiB; | 
|         |     24 use constant ME  => basename $0; | 
|         |     25  | 
|         |     26 sub find_data_dir; | 
|         |     27  | 
|         |     28 MAIN: { | 
|         |     29  | 
|         |     30     Getopt::Long::Configure(qw(Bundling)); | 
|         |     31     GetOptions( | 
|         |     32         "h|help" => sub { pod2usage(-verbose => 1, -exit => 0) }, | 
|         |     33         "m|man"  => sub { | 
|         |     34             pod2usage( | 
|         |     35                 -verbose   => 2, | 
|         |     36                 -exit      => 0, | 
|         |     37                 -noperldoc => system( | 
|         |     38                     "perldoc -V 1>/dev/null | 
|         |     39 			  2>&1" | 
|         |     40                 ) | 
|         |     41             ); | 
|         |     42         }, | 
|         |     43       ) | 
|         |     44       and @ARGV == 2 | 
|         |     45       or pod2usage; | 
|         |     46  | 
|         |     47     my $idx       = shift; | 
|         |     48     my $dst       = shift; | 
|         |     49     my $blocksize = undef; | 
|         |     50     my $data      = find_data_dir($idx); | 
|         |     51  | 
|         |     52     open(my $fh => $idx); | 
|         |     53     { local $/ = ""; $_ = <$fh>; } | 
|         |     54     /^format:\s*1$/m or die ME . ": expected index format 1\n"; | 
|         |     55     ($blocksize) = /^blocksize:\s*(\d+)/m or die ME . ": no blocksize found\n"; | 
|         |     56  | 
|         |     57     my $out; | 
|         |     58     if   ($dst eq "-") { open($out => ">&STDOUT") } | 
|         |     59     else               { open($out => ">", $dst) } | 
|         |     60  | 
|         |     61     while (<$fh>) { | 
|         |     62         next if /^#/; | 
|         |     63         my ($blk, $hash, $path) = split; | 
|         |     64         my ($in, $buffer); | 
|         |     65  | 
|         |     66         if (-f "$data/$path") { | 
|         |     67             open($in => "$data/$path"); | 
|         |     68             binmode($in); | 
|         |     69             local $/ = \$blocksize; | 
|         |     70             $buffer = <$in>; | 
|         |     71         } | 
|         |     72         elsif (-f "$data/$path.gz") { | 
|         |     73             open($in => "$data/$path.gz"); | 
|         |     74             binmode($in); | 
|         |     75             gunzip($in => \$buffer) | 
|         |     76               or die $GunzipError; | 
|         |     77         } | 
|         |     78         else { | 
|         |     79             die ME . ": Can't open $data/$path: $!\n"; | 
|         |     80         } | 
|         |     81         print {$out} $buffer; | 
|         |     82         close($in); | 
|         |     83     } | 
|         |     84     close($out); | 
|         |     85     close($fh); | 
|         |     86 } | 
|         |     87  | 
|         |     88 sub find_data_dir { | 
|         |     89     for (my $dir = shift ; $dir ne "/" ; $dir = abs_path("$dir/..")) { | 
|         |     90         return "$dir/data" if -d "$dir/data" and -d "$dir/idx"; | 
|         |     91     } | 
|         |     92     die ME . ": no data directory found!\n"; | 
|         |     93 } | 
|         |     94  | 
|         |     95 __END__ | 
|         |     96  | 
|         |     97 =head1 NAME | 
|         |     98  | 
|         |     99     imager.restore - cats the blocks of the imager | 
|         |    100  | 
|         |    101 =head1 SYNOPSIS | 
|         |    102  | 
|         |    103     imager.restore {idx} {destination} | 
|         |    104  | 
|         |    105 =head1 DESCRIPTION | 
|         |    106  | 
|         |    107 The B<imager.restore> takes all the blocks from the IDX file and | 
|         |    108 cats them as one data stream. The destination can be any block device, | 
|         |    109 a file name or even B<-> (STDOUT). | 
|         |    110  | 
|         |    111  | 
|         |    112 =cut |