diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2006-03-04 11:31:19 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2006-03-04 11:31:19 +0000 |
commit | 3d690a93ced317bfbed33aa806263a506af1c566 (patch) | |
tree | 6d4f20643ad9ebb6376b90da0bbbbc3e55356bfb | |
parent | 9b35e98df2d4fcebc393c744ad750804061c88bd (diff) |
reorganize code a little bit: Update.pm becomes Replace.pm (since it matches
the -r option), and the find_update code moves to Update.pm, so that it doesn't
get parsed if -u is not used.
Also make the has_new_sig and uses_old_libs local methods of PackingList,
as it is their natural API.
Reorg a few more routines so that they can be found by pkg_add and by
Update.pm.
May need to split off more stuff to avoid parsing everything...
-rw-r--r-- | usr.sbin/pkg_add/Makefile | 3 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/Interactive.pm | 21 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PackageName.pm | 17 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/Replace.pm | 562 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/Update.pm | 606 | ||||
-rw-r--r-- | usr.sbin/pkg_add/pkg_add | 226 |
6 files changed, 737 insertions, 698 deletions
diff --git a/usr.sbin/pkg_add/Makefile b/usr.sbin/pkg_add/Makefile index f00cb1185f2..dcb1a289832 100644 --- a/usr.sbin/pkg_add/Makefile +++ b/usr.sbin/pkg_add/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.33 2005/09/18 02:56:12 deraadt Exp $ +# $OpenBSD: Makefile,v 1.34 2006/03/04 11:31:18 espie Exp $ .include <bsd.own.mk> @@ -29,6 +29,7 @@ PACKAGES= \ OpenBSD/PkgCfl.pm \ OpenBSD/PkgSpec.pm \ OpenBSD/ProgressMeter.pm \ + OpenBSD/Replace.pm \ OpenBSD/RequiredBy.pm \ OpenBSD/SharedItems.pm \ OpenBSD/SharedLibs.pm \ diff --git a/usr.sbin/pkg_add/OpenBSD/Interactive.pm b/usr.sbin/pkg_add/OpenBSD/Interactive.pm index bbd7ee200d7..eb16f7673c5 100644 --- a/usr.sbin/pkg_add/OpenBSD/Interactive.pm +++ b/usr.sbin/pkg_add/OpenBSD/Interactive.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: Interactive.pm,v 1.2 2006/02/21 19:18:25 espie Exp $ +# $OpenBSD: Interactive.pm,v 1.3 2006/03/04 11:31:18 espie Exp $ # # Copyright (c) 2005 Marc Espie <espie@openbsd.org> # @@ -90,4 +90,23 @@ LOOP2: goto LOOP2; } +sub choose1 +{ + my ($pkgname, $interactive, @l) = @_; + if (@l == 0) { + print "Can't resolve $pkgname\n"; + } elsif (@l == 1) { + return $l[0]; + } elsif (@l != 0) { + print "Ambiguous: $pkgname could be ", join(' ', @l),"\n"; + if ($interactive) { + my $result = OpenBSD::Interactive::ask_list('Choose one package', 1, ("<None>", @l)); + if ($result ne '<None>') { + return $result; + } + } + } + return undef; +} + 1; diff --git a/usr.sbin/pkg_add/OpenBSD/PackageName.pm b/usr.sbin/pkg_add/OpenBSD/PackageName.pm index 4805d3596ca..2401a7e087c 100644 --- a/usr.sbin/pkg_add/OpenBSD/PackageName.pm +++ b/usr.sbin/pkg_add/OpenBSD/PackageName.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: PackageName.pm,v 1.9 2005/08/29 00:42:58 espie Exp $ +# $OpenBSD: PackageName.pm,v 1.10 2006/03/04 11:31:18 espie Exp $ # # Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org> # @@ -121,6 +121,21 @@ sub compile_stemlist bless $hash, "OpenBSD::PackageLocator::_compiled_stemlist"; } +sub available_stems +{ + my $state = shift; + my @avail = OpenBSD::PackageLocator::available(); + if (@avail == 0) { + require OpenBSD::Error; + + OpenBSD::Error::Warn("No packages available in the PKG_PATH\n"); + } + unless ($state->{forced}->{allversions}) { + @avail = OpenBSD::PackageName::keep_most_recent(@avail); + } + return OpenBSD::PackageName::compile_stemlist(@avail); +} + package OpenBSD::PackageLocator::_compiled_stemlist; sub findstem diff --git a/usr.sbin/pkg_add/OpenBSD/Replace.pm b/usr.sbin/pkg_add/OpenBSD/Replace.pm new file mode 100644 index 00000000000..625f267ba6b --- /dev/null +++ b/usr.sbin/pkg_add/OpenBSD/Replace.pm @@ -0,0 +1,562 @@ +# ex:ts=8 sw=4: +# $OpenBSD: Replace.pm,v 1.1 2006/03/04 11:31:18 espie Exp $ +# +# Copyright (c) 2004 Marc Espie <espie@openbsd.org> +# +# 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; + +use OpenBSD::Delete; +use OpenBSD::Interactive; + +package OpenBSD::PackingElement; +sub can_update +{ + my ($self, $install, $state) = @_; + + my $issue = $self->update_issue($install); + + if (defined $issue) { + $state->{okay} = 0; + push(@{$state->{journal}}, $issue); + } +} + +sub validate_depend +{ +} + +sub update_issue($$) { undef } + +sub extract +{ +} + +sub mark_lib +{ +} + +sub unmark_lib +{ +} + +package OpenBSD::PackingElement::FileBase; +use File::Temp qw/tempfile/; + +sub extract +{ + my ($self, $state) = @_; + + my $file = $self->prepare_to_extract($state); + + if (defined $self->{link} || defined $self->{symlink}) { + $self->{zap} = 1; + return; + } + + my $d = dirname($file->{destdir}.$file->{name}); + while (!-d $d && -e _) { + $d = dirname($d); + } + if ($state->{not}) { + print "extracting tempfile under $d\n" if $state->{very_verbose}; + $state->{archive}->skip(); + } else { + if (!-e _) { + File::Path::mkpath($d); + } + my ($fh, $tempname) = tempfile('pkg.XXXXXXXXXX', + DIR => $d); + + print "extracting $tempname\n" if $state->{very_verbose}; + $file->{name} = $tempname; + $self->{tempname} = $tempname; + $file->create(); + } +} + +package OpenBSD::PackingElement::Dir; +sub extract +{ + my ($self, $state) = @_; + my $fullname = $self->fullname(); + my $destdir = $state->{destdir}; + + return if -e $destdir.$fullname; + print "new directory ", $destdir, $fullname, "\n" if $state->{very_verbose}; + return if $state->{not}; + File::Path::mkpath($destdir.$fullname); +} + +package OpenBSD::PackingElement::Sample; +sub extract +{ +} + +package OpenBSD::PackingElement::Sampledir; +sub extract +{ +} + +package OpenBSD::PackingElement::ScriptFile; +sub update_issue($$) +{ + return $_[0]->{name}." script"; +} + +package OpenBSD::PackingElement::FINSTALL; +sub update_issue($$) +{ + return undef if !$_[1]; + return $_[0]->SUPER::update_issue($_[1]); +} + +package OpenBSD::PackingElement::FDEINSTALL; +sub update_issue($$) +{ + return undef if $_[1]; + return $_[0]->SUPER::update_issue($_[1]); +} + +package OpenBSD::PackingElement::Exec; +sub update_issue($$) +{ + return undef if !$_[1]; + return '@exec '.$_[0]->{expanded}; +} + +package OpenBSD::PackingElement::Unexec; +sub update_issue($$) +{ + return undef if $_[1]; + my $self = $_[0]; + + # those are deemed innocuous + if ($self->{expanded} =~ m|^/sbin/ldconfig\s+\-R\b| or + $self->{expanded} =~ m|^install-info\s+\-\-delete\b|) { + return undef; + } else { + return '@unexec '.$self->{expanded}; + } +} + +package OpenBSD::PackingElement::Depend; +use OpenBSD::Error; + +sub check_replacement_spec +{ + my ($self, $state, $wanting, $toreplace, $replacement) = @_; + + # nothing to validate if old dependency doesn't concern us. + return unless OpenBSD::PkgSpec::match($self->{pattern}, $toreplace); + # nothing to do if new dependency just matches + return if OpenBSD::PkgSpec::match($self->{pattern}, $replacement); + + if ($state->{forced}->{updatedepends}) { + Warn "Forward dependency of $wanting on $toreplace doesn't match $replacement, forcing it\n"; + $state->{forcedupdates} = {} unless defined $state->{forcedupdates}; + $state->{forcedupdates}->{$wanting} = 1; + } elsif ($state->{interactive}) { + + if (OpenBSD::Interactive::confirm("Forward dependency of $wanting on $toreplace doesn't match $replacement, proceed with update anyways", 1, 0, 'updatedepends')) { + $state->{forcedupdates} = {} unless defined $state->{forcedupdates}; + $state->{forcedupdates}->{$wanting} = 1; + } else { + $state->{okay} = 0; + } + } else { + $state->{okay} = 0; + Warn "Can't update forward dependency of $wanting on $toreplace: $replacement doesn't match (use -F updatedepends to force it)\n"; + } +} + +package OpenBSD::PackingElement::LibDepend; +sub validate_depend +{ + my ($self, $state, $wanting, $toreplace, $replacement) = @_; + + if (defined $self->{name}) { + return unless $self->{name} eq $wanting; + } + $self->check_replacement_spec($state, $wanting, $toreplace, $replacement); +} + +package OpenBSD::PackingElement::Lib; +sub mark_lib +{ + my ($self, $libs, $libpatterns) = @_; + my $libname = $self->fullname(); + if ($libname =~ m/^(.*\.so\.)(\d+)\.(\d+)$/) { + $libpatterns->{"$1"} = [$2, $3, $libname]; + } + $libs->{"$libname"} = 1; +} + +sub unmark_lib +{ + my ($self, $libs, $libpatterns) = @_; + my $libname = $self->fullname(); + if ($libname =~ m/^(.*\.so\.)(\d+)\.(\d+)$/) { + my ($pat, $major, $minor) = ($1, $2, $3); + my $p = $libpatterns->{"$pat"}; + if (defined $p && $p->[0] == $major && $p->[1] <= $minor) { + my $n = $p->[2]; + delete $libs->{"$n"}; + } + } + delete $libs->{"$libname"}; +} + +package OpenBSD::PackingElement::NewDepend; +sub validate_depend +{ + my ($self, $state, $wanting, $toreplace, $replacement) = @_; + + if (defined $self->{name}) { + return unless $self->{name} eq $wanting; + } + $self->check_replacement_spec($state, $wanting, $toreplace, $replacement); +} + +package OpenBSD::PackingElement::Dependency; +sub validate_depend +{ + my ($self, $state, $wanting, $toreplace, $replacement) = @_; + + $self->check_replacement_spec($state, $wanting, $toreplace, $replacement); +} + +package OpenBSD::Replace; +use OpenBSD::RequiredBy; +use OpenBSD::PackingList; +use OpenBSD::PackageInfo; +use OpenBSD::Error; +use OpenBSD::Interactive; + +sub can_do +{ + my ($toreplace, $replacement, $state, $ignore) = @_; + + $state->{okay} = 1; + $state->{libs_to_check} = []; + my $plist = OpenBSD::PackingList->from_installation($toreplace); + if (!defined $plist) { + Fatal "Couldn't find packing-list for $toreplace\n"; + } + $state->{journal} = []; + $plist->visit('can_update', 0, $state); + if ($state->{okay} == 0) { + Warn "Old package ", $plist->pkgname(), " contains potentially unsafe operations\n"; + for my $i (@{$state->{journal}}) { + Warn "\t$i\n"; + } + if ($state->{forced}->{update}) { + Warn "(forcing update)\n"; + $state->{okay} = 1; + } elsif ($state->{interactive}) { + + if (OpenBSD::Interactive::confirm("proceed with update anyways", 1, 0, 'update')) { + $state->{okay} = 1; + } + } + } + my @wantlist = OpenBSD::RequiredBy->new($toreplace)->list(); + my @r = (); + for my $wanting (@wantlist) { + push(@r, $wanting) if !defined $ignore->{$wanting}; + } + if (@r) { + print "Verifying dependencies still match for ", + join(', ', @r), "\n" if $state->{verbose}; + for my $wanting (@wantlist) { + my $p2 = OpenBSD::PackingList->from_installation( + $wanting, \&OpenBSD::PackingList::DependOnly); + if (!defined $p2) { + Warn "Error: $wanting missing from installation\n" + } else { + $p2->visit('validate_depend', $state, $wanting, + $toreplace, $replacement); + } + } + } + + if ($state->{okay}) { + try { + OpenBSD::Delete::validate_plist($plist, $state); + } catchall { + Warn "$_"; + return 0; + }; + } + + $plist->{wantlist} = \@wantlist; + $plist->{libs_to_check} = $state->{libs_to_check}; + + return $state->{okay} ? $plist : 0; +} + +sub is_safe +{ + my ($plist, $state) = @_; + $state->{okay} = 1; + $state->{journal} = []; + $plist->visit('can_update', 1, $state); + if ($state->{okay} == 0) { + Warn "New package ", $plist->pkgname(), + " contains potentially unsafe operations\n"; + for my $i (@{$state->{journal}}) { + Warn "\t$i\n"; + } + if ($state->{forced}->{update}) { + Warn "(forcing update)\n"; + $state->{okay} = 1; + } elsif ($state->{interactive}) { + if (OpenBSD::Interactive::confirm("proceed with update anyways", 1, 0, 'update')) { + $state->{okay} = 1; + } + } + } + return $state->{okay}; +} + +# create a packing-list with only the libraries we want to keep around. +sub split_libs +{ + my ($plist, $to_split) = @_; + + my $items = []; + + my $splitted = OpenBSD::PackingList->new(); + + OpenBSD::PackingElement::Name->add($splitted, ".libs-".$plist->pkgname()); + if (defined $plist->{conflict}) { + for my $item (@{$plist->{conflict}}) { + $item->clone()->add_object($splitted); + } + } + if (defined $plist->{pkgcfl}) { + for my $item (@{$plist->{pkgcfl}}) { + $item->clone()->add_object($splitted); + } + } + if (defined $plist->{'no-default-conflict'}) { + # we conflict with the package we just removed... + OpenBSD::PackingElement::Conflict->add($splitted, $plist->pkgname()); + } else { + require OpenBSD::PackageName; + + my $stem = OpenBSD::PackageName::splitstem($plist->pkgname()); + OpenBSD::PackingElement::Conflict->add($splitted, $stem."-*"); + } + + for my $item (@{$plist->{items}}) { + if ($item->isa("OpenBSD::PackingElement::Lib") && + defined $to_split->{$item->fullname()}) { + $item->clone()->add_object($splitted); + next; + } + if ($item->isa("OpenBSD::PackingElement::Cwd")) { + $item->clone()->add_object($splitted); + } + push(@$items, $item); + } + $plist->{items} = $items; + return $splitted; +} + +sub convert_to_requiring +{ + my $pkg = shift; + + my $plist = OpenBSD::PackingList->from_installation($pkg); + if (!defined $plist) { + Warn "Couldn't read plist for $pkg\n"; + return; + } + my $r = OpenBSD::Requiring->new($pkg); + for my $item (@{$plist->{pkgdep}}) { + $r->add($item->{name}); + } + delete $plist->{pkgdep}; + $plist->to_installation(); +} + +sub walk_depends_closure +{ + my ($start, $plist, $state) = @_; + my @todo = ($start); + my $done = {}; + my $depend = 0; + my $name = $plist->pkgname(); + + print "Packages that depend on those shared libraries:\n" + if $state->{beverbose}; + + my $write = OpenBSD::RequiredBy->new($name); + + while (my $pkg = shift @todo) { + $done->{$pkg} = 1; + for my $pkg2 (OpenBSD::RequiredBy->new($pkg)->list()) { + next if $done->{$pkg2}; + push(@todo, $pkg2); + print "\t$pkg2\n" if $state->{beverbose}; + $done->{$pkg2} = 1; + $write->add($pkg2); + my $l = OpenBSD::Requiring->new($pkg2); + if (!$l->list()) { + convert_to_requiring($pkg2); + } + $l->add($name); + $depend = 1; + } + } +# if (!$depend && $state->{interactive}) { +# if ($state->{forced}->{zapoldlibs} || +# OpenBSD::Interactive::confirm("Nothing depends on $name. Delete it", 1, 0)) { +# OpenBSD::Delete::delete_plist($plist, $state); +# } +# } +} + + + +sub save_old_libraries +{ + my ($new_plist, $state) = @_; + + for my $old_plist (@{$new_plist->{replacing}}) { + + my $libs = {}; + my $p = {}; + + print "Looking for changes in shared libraries\n" + if $state->{beverbose}; + $old_plist->visit('mark_lib', $libs, $p); + $new_plist->visit('unmark_lib', $libs, $p); + + if (%$libs) { + print "Libraries to keep: ", join(",", sort(keys %$libs)), "\n" + if $state->{beverbose}; + my $stub_list = split_libs($old_plist, $libs); + my $stub_name = $stub_list->pkgname(); + my $dest = installed_info($stub_name); + print "Keeping them in $stub_name\n" if $state->{beverbose}; + if ($state->{not}) { + $stub_list->to_cache(); + $old_plist->to_cache(); + } else { + require OpenBSD::md5; + + mkdir($dest); + my $oldname = $old_plist->pkgname(); + open my $descr, '>', $dest.DESC; + print $descr "Stub libraries for $oldname\n"; + close $descr; + my $f = OpenBSD::PackingElement::FDESC->add($stub_list, DESC); + $f->{ignore} = 1; + $f->{md5} = OpenBSD::md5::fromfile($dest.DESC); + $stub_list->to_installation(); + $old_plist->to_installation(); + } + add_installed($stub_name); + + require OpenBSD::PkgCfl; + OpenBSD::PkgCfl::register($stub_list, $state); + + walk_depends_closure($old_plist->pkgname(), $stub_list, $state); + } else { + print "No libraries to keep\n" if $state->{beverbose}; + } + } +} + + +sub adjust_dependency +{ + my ($dep, $from, $into) = @_; + + my $l = OpenBSD::Requiring->new($dep); + if (!$l->list()) { + convert_to_requiring($dep); + } + $l->delete($from); + $l->add($into); +} + +sub figure_out_libs +{ + my ($plist, $state, @libs) = @_; + + my $has = {}; + my $result = []; + + for my $item (@{$plist->{items}}) { + next unless $item->IsFile(); + $has->{$item->fullname()} = 1; + } + + for my $oldlib (@libs) { + print "Checking for collisions with $oldlib... " + if $state->{verbose}; + +# require OpenBSD::RequiredBy; +# +# if (OpenBSD::RequiredBy->new($oldlib)->list() == 0) { +# require OpenBSD::Delete; +# +# OpenBSD::Delete::delete_package($oldlib, $state); +# delete_installed($oldlib); +# next; +# } + + my $p = OpenBSD::PackingList->from_installation($oldlib); + my $n = []; + my $delete = []; + my $empty = 1; + my $doit = 0; + for my $file (@{$p->{items}}) { + if ($file->IsFile()) { + if ($has->{$file->fullname()}) { + $doit = 1; + push(@$delete, $file); + next; + } else { + $empty = 0; + } + } + push(@$n, $file); + } + $p->{items} = $n; + if ($doit) { + print "some found\n" if $state->{verbose}; + my $dummy = {items => $delete}; + push(@$result, + { plist => $p, + todelete => $dummy, + empty => $empty}); + require OpenBSD::Delete; + OpenBSD::Delete::validate_plist($dummy, $state); + } else { + print "none found\n" if $state->{verbose}; + } + } + if (@$result) { + $plist->{old_libs} = $result; + return 0; + } + return 1; +} + +1; diff --git a/usr.sbin/pkg_add/OpenBSD/Update.pm b/usr.sbin/pkg_add/OpenBSD/Update.pm index 051ac991cf9..57d58fb1497 100644 --- a/usr.sbin/pkg_add/OpenBSD/Update.pm +++ b/usr.sbin/pkg_add/OpenBSD/Update.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: Update.pm,v 1.61 2006/02/21 19:20:17 espie Exp $ +# $OpenBSD: Update.pm,v 1.62 2006/03/04 11:31:18 espie Exp $ # # Copyright (c) 2004 Marc Espie <espie@openbsd.org> # @@ -14,549 +14,119 @@ # 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; -use OpenBSD::Delete; +package OpenBSD::Update; +use OpenBSD::ProgressMeter; use OpenBSD::Interactive; +use OpenBSD::PackageInfo; +use OpenBSD::PackageLocator; +use OpenBSD::PackageName; -package OpenBSD::PackingElement; -sub can_update -{ - my ($self, $install, $state) = @_; - - my $issue = $self->update_issue($install); - - if (defined $issue) { - $state->{okay} = 0; - push(@{$state->{journal}}, $issue); - } -} - -sub validate_depend -{ -} - -sub update_issue($$) { undef } - -sub extract -{ -} - -sub mark_lib -{ -} - -sub unmark_lib -{ -} - -package OpenBSD::PackingElement::FileBase; -use File::Temp qw/tempfile/; - -sub extract -{ - my ($self, $state) = @_; - - my $file = $self->prepare_to_extract($state); - - if (defined $self->{link} || defined $self->{symlink}) { - $self->{zap} = 1; - return; - } - - my $d = dirname($file->{destdir}.$file->{name}); - while (!-d $d && -e _) { - $d = dirname($d); - } - if ($state->{not}) { - print "extracting tempfile under $d\n" if $state->{very_verbose}; - $state->{archive}->skip(); - } else { - if (!-e _) { - File::Path::mkpath($d); - } - my ($fh, $tempname) = tempfile('pkg.XXXXXXXXXX', - DIR => $d); - - print "extracting $tempname\n" if $state->{very_verbose}; - $file->{name} = $tempname; - $self->{tempname} = $tempname; - $file->create(); - } -} - -package OpenBSD::PackingElement::Dir; -sub extract -{ - my ($self, $state) = @_; - my $fullname = $self->fullname(); - my $destdir = $state->{destdir}; - - return if -e $destdir.$fullname; - print "new directory ", $destdir, $fullname, "\n" if $state->{very_verbose}; - return if $state->{not}; - File::Path::mkpath($destdir.$fullname); -} - -package OpenBSD::PackingElement::Sample; -sub extract -{ -} - -package OpenBSD::PackingElement::Sampledir; -sub extract -{ -} - -package OpenBSD::PackingElement::ScriptFile; -sub update_issue($$) -{ - return $_[0]->{name}." script"; -} - -package OpenBSD::PackingElement::FINSTALL; -sub update_issue($$) -{ - return undef if !$_[1]; - return $_[0]->SUPER::update_issue($_[1]); -} - -package OpenBSD::PackingElement::FDEINSTALL; -sub update_issue($$) -{ - return undef if $_[1]; - return $_[0]->SUPER::update_issue($_[1]); -} - -package OpenBSD::PackingElement::Exec; -sub update_issue($$) -{ - return undef if !$_[1]; - return '@exec '.$_[0]->{expanded}; -} - -package OpenBSD::PackingElement::Unexec; -sub update_issue($$) -{ - return undef if $_[1]; - my $self = $_[0]; - - # those are deemed innocuous - if ($self->{expanded} =~ m|^/sbin/ldconfig\s+\-R\b| or - $self->{expanded} =~ m|^install-info\s+\-\-delete\b|) { - return undef; - } else { - return '@unexec '.$self->{expanded}; - } -} - -package OpenBSD::PackingElement::Depend; -use OpenBSD::Error; - -sub check_replacement_spec -{ - my ($self, $state, $wanting, $toreplace, $replacement) = @_; - - # nothing to validate if old dependency doesn't concern us. - return unless OpenBSD::PkgSpec::match($self->{pattern}, $toreplace); - # nothing to do if new dependency just matches - return if OpenBSD::PkgSpec::match($self->{pattern}, $replacement); - - if ($state->{forced}->{updatedepends}) { - Warn "Forward dependency of $wanting on $toreplace doesn't match $replacement, forcing it\n"; - $state->{forcedupdates} = {} unless defined $state->{forcedupdates}; - $state->{forcedupdates}->{$wanting} = 1; - } elsif ($state->{interactive}) { - - if (OpenBSD::Interactive::confirm("Forward dependency of $wanting on $toreplace doesn't match $replacement, proceed with update anyways", 1, 0, 'updatedepends')) { - $state->{forcedupdates} = {} unless defined $state->{forcedupdates}; - $state->{forcedupdates}->{$wanting} = 1; - } else { - $state->{okay} = 0; - } - } else { - $state->{okay} = 0; - Warn "Can't update forward dependency of $wanting on $toreplace: $replacement doesn't match (use -F updatedepends to force it)\n"; - } -} -package OpenBSD::PackingElement::LibDepend; -sub validate_depend +sub find { - my ($self, $state, $wanting, $toreplace, $replacement) = @_; + my ($old, $new, $state) = @_; + my @list = (); - if (defined $self->{name}) { - return unless $self->{name} eq $wanting; - } - $self->check_replacement_spec($state, $wanting, $toreplace, $replacement); -} + OpenBSD::PackageInfo::solve_installed_names($old, \@list, "(updating them all)", $state); + unless (defined $state->{full_update} or defined $state->{forced}->{noclosure}) { + require OpenBSD::RequiredBy; -package OpenBSD::PackingElement::Lib; -sub mark_lib -{ - my ($self, $libs, $libpatterns) = @_; - my $libname = $self->fullname(); - if ($libname =~ m/^(.*\.so\.)(\d+)\.(\d+)$/) { - $libpatterns->{"$1"} = [$2, $3, $libname]; + @list = OpenBSD::Requiring->compute_closure(@list); } - $libs->{"$libname"} = 1; -} + my @cantupdate = (); + my $hash = OpenBSD::PackageName::available_stems($state); -sub unmark_lib -{ - my ($self, $libs, $libpatterns) = @_; - my $libname = $self->fullname(); - if ($libname =~ m/^(.*\.so\.)(\d+)\.(\d+)$/) { - my ($pat, $major, $minor) = ($1, $2, $3); - my $p = $libpatterns->{"$pat"}; - if (defined $p && $p->[0] == $major && $p->[1] <= $minor) { - my $n = $p->[2]; - delete $libs->{"$n"}; + 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; } - } - delete $libs->{"$libname"}; -} - -package OpenBSD::PackingElement::NewDepend; -sub validate_depend -{ - my ($self, $state, $wanting, $toreplace, $replacement) = @_; - - if (defined $self->{name}) { - return unless $self->{name} eq $wanting; - } - $self->check_replacement_spec($state, $wanting, $toreplace, $replacement); -} - -package OpenBSD::PackingElement::Dependency; -sub validate_depend -{ - my ($self, $state, $wanting, $toreplace, $replacement) = @_; - - $self->check_replacement_spec($state, $wanting, $toreplace, $replacement); -} - -package OpenBSD::Update; -use OpenBSD::RequiredBy; -use OpenBSD::PackingList; -use OpenBSD::PackageInfo; -use OpenBSD::Error; -use OpenBSD::Interactive; - -sub can_do -{ - my ($toreplace, $replacement, $state, $ignore) = @_; - - $state->{okay} = 1; - $state->{libs_to_check} = []; - my $plist = OpenBSD::PackingList->from_installation($toreplace); - if (!defined $plist) { - Fatal "Couldn't find packing-list for $toreplace\n"; - } - $state->{journal} = []; - $plist->visit('can_update', 0, $state); - if ($state->{okay} == 0) { - Warn "Old package ", $plist->pkgname(), " contains potentially unsafe operations\n"; - for my $i (@{$state->{journal}}) { - Warn "\t$i\n"; + my @l2 = (); + if (@l == 1 && $state->{forced}->{pkgpath}) { + OpenBSD::ProgressMeter::clear(); + print "Directly updating $pkgname -> ", $l[0], "\n"; + push(@$new, $l[0]); + next; } - if ($state->{forced}->{update}) { - Warn "(forcing update)\n"; - $state->{okay} = 1; - } elsif ($state->{interactive}) { - - if (OpenBSD::Interactive::confirm("proceed with update anyways", 1, 0, 'update')) { - $state->{okay} = 1; - } + my $plist = OpenBSD::PackingList->from_installation($pkgname, \&OpenBSD::PackingList::UpdateInfoOnly); + if (!defined $plist) { + Fatal("Can't locate $pkgname"); } - } - my @wantlist = OpenBSD::RequiredBy->new($toreplace)->list(); - my @r = (); - for my $wanting (@wantlist) { - push(@r, $wanting) if !defined $ignore->{$wanting}; - } - if (@r) { - print "Verifying dependencies still match for ", - join(', ', @r), "\n" if $state->{verbose}; - for my $wanting (@wantlist) { - my $p2 = OpenBSD::PackingList->from_installation( - $wanting, \&OpenBSD::PackingList::DependOnly); - if (!defined $p2) { - Warn "Error: $wanting missing from installation\n" - } else { - $p2->visit('validate_depend', $state, $wanting, - $toreplace, $replacement); + 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 ($state->{okay}) { - try { - OpenBSD::Delete::validate_plist($plist, $state); - } catchall { - Warn "$_"; - return 0; - }; - } - $plist->{wantlist} = \@wantlist; - $plist->{libs_to_check} = $state->{libs_to_check}; - - return $state->{okay} ? $plist : 0; -} - -sub is_safe -{ - my ($plist, $state) = @_; - $state->{okay} = 1; - $state->{journal} = []; - $plist->visit('can_update', 1, $state); - if ($state->{okay} == 0) { - Warn "New package ", $plist->pkgname(), - " contains potentially unsafe operations\n"; - for my $i (@{$state->{journal}}) { - Warn "\t$i\n"; - } - if ($state->{forced}->{update}) { - Warn "(forcing update)\n"; - $state->{okay} = 1; - } elsif ($state->{interactive}) { - if (OpenBSD::Interactive::confirm("proceed with update anyways", 1, 0, 'update')) { - $state->{okay} = 1; + 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; } } - } - return $state->{okay}; -} - -# create a packing-list with only the libraries we want to keep around. -sub split_libs -{ - my ($plist, $to_split) = @_; - - my $items = []; - - my $splitted = OpenBSD::PackingList->new(); - - OpenBSD::PackingElement::Name->add($splitted, ".libs-".$plist->pkgname()); - if (defined $plist->{conflict}) { - for my $item (@{$plist->{conflict}}) { - $item->clone()->add_object($splitted); - } - } - if (defined $plist->{pkgcfl}) { - for my $item (@{$plist->{pkgcfl}}) { - $item->clone()->add_object($splitted); - } - } - if (defined $plist->{'no-default-conflict'}) { - # we conflict with the package we just removed... - OpenBSD::PackingElement::Conflict->add($splitted, $plist->pkgname()); - } else { - require OpenBSD::PackageName; - - my $stem = OpenBSD::PackageName::splitstem($plist->pkgname()); - OpenBSD::PackingElement::Conflict->add($splitted, $stem."-*"); - } - - for my $item (@{$plist->{items}}) { - if ($item->isa("OpenBSD::PackingElement::Lib") && - defined $to_split->{$item->fullname()}) { - $item->clone()->add_object($splitted); - next; - } - if ($item->isa("OpenBSD::PackingElement::Cwd")) { - $item->clone()->add_object($splitted); - } - push(@$items, $item); - } - $plist->{items} = $items; - return $splitted; -} - -sub convert_to_requiring -{ - my $pkg = shift; - - my $plist = OpenBSD::PackingList->from_installation($pkg); - if (!defined $plist) { - Warn "Couldn't read plist for $pkg\n"; - return; - } - my $r = OpenBSD::Requiring->new($pkg); - for my $item (@{$plist->{pkgdep}}) { - $r->add($item->{name}); - } - delete $plist->{pkgdep}; - $plist->to_installation(); -} - -sub walk_depends_closure -{ - my ($start, $plist, $state) = @_; - my @todo = ($start); - my $done = {}; - my $depend = 0; - my $name = $plist->pkgname(); - - print "Packages that depend on those shared libraries:\n" - if $state->{beverbose}; - - my $write = OpenBSD::RequiredBy->new($name); - - while (my $pkg = shift @todo) { - $done->{$pkg} = 1; - for my $pkg2 (OpenBSD::RequiredBy->new($pkg)->list()) { - next if $done->{$pkg2}; - push(@todo, $pkg2); - print "\t$pkg2\n" if $state->{beverbose}; - $done->{$pkg2} = 1; - $write->add($pkg2); - my $l = OpenBSD::Requiring->new($pkg2); - if (!$l->list()) { - convert_to_requiring($pkg2); - } - $l->add($name); - $depend = 1; + 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 (!$depend && $state->{interactive}) { -# if ($state->{forced}->{zapoldlibs} || -# OpenBSD::Interactive::confirm("Nothing depends on $name. Delete it", 1, 0)) { -# OpenBSD::Delete::delete_plist($plist, $state); -# } -# } -} - - - -sub save_old_libraries -{ - my ($new_plist, $state) = @_; - - for my $old_plist (@{$new_plist->{replacing}}) { - - my $libs = {}; - my $p = {}; - - print "Looking for changes in shared libraries\n" - if $state->{beverbose}; - $old_plist->visit('mark_lib', $libs, $p); - $new_plist->visit('unmark_lib', $libs, $p); - - if (%$libs) { - print "Libraries to keep: ", join(",", sort(keys %$libs)), "\n" - if $state->{beverbose}; - my $stub_list = split_libs($old_plist, $libs); - my $stub_name = $stub_list->pkgname(); - my $dest = installed_info($stub_name); - print "Keeping them in $stub_name\n" if $state->{beverbose}; - if ($state->{not}) { - $stub_list->to_cache(); - $old_plist->to_cache(); + + 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 { - require OpenBSD::md5; - - mkdir($dest); - my $oldname = $old_plist->pkgname(); - open my $descr, '>', $dest.DESC; - print $descr "Stub libraries for $oldname\n"; - close $descr; - my $f = OpenBSD::PackingElement::FDESC->add($stub_list, DESC); - $f->{ignore} = 1; - $f->{md5} = OpenBSD::md5::fromfile($dest.DESC); - $stub_list->to_installation(); - $old_plist->to_installation(); + push(@$new, $l2[0]); } - add_installed($stub_name); - - require OpenBSD::PkgCfl; - OpenBSD::PkgCfl::register($stub_list, $state); - - walk_depends_closure($old_plist->pkgname(), $stub_list, $state); + } elsif (@l2 == 0) { + push(@cantupdate, $pkgname); } else { - print "No libraries to keep\n" if $state->{beverbose}; - } - } -} - - -sub adjust_dependency -{ - my ($dep, $from, $into) = @_; - - my $l = OpenBSD::Requiring->new($dep); - if (!$l->list()) { - convert_to_requiring($dep); - } - $l->delete($from); - $l->add($into); -} - -sub figure_out_libs -{ - my ($plist, $state, @libs) = @_; - - my $has = {}; - my $result = []; - - for my $item (@{$plist->{items}}) { - next unless $item->IsFile(); - $has->{$item->fullname()} = 1; - } - - for my $oldlib (@libs) { - print "Checking for collisions with $oldlib... " - if $state->{verbose}; - -# require OpenBSD::RequiredBy; -# -# if (OpenBSD::RequiredBy->new($oldlib)->list() == 0) { -# require OpenBSD::Delete; -# -# OpenBSD::Delete::delete_package($oldlib, $state); -# delete_installed($oldlib); -# next; -# } - - my $p = OpenBSD::PackingList->from_installation($oldlib); - my $n = []; - my $delete = []; - my $empty = 1; - my $doit = 0; - for my $file (@{$p->{items}}) { - if ($file->IsFile()) { - if ($has->{$file->fullname()}) { - $doit = 1; - push(@$delete, $file); - next; - } else { - $empty = 0; - } + my $result = OpenBSD::Interactive::choose1($pkgname, $state->{interactive}, sort @l2); + if (defined $result) { + push(@$new, $result); + } else { + $state->{issues} = 1; } - push(@$n, $file); } - $p->{items} = $n; - if ($doit) { - print "some found\n" if $state->{verbose}; - my $dummy = {items => $delete}; - push(@$result, - { plist => $p, - todelete => $dummy, - empty => $empty}); - require OpenBSD::Delete; - OpenBSD::Delete::validate_plist($dummy, $state); - } else { - print "none found\n" if $state->{verbose}; - } - } - if (@$result) { - $plist->{old_libs} = $result; - return 0; } - return 1; + OpenBSD::ProgressMeter::next(); + return @cantupdate; } 1; diff --git a/usr.sbin/pkg_add/pkg_add b/usr.sbin/pkg_add/pkg_add index 61d3309c98a..bda21903089 100644 --- a/usr.sbin/pkg_add/pkg_add +++ b/usr.sbin/pkg_add/pkg_add @@ -1,7 +1,7 @@ #! /usr/bin/perl # ex:ts=8 sw=4: -# $OpenBSD: pkg_add,v 1.216 2006/02/10 11:42:51 espie Exp $ +# $OpenBSD: pkg_add,v 1.217 2006/03/04 11:31:18 espie Exp $ # # Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org> # @@ -41,27 +41,6 @@ my $bad = 0; our %forced = (); our $not; -sub uses_old_libs -{ - my $plist = shift; - require OpenBSD::RequiredBy; - - my $d = OpenBSD::Requiring->new($plist->pkgname()); - return grep {/^\.libs\-/} $d->list(); -} - -sub has_new_sig -{ - my ($plist, $state) = @_; - if (!defined $plist->{new_sig}) { - my $n = OpenBSD::PackingList->from_installation($plist->pkgname())->signature(); - my $o = $plist->signature(); - print "Comparing full signature for ", $plist->pkgname(), " \"$o\" vs. \"$n\": ", $n eq $o ? "equal\n" : "different\n" - if $state->{very_verbose}; - $plist->{new_sig} = $n ne $o; - } - return $plist->{new_sig}; -} sub can_install($$$) @@ -76,7 +55,7 @@ sub can_install($$$) if ((keys %conflicts) == 1 && (keys %conflicts)[0] eq $pkgname) { if (!$state->{forced}->{installed} && - !has_new_sig($plist, $state) && !uses_old_libs($plist)) { + !$plist->has_new_sig($state) && !$plist->uses_old_libs()) { print "Already installed: $pkgname\n"; return 1; } @@ -94,8 +73,8 @@ sub can_install($$$) if (!$state->{replace}) { if (@conflicts == 1 && is_installed($plist->pkgname()) && - !has_new_sig($plist, $state) && - !uses_old_libs($plist)) { + !$plist->has_new_sig($state) && + !$plist->uses_old_libs()) { print "Not reinstalling $pkgname\n" if $state->{verbose}; OpenBSD::SharedLibs::add_package_libs($plist->pkgname()); $state->{installed}->{$pkgname} = 1; @@ -112,23 +91,23 @@ sub can_install($$$) return undef; } - require OpenBSD::Update; + require OpenBSD::Replace; if (is_installed($plist->pkgname()) && !$state->{forced}->{installed}) { - if (!has_new_sig($plist, $state) && !uses_old_libs($plist)) { + if (!$plist->has_new_sig($state) && !$plist->uses_old_libs()) { print "Not reinstalling $pkgname\n" if $state->{verbose}; OpenBSD::SharedLibs::add_package_libs($plist->pkgname()); $state->{installed}->{$pkgname} = 1; return undef; } } - if (!OpenBSD::Update::is_safe($plist, $state)) { + if (!OpenBSD::Replace::is_safe($plist, $state)) { print "Can't safely update to $pkgname (use -F update to force it)\n"; $errors++; return undef; } - if (!OpenBSD::Update::figure_out_libs($plist, $state, @libs)) { + if (!OpenBSD::Replace::figure_out_libs($plist, $state, @libs)) { print "Can't update to $pkgname because of collision with old libs\n"; $errors++; return undef; @@ -141,7 +120,7 @@ sub can_install($$$) return undef; } - my $rplist = OpenBSD::Update::can_do($toreplace, $pkgname, + my $rplist = OpenBSD::Replace::can_do($toreplace, $pkgname, $state, \%conflicts); if (!$rplist) { print "Can't update $toreplace into $pkgname\n"; @@ -315,12 +294,12 @@ sub really_add($$) local $SIG{'TERM'} = $handler; if ($replacing) { - require OpenBSD::Update; + require OpenBSD::Replace; OpenBSD::ProgressMeter::set_header("$pkgname (extracting)"); if (@toreplace) { - OpenBSD::Update::save_old_libraries($plist, $state); + OpenBSD::Replace::save_old_libraries($plist, $state); } my $donesize = 0; @@ -456,7 +435,7 @@ sub really_add($$) # and add dependencies corresponding to the replacement for my $op (@toreplace) { require OpenBSD::RequiredBy; - require OpenBSD::Update; + require OpenBSD::Replace; my $opkgname = $op->pkgname(); print "Adjusting dependencies for $pkgname/$opkgname\n" @@ -469,7 +448,7 @@ sub really_add($$) } print "\t$dep\n" if $state->{beverbose}; $d->add($dep); - OpenBSD::Update::adjust_dependency($dep, $opkgname, $pkgname); + OpenBSD::Replace::adjust_dependency($dep, $opkgname, $pkgname); } } } @@ -538,7 +517,7 @@ sub install_package if (is_installed($plist->pkgname()) && !$state->{forced}->{installed}) { if ($state->{replace}) { - if (!has_new_sig($plist, $state) && !uses_old_libs($plist)) { + if (!$plist->has_new_sig($state) && !$plist->uses_old_libs()) { OpenBSD::SharedLibs::add_package_libs($plist->pkgname()); $state->{installed}->{$handle->{pkgname}} = 1; $handle->close_now(); @@ -613,143 +592,6 @@ sub install_package } -sub choose1 -{ - my ($pkgname, $interactive, @l) = @_; - if (@l == 0) { - print "Can't resolve $pkgname\n"; - $bad = 1; - } elsif (@l == 1) { - return $l[0]; - } elsif (@l != 0) { - print "Ambiguous: $pkgname could be ", join(' ', @l),"\n"; - if ($interactive) { - my $result = OpenBSD::Interactive::ask_list('Choose one package', 1, ("<None>", @l)); - if ($result eq '<None>') { - $bad = 1; - } else { - return $result; - } - } else { - $bad = 1; - } - } - return undef; -} - -sub available_stems -{ - my $state = shift; - my @avail = OpenBSD::PackageLocator::available(); - if (@avail == 0) { - Warn "No packages available in the PKG_PATH\n"; - } - unless ($state->{forced}->{allversions}) { - @avail = OpenBSD::PackageName::keep_most_recent(@avail); - } - return OpenBSD::PackageName::compile_stemlist(@avail); -} - -sub find_updates -{ - 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 = 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 (!uses_old_libs($plist)) { - 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] && !uses_old_libs($plist)) { - 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 = choose1($pkgname, $state->{interactive}, sort @l2); - push(@$new, $result) if defined $result; - } - } - OpenBSD::ProgressMeter::next(); - return @cantupdate; -} - sub find_truenames { my ($old, $new, $state) = @_; @@ -759,14 +601,18 @@ sub find_truenames for my $pkgname (@$old) { if (OpenBSD::PackageName::is_stem($pkgname)) { if (!defined $h) { - $h = available_stems($state); + $h = OpenBSD::PackageName::available_stems($state); } my @l = $h->findstem($pkgname); if (@l > 1) { @l = OpenBSD::PackageName::keep_most_recent(@l); } - my $result = choose1($pkgname, $state->{interactive}, sort @l); - push(@$new, $result) if defined $result; + my $result = OpenBSD::Interactive::choose1($pkgname, $state->{interactive}, sort @l); + if (defined $result) { + push(@$new, $result); + } else { + $bad = 1; + } } else { push(@$new, $pkgname); } @@ -887,11 +733,13 @@ lock_db($state->{not}); my @todo = (); if ($opt_u) { + require OpenBSD::Update; + if (@ARGV == 0) { @ARGV = sort(installed_packages()); $state->{full_update} = 1; } - my @cantupdate = find_updates(\@ARGV, \@todo, $state); + my @cantupdate = OpenBSD::Update::find(\@ARGV, \@todo, $state); if (@cantupdate > 0) { print "Cannot find updates for ", join(' ', @cantupdate), "\n"; unless ($state->{forced}->{alwaysupdate} || @@ -899,7 +747,7 @@ if ($opt_u) { exit(1); } } - if ($bad) { + if (defined $state->{issues}) { print "There are some ambiguities. Please run in interactive ". "mode again.\n"; } @@ -965,3 +813,27 @@ rethrow $dielater; if ($bad) { exit(1); } + +package OpenBSD::PackingList; + +sub uses_old_libs +{ + my $plist = shift; + require OpenBSD::RequiredBy; + + my $d = OpenBSD::Requiring->new($plist->pkgname()); + return grep {/^\.libs\-/} $d->list(); +} + +sub has_new_sig +{ + my ($plist, $state) = @_; + if (!defined $plist->{new_sig}) { + my $n = OpenBSD::PackingList->from_installation($plist->pkgname())->signature(); + my $o = $plist->signature(); + print "Comparing full signature for ", $plist->pkgname(), " \"$o\" vs. \"$n\": ", $n eq $o ? "equal\n" : "different\n" + if $state->{very_verbose}; + $plist->{new_sig} = $n ne $o; + } + return $plist->{new_sig}; +} |