diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2003-10-16 17:43:35 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2003-10-16 17:43:35 +0000 |
commit | f590f7679f0eb9b733faf2b7287dc4c6f250cdac (patch) | |
tree | 0782149036d61c04d496ff0698bf4e86ff8cc633 /usr.sbin/pkg_add/OpenBSD | |
parent | b3fb36e241c10f88ff39c1fde2c2f0bfea706bea (diff) |
new import of my pkgtools, after a slight naming disagreement with the
Upper Management...
Diffstat (limited to 'usr.sbin/pkg_add/OpenBSD')
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PackageInfo.pm | 115 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PackageLocator.pm | 268 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PackageName.pm | 250 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PackingElement.pm | 542 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PackingList.pm | 142 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PkgCfl.pm | 68 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/RequiredBy.pm | 81 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/Temp.pm | 44 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/Ustar.pm | 278 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/md5.pm | 43 |
10 files changed, 1831 insertions, 0 deletions
diff --git a/usr.sbin/pkg_add/OpenBSD/PackageInfo.pm b/usr.sbin/pkg_add/OpenBSD/PackageInfo.pm new file mode 100644 index 00000000000..e562aa00450 --- /dev/null +++ b/usr.sbin/pkg_add/OpenBSD/PackageInfo.pm @@ -0,0 +1,115 @@ +# $OpenBSD: PackageInfo.pm,v 1.1 2003/10/16 17:43:34 espie Exp $ +# +# Copyright (c) 2003 Marc Espie. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD +# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use strict; +use warnings; +package OpenBSD::PackageInfo; +our @ISA=qw(Exporter); +our @EXPORT=qw(installed_packages installed_info info_names is_info_name + add_installed is_installed CONTENTS COMMENT DESC INSTALL DEINSTALL REQUIRE + REQUIRED_BY DISPLAY MTREE_DIRS); + +use OpenBSD::PackageName; +use constant { + CONTENTS => '+CONTENTS', + COMMENT => '+COMMENT', + DESC => '+DESC', + INSTALL => '+INSTALL', + DEINSTALL => '+DEINSTALL', + REQUIRE => '+REQUIRE', + REQUIRED_BY => '+REQUIRED_BY', + DISPLAY => '+DISPLAY', + MTREE_DIRS => '+MTREE_DIRS' }; + +my $pkg_db = $ENV{"PKG_DBDIR"} || '/var/db/pkg'; + +our @list; +my $read_list; + +our @info = (CONTENTS, COMMENT, DESC, INSTALL, DEINSTALL, REQUIRE, REQUIRED_BY, DISPLAY, MTREE_DIRS); + +our %info = (); +for my $i (@info) { + my $j = $i; + $j =~ s/\+/F/; + $info{$i} = $j; +} + +sub add_installed +{ + if (!$read_list) { + installed_packages(); + } + push(@list, @_); +} + +sub installed_packages() +{ + if (!$read_list) { + @list = (); + $read_list = 1; + + opendir(my $dir, $pkg_db) or die "Bad pkg_db"; + while (my $e = readdir($dir)) { + next if $e eq '.' or $e eq '..'; + next unless -d "$pkg_db/$e"; + if (-f "$pkg_db/$e/+CONTENTS") { + add_installed($e); + } else { + print "Warning: $e is not really a package"; + } + } + close($dir); + } + return @list; +} + +sub installed_info($) +{ + my $name = shift; + return "$pkg_db/$name/"; +} + +sub is_installed($) +{ + my $name = shift; + my $dir = installed_info($name); + return unless -d $dir; + return unless -f $dir.CONTENTS; + return $dir; +} + +sub info_names() +{ + return @info; +} + +sub is_info_name($) +{ + my $name = shift; + return $info{$name}; +} + +1; diff --git a/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm b/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm new file mode 100644 index 00000000000..c195d3ca289 --- /dev/null +++ b/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm @@ -0,0 +1,268 @@ +# $OpenBSD: PackageLocator.pm,v 1.1 2003/10/16 17:43:34 espie Exp $ +# +# Copyright (c) 2003 Marc Espie. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD +# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use strict; +use warnings; + +# XXX we don't want to load Ustar all the time +package OpenBSD::Ustar; + +our $AUTOLOAD; + +sub AUTOLOAD { + eval { require OpenBSD::Ustar; + }; + goto &$AUTOLOAD; +} + +package OpenBSD::PackageLocation; + +sub _new +{ + my ($class, $location) = @_; + bless { location => $location }, $class; +} + +sub new +{ + my ($class, $location) = @_; + if ($location =~ m/^ftp\:/i) { + return OpenBSD::PackageLocation::FTP->_new($location); + } elsif ($location =~ m/^http\:/i) { + return OpenBSD::PackageLocation::HTTP->_new($location); + } elsif ($location =~ m/^scp\:/i) { + return OpenBSD::PackageLocation::SCP->_new($location); + } else { + return OpenBSD::PackageLocation::Local->_new($location); + } +} + +package OpenBSD::PackageLocation::SCP; +our @ISA=qw(OpenBSD::PackageLocation OpenBSD::PackageLocation::FTPorSCP); + +sub _new +{ + my ($class, $location) = @_; + $location =~ s/scp\:\/\///i; + $location =~ m/\//; + bless { host => $`, path => "/$'" }, $class; +} + +sub open +{ + my ($self, $name) = @_; + my $host = $self->{host}; + my $path = $self->{path}; + open(my $fh, '-|', "scp $host:$path$name /dev/stdout 2> /dev/null|gzip -d -c -q - 2> /dev/null") or return undef; + return $fh; +} + +sub list +{ + my ($self) = @_; + my $host = $self->{host}; + my $path = $self->{path}; + return _list("ssh $host ls -l $path"); +} + +package OpenBSD::PackageLocation::Local; +our @ISA=qw(OpenBSD::PackageLocation); + +sub open +{ + my ($self, $name) = @_; + my $fullname = $self->{location}.$name; + open(my $fh, '-|', "gzip -d -c -q 2>/dev/null $fullname") or return undef; + return $fh; +} + +sub list +{ + my $self = shift; + my @l = (); + opendir(my $dir, $self->{location}) or return undef; + while (my $e = readdir $dir) { + next unless -f "$dir/$e"; + next unless $e = ~ m/\.tgz$/; + push(@l, $`); + } + close($dir); + return @l; +} + +package OpenBSD::PackageLocation::FTPorSCP; + +sub _list +{ + my ($self, $cmd) = @_; + 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); + } + close($fh); + return @l; +} + +package OpenBSD::PackageLocation::HTTPorFTP; +sub open +{ + my ($self, $name) = @_; + my $fullname = $self->{location}.$name; + open(my $fh, '-|', "ftp -o - $fullname 2>/dev/null|gzip -d -c -q - 2>/dev/null") or return undef; + return $fh; +} + +package OpenBSD::PackageLocation::HTTP; +our @ISA=qw(OpenBSD::PackageLocation::HTTPorFTP OpenBSD::PackageLocation); +sub list +{ + my ($self) = @_; + my $fullname = $self->{location}; + my @l =(); + local $_; + open(my $fh, '-|', "echo ls|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); + return @l; +} + +package OpenBSD::PackageLocation::FTP; +our @ISA=qw(OpenBSD::PackageLocation::HTTPorFTP OpenBSD::PackageLocation OpenBSD::PackageLocation::FTPorSCP); + +sub list +{ + my ($self) = @_; + my $fullname = $self->{location}; + return _list("echo ls|ftp -o - $fullname 2>/dev/null"); +} + + +package OpenBSD::PackageLocator; + +# this returns an archive handle from an uninstalled package name, currently +# There is a cache available. + +use OpenBSD::PackageInfo; +use OpenBSD::Temp; + +my %packages; +my @pkgpath; + +if (defined $ENV{PKG_PATH}) { + my @tentative = split /\:/, $ENV{PKG_PATH}; + @pkgpath = (); + while (my $i = shift @tentative) { + if ($i =~ m/^(?:ftp|http|scp)$/i) { + $i.= ":".(shift @tentative); + } + $i =~ m|/$| or $i.='/'; + unshift @pkgpath, OpenBSD::PackageLocation->new($i); + } +} + +sub find +{ + my $class = shift; + local $_ = shift; + $_.=".tgz" unless m/\.tgz$/; + if (exists $packages{$_}) { + return $packages{$_}; + } + my $package; + if (m/\//) { + my $location = OpenBSD::PackageLocation->new($_); + $package = openAbsolute($location, ''); + } else { + for my $p (@pkgpath) { + $package = openAbsolute($p, $_); + last if defined $package; + } + } + return $package unless defined $package; + $packages{$_} = $package; + bless $package, $class; +} + +sub info +{ + my $self = shift; + return $self->{dir}; +} + +sub close +{ + my $self = shift; + close($self->{fh}); + $self->{fh} = undef; + $self->{archive} = undef; +} + +sub openAbsolute +{ + my ($location, $name) = @_; + my $fh = $location->open($name); + if (!defined $fh) { + return undef; + } + my $archive = new OpenBSD::Ustar $fh; + my $dir = OpenBSD::Temp::dir(); + + my $self = { name => $_, fh => $fh, archive => $archive, dir => $dir }; + # check that Open worked + while (my $e = $archive->next()) { + if ($e->isFile() && is_info_name($e->{name})) { + $e->{name}=$dir.$e->{name}; + $e->create(); + } else { + $archive->unput(); + last; + } + } + if (-f $dir.CONTENTS) { + return $self; + } else { + CORE::close($fh); + return undef; + } +} + +# allows the autoloader to work correctly +sub DESTROY +{ +} + +1; diff --git a/usr.sbin/pkg_add/OpenBSD/PackageName.pm b/usr.sbin/pkg_add/OpenBSD/PackageName.pm new file mode 100644 index 00000000000..512a770b58d --- /dev/null +++ b/usr.sbin/pkg_add/OpenBSD/PackageName.pm @@ -0,0 +1,250 @@ +# $OpenBSD: PackageName.pm,v 1.1 2003/10/16 17:43:34 espie Exp $ +# +# Copyright (c) 2003 Marc Espie. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD +# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use strict; +use warnings; +package OpenBSD::PackageName; + +sub new +{ + my ($class, $name) = @_; + my $self = { name => $name }; +# remove irrelevant filesystem info + $name =~ s|.*/||; + $name =~ s|\.tgz||; + $self->{pkgname} = $name; +# cut pkgname into pieces + my @list = splitname($name); + $self->{stem} = $list[0]; + $self->{version} = $list[1]; + $self->{flavors} = []; + push @{$self->{flavors}}, @list[2,]; + bless $self, $class; +} + +# see package-specs(7) +sub splitname +{ + local $_ = shift; + if (/\-(?=\d)/) { + my $stem = $`; + my $rest = $'; + my @all = split /\-/, $rest; + return ($stem, @all); + } else { + return ($_); + } +} + +# 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); + + # first, handle special characters (shell -> perl) + $p =~ s/\./\\\./g; + $p =~ s/\+/\\\+/g; + $p =~ s/\*/\.\*/g; + $p =~ s/\?/\./g; + + # 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) = ($`, $1, $'); + # okay, so no version marker. Assume no flavor spec. + } else { + ($stemspec, $vspec, $flavorspec) = ($p, '', ''); + } + + $p = "$stemspec-\.\*" 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/PackingElement.pm b/usr.sbin/pkg_add/OpenBSD/PackingElement.pm new file mode 100644 index 00000000000..e30a917ef28 --- /dev/null +++ b/usr.sbin/pkg_add/OpenBSD/PackingElement.pm @@ -0,0 +1,542 @@ +# $OpenBSD: PackingElement.pm,v 1.1 2003/10/16 17:43:34 espie Exp $ +# +# Copyright (c) 2003 Marc Espie. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD +# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# This is the basic class, which is mostly abstract, except for +# setKeyword and Factory. +# It does provide base methods for stuff under it, though. + +use strict; +use warnings; +use OpenBSD::PackageInfo; +package OpenBSD::PackingElement; +use File::Basename; +our %keyword; + +sub Factory +{ + local $_ = shift; + if (m/^\@(\S+)\s*/) { + my $cmd = $1; + my $args = $'; + + if (defined $keyword{$cmd}) { + $keyword{$cmd}->add(@_, $args); + } else { + OpenBSD::PackingElement::Other->add(@_, "\@$cmd $args"); + } + } else { + OpenBSD::PackingElement::File->add(@_, $_); + } +} + +sub setKeyword { + my ($class, $k) = @_; + $keyword{$k} = $class; +} + +sub category() { 'items' } + +sub new +{ + my ($class, $args) = @_; + bless { name => $args }, $class; +} + +sub destate +{ +} + +sub add +{ + my ($class, $plist, @args) = @_; + + my $self = $class->new(@args); + $self->destate($plist->{state}); + $plist->add2list($self); + return $self; +} + +sub keyword() { return; } + +sub write +{ + my ($self, $fh) = @_; + print $fh "\@", $self->keyword()," ", $self->{name}, "\n"; +} + +sub compute_fullname +{ + my ($self, $state) = @_; + + $self->{cwd} = $state->{cwd}; + my $fullname = $self->{fullname} = + File::Spec->canonpath(File::Spec->catfile($state->{cwd}, $self->{name})); + $state->{lastfile} = $self; + return $fullname; +} + +sub expand +{ + my $state = $_[2]; + local $_ = $_[1]; + if (m/\%F/) { + die "Bad expand" unless defined $state->{lastfile}; + s/\%F/$state->{lastfile}->{name}/g; + } + if (m/\%D/) { + die "Bad expand" unless defined $state->{cwd}; + s/\%D/$state->{cwd}/g; + } + if (m/\%B/) { + die "Bad expand" unless defined $state->{lastfile}; + s/\%B/dirname($state->{lastfile}->fullname())/ge; + } + if (m/\%f/) { + die "Bad expand" unless defined $state->{lastfile}; + s/\%f/basename($state->{lastfile}->fullname())/ge; + } + return $_; +} +sub IsFile() { 0 } + +sub fullname($) +{ + return $_[0]->{fullname}; +} + +package OpenBSD::PackingElement::File; +our @ISA=qw(OpenBSD::PackingElement); +use File::Spec; +use OpenBSD::PackageInfo qw(is_info_name); +__PACKAGE__->setKeyword('file'); + +sub write +{ + my ($self, $fh) = @_; + print $fh "\@ignore\n" if defined $self->{ignore}; + if ($self->{name} =~ m/^\@/) { + $self->SUPER::write($fh); + } else { + print $fh $self->{name}, "\n"; + } + if (defined $self->{md5}) { + print $fh "\@comment MD5:", $self->{md5}, "\n"; + } +} + +sub destate +{ + my ($self, $state) = @_; + $self->compute_fullname($state); + if (defined $state->{mode}) { + $self->{mode} = $state->{mode}; + } + if (defined $state->{owner}) { + $self->{owner} = $state->{owner}; + } + if (defined $state->{group}) { + $self->{group} = $state->{group}; + } + if (defined $state->{nochecksum}) { + $self->{nochecksum} = 1; + undef $state->{nochecksum}; + } + if (defined $state->{ignore}) { + $self->{ignore} = 1; + undef $state->{ignore}; + } +} + +sub add +{ + my ($class, $plist, @args) = @_; + + my $self = $class->new(@args); + $self->destate($plist->{state}); + my $j = is_info_name($self->fullname()); + if ($j) { + bless $self, "OpenBSD::PackingElement::$j"; + $plist->addunique($self); + } else { + $plist->add2list($self); + } + return $self; +} + +sub add_md5 +{ + my ($self, $md5) = @_; + $self->{md5} = $md5; +} + +sub IsFile() { 1 } + +package OpenBSD::PackingElement::Other; +our @ISA=qw(OpenBSD::PackingElement); + +package OpenBSD::PackingElement::Ignore; +our @ISA=qw(OpenBSD::PackingElement); +__PACKAGE__->setKeyword('ignore'); + +sub add +{ + my ($class, $plist, @args) = @_; + $plist->{state}->{ignore} = 1; + return undef; +} + +# Comment is very special +package OpenBSD::PackingElement::Comment; +our @ISA=qw(OpenBSD::PackingElement); +__PACKAGE__->setKeyword('comment'); +sub keyword() { "comment" } + +sub add +{ + my ($class, $plist, @args) = @_; + + if ($args[0] =~ m/^MD5:\s*/) { + $plist->{state}->{lastfile}->add_md5($'); + return undef; + } elsif ($args[0] =~ m/^subdir\=(.*?)\s+cdrom\=(.*?)\s+ftp\=(.*?)\s*$/) { + OpenBSD::PackingElement::ExtraInfo->add($plist, $1, $2, $3); + } elsif ($args[0] eq 'no checksum') { + $plist->{state}->{nochecksum} = 1; + return undef; + } else { + my $self = $class->new(@args); + $self->destate($plist->{state}); + $plist->add2list($self); + return $self; + } +} + +package OpenBSD::PackingElement::Option; +our @ISA=qw(OpenBSD::PackingElement); +__PACKAGE__->setKeyword('option'); +sub keyword() { 'option' } + +sub add +{ + my ($class, $plist, @args) = @_; + if ($args[0] eq 'no-default-conflict') { + shift; + return OpenBSD::PackingElement::NoDefaultConflict->add(@_); + } else { + die "Unknown option: $args[0]"; + } +} + +package OpenBSD::PackingElement::NoDefaultConflict; +our @ISA=qw(OpenBSD::PackingElement::Unique); +sub category() { 'no-default-conflict' } +sub keyword() { 'option' } + +# The special elements that don't end in the right place +package OpenBSD::PackingElement::ExtraInfo; +our @ISA=qw(OpenBSD::PackingElement); + +sub category() { 'extrainfo' } + + +sub new +{ + my ($class, $subdir, $cdrom, $ftp) = @_; + bless { subdir => $subdir, cdrom => $cdrom, ftp => $ftp}, $class; +} + +sub add +{ + my ($class, $plist, @args) = @_; + my $self = $class->new(@args); + $plist->addunique($self); + return $self; +} + +sub write +{ + my ($self, $fh) = @_; + print $fh "\@comment subdir=", $self->{subdir}, + " cdrom=", $self->{cdrom}, + " ftp=", $self->{ftp}, "\n"; +} + +package OpenBSD::PackingElement::PkgDep; +our @ISA=qw(OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('pkgdep'); +sub keyword() { "pkgdep" } +sub category() { "pkgdep" } + +package OpenBSD::PackingElement::PkgConflict; +our @ISA=qw(OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('pkgcfl'); +sub keyword() { "pkgcfl" } +sub category() { "pkgcfl" } + + +package OpenBSD::PackingElement::NewDepend; + +our @ISA=qw(OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('newdepend'); +sub category() { "newdepend" } + +sub new +{ + my ($class, $args) = @_; + my ($name, $pattern, $def) = split /\:/, $args; + bless { name => $name, pattern => $pattern, def => $def }, $class; +} + +sub write +{ + my ($self, $fh) = @_; + print $fh "\@newdepend ", $self->{name}, ':', + $self->{pattern}, ':', $self->{def}, "\n"; +} + +package OpenBSD::PackingElement::LibDepend; + +our @ISA=qw(OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('libdepend'); +sub category() { "libdepend" } + +sub new +{ + my ($class, $args) = @_; + my ($name, $libspec, $pattern, $def) = split /\:/, $args; + bless { name => $name, libspec => $libspec, pattern => $pattern, + def => $def }, $class; +} + +sub write +{ + my ($self, $fh) = @_; + print $fh "\@libdepend ", $self->{name}, ':', + $self->{libspec}, ':', + $self->{pattern}, ':', $self->{def}, "\n"; +} + +package OpenBSD::PackingElement::Unique; +our @ISA=qw(OpenBSD::PackingElement); + +sub add +{ + my ($class, $plist, @args) = @_; + + my $self = $class->new(@args); + $self->destate($plist->{state}); + $plist->addunique($self); + return $self; +} + +package OpenBSD::PackingElement::Name; +use File::Spec; +our @ISA=qw(OpenBSD::PackingElement::Unique OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('name'); +sub keyword() { "name" } +sub category() { "name" } + +package OpenBSD::PackingElement::Cwd; +use File::Spec; +our @ISA=qw(OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('cwd'); + +sub keyword() { 'cwd' } + +sub destate +{ + my ($self, $state) = @_; + $state->{cwd} = $self->{name}; +} + +package OpenBSD::PackingElement::Owner; +our @ISA=qw(OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('owner'); +sub keyword() { 'owner' } + +sub destate +{ + my ($self, $state) = @_; + + if ($self->{name} eq '') { + undef $state->{owner}; + } else { + $state->{owner} = $self->{name}; + } +} + +package OpenBSD::PackingElement::Group; +our @ISA=qw(OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('group'); +sub keyword() { 'group' } + +sub destate +{ + my ($self, $state) = @_; + + if ($self->{name} eq '') { + undef $state->{group}; + } else { + $state->{group} = $self->{name}; + } +} + +package OpenBSD::PackingElement::Mode; +our @ISA=qw(OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('mode'); +sub keyword() { 'mode' } + +sub destate +{ + my ($self, $state) = @_; + + if ($self->{name} eq '') { + undef $state->{mode}; + } else { + $state->{mode} = $self->{name}; + } +} + +package OpenBSD::PackingElement::Exec; +our @ISA=qw(OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('exec'); + +sub keyword() { "exec" } + +sub destate +{ + my ($self, $state) = @_; + $self->{expanded} = $self->expand($self->{name}, $state); +} + +package OpenBSD::PackingElement::Unexec; +our @ISA=qw(OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('unexec'); +sub keyword() { "unexec" } + +sub destate +{ + my ($self, $state) = @_; + $self->{expanded} = $self->expand($self->{name}, $state); +} + +package OpenBSD::PackingElement::ExtraUnexec; +our @ISA=qw(OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('extraunexec'); +sub keyword() { "extraunexec" } + +sub destate +{ + my ($self, $state) = @_; + $self->{expanded} = $self->expand($self->{name}, $state); +} + +package OpenBSD::PackingElement::DirRm; +our @ISA=qw(OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('dirrm'); +sub keyword() { "dirrm" } + +sub destate +{ + my ($self, $state) = @_; + $self->compute_fullname($state); +} + +package OpenBSD::PackingElement::Extra; +our @ISA=qw(OpenBSD::PackingElement); + +__PACKAGE__->setKeyword('extra'); +sub keyword() { 'extra' } + +sub destate +{ + my ($self, $state) = @_; + $self->compute_fullname($state); +} + +package OpenBSD::PackingElement::SpecialFile; +our @ISA=qw(OpenBSD::PackingElement::Unique); + +sub add_md5 +{ + my ($self, $md5) = @_; + $self->{md5} = $md5; +} + +sub write +{ + &OpenBSD::PackingElement::File::write; +} + +package OpenBSD::PackingElement::FCONTENTS; +our @ISA=qw(OpenBSD::PackingElement::SpecialFile); +sub category() { OpenBSD::PackageInfo::CONTENTS } + +package OpenBSD::PackingElement::FCOMMENT; +our @ISA=qw(OpenBSD::PackingElement::SpecialFile); +sub category() { OpenBSD::PackageInfo::COMMENT } + +package OpenBSD::PackingElement::FDESC; +our @ISA=qw(OpenBSD::PackingElement::SpecialFile); +sub category() { OpenBSD::PackageInfo::DESC } + +package OpenBSD::PackingElement::FINSTALL; +our @ISA=qw(OpenBSD::PackingElement::SpecialFile); +sub category() { OpenBSD::PackageInfo::INSTALL } + +package OpenBSD::PackingElement::FDEINSTALL; +our @ISA=qw(OpenBSD::PackingElement::SpecialFile); +sub category() { OpenBSD::PackageInfo::DEINSTALL } + +package OpenBSD::PackingElement::FREQUIRE; +our @ISA=qw(OpenBSD::PackingElement::SpecialFile); +sub category() { OpenBSD::PackageInfo::REQUIRE } + +package OpenBSD::PackingElement::FREQUIRED_BY; +our @ISA=qw(OpenBSD::PackingElement::SpecialFile); +sub category() { OpenBSD::PackageInfo::REQUIRED_BY } + +package OpenBSD::PackingElement::FDISPLAY; +our @ISA=qw(OpenBSD::PackingElement::SpecialFile); +sub category() { OpenBSD::PackageInfo::DISPLAY } + +package OpenBSD::PackingElement::FMTREE_DIRS; +our @ISA=qw(OpenBSD::PackingElement::SpecialFile); +sub category() { OpenBSD::PackageInfo::MTREE_DIRS } + +1; diff --git a/usr.sbin/pkg_add/OpenBSD/PackingList.pm b/usr.sbin/pkg_add/OpenBSD/PackingList.pm new file mode 100644 index 00000000000..24b3786a6e9 --- /dev/null +++ b/usr.sbin/pkg_add/OpenBSD/PackingList.pm @@ -0,0 +1,142 @@ +# $OpenBSD: PackingList.pm,v 1.1 2003/10/16 17:43:34 espie Exp $ +# +# Copyright (c) 2003 Marc Espie. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD +# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use strict; +use warnings; +package OpenBSD::PackingList; + +use OpenBSD::PackingElement; +use OpenBSD::PackageInfo; + +sub new +{ + my $class = shift; + bless {state => + {default_owner=>'root', + default_group=>'bin', + default_mode=> 0444} }, $class; +} + +sub read +{ + my ($a, $fh, $code) = @_; + my $plist; + if (ref $a) { + $plist = $a; + } else { + $plist = new $a; + } + while (<$fh>) { + next if m/^\s*$/; + next if defined $code and !&$code; + chomp; + OpenBSD::PackingElement::Factory($_, $plist); + } + return $plist; +} + +sub OpenBSD::PackingList::DirrmOnly +{ + m/^\@cwd/ || m/^\@dirrm/ || m/^\@name/; +} + +sub OpenBSD::PackingList::FilesOnly +{ + m/^\@cwd/ || m/^\@name/ || !m/^\@/; +} + +sub OpenBSD::PackingList::ConflictOnly +{ + m/^\@pkgcfl/ || m/^\@option/ || m/^\@name/; +} + +sub write +{ + my ($self, $fh) = @_; + $self->{name}->write($fh); + if (defined $self->{'no-default-conflict'}) { + $self->{'no-default-conflict'}->write($fh); + } + $self->{extrainfo}->write($fh); + for my $listname (qw(pkgcfl pkgdep newdepend libdepend items)) { + if (defined $self->{$listname}) { + for my $item (@{$self->{$listname}}) { + $item->write($fh); + } + } + } + for my $special (OpenBSD::PackageInfo::info_names()) { + $self->{$special}->write($fh) if defined $self->{$special}; + } +} + +sub fromfile +{ + my ($a, $fname, $code) = @_; + open(my $fh, '<', $fname) or return undef; + my $plist = $a->read($fh, $code); + close($fh); + return $plist; +} + +sub tofile +{ + my ($self, $fname) = @_; + open(my $fh, '>', $fname) or return undef; + $self->write($fh); + close($fh) or return undef; + return 1; +} + +sub add2list +{ + my ($plist, $object) = @_; + my $category = $object->category(); + $plist->{$category} = [] unless defined $plist->{$category}; + push @{$plist->{$category}}, $object; +} + +sub addunique +{ + my ($plist, $object) = @_; + my $category = $object->category(); + if (defined $plist->{$category}) { + die "Duplicate $category in plist\n"; + } + $plist->{$category} = $object; +} + +sub pkgname($) +{ + my $self = shift; + return $self->{name}->{name}; +} + +# allows the autoloader to work correctly +sub DESTROY +{ +} + +1; diff --git a/usr.sbin/pkg_add/OpenBSD/PkgCfl.pm b/usr.sbin/pkg_add/OpenBSD/PkgCfl.pm new file mode 100644 index 00000000000..a101e635b0f --- /dev/null +++ b/usr.sbin/pkg_add/OpenBSD/PkgCfl.pm @@ -0,0 +1,68 @@ +# $OpenBSD: PkgCfl.pm,v 1.1 2003/10/16 17:43:34 espie Exp $ +# +# Copyright (c) 2003 Marc Espie. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD +# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use strict; +use warnings; +package OpenBSD::PkgCfl; + +sub glob2re +{ + local $_ = shift; + s/\./\\\./g; + s/\+/\\\+/g; + s/\*/\.\*/g; + s/\?/\./g; + return "^$_\$"; +} + +sub make_conflict_list($) +{ + my ($class, $plist) = @_; + my $l = []; + + unless (defined $plist->{'no-default-conflict'}) { + my $stem = (OpenBSD::PackageName::splitname$plist->pkgname())[0]; + push(@$l, "^\Q$stem\E-\\d.*\$"); + } + if (defined $plist->{pkgcfl}) { + for my $cfl (@{$plist->{pkgcfl}}) { + push(@$l, glob2re($cfl->{name})); + } + } + bless $l, $class; +} + +sub conflicts_with +{ + my ($self, @pkgnames) = @_; + for my $cfl (@$self) { + if (grep { m/$cfl/ } @pkgnames) { + return 1; + } + } + return 0; +} + +1; diff --git a/usr.sbin/pkg_add/OpenBSD/RequiredBy.pm b/usr.sbin/pkg_add/OpenBSD/RequiredBy.pm new file mode 100644 index 00000000000..0ac99cbd5f1 --- /dev/null +++ b/usr.sbin/pkg_add/OpenBSD/RequiredBy.pm @@ -0,0 +1,81 @@ +# ex:ts=8 sw=4: +# $OpenBSD: RequiredBy.pm,v 1.1 2003/10/16 17:43:34 espie Exp $ +# +# Copyright (c) 2003 Marc Espie. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD +# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package OpenBSD::RequiredBy; +use strict; +use warnings; +use OpenBSD::PackageInfo; + +sub new +{ + my ($class, $pkgname) = @_; + my $f = installed_info($pkgname).REQUIRED_BY; + bless \$f, $class; +} + +sub list($) +{ + my $self = shift; + + my $l = []; + return $l unless -f $$self; + open(my $fh, '<', $$self) or + die "Problem opening required list: $$self\n"; + local $_; + while(<$fh>) { + chomp $_; + s/\s+$//; + next if /^$/; + push(@$l, $_); + } + close($fh); + return $l; +} + +sub delete +{ + my ($self, $pkgname) = @_; + my @lines = grep { $_ ne $pkgname } @{$self->list()}; + unlink($$self) or die "Can't erase $$self"; + if (@lines > 0) { + $self->add(@lines); + } +} + +sub add +{ + my ($self, @pkgnames) = @_; + open(my $fh, '>>', $$self) or + die "Can't add dependencies to $$self"; + print $fh join("\n", @pkgnames), "\n"; + close($fh); +} + +sub DESTROY +{ +} + +1; diff --git a/usr.sbin/pkg_add/OpenBSD/Temp.pm b/usr.sbin/pkg_add/OpenBSD/Temp.pm new file mode 100644 index 00000000000..8acd7c6bda0 --- /dev/null +++ b/usr.sbin/pkg_add/OpenBSD/Temp.pm @@ -0,0 +1,44 @@ +use strict; +# $OpenBSD: Temp.pm,v 1.1 2003/10/16 17:43:34 espie Exp $ +# +# Copyright (c) 2003 Marc Espie. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD +# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use warnings; +package OpenBSD::Temp; + +use File::Temp; +my $tempbase = $ENV{'PKG_TMPDIR'} || '/var/tmp'; + +sub dir() +{ + return File::Temp::tempdir("pkginfo.XXXXXXXXXXX", DIR => $tempbase, + CLEANUP => 1).'/'; +} + +sub list($) +{ + return File::Temp::tempfile("list.XXXXXXXXXXX", DIR => shift); +} + +1; diff --git a/usr.sbin/pkg_add/OpenBSD/Ustar.pm b/usr.sbin/pkg_add/OpenBSD/Ustar.pm new file mode 100644 index 00000000000..59c0365e946 --- /dev/null +++ b/usr.sbin/pkg_add/OpenBSD/Ustar.pm @@ -0,0 +1,278 @@ +# $OpenBSD: Ustar.pm,v 1.1 2003/10/16 17:43:34 espie Exp $ +# +# Copyright (c) 2002 Marc Espie. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD +# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Handle utar archives + +# Prototype of new pkg* implementation, tar module. +# Interface is likely to change A LOT in the near future... + +use strict; +use warnings; +package OpenBSD::Ustar; +# helps autoloader +sub DESTROY +{ +} + +use constant FILE => "\0"; +use constant FILE1 => '0'; +use constant HARDLINK => '1'; +use constant SOFTLINK => '2'; +use constant CHARDEVICE => '3'; +use constant BLOCKDEVICE => '4'; +use constant DIR => '5'; +use constant FIFO => '6'; +use constant CONTFILE => '7'; +use File::Path (); +use File::Basename (); + +my $uidcache = {}; +my $gidcache = {}; +my $buffsize = 2 * 1024 * 1024; + +sub new +{ + my ($class, $fh) = @_; + + return bless { fh => $fh, swallow => 0, unput => 0} , $class; +} + + +sub name2uid +{ + my $name = shift; + return $uidcache->{$name} if defined $uidcache->{$name}; + my @entry = getpwnam($name); + if (@entry == 0) { + return $uidcache->{$name} = shift; + } else { + return $uidcache->{$name} = $entry[2]; + } +} + +sub name2gid +{ + my $name = shift; + return $gidcache->{$name} if defined $gidcache->{$name}; + my @entry = getgrnam($name); + if (@entry == 0) { + return $gidcache->{$name} = shift; + } else { + return $gidcache->{$name} = $entry[2]; + } +} + +sub skip +{ + my $self = shift; + return if $self->{swallow} == 0; + + my $temp; + while ($self->{swallow} > $buffsize) { + read($self->{fh}, $temp, $buffsize); + $self->{swallow} -= $buffsize; + } + read($self->{fh}, $temp, $self->{swallow}); + $self->{swallow} = 0; +} + +sub unput +{ + my $self = shift; + $self->{unput} = 1; +} + +sub next +{ + my $self = shift; + if ($self->{unput}) { + $self->{unput} = 0; + return $self->{current}; + } + # get rid of the current object + $self->skip(); + my $header; + my $n = read $self->{fh}, $header, 512; + return undef if $n == 0; + die "Error while reading header" + unless defined $n and $n == 512; + if ($header eq "\0"x512) { + return $self->next(); + } + # decode header + my ($name, $mode, $uid, $gid, $size, $mtime, $chksum, $type, + $linkname, $magic, $version, $uname, $gname, $major, $minor, + $prefix) = unpack('a100a8a8a8a12a12a8aa100a6a2a32a32a8a8a155', $header); + if ($magic ne "ustar\0" || $version ne '00') { + die "Not an ustar archive header"; + } + # verify checksum + my $value = $header; + substr($value, 148, 8) = " "x8; + my $ck2 = unpack("%C*", $value); + if ($ck2 != oct($chksum)) { + die "Bad archive checksum"; + } + $name =~ s/\0*$//; + $mode = oct($mode) & 0xfff; + $uname =~ s/\0*$//; + $gname =~ s/\0*$//; + $uid = oct($uid); + $gid = oct($gid); + $uid = name2uid($uname, $uid); + $gid = name2gid($uname, $gid); + $mtime = oct($mtime); + unless ($prefix =~ m/^\0/) { + $prefix =~ s/\0*$//; + $name = "$prefix/$name"; + } + + $size = oct($size); + my $result= { + name => $name, + mode => $mode, + mtime=> $mtime, + linkname=> $linkname, + uname => $uname, + uid => $uid, + gname => $gname, + gid => $gid, + size => $size, + archive => $self + }; + # adjust swallow + $self->{swallow} = $size; + if ($size % 512) { + $self->{swallow} += 512 - $size % 512; + } + if ($type eq DIR) { + bless $result, 'OpenBSD::Ustar::Dir'; + } elsif ($type eq HARDLINK) { + bless $result, 'OpenBSD::Ustar::HardLink'; + } elsif ($type eq SOFTLINK) { + bless $result, 'OpenBSD::Ustar::SoftLink'; + } elsif ($type eq FILE || $type eq FILE1) { + bless $result, 'OpenBSD::Ustar::File'; + } else { + die "Unsupported type"; + } + $self->{current} = $result; + return $result; +} + +package OpenBSD::Ustar::Object; +sub set_modes +{ + my $self = shift; + chmod $self->{mode}, $self->{name}; + chown $self->{uid}, $self->{gid}, $self->{name}; +} + +sub make_basedir +{ + my $self = shift; + my $dir = File::Basename::dirname($self->{name}); + File::Path::mkpath($dir) unless -d $dir; +} + +sub isDir() { 0 } +sub isFile() { 0 } +sub isLink() { 0 } +sub isSymLink() { 0 } +sub isHardLink() { 0 } + +package OpenBSD::Ustar::Dir; +our @ISA=qw(OpenBSD::Ustar::Object); + +sub create +{ + my $self = shift; + File::Path::mkpath($self->{name}); + $self->SUPER::set_modes(); +} + +sub isDir() { 1 } + +package OpenBSD::Ustar::HardLink; +our @ISA=qw(OpenBSD::Ustar::Object); + +sub create +{ + my $self = shift; + $self->make_basedir($self->{name}); + if (defined $self->{cwd}) { + link $self->{cwd}."/".$self->{linkname}, $self->{name}; + } else { + link $self->{linkname}, $self->{name}; + } +} + +sub isLink() { 1 } +sub isHardLink() { 1 } + +package OpenBSD::Ustar::SoftLink; +our @ISA=qw(OpenBSD::Ustar::Object); + +sub create +{ + my $self = shift; + $self->make_basedir($self->{name}); + symlink $self->{linkname}, $self->{name}; +} + +sub isLink() { 1 } +sub isHardLink() { 1 } + +package OpenBSD::Ustar::File; +our @ISA=qw(OpenBSD::Ustar::Object); + +use IO::File; + +sub create +{ + my $self = shift; + $self->make_basedir($self->{name}); + my $out = new IO::File $self->{name}, "w"; + if (!defined $out) { + print "Can't write to ", $self->{name}, "\n"; + return; + } + $self->SUPER::set_modes(); + my $buffer; + my $toread = $self->{size}; + while ($toread > 0) { + my $maxread = $buffsize; + $maxread = $toread if $maxread > $toread; + read($self->{archive}->{fh}, $buffer, $maxread); + $self->{archive}->{swallow} -= $maxread; + print $out $buffer; + $toread -= $maxread; + } + $out->close(); +} + +sub isFile() { 1 } + +1; diff --git a/usr.sbin/pkg_add/OpenBSD/md5.pm b/usr.sbin/pkg_add/OpenBSD/md5.pm new file mode 100644 index 00000000000..478d735e5b1 --- /dev/null +++ b/usr.sbin/pkg_add/OpenBSD/md5.pm @@ -0,0 +1,43 @@ +# $OpenBSD: md5.pm,v 1.1 2003/10/16 17:43:34 espie Exp $ +# +# Copyright (c) 2003 Marc Espie. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD +# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use strict; +use warnings; + +package OpenBSD::md5; +use Digest::MD5; + +sub fromfile +{ + my $fname = shift; + die "No such file: \"$fname\"\n" unless -f $fname; + open(my $file, '<', $fname) or return; + my $md5 = new Digest::MD5; + + $md5->addfile($file); + close($file); + return $md5->hexdigest(); +} +1; |