summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2005-06-13 14:24:07 +0000
committerMarc Espie <espie@cvs.openbsd.org>2005-06-13 14:24:07 +0000
commit13356baba7c3cc35d3bc28e2d0677828ea7aa158 (patch)
tree8a1bd4aa99b85995fbaf486466201e289c9764da
parentfd3f4a26819cd788a8d84d230dbdbef89b9e2dd1 (diff)
fix archive header writing.
add pad() method to finish archives. With this, writing Ustar archives work.
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Ustar.pm36
-rw-r--r--usr.sbin/pkg_add/pod/OpenBSD::Ustar.pod6
2 files changed, 26 insertions, 16 deletions
diff --git a/usr.sbin/pkg_add/OpenBSD/Ustar.pm b/usr.sbin/pkg_add/OpenBSD/Ustar.pm
index cfdc556d19c..813b23a2879 100644
--- a/usr.sbin/pkg_add/OpenBSD/Ustar.pm
+++ b/usr.sbin/pkg_add/OpenBSD/Ustar.pm
@@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
-# $OpenBSD: Ustar.pm,v 1.20 2005/06/13 13:11:11 espie Exp $
+# $OpenBSD: Ustar.pm,v 1.21 2005/06/13 14:24:06 espie Exp $
#
# Copyright (c) 2002-2004 Marc Espie <espie@openbsd.org>
#
@@ -31,7 +31,7 @@ use constant {
DIR => '5',
FIFO => '6',
CONTFILE => '7',
- USTAR_HEADER => 'a100a8a8a8a12a12a8aa100a6a2a32a32a8a8a155',
+ USTAR_HEADER => 'a100a8a8a8a12a12a8aa100a6a2a32a32a8a8a155a12',
};
use File::Path ();
@@ -86,7 +86,7 @@ sub next
# decode header
my ($name, $mode, $uid, $gid, $size, $mtime, $chksum, $type,
$linkname, $magic, $version, $uname, $gname, $major, $minor,
- $prefix) = unpack(USTAR_HEADER, $header);
+ $prefix, $pad) = unpack(USTAR_HEADER, $header);
if ($magic ne "ustar\0" || $version ne '00') {
die "Not an ustar archive header";
}
@@ -174,20 +174,20 @@ sub mkheader
for (1 .. 2) {
$header = pack(USTAR_HEADER,
$name,
- sprintf("%o", $entry->{mode}),
- sprintf("%o", $entry->{uid}),
- sprintf("%o", $entry->{gid}),
- sprintf("%o", $entry->{size}),
- sprintf("%o", $entry->{mtime}),
+ sprintf("%07o", $entry->{mode}),
+ sprintf("%07o", $entry->{uid}),
+ sprintf("%07o", $entry->{gid}),
+ sprintf("%011o", $entry->{size}),
+ sprintf("%011o", $entry->{mtime}),
$cksum,
$type,
$linkname,
'ustar', '00',
$entry->{uname},
$entry->{gname},
- '0', '0',
- $prefix);
- $cksum = unpack("%C*", $header);
+ "\0", "\0",
+ $prefix, "\0");
+ $cksum = sprintf("%07o", unpack("%C*", $header));
}
return $header;
}
@@ -222,13 +222,19 @@ sub prepare
$entry->{linkname} = readlink("$destdir/$filename");
bless $entry, "OpenBSD::Ustar::SoftLink";
} elsif (-d _) {
- bless $entry, "OpenBSD::UStar::Dir";
+ bless $entry, "OpenBSD::Ustar::Dir";
} else {
bless $entry, "OpenBSD::Ustar::File";
}
return $entry;
}
+sub pad
+{
+ my $fh = $_[0]->{fh};
+ print $fh "\0"x1024;
+}
+
package OpenBSD::Ustar::Object;
sub set_modes
{
@@ -249,9 +255,10 @@ sub write
{
my $self = shift;
my $arc = $self->{archive};
+ my $out = $arc->{fh};
my $header = OpenBSD::Ustar::mkheader($self, $self->type());
- syswrite($arc->{fh}, $header, 512);
+ print $out $header;
$self->write_contents($arc);
my $k = $self->{key};
if (!defined $arc->{key}->{$k}) {
@@ -431,7 +438,6 @@ sub write_contents
if (!defined read($fh, $buffer, $maxread)) {
die "Error reading from file: $!";
}
- $self->{archive}->{swallow} -= $maxread;
unless (print $out $buffer) {
die "Error writing to archive: $!";
}
@@ -445,6 +451,6 @@ sub write_contents
sub isFile() { 1 }
-sub type() { OpenBSD::Ustar::FILE }
+sub type() { OpenBSD::Ustar::FILE1 }
1;
diff --git a/usr.sbin/pkg_add/pod/OpenBSD::Ustar.pod b/usr.sbin/pkg_add/pod/OpenBSD::Ustar.pod
index f17ac98fc45..2695ee7ad1e 100644
--- a/usr.sbin/pkg_add/pod/OpenBSD::Ustar.pod
+++ b/usr.sbin/pkg_add/pod/OpenBSD::Ustar.pod
@@ -1,4 +1,4 @@
-$OpenBSD: OpenBSD::Ustar.pod,v 1.4 2005/06/13 12:54:11 espie Exp $
+$OpenBSD: OpenBSD::Ustar.pod,v 1.5 2005/06/13 14:24:06 espie Exp $
=head1 NAME
@@ -25,6 +25,7 @@ OpenBSD::Ustar - simple access to Ustar C<tar(1)> archives
# tweak some entry parameters
$o->write();
+ $wrarc->pad();
close($out);
=head1 DESCRIPTION
@@ -69,6 +70,9 @@ elements or not.
Actual writing is performed through C<$o-E<gt>write()> and is not mandatory
either.
+Writing valid archives requires calling C<$wrarc-E<gt>pad()> after archiving
+all the entries to complete the archive with blank-filled blocks.
+
Client code may decide to abort archive extraction early, or to run it through
until C<$arc-E<gt>next()> returns false. The C<OpenBSD::Ustar> object doesn't
hold any resources and doesn't need any specific clean-up. However, client