#!/usr/bin/perl -w # create list of older rpms to be replaced by newer packages # Michal Jaegermann, michal@harddata.com, 2007/June/18 # pass a list of directories to operate on; if empty works # on cwd. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. use strict; use File::Find; my $cwd = `pwd`; chomp $cwd; if (@ARGV) { @ARGV = grep( ! -f $_, @ARGV); # ignore files - old scripts compatibility map { $_ = "$cwd/$_" unless m/^\//; } @ARGV; } $ARGV[0] = $cwd unless (@ARGV); # print "@ARGV", "\n"; # exit; my %fn = (); my $cdir; sub find_older { # sort packages on mtime and drop the newest one my $pkg = shift; my $count = shift; my ($arch, $fname, $rel, $ver); my $mtime; my @names = (); my %time; ($pkg, $arch) = ($pkg =~ m/^(.+)\.([^.]+)$/); while ($count > 0) { $ver = shift; $rel = shift; next unless defined $ver and defined $rel; $fname = "$pkg-$ver-$rel.$arch.rpm"; next unless -e "$cdir/$fname"; (undef,undef,undef,undef, undef,undef,undef,undef, undef,$mtime,undef,undef,undef) = stat "$cdir/$fname"; $time{$mtime} = $fname; $count--; } for $mtime (sort {$a <=> $b} keys %time) { push @names, $time{$mtime}; } pop @names; return @names; } sub process_packages { # only if a package shows up with different release-version # bother to look which are older and show a list of # all packages which can be removed my @oldpacks; return unless defined $cdir; foreach my $pkg ( keys %fn) { next if $fn{$pkg}[0] == 1; @oldpacks = find_older $pkg, @{ $fn{$pkg} }; foreach (@oldpacks) { print "$cdir/$_\n"; } } } sub worker { # create table indexed by a package name (with arch as a part # of this name) counting how many different versions and releases # we got my ($pname, $ver, $rel, $arch); if (-d ) { # new directory - process what we collected so far process_packages; %fn = (); undef $cdir; } else { $cdir = $File::Find::dir unless defined $cdir; ($pname, $ver, $rel) = m/^(.+)-([^-]+)-([^-]+)\.rpm$/; return unless defined $rel and defined $ver and defined $pname; ($rel, $arch) = ($rel =~ m/^(.+)\.([^.]+)$/); return unless defined $rel and defined $arch; $pname .= ".$arch"; if (exists $fn{$pname}) { $fn{$pname}[0] += 1; push @{ $fn{$pname} }, $ver, $rel; } else { $fn{$pname} = [1, $ver, $rel]; } } } find \&worker, @ARGV; process_packages;