86
use Pristine::Tar::Delta;
87
use Pristine::Tar::Formats;
87
88
use File::Basename qw/basename/;
91
use constant BZIP2_DEBUG => 1;
93
# magic identification
94
use constant BZIP2_ID1 => 0x42;
95
use constant BZIP2_ID2 => 0x5a;
97
# compression methods, 'h' for Bzip2 ('H'uffman coding), '0' for Bzip1 (deprecated)
98
use constant BZIP2_METHOD_HUFFMAN => 0x68;
100
94
my @supported_bzip2_programs = qw(bzip2 pbzip2 zgz);
101
genbz2 => [\&genbz2, 2],
102
gendelta => [\&gendelta, 2],
108
110
print STDERR "Usage: pristine-bz2 [-vdkt] gendelta file.bz2 delta\n";
109
111
print STDERR " pristine-bz2 [-vdkt] genbz2 delta file\n";
113
print STDERR "debug: @_\n" if $debug;
117
print STDERR "pristine-bz2: @_\n" if $verbose;
122
if (system(@_) != 0) {
123
die "command failed: @_\n";
129
my ($in, $out, @args) = @_;
130
vprint(@args, "<", $in, ">", $out);
131
open INFILE, "<", $in or die("Could not open '$in' for reading: $!\n");
132
open OUTFILE, ">", $out or die("Could not open '$out' for reading: $!\n");
133
my $pid = open2(">&OUTFILE", "<&INFILE", @args);
138
return File::Temp::tempdir("pristine-bz2.XXXXXXXXXX",
139
TMPDIR => 1, CLEANUP => !$keep);
143
115
my $filename = shift;
117
if (! is_bz2($filename)) {
118
error "This is not a valid BZip2 archive.";
146
121
open(BZIP2, "< $filename")
147
122
or die("Could not open '$filename' for reading: $!\n");
149
125
if (read(BZIP2, $chars, 4) != 4) {
150
126
die("Unable to read from input\n");
155
131
# we actually want the value, not the ascii position
158
if ($id1 != BZIP2_ID1 || $id2 != BZIP2_ID2 || $method != BZIP2_METHOD_HUFFMAN || $level !~ /^[1-9]$/) {
159
die("This is not a valid BZip2 archive.\n");
134
if ($level !~ /^[1-9]$/) {
135
error "Unknown compression level $level\n";
274
my $tempdir=tempdir();
277
$delta="$tempdir/in";
278
open (OUT, ">", $delta) || die "$delta: $!";
285
doit("tar", "xf", File::Spec->rel2abs($delta), "-C", $tempdir);
286
if (! -e "$tempdir/type") {
287
die "failed to genbz2 delta $delta\n";
290
open (IN, "$tempdir/version") || die "delta lacks version number ($!)";
293
die "delta is version $version, not supported\n";
296
if (open (IN, "$tempdir/type")) {
299
if ($type ne "bz2") {
300
die "delta is for a $type, not a bz2\n";
305
open (IN, "$tempdir/params") || die "delta lacks params file ($!)";
308
my @params=split(' ', $params);
311
next if /^(-[1-9])$/;
312
next if $_ eq '--old-bzip2';
313
die "paranoia check failed on params file from delta ($params)";
315
@params=split(' ', $params);
318
open (IN, "$tempdir/program") || die "delta lacks program file ($!)";
252
my $delta=Pristine::Tar::Delta::read(Tarball => $deltafile);
253
Pristine::Tar::Delta::assert($delta, type => "bz2", maxversion => 2,
254
fields => [qw{params program}]);
256
my @params=split(' ', $delta->{params});
257
foreach my $param (@params) {
258
next if $param=~/^(-[1-9])$/;
259
next if $param eq '--old-bzip2';
260
die "paranoia check failed on params from delta (@params)";
263
my $program=$delta->{program};
321
264
if (! grep { $program eq $_ } @supported_bzip2_programs) {
322
die "paranoia check failed on program file from delta ($program)";
265
die "paranoia check failed on program from delta ($program)";
326
268
if ($program eq 'zgz') {
327
269
# unlike bzip2, zgz only uses sdio
337
279
my $bzip2file=shift;
340
my $tempdir=tempdir();
345
$delta="$tempdir/out";
348
my @files=qw(version type params program);
350
my ($program, @params)=
351
reproducebzip2($tempdir, $bzip2file);
353
open(OUT, ">", "$tempdir/version") || die "$!";
356
open(OUT, ">", "$tempdir/type") || die "$!";
359
open(OUT, ">", "$tempdir/params") || die "$!";
360
print OUT "@params\n";
362
open(OUT, ">", "$tempdir/program") || die "$!";
363
print OUT "$program\n";
366
doit("tar", "czf", $delta, "-C", $tempdir, @files);
373
Getopt::Long::Configure("bundling");
375
"v|verbose!" => \$verbose,
376
"d|debug!" => \$debug,
385
if ($command eq 'genbz2') {
388
elsif ($command eq 'gendelta') {
392
print STDERR "Unknown subcommand \"$command\"\n";
282
my ($program, @params) = reproducebzip2($bzip2file);
284
Pristine::Tar::Delta::write(Tarball => $deltafile, {