summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2006-03-04 11:31:19 +0000
committerMarc Espie <espie@cvs.openbsd.org>2006-03-04 11:31:19 +0000
commit3d690a93ced317bfbed33aa806263a506af1c566 (patch)
tree6d4f20643ad9ebb6376b90da0bbbbc3e55356bfb /usr.sbin
parent9b35e98df2d4fcebc393c744ad750804061c88bd (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...
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/pkg_add/Makefile3
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Interactive.pm21
-rw-r--r--usr.sbin/pkg_add/OpenBSD/PackageName.pm17
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Replace.pm562
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Update.pm606
-rw-r--r--usr.sbin/pkg_add/pkg_add226
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};
+}