summaryrefslogtreecommitdiff
path: root/usr.sbin/pkg_add
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2005-09-04 22:47:57 +0000
committerMarc Espie <espie@cvs.openbsd.org>2005-09-04 22:47:57 +0000
commit2491e24fbcb5bf7f102559b04685505a55540a40 (patch)
treeadf517bc59741fd86b70ae1478ebd17ed891f00b /usr.sbin/pkg_add
parentdb2b33c1ae5ac54b7cf4811c71ed9a875ec2490d (diff)
* New -i interactive option, that can ask obnoxious questions.
* move the signature code to a packing-list method, prepend the pkgname. * depend on distant listings, cache these systematically. * cut the PKG_PATH at :/ systematically, much simpler than parsing URLs. People should get used to trailing /s. * let pkg_add -u actually run the update. * check for signature in more places, for instance, let pkg_add installed_stuff be a void operation. * grab enough stuff during updates to check signatures, so that pkg_add -u can report updates that are not needed right away, instead of waiting for the more confusing `trying to update' * beginning of @module support. * @pkgpath support, including updates. * systematically expand stems when applicable. * use visitors systematically in pkg_info. * pkg_info -S reports signature. * remove hardcoding of categories in PackingList, so that future modules will be able to expand them. * add @updateset and @incompatibility keywords.
Diffstat (limited to 'usr.sbin/pkg_add')
-rw-r--r--usr.sbin/pkg_add/Makefile3
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Add.pm13
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Dependencies.pm28
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Interactive.pm83
-rw-r--r--usr.sbin/pkg_add/OpenBSD/PackageInfo.pm53
-rw-r--r--usr.sbin/pkg_add/OpenBSD/PackageLocator.pm128
-rw-r--r--usr.sbin/pkg_add/OpenBSD/PackingElement.pm80
-rw-r--r--usr.sbin/pkg_add/OpenBSD/PackingList.pm51
-rw-r--r--usr.sbin/pkg_add/OpenBSD/ProgressMeter.pm9
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Update.pm68
-rw-r--r--usr.sbin/pkg_add/pkg_add201
-rw-r--r--usr.sbin/pkg_add/pkg_add.18
-rw-r--r--usr.sbin/pkg_add/pkg_create16
-rw-r--r--usr.sbin/pkg_add/pkg_delete48
-rw-r--r--usr.sbin/pkg_add/pkg_delete.18
-rw-r--r--usr.sbin/pkg_add/pkg_info87
-rw-r--r--usr.sbin/pkg_add/pkg_info.18
-rw-r--r--usr.sbin/pkg_add/pod/OpenBSD::PackingList.pod14
18 files changed, 655 insertions, 251 deletions
diff --git a/usr.sbin/pkg_add/Makefile b/usr.sbin/pkg_add/Makefile
index e001d7cebdd..eab24498e4f 100644
--- a/usr.sbin/pkg_add/Makefile
+++ b/usr.sbin/pkg_add/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.29 2005/08/17 09:45:45 espie Exp $
+# $OpenBSD: Makefile,v 1.30 2005/09/04 22:47:56 espie Exp $
.include <bsd.own.mk>
@@ -15,6 +15,7 @@ PACKAGES= \
OpenBSD/Error.pm \
OpenBSD/Getopt.pm \
OpenBSD/IdCache.pm \
+ OpenBSD/Interactive.pm \
OpenBSD/Mtree.pm \
OpenBSD/PackageInfo.pm \
OpenBSD/PackageLocator.pm \
diff --git a/usr.sbin/pkg_add/OpenBSD/Add.pm b/usr.sbin/pkg_add/OpenBSD/Add.pm
index f65d581d6ad..caa3c10715f 100644
--- a/usr.sbin/pkg_add/OpenBSD/Add.pm
+++ b/usr.sbin/pkg_add/OpenBSD/Add.pm
@@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
-# $OpenBSD: Add.pm,v 1.39 2005/08/22 11:25:59 espie Exp $
+# $OpenBSD: Add.pm,v 1.40 2005/09/04 22:47:56 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -23,6 +23,17 @@ use OpenBSD::PackageInfo;
use OpenBSD::ArcCheck;
use File::Copy;
+sub is_needed
+{
+ my ($plist, $state) = @_;
+ my $oplist = OpenBSD::PackingList->from_installation($plist->pkgname());
+ my $n = $plist->signature();
+ my $o = $oplist->signature();
+ print "Comparing full signature for ", $plist->pkgname(), " \"$o\" vs. \"$n\": ", $n eq $o ? "equal\n" : "different\n"
+ if $state->{very_verbose};
+ return $n ne $o;
+}
+
sub manpages_index
{
my ($state) = @_;
diff --git a/usr.sbin/pkg_add/OpenBSD/Dependencies.pm b/usr.sbin/pkg_add/OpenBSD/Dependencies.pm
index 0e94926513c..36be0ede258 100644
--- a/usr.sbin/pkg_add/OpenBSD/Dependencies.pm
+++ b/usr.sbin/pkg_add/OpenBSD/Dependencies.pm
@@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
-# $OpenBSD: Dependencies.pm,v 1.2 2005/08/10 11:36:28 espie Exp $
+# $OpenBSD: Dependencies.pm,v 1.3 2005/09/04 22:47:56 espie Exp $
#
# Copyright (c) 2005 Marc Espie <espie@openbsd.org>
#
@@ -25,6 +25,7 @@ use OpenBSD::PkgSpec;
use OpenBSD::PackageInfo;
use OpenBSD::SharedLibs;
use OpenBSD::Error;
+use OpenBSD::Interactive;
sub solve
{
@@ -37,6 +38,7 @@ sub solve
$to_install->{OpenBSD::PackageName::url2pkgname($fullname)} =
$fullname;
}
+ my @avail;
# do simple old style pkgdep first
my @deps = ();
@@ -73,8 +75,14 @@ sub solve
next;
}
}
+ if (!@avail) {
+ @avail = OpenBSD::PackageLocator::available();
+ if (!$state->{forced}->{allversions}) {
+ @avail = OpenBSD::PackageName::keep_most_recent(@avail);
+ }
+ }
# try with list of available packages
- @candidates = OpenBSD::PkgSpec::match($dep->{pattern}, OpenBSD::PackageLocator::available());
+ @candidates = OpenBSD::PkgSpec::match($dep->{pattern}, @avail);
# one single choice
if (@candidates == 1) {
push(@deps, $candidates[0]);
@@ -82,14 +90,14 @@ sub solve
next;
}
if (@candidates > 1) {
- # grab default if available
- if (grep {$_ eq $dep->{def}} @candidates) {
- push(@deps, $dep->{def});
- $to_register->{$dep->{def}} = 1;
- next;
- }
- push(@deps, $candidates[0]);
- $to_register->{$candidates[0]} = 1;
+ # put default first if available
+ @candidates = ((grep {$_ eq $dep->{def}} @candidates),
+ (sort (grep {$_ ne $dep->{def}} @candidates)));
+ my $choice =
+ OpenBSD::Interactive::ask_list('Choose dependency for '.$plist->pkgname().': ',
+ $state->{interactive}, @candidates);
+ push(@deps, $choice);
+ $to_register->{$choice} = 1;
next;
}
# can't get a list of packages, assume default
diff --git a/usr.sbin/pkg_add/OpenBSD/Interactive.pm b/usr.sbin/pkg_add/OpenBSD/Interactive.pm
new file mode 100644
index 00000000000..95f0a387c97
--- /dev/null
+++ b/usr.sbin/pkg_add/OpenBSD/Interactive.pm
@@ -0,0 +1,83 @@
+# ex:ts=8 sw=4:
+# $OpenBSD: Interactive.pm,v 1.1 2005/09/04 22:47:56 espie Exp $
+#
+# Copyright (c) 2005 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;
+
+package OpenBSD::Interactive;
+
+sub ask_list
+{
+ my ($prompt, $interactive, @values) = @_;
+ if (!$interactive || !-t STDIN) {
+ return $values[0];
+ }
+ print STDERR $prompt, "\n";
+ my $i = 0;
+ for my $v (@values) {
+ printf STDERR "\t%2d: %s\n", $i, $v;
+ $i++;
+ }
+LOOP:
+ print STDERR "Your choice: ";
+ my $result = <STDIN>;
+ chomp $result;
+ if ($result eq '') {
+ return $values[0];
+ }
+ if ($result =~ m/^\d+$/) {
+ if ($result >= 0 && $result < @values) {
+ return $values[$result];
+ }
+ print STDERR "invalid numeric value !\n";
+ goto LOOP;
+ }
+ if (grep { $result eq $_ } @values) {
+ return $result;
+ } else {
+ print STDERR "Ambiguous value !\n";
+ goto LOOP;
+ }
+}
+
+sub confirm
+{
+ my ($prompt, $interactive, $default) = @_;
+ if (!$interactive || !-t STDIN) {
+ return 0;
+ }
+LOOP2:
+ print STDERR $prompt, $default ? '? [Y/n] ' : '? [y/N] ';
+
+ my $result = <STDIN>;
+ chomp $result;
+ $result =~ s/\s*//g;
+ $result =~ tr/A-Z/a-z/;
+ if ($result eq 'yes' or $result eq 'y') {
+ return 1;
+ }
+ if ($result eq 'no' or $result eq 'n') {
+ return 0;
+ }
+ if ($result eq '') {
+ return $default;
+ }
+ print STDERR "Ambiguous answer\n";
+ goto LOOP2;
+}
+
+1;
diff --git a/usr.sbin/pkg_add/OpenBSD/PackageInfo.pm b/usr.sbin/pkg_add/OpenBSD/PackageInfo.pm
index f0873940f5a..a82351f4e35 100644
--- a/usr.sbin/pkg_add/OpenBSD/PackageInfo.pm
+++ b/usr.sbin/pkg_add/OpenBSD/PackageInfo.pm
@@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
-# $OpenBSD: PackageInfo.pm,v 1.17 2005/01/16 11:16:23 espie Exp $
+# $OpenBSD: PackageInfo.pm,v 1.18 2005/09/04 22:47:56 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -21,13 +21,14 @@ package OpenBSD::PackageInfo;
our @ISA=qw(Exporter);
our @EXPORT=qw(installed_packages installed_info installed_name info_names is_info_name
lock_db unlock_db
- add_installed delete_installed is_installed borked_package CONTENTS COMMENT DESC INSTALL DEINSTALL REQUIRE
+ add_installed delete_installed is_installed borked_package CONTENTS COMMENT DESC INSTALL DEINSTALL REQUIRE MODULE
REQUIRED_BY REQUIRING DISPLAY UNDISPLAY MTREE_DIRS);
use OpenBSD::PackageName;
use constant {
CONTENTS => '+CONTENTS',
COMMENT => '+COMMENT',
+ MODULE => '+MODULE.pm' ,
DESC => '+DESC',
INSTALL => '+INSTALL',
DEINSTALL => '+DEINSTALL',
@@ -43,13 +44,14 @@ my $pkg_db = $ENV{"PKG_DBDIR"} || '/var/db/pkg';
our $list;
-our @info = (CONTENTS, COMMENT, DESC, REQUIRE, INSTALL, DEINSTALL, REQUIRED_BY, REQUIRING, DISPLAY, UNDISPLAY, MTREE_DIRS);
+our @info = (CONTENTS, COMMENT, DESC, REQUIRE, INSTALL, DEINSTALL, REQUIRED_BY, REQUIRING, DISPLAY, UNDISPLAY, MTREE_DIRS, MODULE);
our %info = ();
for my $i (@info) {
my $j = $i;
$j =~ s/\+/F/;
$info{$i} = $j;
+ $info{'+MODULE.pm'} = 'FMODULE';
}
sub _init_list
@@ -193,4 +195,49 @@ sub unlock_db()
}
}
+
+sub solve_installed_names
+{
+ my ($old, $new, $msg, $state) = @_;
+
+ my $installed;
+ my $bad = 0;
+
+ for my $pkgname (@$old) {
+ $pkgname =~ s/\.tgz$//;
+ if (is_installed($pkgname)) {
+ push(@$new, installed_name($pkgname));
+ } else {
+ if (OpenBSD::PackageName::is_stem($pkgname)) {
+ if (!defined $installed) {
+ $installed = OpenBSD::PackageName::compile_stemlist(installed_packages());
+ }
+ my @l = $installed->findstem($pkgname);
+ if (@l == 0) {
+ print "Can't resolve $pkgname to an installed package name\n";
+ $bad = 1;
+ } elsif (@l == 1) {
+ push(@$new, $l[0]);
+ } elsif (@l != 0) {
+ print "Ambiguous: $pkgname could be ", join(' ', @l),"\n";
+ if ($state->{forced}->{ambiguous}) {
+ print "$msg\n";
+ push(@$new, @l);
+ } else {
+ if ($state->{interactive}) {
+ require OpenBSD::ProgressMeter;
+
+ my $result = OpenBSD::ProgressMeter::ask_list('Choose one package', 1, ("<None>", sort @l));
+ push(@$new, $result) if $result ne '<None>';
+ } else {
+ $bad = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ return $bad;
+}
+
1;
diff --git a/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm b/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm
index 9bfd62dff0e..bd9f3acce36 100644
--- a/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm
+++ b/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm
@@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
-# $OpenBSD: PackageLocator.pm,v 1.20 2005/08/22 11:30:30 espie Exp $
+# $OpenBSD: PackageLocator.pm,v 1.21 2005/09/04 22:47:56 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -89,7 +89,6 @@ sub open
# kill old files if too many
my $already = $self->make_room();
-
my $p = $self->pipename($object->{name});
open(my $fh, '-|', $p) or return undef;
@@ -100,20 +99,32 @@ sub open
return $fh;
}
-# by default, we don't know how to list packages there.
-sub simplelist
+package OpenBSD::PackageLocation::SCP;
+our @ISA=qw(OpenBSD::PackageLocation OpenBSD::PackageLocation::FTPorSCP);
+
+our %distant = ();
+
+sub maxcount
{
+ return 2;
}
-package OpenBSD::PackageLocation::SCP;
-our @ISA=qw(OpenBSD::PackageLocation OpenBSD::PackageLocation::FTPorSCP);
+sub opened
+{
+ my $self = $_[0];
+ my $k = $self->{key};
+ if (!defined $distant{$k}) {
+ $distant{$k} = [];
+ }
+ return $distant{$k};
+}
sub _new
{
my ($class, $location) = @_;
$location =~ s/scp\:\/\///i;
$location =~ m/\//;
- bless { host => $`, path => "/$'" }, $class;
+ bless { host => $`, key => $`, path => "/$'" }, $class;
}
sub pipename
@@ -127,9 +138,12 @@ sub pipename
sub list
{
my ($self) = @_;
- my $host = $self->{host};
- my $path = $self->{path};
- return $self->_list("ssh $host ls -l $path");
+ if (!defined $self->{list}) {
+ my $host = $self->{host};
+ my $path = $self->{path};
+ $self->{list} = $self->_list("ssh $host ls -l $path");
+ }
+ return $self->{list};
}
package OpenBSD::PackageLocation::Local;
@@ -151,21 +165,16 @@ sub may_exist
sub list
{
my $self = shift;
- my @l = ();
+ my $l = [];
my $dname = $self->{location};
- opendir(my $dir, $dname) or return undef;
+ opendir(my $dir, $dname) or return $l;
while (my $e = readdir $dir) {
next unless -f "$dname/$e";
next unless $e =~ m/\.tgz$/;
- push(@l, $`);
+ push(@$l, $`);
}
close($dir);
- return @l;
-}
-
-sub simplelist
-{
- return $_[0]->list();
+ return $l;
}
package OpenBSD::PackageLocation::Local::Pipe;
@@ -186,22 +195,22 @@ package OpenBSD::PackageLocation::FTPorSCP;
sub _list
{
my ($self, $cmd) = @_;
- my @l =();
+ my $l =[];
local $_;
open(my $fh, '-|', "$cmd") or return undef;
while(<$fh>) {
chomp;
next if m/^d.*\s+\S/;
next unless m/([^\s]+)\.tgz\s*$/;
- push(@l, $1);
+ push(@$l, $1);
}
close($fh);
- return @l;
+ return $l;
}
package OpenBSD::PackageLocation::HTTPorFTP;
-my %distant = ();
+our %distant = ();
sub maxcount
{
@@ -240,21 +249,23 @@ our @ISA=qw(OpenBSD::PackageLocation::HTTPorFTP OpenBSD::PackageLocation);
sub list
{
my ($self) = @_;
- $self->make_room();
- my $fullname = $self->{location};
- my @l =();
- local $_;
- open(my $fh, '-|', "ftp -o - $fullname 2>/dev/null") or return undef;
- # XXX assumes a pkg HREF won't cross a line. Is this the case ?
- while(<$fh>) {
- chomp;
- for my $pkg (m/\<A\s+HREF=\"(.*?)\.tgz\"\>/gi) {
- next if $pkg =~ m|/|;
- push(@l, $pkg);
+ if (!defined $self->{list}) {
+ $self->make_room();
+ my $fullname = $self->{location};
+ my $l = $self->{list} = [];
+ local $_;
+ open(my $fh, '-|', "ftp -o - $fullname 2>/dev/null") or return undef;
+ # XXX assumes a pkg HREF won't cross a line. Is this the case ?
+ while(<$fh>) {
+ chomp;
+ for my $pkg (m/\<A\s+HREF=\"(.*?)\.tgz\"\>/gi) {
+ next if $pkg =~ m|/|;
+ push(@$l, $pkg);
+ }
}
+ close($fh);
}
- close($fh);
- return @l;
+ return $self->{list};
}
package OpenBSD::PackageLocation::FTP;
@@ -263,9 +274,12 @@ our @ISA=qw(OpenBSD::PackageLocation::HTTPorFTP OpenBSD::PackageLocation OpenBSD
sub list
{
my ($self) = @_;
- $self->make_room();
- my $fullname = $self->{location};
- return $self->_list("echo nlist|ftp -o - $fullname 2>/dev/null");
+ if (!defined $self->{list}) {
+ $self->make_room();
+ my $fullname = $self->{location};
+ $self->{list} = $self->_list("echo nlist *.tgz|ftp -o - $fullname 2>/dev/null");
+ }
+ return $self->{list};
}
@@ -279,14 +293,18 @@ use OpenBSD::Temp;
my %packages;
my @pkgpath;
+my $need_new_cache = 1;
+my $available_packages = {};
+my @pkglist = ();
+
if (defined $ENV{PKG_PATH}) {
- my @tentative = split /\:/, $ENV{PKG_PATH};
+ my $pkgpath = $ENV{PKG_PATH};
+ $pkgpath =~ s/^\:+//;
+ $pkgpath =~ s/\:+$//;
+ my @tentative = split /\/\:/, $pkgpath;
@pkgpath = ();
while (my $i = shift @tentative) {
- if ($i =~ m/^(?:ftp|http|scp)$/i) {
- $i.= ":".(shift @tentative);
- }
$i =~ m|/$| or $i.='/';
push @pkgpath, OpenBSD::PackageLocation->new($i);
}
@@ -318,6 +336,7 @@ sub find
$package = $class->openAbsolute($location, $pkgname, $arch);
if (defined $package) {
push(@pkgpath, $location);
+ $need_new_cache = 1;
}
} else {
for my $p (@pkgpath) {
@@ -331,20 +350,17 @@ sub find
sub available
{
- my @l = ();
- foreach my $loc (@pkgpath) {
- push(@l, $loc->simplelist());
- }
- return @l;
-}
-
-sub distant_available
-{
- my @l = ();
- foreach my $loc (@pkgpath) {
- push(@l, $loc->list());
+ if ($need_new_cache) {
+ $available_packages = {};
+ foreach my $loc (reverse @pkgpath) {
+ foreach my $pkg (@{$loc->list()}) {
+ $available_packages->{$pkg} = $loc;
+ }
+ }
+ @pkglist = keys %$available_packages;
+ $need_new_cache = 0;
}
- return @l;
+ return @pkglist;
}
sub info
diff --git a/usr.sbin/pkg_add/OpenBSD/PackingElement.pm b/usr.sbin/pkg_add/OpenBSD/PackingElement.pm
index 0f4c74a56fe..0ee0f853ac7 100644
--- a/usr.sbin/pkg_add/OpenBSD/PackingElement.pm
+++ b/usr.sbin/pkg_add/OpenBSD/PackingElement.pm
@@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
-# $OpenBSD: PackingElement.pm,v 1.77 2005/08/14 12:01:08 espie Exp $
+# $OpenBSD: PackingElement.pm,v 1.78 2005/09/04 22:47:56 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -138,6 +138,8 @@ sub IsFile() { 0 }
sub NoDuplicateNames() { 0 }
+sub signature {}
+
# Basic class hierarchy
# various stuff that's only linked to objects before/after them
@@ -244,6 +246,12 @@ sub add_object
package OpenBSD::PackingElement::Depend;
our @ISA=qw(OpenBSD::PackingElement::Meta);
+sub signature
+{
+ my ($self, $hash) = @_;
+ $hash->{$self->{def}} = 1;
+}
+
# Abstract class for all file-like elements
package OpenBSD::PackingElement::FileBase;
our @ISA=qw(OpenBSD::PackingElement::FileObject);
@@ -647,6 +655,10 @@ sub category() { "pkgcfl" }
package OpenBSD::PackingElement::PkgDep;
our @ISA=qw(OpenBSD::PackingElement::Depend);
+sub signature
+{
+}
+
__PACKAGE__->setKeyword('pkgdep');
sub keyword() { "pkgdep" }
sub category() { "pkgdep" }
@@ -706,6 +718,11 @@ __PACKAGE__->setKeyword('wantlib');
sub category() { "wantlib" }
sub keyword() { "wantlib" }
+sub signature
+{
+ my ($self, $hash) = @_;
+ $hash->{$self->{name}} = 1;
+}
package OpenBSD::PackingElement::LibDepend;
our @ISA=qw(OpenBSD::PackingElement::Depend);
@@ -736,6 +753,63 @@ sub stringize($)
':'.$self->{libspec}.':'.$self->{pattern}.':'.$self->{def};
}
+package OpenBSD::PackingElement::PkgPath;
+our @ISA=qw(OpenBSD::PackingElement::Meta);
+
+__PACKAGE__->setKeyword('pkgpath');
+sub keyword() { "pkgpath" }
+sub category() { "pkgpath" }
+
+package OpenBSD::PackingElement::Incompatibility;
+our @ISA=qw(OpenBSD::PackingElement::Meta);
+
+__PACKAGE__->setKeyword('incompatibility');
+sub keyword() { "incompatibility" }
+sub category() { "incompatibility" }
+
+package OpenBSD::PackingElement::UpdateSet;
+our @ISA=qw(OpenBSD::PackingElement::Meta);
+
+__PACKAGE__->setKeyword('updateset');
+sub keyword() { "updateset" }
+sub category() { "updateset" }
+
+package OpenBSD::PackingElement::Module;
+our @ISA=qw(OpenBSD::PackingElement::Meta);
+
+use OpenBSD::PackageInfo;
+
+__PACKAGE__->setKeyword('module');
+sub keyword() { "module" }
+sub category() { "module" }
+
+my $installed_modules = {};
+
+sub add
+{
+ my ($class, $plist, @args) = @_;
+
+ require OpenBSD::PkgSpec;
+
+ my @candidates = OpenBSD::PkgSpec::match($args[0], installed_packages());
+ if (@candidates == 1) {
+ if (!defined $installed_modules->{$candidates[0]}) {
+ # pull in the module right here and now;
+ my $f = installed_info($candidates[0]).MODULE;
+ eval "require \"$f\";";
+ if ($@) {
+ die "Error in reading module $f: $@";
+ }
+ }
+ } elsif (@candidates == 0) {
+ $plist->{need_modules} = 1;
+ } else {
+ die "Ambiguous module: ", $args[0];
+ }
+
+ $class->SUPER::add($plist, @args);
+}
+
package OpenBSD::PackingElement::NewUser;
our @ISA=qw(OpenBSD::PackingElement::Action);
__PACKAGE__->setKeyword("newuser");
@@ -1153,6 +1227,10 @@ package OpenBSD::PackingElement::FCONTENTS;
our @ISA=qw(OpenBSD::PackingElement::SpecialFile);
sub category() { OpenBSD::PackageInfo::CONTENTS }
+package OpenBSD::PackingElement::FMODULE;
+our @ISA=qw(OpenBSD::PackingElement::SpecialFile);
+sub category() { OpenBSD::PackageInfo::MODULE }
+
package OpenBSD::PackingElement::ScriptFile;
our @ISA=qw(OpenBSD::PackingElement::SpecialFile);
use OpenBSD::Error;
diff --git a/usr.sbin/pkg_add/OpenBSD/PackingList.pm b/usr.sbin/pkg_add/OpenBSD/PackingList.pm
index af9360785a7..d0c83e84982 100644
--- a/usr.sbin/pkg_add/OpenBSD/PackingList.pm
+++ b/usr.sbin/pkg_add/OpenBSD/PackingList.pm
@@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
-# $OpenBSD: PackingList.pm,v 1.47 2005/08/17 10:00:19 espie Exp $
+# $OpenBSD: PackingList.pm,v 1.48 2005/09/04 22:47:56 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -74,6 +74,10 @@ sub read
next if m/^\s*$/;
chomp;
OpenBSD::PackingElement::Factory($_, $plist);
+ if ($plist->{need_modules}) {
+ close($fh);
+ open($fh, '<', '/dev/null');
+ }
});
return $plist;
}
@@ -159,6 +163,27 @@ sub ExtraInfoOnly
}
}
+sub UpdateInfoOnly
+{
+ my ($fh, $cont) = @_;
+ local $_;
+ while (<$fh>) {
+ # XXX optimization
+ if (m/^\@arch\b/o) {
+ while (<$fh>) {
+ if (m/^\@(?:depend|wantlib|pkgdep|newdepend|libdepend|pkgpath)\b/o) {
+ &$cont($_);
+ } elsif (m/^\@(?:groups|users|cwd)\b/o) {
+ last;
+ }
+ }
+ return;
+ }
+ next unless m/^\@(?:name\b|depend\b|wantlib\b|pkgdep\b|newdepend\b|libdepend\b|pkgpath\b|comment\s+subdir\=|arch\b)/o;
+ &$cont($_);
+ }
+}
+
sub FatOnly
{
my ($fh, $cont) = @_;
@@ -306,6 +331,16 @@ sub pkgbase($)
}
}
+our @unique_categories =
+ (qw(name no-default-conflict manual-installation extrainfo arch));
+
+our @list_categories =
+ (qw(pkgcfl conflict depend wantlib pkgdep newdepend
+ libdepend module groups users items));
+
+our @cache_categories =
+ (qw(depend wantlib pkgdep newdepend libdepend));
+
sub visit
{
my ($self, $method, @l) = @_;
@@ -320,7 +355,7 @@ sub visit
}
}
- for my $unique_item (qw(name no-default-conflict manual-installation extrainfo arch)) {
+ for my $unique_item (@unique_categories) {
$self->{$unique_item}->$method(@l) if defined $self->{$unique_item};
}
@@ -328,7 +363,7 @@ sub visit
$self->{$special}->$method(@l) if defined $self->{$special};
}
- for my $listname (qw(modules pkgcfl conflict depend wantlib pkgdep newdepend libdepend groups users items)) {
+ for my $listname (@list_categories) {
if (defined $self->{$listname}) {
for my $item (@{$self->{$listname}}) {
$item->$method(@l);
@@ -368,7 +403,7 @@ sub to_cache
my ($self) = @_;
return if defined $plist_cache->{$self->pkgname()};
my $plist = new OpenBSD::PackingList;
- for my $c (qw(depend wantlib pkgdep newdepend libdepend)) {
+ for my $c (@cache_categories) {
if (defined $self->{$c}) {
$plist->{$c} = $self->{$c};
}
@@ -388,6 +423,14 @@ sub to_installation
}
+sub signature
+{
+ my $self = shift;
+ my $k = {};
+ $self->visit('signature', $k);
+ return join(',', $self->pkgname(), sort keys %$k);
+}
+
sub forget
{
}
diff --git a/usr.sbin/pkg_add/OpenBSD/ProgressMeter.pm b/usr.sbin/pkg_add/OpenBSD/ProgressMeter.pm
index 68152be9817..a4e24e536fe 100644
--- a/usr.sbin/pkg_add/OpenBSD/ProgressMeter.pm
+++ b/usr.sbin/pkg_add/OpenBSD/ProgressMeter.pm
@@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
-# $OpenBSD: ProgressMeter.pm,v 1.5 2004/12/29 14:10:27 espie Exp $
+# $OpenBSD: ProgressMeter.pm,v 1.6 2005/09/04 22:47:56 espie Exp $
#
# Copyright (c) 2004 Marc Espie <espie@openbsd.org>
#
@@ -68,10 +68,9 @@ sub set_header
$header = shift;
if (!$enabled) {
$isatty = 0;
- } else {
- if (!defined $isatty) {
- $isatty = -t STDERR;
- }
+ }
+ if (!defined $isatty) {
+ $isatty = -t STDERR;
}
if ($isatty) {
find_window_size();
diff --git a/usr.sbin/pkg_add/OpenBSD/Update.pm b/usr.sbin/pkg_add/OpenBSD/Update.pm
index 9a0aa61ead3..24493147f3e 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.55 2005/08/16 21:34:10 espie Exp $
+# $OpenBSD: Update.pm,v 1.56 2005/09/04 22:47:56 espie Exp $
#
# Copyright (c) 2004 Marc Espie <espie@openbsd.org>
#
@@ -19,6 +19,7 @@ use strict;
use warnings;
use OpenBSD::Delete;
+use OpenBSD::Interactive;
package OpenBSD::PackingElement;
sub can_update
@@ -51,10 +52,6 @@ sub unmark_lib
{
}
-sub build_context
-{
-}
-
package OpenBSD::PackingElement::FileBase;
use File::Temp qw/tempfile/;
@@ -170,7 +167,7 @@ sub validate_depend
$state->{forcedupdates}->{$wanting} = 1;
} else {
$state->{okay} = 0;
- Warn "Can't update forward dependency of $wanting on $toreplace: $replacement doesn't match\n";
+ Warn "Can't update forward dependency of $wanting on $toreplace: $replacement doesn't match (use -F updatedepends to force it)\n";
}
}
}
@@ -201,25 +198,6 @@ sub unmark_lib
delete $libs->{"$libname"};
}
-package OpenBSD::PackingElement::Wantlib;
-sub build_context
-{
- my ($self, $hash) = @_;
- $hash->{$self->{name}} = 1;
-}
-
-package OpenBSD::PackingElement::Depend;
-sub build_context
-{
- my ($self, $hash) = @_;
- $hash->{$self->{def}} = 1;
-}
-
-package OpenBSD::PackingElement::PkgDep;
-sub build_context
-{
-}
-
package OpenBSD::PackingElement::NewDepend;
use OpenBSD::Error;
sub validate_depend
@@ -235,7 +213,7 @@ sub validate_depend
Warn "Forward dependency of $wanting on $toreplace doesn't match $replacement, forcing it\n";
} else {
$state->{okay} = 0;
- Warn "Can't update forward dependency of $wanting on $toreplace: $replacement doesn't match\n";
+ Warn "Can't update forward dependency of $wanting on $toreplace: $replacement doesn't match (use -F updatedepends to force it)\n";
}
}
}
@@ -253,7 +231,7 @@ sub validate_depend
Warn "Forward dependency of $wanting on $toreplace doesn't match $replacement, forcing it\n";
} else {
$state->{okay} = 0;
- Warn "Can't update forward dependency of $wanting on $toreplace: $replacement doesn't match\n";
+ Warn "Can't update forward dependency of $wanting on $toreplace: $replacement doesn't match (use -F updatedepends to force it)\n";
}
}
}
@@ -284,6 +262,12 @@ sub can_do
if ($state->{forced}->{update}) {
Warn "(forcing update)\n";
$state->{okay} = 1;
+ } elsif ($state->{interactive}) {
+ require OpenBSD::Interactive;
+
+ if (OpenBSD::Interactive::confirm("proceed with update anyways", 1, 0)) {
+ $state->{okay} = 1;
+ }
}
}
my @wantlist = OpenBSD::RequiredBy->new($toreplace)->list();
@@ -329,7 +313,7 @@ sub is_safe
for my $i (@{$state->{journal}}) {
Warn "\t$i\n";
}
- if ($state->{forced}->{update}) {
+ if ($state->{forced}->{update} || OpenBSD::Interactive::confirm("Proceed with update anyways", $state->{interactive}, 0)) {
Warn "(forcing update)\n";
$state->{okay} = 1;
}
@@ -401,9 +385,11 @@ sub convert_to_requiring
sub walk_depends_closure
{
- my ($start, $name, $state) = @_;
+ 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};
@@ -423,8 +409,15 @@ sub walk_depends_closure
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);
+# }
+# }
}
@@ -473,7 +466,7 @@ sub save_old_libraries
require OpenBSD::PkgCfl;
OpenBSD::PkgCfl::register($stub_list, $state);
- walk_depends_closure($old_plist->pkgname(), $stub_name, $state);
+ walk_depends_closure($old_plist->pkgname(), $stub_list, $state);
} else {
print "No libraries to keep\n" if $state->{beverbose};
}
@@ -493,21 +486,6 @@ sub adjust_dependency
$l->add($into);
}
-sub is_needed
-{
- my ($plist, $state) = @_;
- my $new_context = {};
- $plist->visit('build_context', $new_context);
- my $oplist = OpenBSD::PackingList->from_installation($plist->pkgname());
- my $old_context = {};
- $oplist->visit('build_context', $old_context);
- my $n = join(',', sort keys %$new_context);
- my $o = join(',', sort keys %$old_context);
- print "Comparing full signature for ", $plist->pkgname(), " \"$o\" vs. \"$n\": ", $n eq $o ? "equal\n" : "different\n"
- if $state->{very_verbose};
- return $n ne $o;
-}
-
sub figure_out_libs
{
my ($plist, $state, @libs) = @_;
diff --git a/usr.sbin/pkg_add/pkg_add b/usr.sbin/pkg_add/pkg_add
index ee60c8c694e..de0e98d4dcf 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.196 2005/08/29 00:42:58 espie Exp $
+# $OpenBSD: pkg_add,v 1.197 2005/09/04 22:47:56 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -31,6 +31,7 @@ use OpenBSD::Vstat;
use OpenBSD::Getopt;
use OpenBSD::Error;
use OpenBSD::ProgressMeter;
+use OpenBSD::Interactive;
use OpenBSD::Add;
use OpenBSD::SharedLibs;
use File::Path;
@@ -40,6 +41,17 @@ my $errors = 0;
our %forced = ();
our $not;
+sub has_new_sig
+{
+ my ($plist, $state) = @_;
+ 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};
+ return $n ne $o;
+}
+
+
sub can_install($$$)
{
my ($plist, $state, $handle) = @_;
@@ -50,14 +62,10 @@ sub can_install($$$)
my %conflicts = map {($_,1)} @conflicts;
- if (defined $conflicts{$pkgname}) {
- if (!$state->{replace}) {
- if (!$state->{forced}->{installed}) {
- print "Can't install $pkgname because it's already installed\n";
- $state->{installed}->{$handle->{pkgname}} = 1;
- $errors++;
- }
- return undef;
+ if ((keys %conflicts) == 1 && (keys %conflicts)[0] eq $pkgname) {
+ if (!OpenBSD::Add::is_needed($plist, $state)) {
+ print "Already installed: $pkgname\n";
+ return 1;
}
}
@@ -72,6 +80,13 @@ sub can_install($$$)
}
if (!$state->{replace}) {
+ if (@conflicts == 1 && is_installed($plist->pkgname()) &&
+ !has_new_sig($plist, $state)) {
+ print "Not reinstalling $pkgname\n" if $state->{verbose};
+ OpenBSD::SharedLibs::add_package_libs($plist->pkgname());
+ $state->{installed}->{$pkgname} = 1;
+ return undef;
+ }
print "Can't install $pkgname because of conflicts (",join(',', @conflicts, @libs), ")\n";
$errors++;
return undef;
@@ -86,14 +101,15 @@ sub can_install($$$)
require OpenBSD::Update;
if (is_installed($plist->pkgname()) && !$state->{forced}->{installed}) {
- if (!OpenBSD::Update::is_needed($plist, $state)) {
+ if (!has_new_sig($plist, $state)) {
+ 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)) {
- print "Can't safely update to $pkgname\n";
+ print "Can't safely update to $pkgname (use -F update to force it)\n";
$errors++;
return undef;
}
@@ -495,10 +511,23 @@ sub install_package
}
my $plist = $handle->{plist};
+ if ($plist->{need_modules}) {
+ if (!defined $handle->{solved_dependencies}) {
+ my @deps = OpenBSD::Dependencies::solve($state, $handle, @todo);
+ if (@deps > 0) {
+ build_deptree($state, $pkg, @deps);
+ return (@deps, $pkg);
+ }
+ } else {
+ my $dir = $handle->info();
+ $plist = $handle->{plist} =
+ OpenBSD::PackingList->fromfile($dir.CONTENTS);
+ }
+ }
if (is_installed($plist->pkgname()) && !$state->{forced}->{installed}) {
if ($state->{replace}) {
- if (!OpenBSD::Update::is_needed($plist, $state)) {
+ if (!OpenBSD::Add::is_needed($plist, $state)) {
OpenBSD::SharedLibs::add_package_libs($plist->pkgname());
$state->{installed}->{$handle->{pkgname}} = 1;
$handle->close();
@@ -568,33 +597,55 @@ sub install_package
return ();
}
+my $bad = 0;
+
+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();
+ 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 = ();
- for my $pkgname (@$old) {
- if (OpenBSD::PackageName::is_stem($pkgname)) {
- my @l = OpenBSD::PackageName::findstem($pkgname,
- installed_packages());
- if (@l == 0) {
- Fatal("Can't resolve $pkgname to an installed package name");
- } elsif (@l == 1) {
- push(@list, $l[0]);
- } else {
- Fatal("Ambiguous: $pkgname could be", join(',', @l));
- }
- } else {
- push(@list, $pkgname);
- }
- }
+ 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::compile_stemlist(OpenBSD::PackageLocator::distant_available());
+ my $hash = available_stems($state);
for my $pkgname (@list) {
my $stem = OpenBSD::PackageName::splitstem($pkgname);
@@ -609,10 +660,11 @@ sub find_updates
push(@$new, $l[0]);
next;
}
- my $plist = OpenBSD::PackingList->from_installation($pkgname, \&OpenBSD::PackingList::ExtraInfoOnly);
+ 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) {
@@ -621,18 +673,32 @@ sub find_updates
$handle->close();
my $dir = $handle->info();
my $p2 = OpenBSD::PackingList->fromfile($dir.CONTENTS,
- \&OpenBSD::PackingList::ExtraInfoOnly);
+ \&OpenBSD::PackingList::UpdateInfoOnly);
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 ($p2->{name} eq $plist->{extrainfo}->{subdir}) {
+ push(@l2, $candidate);
+ last;
+ }
+ }
}
}
- print "Updating $pkgname -> ", join(' ', @l2), "\n";
+ if (defined $found && @l2 == 1 && $found eq $l2[0]) {
+ print "No need to update $pkgname\n";
+ next;
+ }
+ 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) {
@@ -640,14 +706,42 @@ sub find_updates
}
if (@l2 == 1) {
- push(@$new, $l2[0]);
- } else {
+ if (defined $found && $found eq $l2[0]) {
+ print "No need to update $pkgname\n";
+ } else {
+ push(@$new, $l2[0]);
+ }
+ } elsif (@l2 == 0) {
push(@cantupdate, $pkgname);
+ } else {
+ push(@$new, choose1($pkgname, $state->{interactive}, sort @l2));
}
}
return @cantupdate;
}
+sub find_truenames
+{
+ my ($old, $new, $state) = @_;
+
+ my $h;
+
+ for my $pkgname (@$old) {
+ if (OpenBSD::PackageName::is_stem($pkgname)) {
+ if (!defined $h) {
+ $h = available_stems($state);
+ }
+ my @l = $h->findstem($pkgname);
+ if (@l > 1) {
+ @l = OpenBSD::PackageName::keep_most_recent(@l);
+ }
+ push(@$new, choose1($pkgname, $state->{interactive}, sort @l));
+ } else {
+ push(@$new, $pkgname);
+ }
+ }
+}
+
sub reorder
{
my $l = shift;
@@ -661,13 +755,13 @@ sub reorder
}
}
-set_usage('pkg_add [-acInqrvvx] [-A arch] [-B pkg-destdir] [-F keywords]',
+set_usage('pkg_add [-aciInqrvvx] [-A arch] [-B pkg-destdir] [-F keywords]',
'[-L localbase] [-P type] [-Q quick-destdir] pkgname [...]');
-our ($opt_a, $opt_v, $opt_n, $opt_I, $opt_L, $opt_B, $opt_A, $opt_P, $opt_Q, $opt_x, $opt_r, $opt_q, $opt_c, $opt_u);
+our ($opt_a, $opt_v, $opt_n, $opt_I, $opt_L, $opt_B, $opt_A, $opt_P, $opt_Q, $opt_x, $opt_r, $opt_q, $opt_c, $opt_i, $opt_u);
$opt_v = 0;
try {
- getopts('aqchuvnrxIL:f:F:B:A:P:Q:',
+ getopts('aqchivnruxIL:f:F:B:A:P:Q:',
{'v' => sub {++$opt_v;},
'h' => sub { Usage(); },
'F' => sub {
@@ -692,7 +786,6 @@ $state->{cache} = {};
$state->{installed} = {};
$state->{deptree} = {};
$state->{do_faked} = 0;
-$state->{replace} = $opt_r;
$state->{localbase} = $opt_L;
$state->{arch} = $opt_A;
$state->{forced} = \%forced;
@@ -731,7 +824,7 @@ if (defined $state->{destdir}) {
}
-$state->{not} = $opt_n || $opt_u;
+$state->{not} = $opt_n;
# XXX RequiredBy
$not = $opt_n;
$state->{quick} = $opt_q;
@@ -739,7 +832,9 @@ $state->{extra} = $opt_c;
$state->{dont_run_scripts} = $opt_I;
$state->{very_verbose} = $opt_v >= 2;
$state->{verbose} = $opt_v;
+$state->{interactive} = $opt_i;
$state->{beverbose} = $opt_n || ($opt_v >= 2);
+$state->{replace} = $opt_r || $opt_u;
if (@ARGV == 0 && !$opt_u) {
Usage "Missing pkgname";
@@ -757,27 +852,35 @@ if ($< && !$forced{nonroot}) {
}
lock_db($state->{not});
+
+my @todo = ();
+
if ($opt_u) {
if (@ARGV == 0) {
@ARGV = sort(installed_packages());
$state->{full_update} = 1;
}
- my @todo = ();
my @cantupdate = find_updates(\@ARGV, \@todo, $state);
- print "Update using pkg_add -r ", join(' ', @todo), "\n";
if (@cantupdate > 0) {
- print "Cannot find updates for ",join(' ', @cantupdate), "\n";
+ unless ($state->{forced}->{alwaysupdate} ||
+ OpenBSD::Interactive::confirm("Cannot find updates for ".join(' ', @cantupdate).". Proceed", $state->{interactive}, 0)) {
+ exit(1);
+ }
+ }
+ print "Running the equivalent of pkg_add -r ", join(' ', @todo), "\n";
+} else {
+ find_truenames(\@ARGV, \@todo, $state);
+ if (defined $state->{forced}->{kitchensink}) {
+ reorder(\@todo);
+ if (!$opt_r) {
+ @todo = grep {s/\.tgz$//; !is_installed($_);} @todo;
+ }
+ print "Adding in order:\n", (map { "\t$_\n" } @todo), "\n";
}
- exit(0);
}
-my @todo = (@ARGV);
-if (defined $state->{forced}->{kitchensink}) {
- reorder(\@todo);
- if (!$opt_r) {
- @todo = grep {s/\.tgz$//; !is_installed($_);} @todo;
- }
- print "Adding in order:\n", (map { "\t$_\n" } @todo), "\n";
+if ($bad) {
+ exit(1);
}
eval {
diff --git a/usr.sbin/pkg_add/pkg_add.1 b/usr.sbin/pkg_add/pkg_add.1
index 692d9d7df6a..260aaa3deae 100644
--- a/usr.sbin/pkg_add/pkg_add.1
+++ b/usr.sbin/pkg_add/pkg_add.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pkg_add.1,v 1.46 2005/08/17 19:22:31 espie Exp $
+.\" $OpenBSD: pkg_add.1,v 1.47 2005/09/04 22:47:56 espie Exp $
.\"
.\" FreeBSD install - a package for the installation and maintenance
.\" of non-core utilities.
@@ -26,7 +26,7 @@
.Sh SYNOPSIS
.Nm pkg_add
.Bk -words
-.Op Fl acInqruvx
+.Op Fl aciInqruvx
.Op Fl A Ar arch
.Op Fl B Ar pkg-destdir
.Op Fl F Ar keywords
@@ -175,6 +175,10 @@ unsafe update: old packing-list will run scripts that may fail.
.It Ar updatedepends
force update even if forward dependencies no longer match.
.El
+.It Fl i
+Switch on interactive mode.
+.Nm
+may ask questions to the user if faced with difficult decisions.
.It Fl I
If scripts exist for a given package, do not execute them.
.It Fl L Ar localbase
diff --git a/usr.sbin/pkg_add/pkg_create b/usr.sbin/pkg_add/pkg_create
index 3b1943783ed..785a5da8463 100644
--- a/usr.sbin/pkg_add/pkg_create
+++ b/usr.sbin/pkg_add/pkg_create
@@ -1,6 +1,6 @@
#! /usr/bin/perl
# ex:ts=8 sw=4:
-# $OpenBSD: pkg_create,v 1.37 2005/08/14 12:01:08 espie Exp $
+# $OpenBSD: pkg_create,v 1.38 2005/09/04 22:47:56 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -264,7 +264,7 @@ our $errors = 0;
our ($opt_p, $opt_f, $opt_c, $opt_d, $opt_v, $opt_i, $opt_k, $opt_r,
$opt_S, $opt_h, $opt_s, $opt_O, $opt_A, $opt_L,
- $opt_M, $opt_U, $opt_P, $opt_W, $opt_n,
+ $opt_m, $opt_M, $opt_U, $opt_P, $opt_W, $opt_n,
$opt_B);
my @contents;
@@ -272,13 +272,13 @@ my $regen_package = 0;
set_usage(
'pkg_create [-hnv] [-A arches] [-B pkg-destdir] [-D name=value]',
-'[-i iscript] [-k dscript] [-L localbase] [-M displayfile]',
+'[-i iscript] [-k dscript] [-L localbase] [-M module] [-M displayfile]',
'[-P pkg-dependency] [-p prefix] [-r rscript] [-S pkg-destdir]',
'[-U undisplayfile] [-W wantedlib] -c desc -d desc -f packinglist pkgname');
my $plist = new OpenBSD::PackingList;
try {
- getopts('hp:f:c:d:vi:k:r:M:U:S:hs:OA:L:B:D:P:W:n',
+ getopts('hp:f:c:d:vi:k:r:m:M:U:S:hs:OA:L:B:D:P:W:n',
{'D' =>
sub {
local $_ = shift;
@@ -367,6 +367,9 @@ if (defined $opt_M) {
copy_subst($opt_M, '>', $dir.DISPLAY);
}
+if (defined $opt_m) {
+ copy_subst($opt_m, '>', $dir.MODULE);
+}
if (defined $opt_U) {
copy_subst($opt_U, '>', $dir.UNDISPLAY);
}
@@ -477,6 +480,11 @@ if (!defined $plist->{extrainfo} &&
$fullpkgpath, $cdrom, $ftp);
}
+if ($plist->{need_modules}) {
+ print STDERR "Error: some needed modules were not found\n";
+ $errors++;
+}
+
if ($regen_package) {
$plist->checksum($base);
diff --git a/usr.sbin/pkg_add/pkg_delete b/usr.sbin/pkg_add/pkg_delete
index 93a176dfdcc..f60b2a0bab0 100644
--- a/usr.sbin/pkg_add/pkg_delete
+++ b/usr.sbin/pkg_add/pkg_delete
@@ -1,6 +1,6 @@
#!/usr/bin/perl
# ex:ts=8 sw=4:
-# $OpenBSD: pkg_delete,v 1.90 2005/08/17 18:44:24 espie Exp $
+# $OpenBSD: pkg_delete,v 1.91 2005/09/04 22:47:56 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -24,19 +24,20 @@ use OpenBSD::PackingOld;
use OpenBSD::RequiredBy;
use OpenBSD::Error;
use OpenBSD::ProgressMeter;
+use OpenBSD::Interactive;
use OpenBSD::Delete;
use OpenBSD::PackageInfo;
our %forced = ();
our $not;
-set_usage('pkg_delete [-cInqvx] [-B pkg-destdir] [-F keywords] pkgname [...]');
-our ($opt_v, $opt_D, $opt_d, $opt_n, $opt_q, $opt_p, $opt_c, $opt_L, $opt_B, $opt_I, $opt_x);
+set_usage('pkg_delete [-ciInqvx] [-B pkg-destdir] [-F keywords] pkgname [...]');
+our ($opt_v, $opt_D, $opt_d, $opt_n, $opt_q, $opt_p, $opt_c, $opt_L, $opt_B, $opt_I, $opt_i, $opt_x);
$opt_v = 0;
try {
- getopts('vchxDdnf:F:qpS:L:B:I',
+ getopts('vchixDdnf:F:qpS:L:B:I',
{'v' => sub {++$opt_v;},
'h' => sub { Usage(); },
'F' => sub {
@@ -88,6 +89,7 @@ $state->{extra} = $opt_c;
$state->{dont_run_scripts} = $opt_I;
$state->{forced} = \%forced;
$state->{destdir} = $opt_B;
+$state->{interactive} = $opt_i;
if ($opt_B eq '') {
$state->{destdirname} = '';
} else {
@@ -114,31 +116,8 @@ if ($< && !$forced{nonroot}) {
my @realnames;
my $bad;
-for my $pkgname (@ARGV) {
- $pkgname =~ s/\.tgz$//;
- if (is_installed($pkgname)) {
- push(@realnames, installed_name($pkgname));
- } else {
- if (OpenBSD::PackageName::is_stem($pkgname)) {
- my @l = OpenBSD::PackageName::findstem($pkgname,
- installed_packages());
- if (@l == 0) {
- print "Can't resolve $pkgname to an installed package name\n";
- $bad = 1 unless $forced{uninstalled};
- } elsif (@l == 1) {
- push(@realnames, $l[0]);
- } elsif (@l != 0) {
- print "Ambiguous: $pkgname could be ", join(' ', @l),"\n";
- if ($forced{ambiguous}) {
- print "(removing them all)\n";
- push(@realnames, @l);
- } else {
- $bad = 1;
- }
- }
- }
- }
-}
+OpenBSD::PackageInfo::solve_installed_names(\@ARGV, \@realnames,
+ "(removing them all)", $state);
my @todo = OpenBSD::RequiredBy->compute_closure(@realnames);
@@ -149,12 +128,11 @@ if (@todo > @realnames) {
}
print "Can't remove ", join(' ', @ARGV), " without also removing:\n",
join(' ', keys(%extra_rm)), "\n";
- if ($forced{dependencies}) {
- if (keys(%extra_rm) > 1) {
- print "(removing them as well)\n";
- } else {
- print "(removing it as well)\n";
- }
+ my $them = keys(%extra_rm) > 1 ? 'them' : 'it';
+ if ($forced{dependencies} or
+ OpenBSD::Interactive::confirm("Do you want to remove $them as well", $state->{interactive}, 0)) {
+ print "(removing $them as well)\n";
+ push(@realnames, keys(%extra_rm));
} else {
$bad = 1;
}
diff --git a/usr.sbin/pkg_add/pkg_delete.1 b/usr.sbin/pkg_add/pkg_delete.1
index 088c2e0afd8..be27e327554 100644
--- a/usr.sbin/pkg_add/pkg_delete.1
+++ b/usr.sbin/pkg_add/pkg_delete.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pkg_delete.1,v 1.17 2005/01/03 01:02:45 espie Exp $
+.\" $OpenBSD: pkg_delete.1,v 1.18 2005/09/04 22:47:56 espie Exp $
.\"
.\" FreeBSD install - a package for the installation and maintenance
.\" of non-core utilities.
@@ -25,7 +25,7 @@
.Nd a utility for deleting previously installed software package distributions
.Sh SYNOPSIS
.Nm pkg_delete
-.Op Fl cInqvx
+.Op Fl ciInqvx
.Op Fl B Ar pkg-destdir
.Op Fl F Ar keywords
.Ar pkgname Op Ar ...
@@ -81,6 +81,10 @@ external scripts may fail.
.It Ar uninstalled
proceed even if some package names don't resolve to installed package names.
.El
+.It Fl i
+Switch on interactive mode.
+.Nm
+may ask questions to the user if faced with difficult decisions.
.It Fl I
If scripts exist for a given package, do not execute them.
.It Fl n
diff --git a/usr.sbin/pkg_add/pkg_info b/usr.sbin/pkg_add/pkg_info
index 1a6f967a505..e91327ed8ec 100644
--- a/usr.sbin/pkg_add/pkg_info
+++ b/usr.sbin/pkg_add/pkg_info
@@ -1,6 +1,6 @@
#! /usr/bin/perl
# ex:ts=8 sw=4:
-# $OpenBSD: pkg_info,v 1.30 2005/08/16 08:59:38 espie Exp $
+# $OpenBSD: pkg_info,v 1.31 2005/09/04 22:47:56 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -23,6 +23,45 @@ use OpenBSD::PackageName;
use OpenBSD::Getopt;
use OpenBSD::Error;
+package OpenBSD::PackingElement;
+sub dump_file
+{
+}
+
+sub hunt_file
+{
+}
+
+sub sum_up
+{
+ my ($self, $rsize) = @_;
+ if (defined $self->{size}) {
+ $$rsize += $self->{size};
+ }
+}
+
+package OpenBSD::PackingElement::FileBase;
+sub dump_file
+{
+ my ($item, $opt_K) = @_;
+ if ($opt_K) {
+ print '@', $item->keyword(), " ";
+ }
+ print $item->fullname(), "\n";
+}
+
+sub hunt_file
+{
+ my ($item, $h, $pkgname, $l) = @_;
+ my $fname = $item->fullname();
+ if (defined $h->{$fname}) {
+ push(@{$h->{$fname}}, $pkgname);
+ push(@$l, $pkgname);
+ }
+}
+
+package main;
+
my $total_size = 0;
my $pkgs = 0;
@@ -115,14 +154,7 @@ sub filter_files
my $plist = OpenBSD::PackingList->fromfile($dir.CONTENTS,
\&OpenBSD::PackingList::FilesOnly);
- for my $item (@{$plist->{items}}) {
- next unless $item->IsFile();
- my $fname = $item->fullname();
- if (defined $search->{"$fname"}) {
- push(@{$search->{$fname}}, $pkg);
- push(@result, $pkg);
- }
- }
+ $plist->visit('hunt_file', $search, $pkg, \@result);
});
}
return @result;
@@ -158,7 +190,7 @@ sub find_by_path
our ($opt_c, $opt_D, $opt_d, $opt_f, $opt_I, $opt_i, $opt_k, $opt_K, $opt_L,
$opt_m, $opt_p, $opt_q, $opt_R, $opt_r, $opt_s, $opt_v, $opt_h, $opt_l,
- $opt_a, $opt_M, $opt_U, $opt_A);
+ $opt_a, $opt_M, $opt_U, $opt_A, $opt_S);
my $terse = 0;
my $exit_code = 0;
my @sought_files;
@@ -220,11 +252,11 @@ sub print_info
print "\n";
}
my $plist;
- if ($opt_f || $opt_L || $opt_s) {
+ if ($opt_f || $opt_L || $opt_s || $opt_S) {
require OpenBSD::PackingOld;
require OpenBSD::PackingList;
- if ($opt_f || $opt_s) {
+ if ($opt_f || $opt_s || $opt_S) {
$plist = OpenBSD::PackingList->fromfile($dir.CONTENTS);
} else {
$plist = OpenBSD::PackingList->fromfile($dir.CONTENTS, \&OpenBSD::PackingList::FilesOnly);
@@ -233,27 +265,21 @@ sub print_info
}
if ($opt_L) {
print $opt_l, "Files:\n" unless $opt_q;
- for my $item (@{$plist->{items}}) {
- next unless $item->IsFile();
- if ($opt_K) {
- print '@', $item->keyword(), " ";
- }
- print $item->fullname(), "\n";
- }
+ $plist->visit('dump_file', $opt_K);
print "\n";
}
if ($opt_s) {
my $size = 0;
- for my $item (@{$plist->{items}}) {
- next unless $item->IsFile();
- if (defined $item->{size}) {
- $size += $item->{size};
- }
- }
- print "Size: $size\n";
+ $plist->visit('sum_up', \$size);
+ print "Size: " unless $opt_q;
+ print "$size\n";
$total_size += $size;
$pkgs++;
}
+ if ($opt_S) {
+ print "Signature: " unless $opt_q;
+ print $plist->signature(), "\n";
+ }
if ($opt_f) {
print $opt_l, "Packing list:\n" unless $opt_q;
@@ -264,11 +290,11 @@ sub print_info
}
}
-set_usage('pkg_info [-cDdfIiKkLMpqRrsUv] [-E fname] [-e pkgname] [-l str] pkgname...', 'pkg_info [-Aa flags]');
+set_usage('pkg_info [-cDdfIiKkLMpqRrsSUv] [-E fname] [-e pkgname] [-l str] pkgname...', 'pkg_info [-Aa flags]');
my $locked;
try {
- getopts('cDdfhIikKLmpqRrsUve:E:Ml:aA',
+ getopts('cDdfhIikKLmpqRrsSUve:E:Ml:aA',
{'e' =>
sub {
my $pat = shift;
@@ -306,7 +332,8 @@ if ($opt_D) {
}
unless ($opt_c || $opt_M || $opt_U || $opt_d || $opt_f || $opt_I || $opt_i ||
- $opt_k || $opt_L || $opt_m || $opt_p || $opt_R || $opt_r || $opt_s || $terse) {
+ $opt_k || $opt_L || $opt_m || $opt_p || $opt_R || $opt_r || $opt_s ||
+ $opt_S || $terse) {
if (@ARGV == 0) {
$opt_I = $opt_a = 1;
} else {
@@ -316,7 +343,7 @@ unless ($opt_c || $opt_M || $opt_U || $opt_d || $opt_f || $opt_I || $opt_i ||
if ($opt_v) {
$opt_c = $opt_d = $opt_f = $opt_i = $opt_k = $opt_r = $opt_M =
- $opt_U = $opt_m = $opt_R = $opt_s = 1;
+ $opt_U = $opt_m = $opt_R = $opt_s = $opt_S = 1;
}
if (!defined $opt_l) {
diff --git a/usr.sbin/pkg_add/pkg_info.1 b/usr.sbin/pkg_add/pkg_info.1
index 03c9fcb9614..d54393fef6c 100644
--- a/usr.sbin/pkg_add/pkg_info.1
+++ b/usr.sbin/pkg_add/pkg_info.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pkg_info.1,v 1.16 2005/03/13 09:19:02 espie Exp $
+.\" $OpenBSD: pkg_info.1,v 1.17 2005/09/04 22:47:56 espie Exp $
.\"
.\" FreeBSD install - a package for the installation and maintenance
.\" of non-core utilities.
@@ -26,7 +26,7 @@
.Sh SYNOPSIS
.Nm pkg_info
.Bk -words
-.Op Fl cDdfIiKkLMpqRrsUv
+.Op Fl cDdfIiKkLMpqRrsSUv
.Op Fl E Ar filename
.Op Fl e Ar pkg-name
.Op Fl l Ar str
@@ -152,6 +152,10 @@ Show which packages require a given package.
Show the requirements script (if any) for each package.
.It Fl s
Show an estimate of the total size of each package.
+.It Fl S
+Show the package signature for each package.
+This signature is a unique tag showing the package name, and the version number
+of every dependency and shared library necessary to build this package.
.It Fl U
Show the deinstall-message file (if any) for each package.
.It Fl v
diff --git a/usr.sbin/pkg_add/pod/OpenBSD::PackingList.pod b/usr.sbin/pkg_add/pod/OpenBSD::PackingList.pod
index 24cb9f0a561..14b1a50218c 100644
--- a/usr.sbin/pkg_add/pod/OpenBSD::PackingList.pod
+++ b/usr.sbin/pkg_add/pod/OpenBSD::PackingList.pod
@@ -1,4 +1,4 @@
-$OpenBSD: OpenBSD::PackingList.pod,v 1.2 2005/03/02 20:10:25 espie Exp $
+$OpenBSD: OpenBSD::PackingList.pod,v 1.3 2005/09/04 22:47:56 espie Exp $
=head1 NAME
@@ -33,6 +33,10 @@ OpenBSD::PackingList - C<pkg_add(1)> packing-list manipulations
# processing packing-lists
$p4->visit('method', @args);
+ # signatures
+ if ($p3->signature() eq $p4->signature()) {
+ }
+
=head1 DESCRIPTION
C<OpenBSD::PackingList> is the only supported interface for access to
@@ -78,6 +82,10 @@ read only dependency information.
read only the extra information field.
+=item UpdateInfoOnly
+
+read only what is needed to decide to update a package.
+
=back
A complete packing-list C<$plist> may be written to disk using the
@@ -109,3 +117,7 @@ to the packing-list (note that C<add_object> only makes sense for subclasses
of C<OpenBSD::PackingElement::Object>).
See L<OpenBSD::PackingElement> for more details.
+C<$plist-E<gt>pkgname()> retrieves a packing-list name (mandatory).
+C<$plist-E<gt>signature()> retrieves a packing-list full signature, composed
+of the package name and dependency information.
+