publicscripts/rpm_compare/rpm_compare

241 lines
5.6 KiB
Text
Raw Normal View History

#!/usr/local/bin/perl -w
# $Id$
# $Source$
use strict;
use Getopt::Std;
use RPM::Perlonly;
use Data::Dumper;
my @RPMPATHS=(
"/home/ward/REDHAT73/ftp.nluug.nl/pub/os/Linux/distr/RedHat/ftp/pub/redhat/linux/7.3/en/os/i386/RedHat/RPMS",
"/home/ward/REDHAT73/ftp.nluug.nl/pub/os/Linux/distr/RedHat/ftp/pub/redhat/linux/updates/7.3/en/os/i386",
"/home/ward/REDHAT73/ftp.nluug.nl/pub/os/Linux/distr/RedHat/ftp/pub/redhat/linux/updates/7.3/en/os/i686",
"/home/ward/REDHAT73/ftp.nluug.nl/pub/os/Linux/distr/RedHat/ftp/pub/redhat/linux/updates/7.3/en/os/noarch",
2003-02-13 10:05:27 +00:00
"/home/ward/REDHAT73/homemade",
);
2003-02-13 10:05:27 +00:00
my %instrpms = ();
my %refrpms = ();
my %option = ();
2003-02-13 10:05:27 +00:00
&cmdline;
# Met pathread en RPM-Perlonly-1.0.1 moet het mogelijk zijn te bepalen
# welke RPM de nieuwste is. Hierna is het (denk ik) relatief eenvoudig
# te bepalen op welke systemen er dus packages geupdate moeten worden...
sub pathread {
my %entry = ();
my ( $line, $prefix );
foreach $prefix ( @RPMPATHS ) {
opendir DH, $prefix;
while ($line = readdir DH) {
if ($line =~ /\.rpm$/ ) {
# &splitname($line);
tie my %rpm, "RPM::Perlonly", "$prefix/$line" or die "Problem, could not open $line: $!";
#foreach ( sort keys %rpm ) {
# print "$_ -> $rpm{$_}\n";
#}
#print "Fullname $line\n";
#print " NAME: $rpm{'NAME'}\n";
#print " VERSION: $rpm{'VERSION'}\n";
#print " RELEASE: $rpm{'RELEASE'}\n";
if ( ! exists( $rpm{'EPOCH'} ) ) {
$rpm{'EPOCH'} = 0;
}
#print " ARCH: $rpm{'ARCH'}\n";
2003-02-13 10:05:27 +00:00
push @{$refrpms{$rpm{'NAME'}}}, ( {
'NAME', $rpm{'NAME'},
'BUILDTIME', $rpm{'BUILDTIME'},
'VERSION', $rpm{'VERSION'},
'RELEASE', $rpm{'RELEASE'},
'EPOCH', $rpm{'EPOCH'},
'ARCH', $rpm{'ARCH'},
'FILENAME', $line
} );
untie(%rpm);
}
#print "$line\n";
}
closedir DH;
}
2003-02-13 10:20:19 +00:00
&outputnewest(%refrpms);
}
sub fileread($) {
my $file = shift;
my $VAR1;
open FH, "<$file" or die "Couldn't open $file: $!";
my $data = do { local $/; <FH>; };
close FH;
eval $data;
2003-02-13 10:05:27 +00:00
%refrpms = %{$VAR1};
&outputnewest(%refrpms);
}
sub serverread($) {
my $server = shift;
2003-02-13 10:05:27 +00:00
my $name;
if ( $option{l} ) {
open CH, "rpm -qa|" or die "Can't fork: $!";
} else {
open CH, "ssh -x $server rpm -qa|" or die "Can't fork: $!";
}
while ( <CH> ) {
chomp;
$name = $_;
$name =~ s/(.*?)-([^-]*)-([^-]*)$/$1/;
unless ( $option{q} ) {
print "$_\n";
print "$name\n";
}
push @{$instrpms{$name}}, $_;
}
close CH;
}
sub comparerpms() {
my ( $correct, $installed );
foreach ( sort keys %instrpms ) {
if ( exists $refrpms{$_} ) {
$correct = @{$refrpms{$_}}[0]->{'FILENAME'};
2003-02-13 10:20:19 +00:00
$correct =~ s/\.(i[36]86|athlon|noarch)(\.rpm)?$//;
2003-02-13 10:05:27 +00:00
foreach $installed ( @{$instrpms{$_}} ) {
unless ( $correct eq $installed ) {
print "\ncorrect: $correct\n";
print "installed: $installed\n";
}
}
} else {
print "\n$_ doesn't exist in reference tree\n";
foreach my $rpm ( @{ $instrpms{$_} } ) {
print " $rpm\n";
}
}
}
}
sub outputnewest(@) {
my %allrpms = @_;
if ( $option{q} ) { return; }
foreach ( sort keys %allrpms) {
# print scalar( @{$allrpms{$_}} ) . " $_\n";
if ( scalar( @{$allrpms{$_}} ) > 1 ) {
@{$allrpms{$_}} = sort buildtimesort @{$allrpms{$_}};
# foreach my $rpm ( sort buildtimesort @{$allrpms{$_}} ) {
# print " " . %{$rpm}->{'BUILDTIME'} . " " . %{$rpm}->{'FILENAME'} . "\n";
# }
}
print @{$allrpms{$_}}[0]->{'FILENAME'}."\n";
}
}
sub buildtimesort {
my $a = %{$a}->{'BUILDTIME'};
my $b = %{$b}->{'BUILDTIME'};
if ( $a > $b ) {
return -1;
} else {
return 1;
}
}
sub splitname($$) {
my $fullname = shift;
my $packagename;
my $version;
my $build;
my $arch;
2003-02-13 10:20:19 +00:00
if ( $fullname =~ /(.*?)-([^-]*)-([^-]*)\.(i[36]86|athlon|noarch)(\.rpm)?$/ ) {
$packagename = $1;
$version = $2;
$build =$3;
$arch = $4;
print "Fullname $fullname\n";
print " PACKAGE: $packagename\n";
print " VERSION: $version\n";
print " BUILD: $build\n";
print " ARCH: $arch\n";
return ( $packagename, $version, $build, $arch );
} else {
print "The magic don't work for $fullname\n";
}
}
2003-02-13 10:05:27 +00:00
sub cmdline {
getopts("f:hlo:pqs:", \%option);
if ( $option{h} ) { &help; }
unless ( $option{f} || $option{l} || $option{p} || $option{s} ) { &help; }
if (
( $option{f} && ( $option{p} || $option{o} ) ) ||
( $option{l} && $option{s} )
) {
&help;
}
if ( $option{f} ) {
&fileread($option{f});
} elsif ( $option{p} ) {
&pathread;
if ( $option{o} ) {
open(FH, ">$option{o}") or die "Couldn't open $option{o}: $!";
print FH Dumper(\%refrpms);
close(FH);
}
}
if ( $option{l} ) {
&serverread("localhost");
} elsif ( $option{s} ) {
&serverread($option{s});
}
if ( ( $option{f} || $option{p} ) && ( $option{l} || $option{s} ) ) {
&comparerpms;
}
}
sub help() {
print << "EOT";
Usage: $0 [option]
-f <file> Read reference rpms from file
-h Display this help
2003-02-13 10:05:27 +00:00
-l Read installed rpms from localhost, overrides -s
-o <file> Write reference rpms to file, only useful in combination with -p
-p Read rpms from build in mirror paths
-q Quiet down a bit
-s <server> Read rpms from server
Usually you'll want to run this program like
$0 -p -o <file>
to build an index to compare you're systems to and then proceed
with something like
$0 -f <file> -s <server>
for each server which you want to check the status of.
EOT
exit;
}
# sorteer routine die "menselijk" sorteerd; bijv.:
# boneym100 elvis1 elvis2 elvis10
#sub wardsort {
# my @a = split(/([0-9]+)/,$a);
# my @b = split(/([0-9]+)/,$b);
#
# foreach my $x (@a)
# {
# my $y = shift @b;
# my $r = ($x =~ /^[0-9]+$/ && $y =~ /^[0-9]+$/) ?
# ($x <=> $y) : ($x cmp $y);
# $r && return $r;
# }
# return -1 if (@b);
# 0;
#}