summaryrefslogtreecommitdiff
path: root/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2006-03-04 13:13:06 +0000
committerMarc Espie <espie@cvs.openbsd.org>2006-03-04 13:13:06 +0000
commit2671c587bc640f9caf86a61f5d0a8a8cca0eb5ca (patch)
tree90d97a87055042fa85bcae27bbf04bace8edbca4 /usr.sbin/pkg_add/OpenBSD/PackageLocator.pm
parent54f12c977cbe82c0a95b797c6c9971492a8e3df7 (diff)
cut down the Locator code into maintainable chunks.
Diffstat (limited to 'usr.sbin/pkg_add/OpenBSD/PackageLocator.pm')
-rw-r--r--usr.sbin/pkg_add/OpenBSD/PackageLocator.pm1011
1 files changed, 4 insertions, 1007 deletions
diff --git a/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm b/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm
index 1ad3fbd537f..496e1e6d9c0 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.51 2006/03/04 11:28:03 espie Exp $
+# $OpenBSD: PackageLocator.pm,v 1.52 2006/03/04 13:13:05 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -18,1014 +18,11 @@
use strict;
use warnings;
-package OpenBSD::PackageRepository;
-
-sub _new
-{
- my ($class, $address) = @_;
- bless { baseurl => $address }, $class;
-}
-
-sub new
-{
- my ($class, $baseurl) = @_;
- if ($baseurl =~ m/^ftp\:/i) {
- return OpenBSD::PackageRepository::FTP->_new($baseurl);
- } elsif ($baseurl =~ m/^http\:/i) {
- return OpenBSD::PackageRepository::HTTP->_new($baseurl);
- } elsif ($baseurl =~ m/^scp\:/i) {
- return OpenBSD::PackageRepository::SCP->_new($baseurl);
- } elsif ($baseurl =~ m/src\:/i) {
- return OpenBSD::PackageRepository::Source->_new($baseurl);
- } else {
- return OpenBSD::PackageRepository::Local->_new($baseurl);
- }
-}
-
-sub available
-{
- my $self = shift;
-
- return @{$self->list()};
-}
-
-sub wipe_info
-{
- my ($self, $pkg) = @_;
-
- require File::Path;
-
- my $dir = $pkg->{dir};
- if (defined $dir) {
-
- File::Path::rmtree($dir);
- delete $pkg->{dir};
- }
-}
-
-# by default, all objects may exist
-sub may_exist
-{
- return 1;
-}
-
-# by default, we don't track opened files for this key
-
-sub opened
-{
- undef;
-}
-
-# hint: 0 premature close, 1 real error. undef, normal !
-
-sub close
-{
- my ($self, $object, $hint) = @_;
- close($object->{fh}) if defined $object->{fh};
- $self->parse_problems($object->{errors}, $hint)
- if defined $object->{errors};
- undef $object->{errors};
- $object->deref();
-}
-
-sub finish_and_close
-{
- my ($self, $object) = @_;
- $self->close($object);
-}
-
-sub close_now
-{
- my ($self, $object) = @_;
- $self->close($object, 0);
-}
-
-sub close_after_error
-{
- my ($self, $object) = @_;
- $self->close($object, 1);
-}
-
-sub close_with_client_error
-{
- my ($self, $object) = @_;
- $self->close($object, 1);
-}
-
-sub make_room
-{
- my $self = shift;
-
- # kill old files if too many
- my $already = $self->opened();
- if (defined $already) {
- # gc old objects
- if (@$already >= $self->maxcount()) {
- @$already = grep { defined $_->{fh} } @$already;
- }
- while (@$already >= $self->maxcount()) {
- my $o = shift @$already;
- $self->close_now($o);
- }
- }
- return $already;
-}
-
-# open method that tracks opened files per-host.
-sub open
-{
- my ($self, $object) = @_;
-
- return undef unless $self->may_exist($object->{name});
-
- # kill old files if too many
- my $already = $self->make_room();
- my $fh = $self->open_pipe($object);
- if (!defined $fh) {
- return undef;
- }
- $object->{fh} = $fh;
- if (defined $already) {
- push @$already, $object;
- }
- return $fh;
-}
-
-sub find
-{
- my ($repository, $name, $arch, $srcpath) = @_;
- $name.=".tgz" unless $name =~ m/\.tgz$/;
- my $self = OpenBSD::PackageLocation->new($repository, $name);
-
- return $self->openPackage($name, $arch);
-}
-
-sub grabPlist
-{
- my ($repository, $name, $arch, $code) = @_;
- $name.=".tgz" unless $name =~ m/\.tgz$/;
- my $self = OpenBSD::PackageLocation->new($repository, $name);
-
- return $self->grabPlist($name, $arch, $code);
-}
-
-sub parse_problems
-{
- my ($self, $filename, $hint) = @_;
- CORE::open(my $fh, '<', $filename) or return;
-
- my $baseurl = $self->{baseurl};
- local $_;
- my $notyet = 1;
- while(<$fh>) {
- next if m/^(?:200|220|221|226|229|230|227|250|331|500|150)[\s\-]/;
- next if m/^EPSV command not understood/;
- next if m/^Trying [\da-f\.\:]+\.\.\./;
- next if m/^Requesting \Q$baseurl\E/;
- next if m/^Remote system type is\s+/;
- next if m/^Connected to\s+/;
- next if m/^remote\:\s+/;
- next if m/^Using binary mode to transfer files/;
- next if m/^Retrieving\s+/;
- next if m/^Succesfully retrieved file/;
- next if m/^\d+\s+bytes\s+received\s+in/;
- next if m/^ftp: connect to address.*: No route to host/;
-
- if (defined $hint && $hint == 0) {
- next if m/^ftp: -: short write/;
- next if m/^421\s+/;
- }
- if ($notyet) {
- print STDERR "Error from $baseurl:\n" if $notyet;
- $notyet = 0;
- }
- if (m/^421\s+/ ||
- m/^ftp: connect: Connection timed out/ ||
- m/^ftp: Can't connect or login to host/) {
- $self->{lasterror} = 421;
- }
- if (m/^550\s+/) {
- $self->{lasterror} = 550;
- }
- print STDERR $_;
- }
- CORE::close($fh);
- unlink $filename;
-}
-
-package OpenBSD::PackageRepository::Installed;
-our @ISA=qw(OpenBSD::PackageRepository);
-use OpenBSD::PackageInfo;
-
-sub new
-{
- bless {}, shift;
-}
-
-sub find
-{
- my ($repository, $name, $arch, $srcpath) = @_;
- my $self;
-
- if (is_installed($name)) {
- $self = OpenBSD::PackageLocation->new($repository, $name);
- $self->{dir} = installed_info($name);
- }
- return $self;
-}
-
-sub grabPlist
-{
- my ($repository, $name, $arch, $code) = @_;
- require OpenBSD::PackingList;
- return OpenBSD::PackingList->from_installation($name, $code);
-}
-
-sub available
-{
- return installed_packages();
-}
-
-sub list
-{
- my @list = installed_packages();
- return \@list;
-}
-
-sub wipe_info
-{
-}
-
-sub may_exist
-{
- my ($self, $name) = @_;
- return is_installed($name);
-}
-
-package PackageRepository::Source;
-
-sub find
-{
- my ($repository, $name, $arch, $srcpath) = @_;
- my $dir;
- my $make;
- if (defined $ENV{'MAKE'}) {
- $make = $ENV{'MAKE'};
- } else {
- $make = '/usr/bin/make';
- }
- if (defined $repository->{baseurl} && $repository->{baseurl} ne '') {
- $dir = $repository->{baseurl}
- } elsif (defined $ENV{PORTSDIR}) {
- $dir = $ENV{PORTSDIR};
- } else {
- $dir = '/usr/ports';
- }
- # figure out the repository name and the pkgname
- my $pkgfile = `cd $dir && SUBDIR=$srcpath ECHO_MSG=: $make show=PKGFILE`;
- chomp $pkgfile;
- if (! -f $pkgfile) {
- system "cd $dir && SUBDIR=$srcpath $make package BULK=Yes";
- }
- if (! -f $pkgfile) {
- return undef;
- }
- $pkgfile =~ m|(.*/)([^/]*)|;
- my ($base, $fname) = ($1, $2);
-
- my $repo = OpenBSD::PackageRepository::Local->_new($base);
- return $repo->find($fname);
-}
-
-package OpenBSD::PackageRepository::Local;
-our @ISA=qw(OpenBSD::PackageRepository);
-
-sub open_pipe
-{
- my ($self, $object) = @_;
- my $pid = open(my $fh, "-|");
- if (!defined $pid) {
- die "Cannot fork: $!";
- }
- if ($pid) {
- return $fh;
- } else {
- open STDERR, ">/dev/null";
- exec {"/usr/bin/gzip"}
- "gzip",
- "-d",
- "-c",
- "-q",
- "-f",
- $self->{baseurl}.$object->{name}
- or die "Can't run gzip";
- }
-}
-
-sub may_exist
-{
- my ($self, $name) = @_;
- return -r $self->{baseurl}.$name;
-}
-
-sub list
-{
- my $self = shift;
- my $l = [];
- my $dname = $self->{baseurl};
- opendir(my $dir, $dname) or return $l;
- while (my $e = readdir $dir) {
- next unless $e =~ m/\.tgz$/;
- next unless -f "$dname/$e";
- push(@$l, $`);
- }
- close($dir);
- return $l;
-}
-
-package OpenBSD::PackageRepository::Local::Pipe;
-our @ISA=qw(OpenBSD::PackageRepository::Local);
-
-sub may_exist
-{
- return 1;
-}
-
-sub open_pipe
-{
- my ($self, $object) = @_;
- my $fullname = $self->{baseurl}.$object->{name};
- my $pid = open(my $fh, "-|");
- if (!defined $pid) {
- die "Cannot fork: $!";
- }
- if ($pid) {
- return $fh;
- } else {
- open STDERR, ">/dev/null";
- exec {"/usr/bin/gzip"}
- "gzip",
- "-d",
- "-c",
- "-q",
- "-f",
- "-"
- or die "can't run gzip";
- }
-}
-
-package OpenBSD::PackageRepository::Distant;
-our @ISA=qw(OpenBSD::PackageRepository);
-
-my $buffsize = 2 * 1024 * 1024;
-
-sub pkg_copy
-{
- my ($in, $dir, $name) = @_;
-
- require File::Temp;
- my $template = $name;
- $template =~ s/\.tgz$/.XXXXXXXX/;
-
- my ($copy, $filename) = File::Temp::tempfile($template,
- DIR => $dir) or die "Can't write copy to cache";
- chmod 0644, $filename;
- my $handler = sub {
- my ($sig) = @_;
- unlink $filename;
- $SIG{$sig} = 'DEFAULT';
- kill $sig, $$;
- };
-
- my $nonempty = 0;
- {
-
- local $SIG{'PIPE'} = $handler;
- local $SIG{'INT'} = $handler;
- local $SIG{'HUP'} = $handler;
- local $SIG{'QUIT'} = $handler;
- local $SIG{'KILL'} = $handler;
- local $SIG{'TERM'} = $handler;
-
- my ($buffer, $n);
- # copy stuff over
- do {
- $n = sysread($in, $buffer, $buffsize);
- if (!defined $n) {
- die "Error reading\n";
- }
- if ($n > 0) {
- $nonempty = 1;
- }
- syswrite $copy, $buffer;
- syswrite STDOUT, $buffer;
- } while ($n != 0);
- close($copy);
- }
-
- if ($nonempty) {
- rename $filename, "$dir/$name";
- } else {
- unlink $filename;
- }
-}
-
-sub open_pipe
-{
- require OpenBSD::Temp;
-
- my ($self, $object) = @_;
- $object->{errors} = OpenBSD::Temp::file();
- $object->{cache_dir} = $ENV{'PKG_CACHE'};
- my $pid = open(my $fh, "-|");
- if (!defined $pid) {
- die "Cannot fork: $!";
- }
- if ($pid) {
- $object->{pid} = $pid;
- return $fh;
- } else {
- open STDERR, '>', $object->{errors};
-
- my $pid2 = open(STDIN, "-|");
-
- if (!defined $pid2) {
- die "Cannot fork: $!";
- }
- if ($pid2) {
- exec {"/usr/bin/gzip"}
- "gzip",
- "-d",
- "-c",
- "-q",
- "-"
- or die "can't run gzip";
- } else {
- if (defined $object->{cache_dir}) {
- my $pid3 = open(my $in, "-|");
- if (!defined $pid3) {
- die "Cannot fork: $!";
- }
- if ($pid3) {
- pkg_copy($in, $object->{cache_dir},
- $object->{name});
- exit(0);
- } else {
- $self->grab_object($object);
- }
- } else {
- $self->grab_object($object);
- }
- }
- }
-}
-
-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;
-}
-
-sub finish_and_close
-{
- my ($self, $object) = @_;
- if (defined $object->{cache_dir}) {
- while (defined $object->intNext()) {
- }
- }
- $self->SUPER::finish_and_close($object);
-}
-
-package OpenBSD::PackageRepository::SCP;
-our @ISA=qw(OpenBSD::PackageRepository::Distant);
-
-
-sub grab_object
-{
- my ($self, $object) = @_;
-
- exec {"/usr/bin/scp"}
- "scp",
- $self->{host}.":".$self->{path}.$object->{name},
- "/dev/stdout"
- or die "can't run scp";
-}
-
-our %distant = ();
-
-sub maxcount
-{
- return 2;
-}
-
-sub opened
-{
- my $self = $_[0];
- my $k = $self->{key};
- if (!defined $distant{$k}) {
- $distant{$k} = [];
- }
- return $distant{$k};
-}
-
-sub _new
-{
- my ($class, $baseurl) = @_;
- $baseurl =~ s/scp\:\/\///i;
- $baseurl =~ m/\//;
- bless { host => $`, key => $`, path => "/$'" }, $class;
-}
-
-sub list
-{
- my ($self) = @_;
- 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::PackageRepository::HTTPorFTP;
-our @ISA=qw(OpenBSD::PackageRepository::Distant);
-
-our %distant = ();
-
-
-sub grab_object
-{
- my ($self, $object) = @_;
- my $ftp = defined $ENV{'FETCH_CMD'} ? $ENV{'FETCH_CMD'} : "/usr/bin/ftp";
- exec {$ftp}
- "ftp",
- "-o",
- "-", $self->{baseurl}.$object->{name}
- or die "can't run ftp";
-}
-
-sub maxcount
-{
- return 1;
-}
-
-sub opened
-{
- my $self = $_[0];
- my $k = $self->{key};
- if (!defined $distant{$k}) {
- $distant{$k} = [];
- }
- return $distant{$k};
-}
-
-sub _new
-{
- my ($class, $baseurl) = @_;
- my $distant_host;
- if ($baseurl =~ m/^(http|ftp)\:\/\/(.*?)\//i) {
- $distant_host = $&;
- }
- bless { baseurl => $baseurl, key => $distant_host }, $class;
-}
-
-
-package OpenBSD::PackageRepository::HTTP;
-our @ISA=qw(OpenBSD::PackageRepository::HTTPorFTP);
-
-sub list
-{
- my ($self) = @_;
- if (!defined $self->{list}) {
- my $error = OpenBSD::Temp::file();
- $self->make_room();
- my $fullname = $self->{baseurl};
- my $l = $self->{list} = [];
- local $_;
- open(my $fh, '-|', "ftp -o - $fullname 2>$error") 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);
- $self->parse_problems($error);
- }
- return $self->{list};
-}
-
-package OpenBSD::PackageRepository::FTP;
-our @ISA=qw(OpenBSD::PackageRepository::HTTPorFTP);
-
-
-sub list
-{
- my ($self) = @_;
- if (!defined $self->{list}) {
- require OpenBSD::Temp;
-
- my $error = OpenBSD::Temp::file();
- $self->make_room();
- my $fullname = $self->{baseurl};
- $self->{list} = $self->_list("echo 'nlist *.tgz'|ftp -o - $fullname 2>$error");
- $self->parse_problems($error);
- }
- return $self->{list};
-}
-
-package OpenBSD::PackageLocation;
-
-use OpenBSD::PackageInfo;
-use OpenBSD::Temp;
-
-sub new
-{
- my ($class, $repository, $name) = @_;
- my $self = { repository => $repository, name => $name};
- bless $self, $class;
-}
-
-sub openArchive
-{
- my $self = shift;
-
- my $fh = $self->{repository}->open($self);
- if (!defined $fh) {
- $self->{repository}->parse_problems($self->{errors})
- if defined $self->{errors};
- undef $self->{errors};
- return undef;
- }
- require OpenBSD::Ustar;
-
- my $archive = new OpenBSD::Ustar $fh;
- $self->{_archive} = $archive;
-}
-
-sub grabInfoFiles
-{
- my $self = shift;
- my $dir = $self->{dir} = OpenBSD::Temp::dir();
-
- if (defined $self->{contents} && ! -f $dir.CONTENTS) {
- open my $fh, '>', $dir.CONTENTS or die "Permission denied";
- print $fh $self->{contents};
- close $fh;
- }
-
- while (my $e = $self->intNext()) {
- if ($e->isFile() && is_info_name($e->{name})) {
- $e->{name}=$dir.$e->{name};
- eval { $e->create(); };
- if ($@) {
- unlink($e->{name});
- $@ =~ s/\s+at.*//;
- print STDERR $@;
- return 0;
- }
- } else {
- $self->unput();
- last;
- }
- }
- return 1;
-}
-
-sub scanPackage
-{
- my $self = shift;
- while (my $e = $self->intNext()) {
- if ($e->isFile() && is_info_name($e->{name})) {
- if ($e->{name} eq CONTENTS && !defined $self->{dir}) {
- $self->{contents} = $e->contents();
- last;
- }
- if (!defined $self->{dir}) {
- $self->{dir} = OpenBSD::Temp::dir();
- }
- $e->{name}=$self->{dir}.$e->{name};
- eval { $e->create(); };
- if ($@) {
- unlink($e->{name});
- $@ =~ s/\s+at.*//;
- print STDERR $@;
- return 0;
- }
- } else {
- $self->unput();
- last;
- }
- }
- return 1;
-}
-
-sub grabPlist
-{
- my ($self, $pkgname, $arch, $code) = @_;
-
- my $pkg = $self->openPackage($pkgname, $arch);
- if (defined $pkg) {
- my $plist = $self->plist($code);
- $pkg->wipe_info();
- $pkg->close_now();
- return $plist;
- } else {
- return undef;
- }
-}
-
-sub openPackage
-{
- my ($self, $pkgname, $arch) = @_;
- if (!$self->openArchive()) {
- return undef;
- }
- $self->scanPackage();
-
- if (defined $self->{contents}) {
- return $self;
- }
-
- # maybe it's a fat package.
- while (my $e = $self->intNext()) {
- unless ($e->{name} =~ m/\/\+CONTENTS$/) {
- last;
- }
- my $prefix = $`;
- my $contents = $e->contents();
- require OpenBSD::PackingList;
-
- $pkgname =~ s/\.tgz$//;
-
- my $plist = OpenBSD::PackingList->fromfile(\$contents,
- \&OpenBSD::PackingList::FatOnly);
- next if defined $pkgname and $plist->pkgname() ne $pkgname;
- if ($plist->has('arch')) {
- if ($plist->{arch}->check($arch)) {
- $self->{filter} = $prefix;
- bless $self, "OpenBSD::FatPackageLocation";
- $self->{contents} = $contents;
- return $self;
- }
- }
- }
- # hopeless
- $self->close_with_client_error();
- $self->wipe_info();
- return undef;
-}
-
-sub wipe_info
-{
- my $self = shift;
- $self->{repository}->wipe_info($self);
-}
-
-sub info
-{
- my $self = shift;
- if (!defined $self->{dir}) {
- $self->grabInfoFiles();
- }
- return $self->{dir};
-}
-
-sub plist
-{
- my ($self, $code) = @_;
-
- require OpenBSD::PackingList;
-
- if (defined $self->{contents}) {
- my $value = $self->{contents};
- return OpenBSD::PackingList->fromfile(\$value, $code);
- } elsif (defined $self->{dir} && -f $self->{dir}.CONTENTS) {
- return OpenBSD::PackingList->fromfile($self->{dir}.CONTENTS,
- $code);
- }
- # hopeless
- $self->close_with_client_error();
-
- return undef;
-}
-
-sub close
-{
- my ($self, $hint) = @_;
- $self->{repository}->close($self, $hint);
-}
-
-sub finish_and_close
-{
- my $self = shift;
- $self->{repository}->finish_and_close($self);
-}
-
-sub close_now
-{
- my $self = shift;
- $self->{repository}->close_now($self);
-}
-
-sub close_after_error
-{
- my $self = shift;
- $self->{repository}->close_after_error($self);
-}
-
-sub close_with_client_error
-{
- my $self = shift;
- $self->{repository}->close_with_client_error($self);
-}
-
-sub deref
-{
- my $self = shift;
- $self->{fh} = undef;
- $self->{_archive} = undef;
-}
-
-sub reopen
-{
- my $self = shift;
- if (!$self->openArchive()) {
- return undef;
- }
- while (my $e = $self->{_archive}->next()) {
- if ($e->{name} eq $self->{_current}->{name}) {
- $self->{_current} = $e;
- return $self;
- }
- }
- return undef;
-}
-
-# proxy for archive operations
-sub next
-{
- my $self = shift;
-
- if (!defined $self->{dir}) {
- $self->grabInfoFiles();
- }
- return $self->intNext();
-}
-
-sub intNext
-{
- my $self = shift;
-
- if (!defined $self->{fh}) {
- if (!$self->reopen()) {
- return undef;
- }
- }
- if (!$self->{_unput}) {
- $self->{_current} = $self->getNext();
- }
- $self->{_unput} = 0;
- return $self->{_current};
-}
-
-sub unput
-{
- my $self = shift;
- $self->{_unput} = 1;
-}
-
-sub getNext
-{
- my $self = shift;
-
- return $self->{_archive}->next();
-}
-
-sub skip
-{
- my $self = shift;
- return $self->{_archive}->skip();
-}
-
-package OpenBSD::FatPackageLocation;
-our @ISA=qw(OpenBSD::PackageLocation);
-
-sub getNext
-{
- my $self = shift;
-
- my $e = $self->SUPER::getNext();
- if ($e->{name} =~ m/^(.*?)\/(.*)$/) {
- my ($beg, $name) = ($1, $2);
- if (index($beg, $self->{filter}) == -1) {
- return $self->next();
- }
- $e->{name} = $name;
- if ($e->isHardLink()) {
- $e->{linkname} =~ s/^(.*?)\///;
- }
- }
- return $e;
-}
-
-package OpenBSD::PackageRepositoryList;
-
-sub new
-{
- my $class = shift;
- return bless {list => [], avail => undef }, $class;
-}
-
-sub add
-{
- my $self = shift;
- push @{$self->{list}}, @_;
- if (@_ > 0) {
- $self->{avail} = undef;
- }
-}
-
-sub find
-{
- my ($self, $pkgname, $arch, $srcpath) = @_;
-
- for my $repo (@{$self->{list}}) {
- my $pkg;
-
- for (my $retry = 5; $retry < 60; $retry *= 2) {
- undef $repo->{lasterror};
- $pkg = $repo->find($pkgname, $arch, $srcpath);
- if (!defined $pkg && defined $repo->{lasterror} &&
- $repo->{lasterror} == 421 &&
- defined $self->{avail} &&
- $self->{avail}->{$pkgname} eq $repo) {
- print STDERR "Temporary error, sleeping $retry seconds\n";
- sleep($retry);
- } else {
- last;
- }
- }
- return $pkg if defined $pkg;
- }
- return undef;
-}
-
-sub grabPlist
-{
- my ($self, $pkgname, $arch, $code) = @_;
-
- for my $repo (@{$self->{list}}) {
- my $plist;
-
- for (my $retry = 5; $retry < 60; $retry *= 2) {
- undef $repo->{lasterror};
- $plist = $repo->grabPlist($pkgname, $arch, $code);
- if (!defined $plist && defined $repo->{lasterror} &&
- $repo->{lasterror} == 421 &&
- defined $self->{avail} &&
- $self->{avail}->{$pkgname} eq $repo) {
- print STDERR "Temporary error, sleeping $retry seconds\n";
- sleep($retry);
- } else {
- last;
- }
- }
- return $plist if defined $plist;
- }
- return undef;
-}
-
-sub available
-{
- my $self = shift;
-
- if (!defined $self->{avail}) {
- my $available_packages = {};
- foreach my $loc (reverse @{$self->{list}}) {
- foreach my $pkg (@{$loc->list()}) {
- $available_packages->{$pkg} = $loc;
- }
- }
- $self->{avail} = $available_packages;
- }
- return keys %{$self->{avail}};
-}
-
package OpenBSD::PackageLocator;
+use OpenBSD::PackageRepositoryList;
+use OpenBSD::PackageRepository;
+
# this returns an archive handle from an uninstalled package name, currently
# There is a cache available.