10

I have a gzip archive with trailing data. If I unpack it using gzip -d it tells me: "decompression OK, trailing garbage ignored" (same goes for gzip -t which can be used as a method of detecting that there is such data).

Now I would like to get to know this garbage, but strangely enough I couldn't find any way to extract it. gzip -l --verbose tells me that the "compressed" size of the archive is the size of the file (i.e. with the trailing data), that's wrong and not helpful. file is also of no help, so what can I do?

10

Figured out now how to get the trailing data.

I created Perl script which creates a file with the trailing data, it's heavily based on https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=604617#10:

#!/usr/bin/perl
use strict;
use warnings; 

use IO::Uncompress::Gunzip qw(:all);
use IO::File;

unshift(@ARGV, '-') unless -t STDIN;

my $input_file_name = shift;
my $output_file_name = shift;

if (! defined $input_file_name) {
  die <<END;
Usage:

  $0 ( GZIP_FILE | - ) [OUTPUT_FILE]

  ... | $0 [OUTPUT_FILE]

Extracts the trailing data of a gzip archive.
Outputs to stdout if no OUTPUT_FILE is given.
- as input file file causes it to read from stdin.

Examples:

  $0 archive.tgz trailing.bin

  cat archive.tgz | $0

END
}

my $in = new IO::File "<$input_file_name" or die "Couldn't open gzip file.\n";
gunzip $in => "/dev/null",
  TrailingData => my $trailing;
undef $in;

if (! defined $output_file_name) {
  print $trailing;
} else {
  open(my $fh, ">", $output_file_name) or die "Couldn't open output file.\n";
  print $fh $trailing;
  close $fh;
  print "Output file written.\n";
}
  • 2
    +1 but IMO, printing to stdout as in the original (but without appending a newline) is better than writing to a hard-coded filename. You can redirect to a file, or pipe to less or hd or hd | less or whatever. – cas Jul 14 '16 at 6:13
  • @cas: Thank you for the input. Added a bit of parameter handling now. My first perl script BTW, I knew the time would come one day. – phk Jul 14 '16 at 10:44
  • 1
    nice improvement. i'd upvote it again if i could :) one more idea - a program like this doesn't really need an input file, it works just as well processing stdin. and a while (<>) loop in perl will read stdin and any file(s) listed in @ARGV....that makes it easy to write scripts that work equally well as a filter (i.e. read stdin, write to stdout) and with named file(s). and stdout, of course, can always be redirected to a file. most of my perl scripts are written as filters to take advantage of this. – cas Jul 14 '16 at 13:57
  • 1
    push @ARGV,'-' if (!@ARGV); before my $input_file_name = shift; is all that's needed here. i.e. a default arg of - (the help message could be printed if $ARGV[0] == '-h' or '--help'. ). For a while(<>) loop you wouldn't even need to do that, but it's probably more trouble than it's worth to write it like that for IO::Uncompress::Gunzip. – cas Jul 15 '16 at 0:36
  • 2
    it's fine. and unshift instead of push makes sense for how you want to use it, still allows an output filename to be specified as the only arg. I'm personally averse to having files being overwritten without some explicit order from the user - redirection or a -o option or something. having a script automagically switch from first arg of two being input to first and only arg being output seems risky and accident-prone to me (tempting murphy). – cas Jul 16 '16 at 0:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.