1#! /usr/bin/perl 2 3# ex:ts=8 sw=4: 4# $OpenBSD: extract_chunks,v 1.2 2014/09/20 09:35:54 espie Exp $ 5# 6# Copyright (c) 2014 Marc Espie <espie@openbsd.org> 7# 8# Permission to use, copy, modify, and distribute this software for any 9# purpose with or without fee is hereby granted, provided that the above 10# copyright notice and this permission notice appear in all copies. 11# 12# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 20# modern packages are "chunked" archives, composed of several gzip files 21# this script can extract each chunk for further analysis, as it is 22# difficult using plain old gunzip to do something like that. 23 24use strict; 25use warnings; 26use IO::Uncompress::AnyUncompress qw($AnyUncompressError); 27use File::Basename; 28 29for my $f (@ARGV) { 30 my $z; 31 unless ($z = IO::Uncompress::AnyUncompress->new($f)) { 32 print STDERR "Bad compressed file $f: $AnyUncompressError\n"; 33 next; 34 } 35 36 my $buffer; 37 my $length = 1024 * 1024; 38 my $stem = basename($f, ".tgz"); 39 my $i = 0; 40 41 while (1) { 42 $i++; 43 # build chunk name in the current directory 44 my $out ="$stem.tar.".sprintf("%04d", $i); 45 open my $fh, ">", $out or die "Can't open chunk $out: $!"; 46 while (1) { 47 my $r = $z->read($buffer, $length); 48 if ($r < 0) { 49 print STDERR "Error reading from $f: ", 50 $AnyUncompressError, "\n"; 51 } 52 if ($r <= 0) { 53 last; 54 } 55 syswrite $fh, $buffer, $r; 56 } 57 close $fh; 58 my $s = $z->nextStream; 59 if ($s == -1) { 60 print STDERR "Error switching to next stream of $f:", 61 $AnyUncompressError, "\n"; 62 } 63 if ($s != 1) { 64 last; 65 } 66 } 67} 68 69