push(@rv, $avail);
}
- # Set pinned versions
- &set_pinned_versions(\@rv);
-
# Filter out dupes and sort by name
@rv = &filter_duplicates(\@rv);
}
}
-# set_pinned_versions(&packages)
-# If on Debian, set available package versions based on APT pinning
-sub set_pinned_versions
-{
-my ($avail) = @_;
-my @davail = grep { $_->{'system'} eq 'apt' } @$avail;
-return 0 if (!@davail);
-my %namemap = map { $_->{'name'}, $_ } @davail;
-my $rv;
-if (&has_command("apt-show-versions")) {
- # Use apt-show-versions to find possible upgrades, including backports
- # and pinned versions.
- my $out = &backquote_command(
- "LANG='' LC_ALL='' apt-show-versions 2>/dev/null");
- foreach my $l (split(/\r?\n/, $out)) {
- if ($l =~ /^(\S+)\/\S+\s+upgradeable\s+from\s+(\S+)\s+to\s+(\S+)/) {
- # Possible upgrade shown .. apply new version to
- # avail object
- my ($name, $oldver, $newver) = ($1, $2, $3);
- my $pkg = $namemap{$name};
- if ($pkg) {
- ($pkg->{'epoch'}, $pkg->{'version'}) =
- &split_epoch($newver);
- $rv++;
- }
- }
- elsif ($l =~ /^(\S+)\/\S+\s+uptodate\s+(\S+)/) {
- # Package shown to be up to date
- my ($name, $newver) = ($1, $2);
- my $pkg = $namemap{$name};
- if ($pkg) {
- ($pkg->{'epoch'}, $pkg->{'version'}) =
- &split_epoch($newver);
- $rv++;
- }
- }
- }
- }
-if (&has_command("apt-cache")) {
- # Use apt-cache to see pinned versions. This excludes backports though.
- my $out = &backquote_command(
- "LANG='' LC_ALL='' apt-cache policy 2>/dev/null");
- foreach my $l (split(/\r?\n/, $out)) {
- if ($l =~ /\s+(\S+)\s+\-\>\s+(\S+)/) {
- my ($name, $pin) = ($1, $2);
- my $pkg = $namemap{$name};
- if ($pkg) {
- ($pkg->{'epoch'}, $pkg->{'version'}) =
- &split_epoch($ver);
- $rv++;
- }
- }
- }
- }
-return $rv;
-}
-
# split_epoch(version)
# Splits a version formatted like 5:x.yy into an epoch and real version
sub split_epoch
}
}
+&set_pinned_versions(\@rv);
return @rv;
}
sub update_system_updates
{
if (&has_command("apt-show-versions")) {
- # This awesome command can give us all updates in one hit
+ # This awesome command can give us all updates in one hit, and takes
+ # pinned versions and backports into account
local @rv;
&open_execute_command(PKGS,
"LANG='' LC_ALL='' apt-show-versions", 1, 1);
return @rv;
}
else {
- # Need to manually compose by calling dpkg and apt-cache showpkg ..
+ # Need to manually compose by calling dpkg and apt-cache showpkg
local %packages;
local $n = &list_packages();
local %currentmap;
}
$pkg->{'version'} = $ver;
$pkg->{'epoch'} = $epoch;
- push(@rv, $pkg);
+ local $newer =
+ $pkg->{'epoch'} <=> $pkg->{'oldepoch'} ||
+ &compare_versions($pkg->{'version'},
+ $pkg->{'oldversion'});
+ if ($newer > 0) {
+ push(@rv, $pkg);
+ }
}
}
close(PKGS);
}
+ &set_pinned_versions(\@rv);
return @rv;
}
}
+# set_pinned_versions(&package-list)
+# Updates the version and epoch fields in a list of available packages based
+# on pinning.
+sub set_pinned_versions
+{
+local ($pkgs) = @_;
+local %pkgmap = map { $_->{'name'}, $_ } @$pkgs;
+&open_execute_command(PKGS,
+ "LANG='' LC_ALL='' apt-cache policy", 1, 1);
+while(<PKGS>) {
+ s/\r|\n//g;
+ if (/\s+(\S+)\s+\-\>\s+(\S+)/) {
+ my ($name, $pin) = ($1, $2);
+ my $pkg = $pkgmap{$name};
+ if ($pkg) {
+ $pkg->{'version'} = $pin;
+ $pkg->{'epoch'} = undef;
+ if ($pkg->{'version'} =~ s/^(\S+)://) {
+ $pkg->{'epoch'} = $1;
+ }
+ }
+ }
+ }
+close(PKGS);
+}
+