diff options
Diffstat (limited to 'usr.sbin/pkg_add')
-rw-r--r-- | usr.sbin/pkg_add/Makefile | 3 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PackageName.pm | 219 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PkgCfl.pm | 9 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PkgSpec.pm | 220 | ||||
-rw-r--r-- | usr.sbin/pkg_add/pkg | 6 | ||||
-rw-r--r-- | usr.sbin/pkg_add/pkg_add | 21 |
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]); |