#!/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; opendir(DIR,$RH_RPMS); my @allrpms= grep (/rpm$/, readdir(DIR) ); closedir(DIR); 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 printf ("%-50s\t", $rpm); 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) { chop $executable; # 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=join('',(sort @RHlibs)); $WBlibline=join('',(sort @WBlibs)); $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)) { chomp($rhrequire); chomp($wbrequire); # print "$rhrequire : $wbrequire\n"; if ($rhrequire gt $wbrequire) { # extra one in wbrequire print "\n\tExtra require $wbrequire";$fileproblems=1; unshift(@RHrequires,$rhrequire); } elsif($rhrequire lt $wbrequire) { # one missing in wbrequire print "\n\tMissing require $rhrequire";$fileproblems=1; unshift(@WBrequires,$wbrequire); } } else { # end of wb array print "\n\tMissing require $rhrequire";$fileproblems=1; } } if(shift(@WBrequires)){ # 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)) { chomp($rhprovide); chomp($wbprovide); # print "$rhprovide : $wbprovide\n"; if ($rhprovide gt $wbprovide) { # extra one in wbprovide print "\n\tExtra provide $wbprovide";$fileproblems=1; unshift(@RHprovides,$rhprovide); } elsif($rhprovide lt $wbprovide) { # one missing in wbprovide print "\n\tMissing provide $rhprovide";$fileproblems=1; unshift(@WBprovides,$wbprovide); } } else { # end of wb array print "\n\tMissing provide $rhprovide";$fileproblems=1; } } if(shift(@WBprovides)){ # extra in the wb array print "\n\tExtra provide $wbprovide";$fileproblems=1; } if ($fileproblems || $libproblems) { print "\n\n";} else {print "MATCH\n";} }