#!/usr/bin/perl -w # $Id: debup2date,v 1.2 2003/08/16 14:51:51 cb Exp $ # (c) Christoph Berg # This program is free software covered by the GNU GPL. # 030816 cb v1.0 (The Debian 10th anniversary release) use Getopt::Std; getopts('ant:v'); $opt_a ||= 0; $opt_n ||= 0; $opt_t ||= "stable"; $opt_v ||= 0; $ENV{'LC_ALL'} = "C"; sub vercmp { my $a = shift; my $b = shift; system "dpkg --compare-versions $a ge $b"; return ($? >> 8) == 0; } sub check_package{ my $package = shift; my ($inst_version, $cand_version, $want_version, $version); open APT, "apt-cache policy $package 2>&1 |" or die "apt-cache: $!"; while() { if(/^(\S+):$/) { die if $1 ne $package; } elsif(/^ Installed: \(none\)/) { } elsif(/^ Installed: (.*)/) { $inst_version = $1; } elsif(/^ Candidate: \(none\)/) { } elsif(/^ Candidate: (.*)/) { $cand_version = $1; } elsif(/^ Version Table:/) { } elsif(/^ (\*\*\*| ) (.*) 0$/) { $version = $2; } elsif(/^ *(\d+) (.*)/) { if($2 =~ /$opt_t/) { if(defined $want_version and $want_version ne $version) { print "more than one version ($want_version, $version) for $package in release $opt_t found, check output of 'apt-cache policy $package' to see if something is wrong\n"; } $want_version ||= $version; } } elsif(/W: Unable to locate package/) { print "$_"; return; } else { die "unknown line: $_"; } } close APT; if(! defined $cand_version) { print "$package exists, but has no candidate, "; # we assume more output is to come, hence no \n } if(! defined $inst_version) { print "$package is not installed\n"; return; } if($inst_version ne $cand_version) { $a = vercmp($inst_version, $cand_version) > 0 ? "older" : "newer"; print "$package $inst_version has a $a candidate $cand_version\n"; } if(! defined $want_version) { print "no version for $package found in release $opt_t\n"; return; } if($inst_version ne $want_version) { $v = vercmp($inst_version, $want_version) > 0; $a = $v ? "newer" : "older"; print "$package $inst_version is $a than $want_version in release $opt_t\n" unless $opt_n and !$v; } elsif($opt_v) { print "$package is up-to-date\n"; } return; } if($opt_a) { open DPKG, "dpkg --get-selections |" or die "dpkg: $!"; while() { /(\S+)\s+(\S+)/ or die "bad match"; check_package($1); } close DPKG; } else { if(@ARGV == 0) { print < This program is free software covered by the GNU GPL. debup2date looks at the output of 'apt-cache policy' to determine which packages do not match the version in a specific Debian release. This can be used to find packages that are ahead of a release, e.g. those installed from testing or unstable on a stable system, or packages installed from non-Debian repositories. Similarly, it notifies of packages where a newer version is available. Usage: $0 [-t release] [-n] [-v] {-a | package ...} -t release release to check against (regexp, matches apt-cache policy output, default is "stable") -n only show notification of newer versions -v verbose (per default, prints nothing about up-to-date packages) -a operate on all packages from 'dpkg --get-selections' EOT } foreach(@ARGV) { check_package($_); } }