#!/usr/bin/perl
# rpm2script: extract install scripts from RPM files
# Copyright (C) 2010 Martin von Gagern
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
use strict;
use warnings;
sub myread($$) {
my ($fh, $len) = @_;
my $rem = $len;
my $res = '';
while ($rem) {
my $count = read $fh, $res, $rem, $len-$rem;
die "Error reading $len bytes" unless $count;
$rem -= $count;
}
return $res;
}
my %tags = ( 1023 => 'PREIN', 1024 => 'POSTIN' );
sub doheader($) {
my ($fh) = @_;
my ($magic, $version, $reserved, $nindex, $sheader) =
unpack('Z[3]CZ[4]L>L>', myread($fh, 16));
die "Bad header magic" unless $magic eq "\x8e\xad\xe8";
my @index = ();
for (1..$nindex) {
push @index, [unpack('L>L>L>L>', myread($fh, 16))];
}
$sheader = $sheader - $sheader%8 + 8 if $sheader%8;
my $store = myread($fh, $sheader);
my %res = ();
for my $item (@index) {
my ($tag, $type, $offset, $count) = @$item;
#printf "tag $tag, type $type, offset $offset, count $count\n";
next if $type != 6;
my $data = unpack('Z*', substr($store, $offset));
$res{$tags{$tag}} = $data if defined $tags{$tag};
}
return %res;
}
sub dofile($) {
my ($file) = @_;
print STDERR "$file\n";
my $fh;
open $fh, "<", $file or die "Error opening '$file'";
my @lead = unpack('Z[4]CCs>s>Z[66]s>s>Z[16]', myread($fh, 96));
die "Bad lead magic" unless $lead[0] eq "\xed\xab\xee\xdb";
doheader($fh);
my %header = doheader($fh);
close $fh or die "Error closing '$file'";
for my $tag (sort values(%tags)) {
if (defined $header{$tag}) {
my $out = "$file.$tag.sh";
open $fh, ">", $out or die "Error opening '$out'";
print $fh $header{$tag};
close $fh or die "Error closing '$out'";
print "$file\t$tag\n";
}
}
}
my $dashdash = 0;
for (@ARGV) {
if ($dashdash || !/^-/) {
dofile($_);
}
elsif (/^(--help|-h|-\?)$/) {
print <