summaryrefslogtreecommitdiff
path: root/usr.sbin/pkg_add/OpenBSD
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2014-06-16 09:02:08 +0000
committerMarc Espie <espie@cvs.openbsd.org>2014-06-16 09:02:08 +0000
commit8a7a26bd77d3ab1d8bf5bf1faea13c3260e8dc76 (patch)
treeec7d823f935a027bc1adbbfb5e7fd6d0d9ed89ca /usr.sbin/pkg_add/OpenBSD
parent0699db7ba96eb6d1e9b8eab8e2910b1df24331eb (diff)
tweak extraction for out-of-order archives: do a first pass
where we register every actual file in the plist by its path relative to cwd. Note every meta info as extracted (for partial packages to make sense), then do a newer extract loop, where each archive member must match by path. That way, we can close archives early as soon as we've extracted every new file. To be used shortly by pkg_create. Note that new packages *won't* be extractible by the old tools.
Diffstat (limited to 'usr.sbin/pkg_add/OpenBSD')
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Add.pm77
1 files changed, 62 insertions, 15 deletions
diff --git a/usr.sbin/pkg_add/OpenBSD/Add.pm b/usr.sbin/pkg_add/OpenBSD/Add.pm
index 31f8d82b40d..ab1beb4a5ab 100644
--- a/usr.sbin/pkg_add/OpenBSD/Add.pm
+++ b/usr.sbin/pkg_add/OpenBSD/Add.pm
@@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
-# $OpenBSD: Add.pm,v 1.153 2014/05/20 05:55:43 espie Exp $
+# $OpenBSD: Add.pm,v 1.154 2014/06/16 09:02:07 espie Exp $
#
# Copyright (c) 2003-2014 Marc Espie <espie@openbsd.org>
#
@@ -113,7 +113,34 @@ sub perform_extraction
$state->{partial} = $handle->{partial};
$state->{archive} = $handle->{location};
$state->{check_digest} = $handle->{plist}{check_digest};
- $state->progress->visit_with_size($handle->{plist}, 'extract', $state);
+ my ($wanted, $tied) = {};
+ $handle->{plist}->find_extractible($state, $wanted, $tied);
+ my $p = $state->progress->new_sizer($handle->{plist}, $state);
+ while (my $file = $state->{archive}->next) {
+ my $e = $tied->{$file->name};
+ if (defined $e) {
+ delete $tied->{$file->name};
+ $e->prepare_to_extract($state, $file);
+ $state->{archive}->skip;
+ $p->advance($e);
+ # skip to next;
+ }
+ $e = $wanted->{$file->name};
+ if (!defined $e) {
+ $state->Fatal("archive member not found #1",
+ $file->name);
+ }
+ delete $wanted->{$file->name};
+ $e->prepare_to_extract($state, $file);
+ $e->extract($state, $file);
+ $p->advance($e);
+ if (keys %$wanted == 0) {
+ return;
+ }
+ }
+ if (keys %$wanted > 0) {
+ $state->fatal("Truncated archive");
+ }
}
my $user_tagged = {};
@@ -181,6 +208,10 @@ sub prepare_for_addition
{
}
+sub find_extractible
+{
+}
+
sub extract
{
my ($self, $state) = @_;
@@ -236,6 +267,16 @@ sub set_modes
}
}
+package OpenBSD::PackingElement::Meta;
+
+# XXX stuff that's invisible to find_extractible should be considered extracted
+# for the most part, otherwise we create broken partial packages
+sub find_extractible
+{
+ my ($self, $state, $wanted, $tied) = @_;
+ $state->{partial}{$self} = 1;
+}
+
package OpenBSD::PackingElement::ExtraInfo;
use OpenBSD::Error;
@@ -360,6 +401,18 @@ use File::Basename;
use File::Path;
use OpenBSD::Temp;
+sub find_extractible
+{
+ my ($self, $state, $wanted, $tied) = @_;
+ $wanted->{$self->name} = $self;
+ return;
+ if ($self->{tied} || $self->{link} || $self->{symlink}) {
+ $tied->{$self->name} = $self;
+ } else {
+ $wanted->{$self->name} = $self;
+ }
+}
+
sub prepare_for_addition
{
my ($self, $state, $pkgname) = @_;
@@ -384,19 +437,11 @@ sub prepare_for_addition
sub prepare_to_extract
{
- my ($self, $state) = @_;
+ my ($self, $state, $file) = @_;
my $fullname = $self->fullname;
my $destdir = $state->{destdir};
- my $file=$state->{archive}->next;
- if (!defined $file) {
- $state->fatal("truncated archive");
- }
$file->{cwd} = $self->cwd;
- if (!$file->check_name($self)) {
- $state->fatal("archive does not match #1 != #2",
- $file->name, $self->name);
- }
if (defined $self->{symlink} || $file->isSymLink) {
unless (defined $self->{symlink} && $file->isSymLink) {
$state->fatal("bogus symlink #1", $self->name);
@@ -427,14 +472,11 @@ sub prepare_to_extract
if (defined $self->{symlink} && $state->{do_faked}) {
$file->{linkname} = $destdir.$file->{linkname};
}
- return $file;
}
sub extract
{
- my ($self, $state) = @_;
-
- my $file = $self->prepare_to_extract($state);
+ my ($self, $state, $file) = @_;
if (defined $self->{link} || defined $self->{symlink}) {
$state->{archive}->skip;
@@ -483,6 +525,7 @@ sub extract
$state->say("extracting #1", $tempname) if $state->verbose >= 3;
+
if (!$file->isFile) {
$state->fatal("can't extract #1, it's not a file",
$self->stringize);
@@ -560,6 +603,10 @@ sub prepare_for_addition
}
}
+sub find_extractible
+{
+}
+
sub extract
{
}