#! /usr/bin/perl # ex:ts=8 sw=4: # $OpenBSD: extract_chunks,v 1.2 2014/09/20 09:35:54 espie Exp $ # # Copyright (c) 2014 Marc Espie # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # modern packages are "chunked" archives, composed of several gzip files # this script can extract each chunk for further analysis, as it is # difficult using plain old gunzip to do something like that. use strict; use warnings; use IO::Uncompress::AnyUncompress qw($AnyUncompressError); use File::Basename; for my $f (@ARGV) { my $z; unless ($z = IO::Uncompress::AnyUncompress->new($f)) { print STDERR "Bad compressed file $f: $AnyUncompressError\n"; next; } my $buffer; my $length = 1024 * 1024; my $stem = basename($f, ".tgz"); my $i = 0; while (1) { $i++; # build chunk name in the current directory my $out ="$stem.tar.".sprintf("%04d", $i); open my $fh, ">", $out or die "Can't open chunk $out: $!"; while (1) { my $r = $z->read($buffer, $length); if ($r < 0) { print STDERR "Error reading from $f: ", $AnyUncompressError, "\n"; } if ($r <= 0) { last; } syswrite $fh, $buffer, $r; } close $fh; my $s = $z->nextStream; if ($s == -1) { print STDERR "Error switching to next stream of $f:", $AnyUncompressError, "\n"; } if ($s != 1) { last; } } }