summaryrefslogtreecommitdiff
path: root/usr.sbin/pkg_add
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/pkg_add')
-rw-r--r--usr.sbin/pkg_add/Makefile3
-rw-r--r--usr.sbin/pkg_add/OpenBSD/PackageName.pm219
-rw-r--r--usr.sbin/pkg_add/OpenBSD/PkgCfl.pm9
-rw-r--r--usr.sbin/pkg_add/OpenBSD/PkgSpec.pm220
-rw-r--r--usr.sbin/pkg_add/pkg6
-rw-r--r--usr.sbin/pkg_add/pkg_add21
6 files changed, 248 insertions, 230 deletions
diff --git a/usr.sbin/pkg_add/Makefile b/usr.sbin/pkg_add/Makefile
index 636b9898aa9..b5646251f4e 100644
--- a/usr.sbin/pkg_add/Makefile
+++ b/usr.sbin/pkg_add/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.10 2004/09/15 18:51:43 espie Exp $
+# $OpenBSD: Makefile,v 1.11 2004/10/11 09:44:06 espie Exp $
MAN=pkg_add.1 pkg_info.1 pkg_create.1 pkg_delete.1 pkg.1
@@ -15,6 +15,7 @@ PACKAGES= \
OpenBSD/PackingList.pm \
OpenBSD/PackingOld.pm \
OpenBSD/PkgCfl.pm \
+ OpenBSD/PkgSpec.pm \
OpenBSD/RequiredBy.pm \
OpenBSD/Temp.pm \
OpenBSD/Ustar.pm \
diff --git a/usr.sbin/pkg_add/OpenBSD/PackageName.pm b/usr.sbin/pkg_add/OpenBSD/PackageName.pm
index 9e180caca03..0447620ae00 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.5 2004/08/06 07:51:17 espie Exp $
+# $OpenBSD: PackageName.pm,v 1.6 2004/10/11 09:44:06 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -28,22 +28,6 @@ sub url2pkgname($)
return $name;
}
-sub new
-{
- my ($class, $name) = @_;
- my $self = { name => $name };
-# remove irrelevant filesystem info
- my $pkgname = url2pkgname($name);
- $self->{pkgname} = $pkgname;
-# cut pkgname into pieces
- my @list = splitname($pkgname);
- $self->{stem} = $list[0];
- $self->{version} = $list[1];
- $self->{flavors} = [];
- push @{$self->{flavors}}, @list[2,];
- bless $self, $class;
-}
-
# see package-specs(7)
sub splitname
{
@@ -58,6 +42,11 @@ sub splitname
}
}
+sub splitstem
+{
+ return (splitname $_[0])[0];
+}
+
sub is_stem
{
local $_ = shift;
@@ -73,7 +62,7 @@ sub findstem
my ($k, @list) = @_;
my @r = ();
for my $n (@list) {
- my $stem = (splitname $n)[0];
+ my $stem = splitstem($n);
if ($k eq $stem) {
push(@r, $n);
}
@@ -81,198 +70,4 @@ sub findstem
return @r;
}
-# all the shit that does handle package specifications
-sub compare_pseudo_numbers
-{
- my ($n, $m) = @_;
-
- my ($n1, $m1);
-
- if ($n =~ m/^\d+/) {
- $n1 = $&;
- $n = $';
- }
- if ($m =~ m/^\d+/) {
- $m1 = $&;
- $m = $';
- }
-
- if ($n1 == $m1) {
- return $n cmp $m;
- } else {
- return $n1 <=> $m1;
- }
-}
-
-
-sub dewey_compare
-{
- my ($a, $b) = @_;
- my ($pa, $pb);
-
- unless ($b =~ m/p\d+$/) { # does the Dewey hold a p<number> ?
- $a =~ s/p\d+$//; # No -> strip it from version.
- }
-
- return 0 if $a =~ /^$b$/; # bare equality
-
- if ($a =~ s/p(\d+)$//) { # extract patchlevels
- $pa = $1;
- }
- if ($b =~ s/p(\d+)$//) {
- $pb = $1;
- }
-
- my @a = split(/\./, $a);
- push @a, $pa if defined $pa; # ... and restore them
- my @b = split(/\\\./, $b);
- push @b, $pb if defined $pb;
- while (@a > 0 && @b > 0) {
- my $va = shift @a;
- my $vb = shift @b;
- next if $va eq $vb;
- return compare_pseudo_numbers($va, $vb);
- }
- if (@a > 0) {
- return 1;
- } else {
- return -1;
- }
-}
-
-sub check_version
-{
- my ($v, $spec) = @_;
- local $_;
-
- # any version spec
- return 1 if $spec eq '.*';
-
- my @specs = split(/,/, $spec);
- for (grep /^\d/, @specs) { # exact number: check match
- return 1 if $v =~ /^$_$/;
- return 1 if $v =~ /^${_}p\d+$/; # allows for recent patches
- }
-
- # Last chance: dewey specs ?
- my @deweys = grep !/^\d/, @specs;
- for (@deweys) {
- if (m/^\<\=|\>\=|\<|\>/) {
- my ($op, $dewey) = ($&, $');
- my $compare = dewey_compare($v, $dewey);
- return 0 if $op eq '<' && $compare >= 0;
- return 0 if $op eq '<=' && $compare > 0;
- return 0 if $op eq '>' && $compare <= 0;
- return 0 if $op eq '>=' && $compare < 0;
- } else {
- return 0; # unknown spec type
- }
- }
- return @deweys == 0 ? 0 : 1;
-}
-
-sub check_1flavor
-{
- my ($f, $spec) = @_;
- local $_;
-
- for (split /-/, $spec) {
- # must not be here
- if (m/^\!/) {
- return 0 if $f->{$'};
- # must be here
- } else {
- return 0 unless $f->{$_};
- }
- }
- return 1;
-}
-
-sub check_flavor
-{
- my ($f, $spec) = @_;
- local $_;
- # no flavor constraints
- return 1 if $spec eq '';
-
- $spec =~ s/^-//;
- # retrieve all flavors
- my %f = map +($_, 1), split /\-/, $f;
-
- # check each flavor constraint
- for (split /,/, $spec) {
- if (check_1flavor(\%f, $_)) {
- return 1;
- }
- }
- return 0;
-}
-
-sub subpattern_match
-{
- my ($p, $list) = @_;
- local $_;
-
- my ($stemspec, $vspec, $flavorspec);
-
-
- # then, guess at where the version number is if any,
-
- # this finds patterns like -<=2.3,>=3.4.p1-
- # the only constraint is that the actual number
- # - must start with a digit,
- # - not contain - or ,
- if ($p =~ m/\-((?:\>|\>\=|\<|\<\=)?\d[^-]*)/) {
- ($stemspec, $vspec, $flavorspec) = ($`, $1, $');
- # `any version' matcher
- } elsif ($p =~ m/\-\*/) {
- ($stemspec, $vspec, $flavorspec) = ($`, '*', $');
- # okay, so no version marker. Assume no flavor spec.
- } else {
- ($stemspec, $vspec, $flavorspec) = ($p, '', '');
- }
-
- $stemspec =~ s/\./\\\./g;
- $stemspec =~ s/\+/\\\+/g;
- $stemspec =~ s/\*/\.\*/g;
- $stemspec =~ s/\?/\./g;
- $vspec =~ s/\./\\\./g;
- $vspec =~ s/\+/\\\+/g;
- $vspec =~ s/\*/\.\*/g;
- $vspec =~ s/\?/\./g;
-
- $p = $stemspec;
- $p.="-.*" if $vspec ne '';
-
- # First trim down the list
- my @l = grep {/^$p$/} @$list;
-
- my @result = ();
- # Now, have to extract the version number, and the flavor...
- for (@l) {
- my ($stem, $v, $flavor);
- if (m/\-(\d[^-]*)/) {
- ($stem, $v, $flavor) = ($`, $1, $');
- if ($stem =~ m/^$stemspec$/ &&
- check_version($v, $vspec) &&
- check_flavor($flavor, $flavorspec)) {
- push(@result, $_);
- }
- }
- }
-
- return @result;
-}
-
-sub pkgspec_match
-{
- my ($pattern, @list) = @_;
- my @l = ();
-
- for my $subpattern (split /\|/, $pattern) {
- push(@l, subpattern_match($subpattern, \@list));
- }
- return @l;
-}
-
1;
diff --git a/usr.sbin/pkg_add/OpenBSD/PkgCfl.pm b/usr.sbin/pkg_add/OpenBSD/PkgCfl.pm
index dab2affb809..19b8792e4ac 100644
--- a/usr.sbin/pkg_add/OpenBSD/PkgCfl.pm
+++ b/usr.sbin/pkg_add/OpenBSD/PkgCfl.pm
@@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
-# $OpenBSD: PkgCfl.pm,v 1.6 2004/10/05 19:52:44 espie Exp $
+# $OpenBSD: PkgCfl.pm,v 1.7 2004/10/11 09:44:06 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -20,6 +20,7 @@ use warnings;
package OpenBSD::PkgCfl;
use OpenBSD::PackageName;
+use OpenBSD::PkgSpec;
sub glob2re
{
@@ -37,8 +38,8 @@ sub make_conflict_list($)
my $l = [];
unless (defined $plist->{'no-default-conflict'}) {
- my $stem = (OpenBSD::PackageName::splitname $plist->pkgname())[0];
- push(@$l, sub { OpenBSD::PackageName::pkgspec_match($stem."-*", @_); });
+ my $stem = OpenBSD::PackageName::splitstem($plist->pkgname());
+ push(@$l, sub { OpenBSD::PkgSpec::match($stem."-*", @_); });
}
if (defined $plist->{pkgcfl}) {
for my $cfl (@{$plist->{pkgcfl}}) {
@@ -48,7 +49,7 @@ sub make_conflict_list($)
}
if (defined $plist->{conflict}) {
for my $cfl (@{$plist->{conflict}}) {
- push(@$l, sub { OpenBSD::PackageName::pkgspec_match($cfl->{name}, @_); });
+ push(@$l, sub { OpenBSD::PkgSpec::match($cfl->{name}, @_); });
}
}
bless $l, $class;
diff --git a/usr.sbin/pkg_add/OpenBSD/PkgSpec.pm b/usr.sbin/pkg_add/OpenBSD/PkgSpec.pm
new file mode 100644
index 00000000000..574311f1bd2
--- /dev/null
+++ b/usr.sbin/pkg_add/OpenBSD/PkgSpec.pm
@@ -0,0 +1,220 @@
+# ex:ts=8 sw=4:
+# $OpenBSD: PkgSpec.pm,v 1.1 2004/10/11 09:44:06 espie Exp $
+#
+# Copyright (c) 2003-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
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use strict;
+use warnings;
+package OpenBSD::PkgSpec;
+
+# one useful function:
+# OpenBSD::PkgSpec::match($pattern, @list) -> @sublist
+# note that @sublist may contain duplicates
+
+# all the shit that does handle package specifications
+sub compare_pseudo_numbers
+{
+ my ($n, $m) = @_;
+
+ my ($n1, $m1);
+
+ if ($n =~ m/^\d+/) {
+ $n1 = $&;
+ $n = $';
+ }
+ if ($m =~ m/^\d+/) {
+ $m1 = $&;
+ $m = $';
+ }
+
+ if ($n1 == $m1) {
+ return $n cmp $m;
+ } else {
+ return $n1 <=> $m1;
+ }
+}
+
+
+sub dewey_compare
+{
+ my ($a, $b) = @_;
+ my ($pa, $pb);
+
+ unless ($b =~ m/p\d+$/) { # does the Dewey hold a p<number> ?
+ $a =~ s/p\d+$//; # No -> strip it from version.
+ }
+
+ return 0 if $a =~ /^$b$/; # bare equality
+
+ if ($a =~ s/p(\d+)$//) { # extract patchlevels
+ $pa = $1;
+ }
+ if ($b =~ s/p(\d+)$//) {
+ $pb = $1;
+ }
+
+ my @a = split(/\./, $a);
+ push @a, $pa if defined $pa; # ... and restore them
+ my @b = split(/\\\./, $b);
+ push @b, $pb if defined $pb;
+ while (@a > 0 && @b > 0) {
+ my $va = shift @a;
+ my $vb = shift @b;
+ next if $va eq $vb;
+ return compare_pseudo_numbers($va, $vb);
+ }
+ if (@a > 0) {
+ return 1;
+ } else {
+ return -1;
+ }
+}
+
+sub check_version
+{
+ my ($v, $spec) = @_;
+ local $_;
+
+ # any version spec
+ return 1 if $spec eq '.*';
+
+ my @specs = split(/,/, $spec);
+ for (grep /^\d/, @specs) { # exact number: check match
+ return 1 if $v =~ /^$_$/;
+ return 1 if $v =~ /^${_}p\d+$/; # allows for recent patches
+ }
+
+ # Last chance: dewey specs ?
+ my @deweys = grep !/^\d/, @specs;
+ for (@deweys) {
+ if (m/^\<\=|\>\=|\<|\>/) {
+ my ($op, $dewey) = ($&, $');
+ my $compare = dewey_compare($v, $dewey);
+ return 0 if $op eq '<' && $compare >= 0;
+ return 0 if $op eq '<=' && $compare > 0;
+ return 0 if $op eq '>' && $compare <= 0;
+ return 0 if $op eq '>=' && $compare < 0;
+ } else {
+ return 0; # unknown spec type
+ }
+ }
+ return @deweys == 0 ? 0 : 1;
+}
+
+sub check_1flavor
+{
+ my ($f, $spec) = @_;
+ local $_;
+
+ for (split /-/, $spec) {
+ # must not be here
+ if (m/^\!/) {
+ return 0 if $f->{$'};
+ # must be here
+ } else {
+ return 0 unless $f->{$_};
+ }
+ }
+ return 1;
+}
+
+sub check_flavor
+{
+ my ($f, $spec) = @_;
+ local $_;
+ # no flavor constraints
+ return 1 if $spec eq '';
+
+ $spec =~ s/^-//;
+ # retrieve all flavors
+ my %f = map +($_, 1), split /\-/, $f;
+
+ # check each flavor constraint
+ for (split /,/, $spec) {
+ if (check_1flavor(\%f, $_)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+sub subpattern_match
+{
+ my ($p, $list) = @_;
+ local $_;
+
+ my ($stemspec, $vspec, $flavorspec);
+
+
+ # then, guess at where the version number is if any,
+
+ # this finds patterns like -<=2.3,>=3.4.p1-
+ # the only constraint is that the actual number
+ # - must start with a digit,
+ # - not contain - or ,
+ if ($p =~ m/\-((?:\>|\>\=|\<|\<\=)?\d[^-]*)/) {
+ ($stemspec, $vspec, $flavorspec) = ($`, $1, $');
+ # `any version' matcher
+ } elsif ($p =~ m/\-\*/) {
+ ($stemspec, $vspec, $flavorspec) = ($`, '*', $');
+ # okay, so no version marker. Assume no flavor spec.
+ } else {
+ ($stemspec, $vspec, $flavorspec) = ($p, '', '');
+ }
+
+ $stemspec =~ s/\./\\\./g;
+ $stemspec =~ s/\+/\\\+/g;
+ $stemspec =~ s/\*/\.\*/g;
+ $stemspec =~ s/\?/\./g;
+ $vspec =~ s/\./\\\./g;
+ $vspec =~ s/\+/\\\+/g;
+ $vspec =~ s/\*/\.\*/g;
+ $vspec =~ s/\?/\./g;
+
+ $p = $stemspec;
+ $p.="-.*" if $vspec ne '';
+
+ # First trim down the list
+ my @l = grep {/^$p$/} @$list;
+
+ my @result = ();
+ # Now, have to extract the version number, and the flavor...
+ for (@l) {
+ my ($stem, $v, $flavor);
+ if (m/\-(\d[^-]*)/) {
+ ($stem, $v, $flavor) = ($`, $1, $');
+ if ($stem =~ m/^$stemspec$/ &&
+ check_version($v, $vspec) &&
+ check_flavor($flavor, $flavorspec)) {
+ push(@result, $_);
+ }
+ }
+ }
+
+ return @result;
+}
+
+sub match
+{
+ my ($pattern, @list) = @_;
+ my @l = ();
+
+ for my $subpattern (split /\|/, $pattern) {
+ push(@l, subpattern_match($subpattern, \@list));
+ }
+ return @l;
+}
+
+1;
diff --git a/usr.sbin/pkg_add/pkg b/usr.sbin/pkg_add/pkg
index c6ba86c6816..e0a630b178b 100644
--- a/usr.sbin/pkg_add/pkg
+++ b/usr.sbin/pkg_add/pkg
@@ -1,6 +1,6 @@
#! /usr/bin/perl
# ex:ts=8 sw=4:
-# $OpenBSD: pkg,v 1.2 2004/08/06 07:51:17 espie Exp $
+# $OpenBSD: pkg,v 1.3 2004/10/11 09:44:06 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -23,11 +23,11 @@ use Getopt::Std;
sub check_dependencies($)
{
eval {
- require OpenBSD::PackageName;
+ require OpenBSD::PkgSpec;
require OpenBSD::PackageInfo;
};
my $dependency = shift;
- my @m = OpenBSD::PackageName::pkgspec_match($dependency,
+ my @m = OpenBSD::PkgSpec::match($dependency,
OpenBSD::PackageInfo::installed_packages());
return (@m != 0) ? 1 : 0;
}
diff --git a/usr.sbin/pkg_add/pkg_add b/usr.sbin/pkg_add/pkg_add
index abc2efa0c82..d62c094b66f 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.62 2004/10/11 09:13:20 espie Exp $
+# $OpenBSD: pkg_add,v 1.63 2004/10/11 09:44:06 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -25,6 +25,7 @@ use OpenBSD::PackageInfo;
use OpenBSD::PackageLocator;
use OpenBSD::PackageName;
use OpenBSD::PkgCfl;
+use OpenBSD::PkgSpec;
use OpenBSD::Vstat;
use Getopt::Std;
use OpenBSD::Error;
@@ -396,8 +397,8 @@ sub pre_add($$)
if ($pkg ne '-') {
print "$operation $pkg\n";
- $pkgname1 = OpenBSD::PackageName->new($pkg);
- return undef unless can_install($pkgname1->{pkgname});
+ $pkgname1 = OpenBSD::PackageName::url2pkgname($pkg);
+ return undef unless can_install($pkgname1);
}
my $handle = OpenBSD::PackageLocator->find($pkg);
@@ -419,16 +420,16 @@ sub pre_add($$)
$errors++;
return undef;
}
- my $pkgname = OpenBSD::PackageName->new($plist->pkgname());
+ my $pkgname = $plist->pkgname();
if (defined $pkgname1) {
- if ($pkgname->{pkgname} ne $pkgname1->{pkgname}) {
+ if ($pkgname ne $pkgname1) {
print "Package name is not consistent ???\n";
$errors++;
return undef;
}
} else {
- print $operation, " ", $pkgname->{pkgname}, "\n";
- return undef unless can_install($pkgname->{pkgname});
+ print "$operation $pkgname\n";
+ return undef unless can_install($pkgname);
}
# second handling of conflicts
my $l = OpenBSD::PkgCfl->make_conflict_list($plist);
@@ -460,7 +461,7 @@ sub solve_dependencies
}
for my $dep (@{$plist->{newdepend}}, @{$plist->{libdepend}}) {
next if defined $dep->{name} and $dep->{name} ne $plist->pkgname();
- my @candidates = OpenBSD::PackageName::pkgspec_match($dep->{pattern}, installed_packages());
+ my @candidates = OpenBSD::PkgSpec::match($dep->{pattern}, installed_packages());
if (@candidates >= 1) {
push(@$to_register, $candidates[0]);
} else {
@@ -471,13 +472,13 @@ sub solve_dependencies
}
}
# try against list of packages to install
- my @candidates = OpenBSD::PackageName::pkgspec_match($dep->{pattern}, keys %{$to_install});
+ my @candidates = OpenBSD::PkgSpec::match($dep->{pattern}, keys %{$to_install});
if (@candidates >= 1) {
push(@deps, $to_install->{$candidates[0]});
push(@$to_register, $candidates[0]);
} else {
# try with list of packages
- my @candidates = OpenBSD::PackageName::pkgspec_match($dep->{pattern}, OpenBSD::PackageLocator::available());
+ my @candidates = OpenBSD::PkgSpec::match($dep->{pattern}, OpenBSD::PackageLocator::available());
# one single choice
if (@candidates == 1) {
push(@deps, $candidates[0]);