Most of the code was already there. This would allow pkg_add to auto-configure a mirror, for the case where PKG_PATH was not specified and where pkg.conf does not exist.
It only triggers when a location ends up empty and when run in interactive mode, e.g., it shouldn't interfere with local lookups. Good idea, or awful ? Index: OpenBSD/PackageLocator.pm =================================================================== RCS file: /cvs/src/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm,v retrieving revision 1.105 diff -u -p -r1.105 PackageLocator.pm --- OpenBSD/PackageLocator.pm 30 Jan 2016 11:29:29 -0000 1.105 +++ OpenBSD/PackageLocator.pm 22 Jun 2016 13:51:40 -0000 @@ -24,6 +24,7 @@ use OpenBSD::PackageRepositoryList; use OpenBSD::PackageRepository; my $default_path; +my $is_configured; sub build_default_path { @@ -37,17 +38,91 @@ sub build_default_path while (my $o = OpenBSD::PackageRepository->parse(\$v, $state)) { $default_path->add($o); } + $is_configured = 1; return; } $default_path->add(OpenBSD::PackageRepository->new("./", $state)->can_be_empty); - return if $state->defines('NOINSTALLPATH'); + if ($state->defines('NOINSTALLPATH')) { + $is_configured = 1; + return; + } return unless defined $state->config->value('installpath'); + $is_configured = 1; for my $i ($state->config->value("installpath")) { $default_path->add(OpenBSD::PackageRepository->new($i, $state)); } } +sub discover_mirror +{ + my ($self, $state) = @_; + + # can't ask the user -> no mirror + return undef unless $state->is_interactive; + + + require OpenBSD::PackageRepository; + my $fake = OpenBSD::PackageRepository->new("http://129.128.5.191/cgi-bin/", $state); + # XXX + bless $fake, "OpenBSD::PackageRepository::Cgi"; + my $l = $fake->list; + my @m = @$l; + my %h; + for my $d (@m) { + my $e = $d; + $d =~ s,^http://(.*?)(/.*?)?\s+(.*)$,$1\t$3,; + $e =~ s/\s+.*$//; + $h{$d} = $e; + } + $m[0] = "<None>"; + my $i = $state->ask_list("No mirror configured, choose one", @m); + if ($i eq "<None>") { + return undef; + } + return $h{$i}; +} + +sub convert_to_packages +{ + my ($self, $url) = @_; + # mirror was "designed" for base releases. + # convert into short installpath version + $url =~ s,^http://(.*)/pub/OpenBSD$,$1, or + $url =~ s,$,/%c/packages/%a,; + return $url; +} + +sub last_chance +{ + if ($is_configured) { + return []; + } + $is_configured = 1; + my ($self, @search) = @_; + my $state = pop @search; + + my $url = $self->discover_mirror($state); + if (!defined $url) { + return []; + } + + $url = $self->convert_to_packages($url); + + # try setting it "permanently" + if (open(my $f, ">>", OpenBSD::Paths->pkgconf)) { + print $f "installpath += $url\n"; + close $f; + } else { + $state->errsay("Couldn't write to #1", OpenBSD::Paths->pkgconf); + } + + # use it for the current round anyway + $default_path->add(OpenBSD::PackageRepository->new($url, $state)); + + return $self->match_locations(@search, $state); +} + sub default_path { if (!defined $default_path) { @@ -107,4 +182,27 @@ sub match_locations return $self->default_path($state)->match_locations(@search); } +package OpenBSD::PackageRepository::Cgi; +our @ISA = qw(OpenBSD::PackageRepository::HTTP); + +# we know how to get a list, we just need to override the specific url +# and parser +sub get_http_list +{ + my ($self, $error) = @_; + + require OpenBSD::Paths; + my $fullname = $self->url."ftplist.cgi?path=".OpenBSD::Paths->os_directory."/".OpenBSD::Paths->machine_architecture; + my $l = []; + my $fh = $self->open_read_ftp(OpenBSD::Paths->ftp." -o - $fullname", + $error) or return; + while(<$fh>) { + chomp; + if (m/^http:\/\//) { + push(@$l, $_); + } + } + $self->close_read_ftp($fh); + return $l; +} 1; Index: OpenBSD/PackageRepositoryList.pm =================================================================== RCS file: /cvs/src/usr.sbin/pkg_add/OpenBSD/PackageRepositoryList.pm,v retrieving revision 1.30 diff -u -p -r1.30 PackageRepositoryList.pm --- OpenBSD/PackageRepositoryList.pm 9 Jul 2015 12:57:55 -0000 1.30 +++ OpenBSD/PackageRepositoryList.pm 22 Jun 2016 13:51:40 -0000 @@ -86,7 +86,7 @@ sub match_locations return $l; } } - return []; + return $self->{state}->repo->last_chance(@search); } 1; Index: OpenBSD/State.pm =================================================================== RCS file: /cvs/src/usr.sbin/pkg_add/OpenBSD/State.pm,v retrieving revision 1.34 diff -u -p -r1.34 State.pm --- OpenBSD/State.pm 6 Apr 2015 11:07:24 -0000 1.34 +++ OpenBSD/State.pm 22 Jun 2016 13:51:40 -0000 @@ -137,6 +137,14 @@ sub match_locations return OpenBSD::PackageLocator->match_locations(@_, $self->{state}); } +sub last_chance +{ + my $self = shift; + require OpenBSD::PackageLocator; + + return OpenBSD::PackageLocator->last_chance(@_, $self->{state}); +} + sub grabPlist { my ($self, $url, $code) = @_; @@ -340,6 +348,11 @@ sub handle_options } local $Exporter::ExportLevel = $state->{export_level}; import OpenBSD::State; +} + +sub is_interactive +{ + return 0; } sub defines