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