package qa::rpmsoname; use strict; use RPM::Header; sub rpmsoname ($) { my $fname = shift; my $rpm = RPM::Header->new($fname) or die "$fname: $RPM::err"; my %filenames = do { my $i = 0; map { $_, $i++ } @{$rpm->filenames||[]} }; my $rpm_realpath = sub ($) { my $i = shift; while (my $link = $$rpm{FILELINKTOS}[$i]) { my $dir = $$rpm{DIRNAMES}[$$rpm{DIRINDEXES}[$i]]; use File::Spec; local $_ = File::Spec->rel2abs($link, $dir); 1 while s#/[^/]+/[.][.]/#/#; # XXX if (exists $filenames{$_}) { $i = $filenames{$_}; } else { my $basename = $$rpm{BASENAMES}[$i]; warn "$fname: outer link $dir$basename -> $_\n"; return; } } return $i; }; my @prov = grep { /^lib[^(\/)\s]+[.]so\b[^(\/)\s]*$/ } @{$$rpm{PROVIDES}}; my @ret; for my $soname (@prov) { my @i = map { $$_[0] } grep { $$_[1] eq $soname } do { my $i = 0; map {[ $i++, $_ ]} @{$$rpm{BASENAMES}}; }; my @j = map { $rpm_realpath->($_) } @i; @j = do { my %j = map { $_, 1 } @j; keys %j }; if (@j == 0) { warn "$fname: no file for $soname\n"; next; } if (@j > 1) { warn "$fname: $soname maps to a few files\n"; } my $i = $j[0]; push @ret, [ $soname, $$rpm{DIRNAMES}[$$rpm{DIRINDEXES}[$i]] . $$rpm{BASENAMES}[$i] ]; } return \@ret; } use qa::memoize qw(memoize_st1); memoize_st1("rpmsoname"); require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw(rpmsoname); 1;