bin/catter
changeset 26 496ee9b0f488
parent 25 94a50c69de28
child 27 82c0df89b287
equal deleted inserted replaced
25:94a50c69de28 26:496ee9b0f488
     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     catter - cats the blocks of the imager
       
   100 
       
   101 =head1 SYNOPSIS
       
   102 
       
   103     catter {idx} {destination}
       
   104 
       
   105 =head1 DESCRIPTION
       
   106 
       
   107 The B<catter> 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