# ex:ts=8 sw=4:
-# $OpenBSD: Add.pm,v 1.190 2022/05/08 11:42:28 espie Exp $
+# $OpenBSD: Add.pm,v 1.191 2022/05/11 07:51:47 espie Exp $
#
# Copyright (c) 2003-2014 Marc Espie <espie@openbsd.org>
#
}
}
+sub skip_to_the_end
+{
+ my ($handle, $state, $tied, $p) = @_;
+ $state->tweak_header("skipping");
+ for my $e (values %$tied) {
+ $e->tie($state);
+ $p->advance($e);
+ }
+ if (keys %$tied > 0) {
+ # skipped entries should still be read in CACHE mode
+ if (defined $state->cache_directory) {
+ while (my $e = $state->{archive}->next) {
+ }
+ } else {
+ $handle->{location}{early_close} = 1;
+ }
+ }
+}
+
sub perform_extraction
{
my ($handle, $state) = @_;
$state->{partial} = $handle->{partial};
$state->{archive} = $handle->{location};
$state->{check_digest} = $handle->{plist}{check_digest};
+
+ # archives are actually stored out of order, find_extractible
+ # will dispatch the packing-list entries into hashes keyed by names.
+ # For "tied" entries, also see tie_files in OpenBSD::PkgAdd.
my ($wanted, $tied) = ({}, {});
$handle->{plist}->find_extractible($state, $wanted, $tied);
my $p = $state->progress->new_sizer($handle->{plist}, $state);
+
+ # so iterate over the archive, and "consume" hashes entry as we go
+ # it's necessary to delete them so that skip_to_the_end will work
+ # correctly (relies on wanted being empty to trigger, and requires
+ # tied to be correct for the progress meter).
while (my $file = $state->{archive}->next) {
if (keys %$wanted == 0) {
- $state->tweak_header("skipping");
- for my $e (values %$tied) {
- $e->tie($state);
- $p->advance($e);
- }
- if (keys %$tied > 0) {
- # skipped entries should still be read in CACHE mode
- if (defined $state->cache_directory) {
- while (my $e = $state->{archive}->next) {
- }
- } else {
- $handle->{location}{early_close} = 1;
- }
- }
+ skip_to_the_end($handle, $state, $tied, $p);
last;
}
my $e = $tied->{$file->name};
$file->name);
}
delete $wanted->{$file->name};
+ # note that readmes are only recorded when !tied, since
+ # we only care if they changed
my $fullname = $e->fullname;
if ($fullname =~ m,^$state->{localbase}/share/doc/pkg-readmes/,) {
push(@{$state->{readmes}}, $fullname);
- }
+ }
$e->prepare_to_extract($state, $file);
$e->extract($state, $file);
}
}
-# used by newuser/newgroup to deal with options.
+# The whole package addition/replacecement works like this:
+# first we run tie_files in PkgAdd to figure out tieto
+# then "find_extractible" figures out the element of the plist that
+# belong in the archive (thus find_extractible is the hook that always
+# gets run on every plist entry just prior to extraction/skipping)
+#
+# Then the actual extraction proceeds through "prepare_to_extract" and
+# either "tie' OR "extract" depending on the element status.
+# Then later on, we run "install".
+#
+# Actual file system entries may get a tempname, or avoid temp altogether
+#
+# In case of replacement, tempname will get used if the name is the same
+# but the file content is different.
+#
+# If pkg_add can figure out the name is the same, it will set avoidtemp
+#
+# Note that directories, hardlinks and symlinks are purely plist objects
+# with no archive existence:
+# Links always get deleted/re-added even in replacement mode, while directory
+# deletion is delayed into OpenBSD::SharedItems, since several packages
+# may mention the same directory.
+#
package OpenBSD::PackingElement;
use OpenBSD::Error;
+# used by newuser/newgroup to deal with options.
my ($uidcache, $gidcache);
sub prepare_for_addition
-$OpenBSD: Intro.pod,v 1.1 2020/12/20 15:30:58 daniel Exp $
+$OpenBSD: Intro.pod,v 1.2 2022/05/11 07:51:47 espie Exp $
=head1 NAME
Currently, pkg_add -u stops at the first entry in the PKG_PATH from which
suitable candidates are found.
-=head1 BUGS AND LIMITATIONS
-
-There are a few desirable changes that will happen in the future:
-
-=over
-
-=item *
-
-there should be some carefully designed mechanisms to register more
-`global' processing, to avoid exec/unexec.
-
-=back
-
=head1 LIST OF MODULES
=over 3
=item OpenBSD::ArcCheck
-additional layer on top of C<OpenBSD::Ustar> that matches extra
-information that the archive format cannot record with a packing-list.
-
+additional layer on top of C<OpenBSD::Ustar> that enforces extra
+rules specific to packages.
+In particular, we don't store timestamps in the packing-list to
+avoid gratuitous changes, and also, a lot of sensitive information
+is not allowed if it's not also annotated in the PackingList.
=item OpenBSD::CollisionReport