#!/usr/bin/perl # # srpm2bin - Print a list of binary RPMS this SRPM produces # # Copyright (C) 2003 Martin K. Petersen # Released under the terms of the GNU General Public License v2. # # Why all these rpm calls instead of parsing the spec file directly? # Two words: macro expansion. use File::Temp qw/ tempdir /; use File::Spec; use File::Basename; use Getopt::Std; # Regular Expression matching RPM packages: # -- sub decompose { $_ = shift; return ($_ =~ /([\w_\.\-\+]+)-([\w\.]+)-([\w\.]+)/); } sub main::HELP_MESSAGE () { print STDERR "List RPM packages generated by an SRPM\n"; print STDERR "Usage: srpm2bin [-a ] SRPM\n"; exit 1; } # Parse command line getopts('a:'); # Find arch $arch = `arch`; chomp $arch; $arch = $opt_a if ($opt_a); $arch =~ s/i.86/i386/; main::HELP_MESSAGE() unless $file = File::Spec->rel2abs(shift); ($pkg, $path, $suffix) = fileparse($file, '.src.rpm'); ($name, $ver, $rel, $tag) = decompose($pkg); # Query package to find out whether it is arch independent $tag = $arch; $tag = "i686" if ($name eq "kernel" && $arch eq "i386"); open SPEC, "rpm -qp $file --qf '[%{BUILDARCHS}\n]' 2>&1 |" or \ die "Can't query $file"; while () { next if (/warning/); if (/noarch/) { $tag = "noarch"; } } close SPEC; # Is the package defined for this arch? $incl_arch = 0; open SPEC, "rpm -qp $file --qf '[%{EXCLUSIVEARCH}\n]' 2>&1| " or \ die "Can't query $file"; while () { next if (/warning/); $incl_arch = 1 if (/\(none\)/); $incl_arch = 1 if (/$arch/); } close SPEC; $excl_arch = 0; open SPEC, "rpm -qp $file --qf '[%{EXCLUDEARCH}\n]' 2>&1| " or \ die "Can't query $file"; while () { next if (/warning/); $excl_arch = 1 if (/$arch/); } close SPEC; if ($incl_arch == 0 || $excl_arch == 1) { # pkg not supported on this arch print STDERR "$pkg not supported on $arch\n"; exit 0; } # Now, this is a bit convoluted, but it doesn't appear that we can get # a subpackage listing from a source RPM. Using --specfile works, # though. So we unpack just the specfile and run a query on that to # get the subpackage list. $spec = `rpm2cpio < $file | cpio -it --quiet | egrep "\.spec\$"`; chomp $spec; die "Couldn't get a file listing from $file" if $spec eq ""; # Make rpm parse the spec file and output a package list die "Can't create a temporary directory" unless $tempdir = tempdir(); chdir $tempdir; system "rpm2cpio < $file | cpio -id --quiet $spec" or "Can't extract $spec from $file"; open PKGLIST, "rpm -q --specfile $spec|" or die "Can't get package list from $spec"; # Print all resulting subpackages while () { chomp; print STDOUT "$_.$tag.rpm\n"; } close PKGLIST; unlink $spec; rmdir $tempdir; # EOF