diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2014-06-16 09:02:08 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2014-06-16 09:02:08 +0000 |
commit | 8a7a26bd77d3ab1d8bf5bf1faea13c3260e8dc76 (patch) | |
tree | ec7d823f935a027bc1adbbfb5e7fd6d0d9ed89ca /usr.sbin/pkg_add/OpenBSD | |
parent | 0699db7ba96eb6d1e9b8eab8e2910b1df24331eb (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.pm | 77 |
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 { } |