# ex:ts=8 sw=4: # $OpenBSD: Update.pm,v 1.64 2006/04/08 23:24:06 bernd Exp $ # # Copyright (c) 2004 Marc Espie # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # use strict; use warnings; package OpenBSD::Update; use OpenBSD::ProgressMeter; use OpenBSD::Interactive; use OpenBSD::PackageInfo; use OpenBSD::PackageLocator; use OpenBSD::PackageName; use OpenBSD::Error; sub find { my ($old, $new, $state) = @_; my @list = (); OpenBSD::PackageInfo::solve_installed_names($old, \@list, "(updating them all)", $state); unless (defined $state->{full_update} or defined $state->{forced}->{noclosure}) { require OpenBSD::RequiredBy; @list = OpenBSD::Requiring->compute_closure(@list); } my @cantupdate = (); my $hash = OpenBSD::PackageName::available_stems($state); OpenBSD::ProgressMeter::set_header("Looking for updates"); for my $pkgname (@list) { next if $pkgname =~ m/^\.libs-/; my $stem = OpenBSD::PackageName::splitstem($pkgname); my @l = $hash->findstem($stem); if (@l == 0) { push(@cantupdate, $pkgname); next; } my @l2 = (); if (@l == 1 && $state->{forced}->{pkgpath}) { OpenBSD::ProgressMeter::clear(); print "Directly updating $pkgname -> ", $l[0], "\n"; push(@$new, $l[0]); next; } my $plist = OpenBSD::PackingList->from_installation($pkgname, \&OpenBSD::PackingList::UpdateInfoOnly); if (!defined $plist) { Fatal("Can't locate $pkgname"); } my $found; for my $candidate (@l) { my $handle = OpenBSD::PackageLocator->find($candidate, $state->{arch}); if (!$handle) { next; } $handle->close_now(); my $p2 = $handle->plist(\&OpenBSD::PackingList::UpdateInfoOnly); if (!$p2) { next; } if ($p2->has('arch')) { unless ($p2->{arch}->check($state->{arch})) { next; } } if ($plist->signature() eq $p2->signature()) { $found = $candidate; } if ($p2->{extrainfo}->{subdir} eq $plist->{extrainfo}->{subdir}) { push(@l2, $candidate); } elsif ($p2->has('pkgpath')) { for my $p (@{$p2->{pkgpath}}) { if ($p->{name} eq $plist->{extrainfo}->{subdir}) { push(@l2, $candidate); last; } } } } if (defined $found && @l2 == 1 && $found eq $l2[0]) { if (!$plist->uses_old_libs()) { my $msg = "No need to update $pkgname"; OpenBSD::ProgressMeter::message($msg); print "$msg\n" if $state->{beverbose}; next; } } OpenBSD::ProgressMeter::clear(); print "Candidates for updating $pkgname -> ", join(' ', @l2), "\n"; # if all packages have the same version, but distinct p, # grab the most recent. if (@l2 > 1) { @l2 = OpenBSD::PackageName::keep_most_recent(@l2); } if (@l2 == 1) { if (defined $found && $found eq $l2[0] && !$plist->uses_old_libs()) { my $msg = "No need to update $pkgname"; OpenBSD::ProgressMeter::message($msg); print "$msg\n" if $state->{beverbose}; } else { push(@$new, $l2[0]); } } elsif (@l2 == 0) { push(@cantupdate, $pkgname); } else { my $result = OpenBSD::Interactive::choose1($pkgname, $state->{interactive}, sort @l2); if (defined $result) { if (defined $found && $found eq $result && !$plist->uses_old_libs()) { print "No need to update $pkgname\n"; } else { push(@$new, $result); } } else { $state->{issues} = 1; } } } OpenBSD::ProgressMeter::next(); return @cantupdate; } 1;