#!/usr/bin/perl -w
#use strict;
#Point these to a directory of RH and rebuilt (aka WB) RPMS
#$WB_RPMS = "/home/test/b8";
#$RH_RPMS = "/home/test/new";
my $WB_RPMS = "/centos-3/build8/i386/RedHat/RPMS";
my $RH_RPMS = "/centos-3/build6/i386/RedHat/RPMS";
# Size difference to trigger error, .1 = plus/minus 10%
my $SizeError=.10;
# Working directories
# Careful where these point, they get a "rm -rf" cleaning!
my $RHTMP="/tmp/RH-$$";
my $WBTMP="/tmp/WB-$$";
my $rpm;
foreach $rpm (sort @allrpms){
my $rpmwb=$rpm;
my $rpmwbf=$rpm;
if (! (-e "$WB_RPMS/$rpm") ) {
print "\nNo equivalent original for $rpm \t trying glob\n";
my $fname= $rpm;
$fname =~ s/(.*)-.*-.*/$1-/;
# print "fname is $fname\n";
my $found = 0;
#print "trying $WB_RPMS/$fname*\n";
my @globmatch = glob("$WB_RPMS/$fname*");
while ($rpmwb = shift @globmatch) {
#while($rpmwb = glob("$WB_RPMS/$fname*")){
my $try = $rpmwb;
# print "\nglob got $try\n ";
$try =~ s/.*\///;
$try =~ s/(.*)-.*-.*/$1-/;
if($try eq $fname)
{
#this is the one
$rpmwbf = $rpmwb;
$rpmwbf =~ s/.*\///;
$found = 1;
while($rpmwb = glob("$WB_RPMS/$fname*")){};
last;
}
}
if(!$found)
{
next;
}
}
if($rpm =~ /^kernel/)
{
next;
}
if($rpm eq $rpmwbf)
{
# only doing difficult ones
# next;
}
else
{
print "$rpm >> $rpmwbf\n";
}
# Initialize
%allfiles=(); %RHhash=(); %WBhash=();
$fileproblems=0; $libproblems=0;
system("rm -rf $RHTMP;mkdir $RHTMP");
system("rm -rf $WBTMP;mkdir $WBTMP");
# Extract RPMS
system("cd $RHTMP/; rpm2cpio $RH_RPMS/$rpm | cpio -id --no-absolute-filenames --quiet");
system("cd $WBTMP/; rpm2cpio $WB_RPMS/$rpmwbf | cpio -id --no-absolute-filenames --quiet");
# Parse name/size info
@RHnamesize=`cd $RHTMP/; find ./ -printf "%p:_:%s:_:%U:_:%G:_:%04m:_:\n"`;
@WBnamesize=`cd $WBTMP/; find ./ -printf "%p:_:%s:_:%U:_:%G:_:%04m:_:\n"`;
for ($i=0;$i<@RHnamesize;$i++){
($file,$size,$uid,$gid,$perms)=split(/:_:/,$RHnamesize[$i]);
$RHhash{"$file"}=$size;
$RHuid{"$file"}=$uid;
$RHgid{"$file"}=$gid;
$RHperms{"$file"}=$perms;
$allfiles{"$file"}=1;
}
for ($i=0;$i<@WBnamesize;$i++){
($file,$size,$uid,$gid,$perms)=split(/:_:/,$WBnamesize[$i]);
$WBhash{"$file"}=$size;
$WBuid{"$file"}=$uid;
$WBgid{"$file"}=$gid;
$WBperms{"$file"}=$perms;
$allfiles{"$file"}=1;
}
# Print and tag file errors if appropraite
foreach $file (keys %allfiles){
if (!(exists $RHhash{"$file"})){
print "\n\tPackage contains extra file: $file";
$fileproblems=1;
}
elsif (!(exists $WBhash{"$file"})){
print "\n\tPackage is missing file: $file";
$fileproblems=1;
}
else {
if ($RHhash{"$file"}>0){
$ratio=($WBhash{"$file"})/($RHhash{"$file"})}
else{
$ratio=1-$WBhash{"$file"}; # Negative ratios indicate filesize vs. zero in RedHat
}
if (($ratio-1)*($ratio-1)>($SizeError*$SizeError)) {
printf("\n\tSize Ratio: %3.2f on file:%s",$ratio,$file);
$fileproblems=1;
};
if ($RHuid{"$file"} ne $WBuid{"$file"}) {
printf("\n\tUid Diff $RHuid{\"$file\"} : $WBuid{\"$file\"} on $file");
$fileproblems=1;
}
if ($RHgid{"$file"} ne $WBgid{"$file"}) {
printf("\n\tGid Diff $RHgid{\"$file\"} : $WBgid{\"$file\"} on $file");
$fileproblems=1;
}
if ($RHperms{"$file"} ne $WBperms{"$file"}) {
printf("\n\tPerms Diff $RHperms{\"$file\"} : $WBperms{\"$file\"} on $file");
$fileproblems=1;
}
}
}
# Select executable files
@RHexec=`cd $RHTMP/; find ./ -perm +111 -type f -print`;
# Check library dependencies
foreach $executable (@RHexec) {
# Move on if no equivalent binary exists in rebuild
if (! (-e "$WBTMP/$executable") ) {next;}
# Get shared libs
@RHlibs=`ldd $RHTMP/$executable`;
@WBlibs=`ldd $WBTMP/$executable`;
# Clean up ldd output
$RHlibline=~ s/=>(.*)(\n)/\n/g; $RHlibline=~ s/(\s+)/ /g;
$WBlibline=~ s/=>(.*)(\n)/\n/g; $WBlibline=~ s/(\s+)/ /g;
@RHlibs=split(/ /,$RHlibline);
@WBlibs=split(/ /,$WBlibline);
# Print and tag library errors
foreach $lib (@RHlibs){
$searchpat=$lib;
$searchpat =~ s/\+/\\\+/g;
$searchpat =~ s/\./\\\./g;
unless ($WBlibline =~ (/$searchpat/)){
print "\n\tMissing link in $executable:\t$lib";$libproblems=1;
}
}
foreach $lib (@WBlibs){
$searchpat=$lib;
$searchpat =~ s/\+/\\\+/g;
$searchpat =~ s/\./\\\./g;
unless ($RHlibline =~ (/$searchpat/)){
print "\n\tExtra link in $executable:\t$lib";$libproblems=1;
}
}
}
# sort out provides and requires
@RHrequires = `rpm -qp --requires $RH_RPMS/$rpm`;
@WBrequires = `rpm -qp --requires $WB_RPMS/$rpmwbf`;
while ($rhrequire = shift(@RHrequires))
{
if($wbrequire = shift(@WBrequires))
{
# print "$rhrequire : $wbrequire\n";
if ($rhrequire gt $wbrequire)
{
# extra one in wbrequire
print "\n\tExtra require $wbrequire";$fileproblems=1;
}
elsif($rhrequire lt $wbrequire)
{
# one missing in wbrequire
print "\n\tMissing require $rhrequire";$fileproblems=1;
}
}
else
{
# end of wb array
print "\n\tMissing require $rhrequire";$fileproblems=1;
}
}
# extra in the wb array
print "\n\tExtra require $wbrequire";$fileproblems=1;
}
@RHprovides = `rpm -qp --provides $RH_RPMS/$rpm`;
@WBprovides = `rpm -qp --provides $WB_RPMS/$rpmwbf`;
while ($rhprovide = shift(@RHprovides))
{
if($wbprovide = shift(@WBprovides))
{
# print "$rhprovide : $wbprovide\n";
if ($rhprovide gt $wbprovide)
{
# extra one in wbprovide
print "\n\tExtra provide $wbprovide";$fileproblems=1;
}
elsif($rhprovide lt $wbprovide)
{
# one missing in wbprovide
print "\n\tMissing provide $rhprovide";$fileproblems=1;
}
}
else
{
# end of wb array
print "\n\tMissing provide $rhprovide";$fileproblems=1;
}
}
# extra in the wb array
print "\n\tExtra provide $wbprovide";$fileproblems=1;
}
if ($fileproblems || $libproblems) { print "\n\n";} else {print "MATCH\n";}
}