summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2004-12-26 15:18:52 +0000
committerMarc Espie <espie@cvs.openbsd.org>2004-12-26 15:18:52 +0000
commit26c886e250d9cf7008d537d086770373b25b2968 (patch)
tree8929a9495cdd4e4cabb2a285f3e274cd32f18259 /usr.sbin
parent825630951e9ec3cc58d1b047891f6c6b73164995 (diff)
put the compress 0 codes into a specific object. Handles the case where
file ends with a block of zero, as sleuthed by sturm@. The object means the code is cleaned up with all the state in one place. Also, better use of constant. And beginnings of an Ustar writer code...
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Ustar.pm120
1 files changed, 97 insertions, 23 deletions
diff --git a/usr.sbin/pkg_add/OpenBSD/Ustar.pm b/usr.sbin/pkg_add/OpenBSD/Ustar.pm
index 628e61bc97f..9621c652364 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.14 2004/12/13 18:50:23 espie Exp $
+# $OpenBSD: Ustar.pm,v 1.15 2004/12/26 15:18:51 espie Exp $
#
# Copyright (c) 2002-2004 Marc Espie <espie@openbsd.org>
#
@@ -21,16 +21,19 @@ use strict;
use warnings;
package OpenBSD::Ustar;
-use constant FILE => "\0";
-use constant FILE1 => '0';
-use constant HARDLINK => '1';
-use constant SOFTLINK => '2';
-use constant CHARDEVICE => '3';
-use constant BLOCKDEVICE => '4';
-use constant DIR => '5';
-use constant FIFO => '6';
-use constant CONTFILE => '7';
-use constant USTAR_HEADER => 'a100a8a8a8a12a12a8aa100a6a2a32a32a8a8a155';
+use constant {
+ FILE => "\0",
+ FILE1 => '0',
+ HARDLINK => '1',
+ SOFTLINK => '2',
+ CHARDEVICE => '3',
+ BLOCKDEVICE => '4',
+ DIR => '5',
+ FIFO => '6',
+ CONTFILE => '7',
+ USTAR_HEADER => 'a100a8a8a8a12a12a8aa100a6a2a32a32a8a8a155',
+};
+
use File::Path ();
use File::Basename ();
use OpenBSD::IdCache;
@@ -140,6 +143,44 @@ sub next
return $result;
}
+sub mkheader
+{
+ my ($entry, $type) = @_;
+ my ($name, $prefix);
+ if (length($name) < 100) {
+ $prefix = '';
+ } elsif (length($name) > 255) {
+ die "Can't fit such a name $name\n";
+ } elsif ($name =~ m|^(.*)/(.{,100})$|) {
+ $prefix = $1;
+ $name = $2;
+ } else {
+ die "Can't fit such a name $name\n";
+ }
+ my $header;
+ my $cksum = ' 'x8;
+ 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}),
+ $cksum,
+ $type,
+ $entry->{linkname},
+ 'ustar', '00',
+ $entry->{uname},
+ $entry->{gname},
+ '0', '0',
+ $prefix);
+ $cksum = unpack("%C*", $header);
+ }
+ return $header;
+}
+
+
package OpenBSD::Ustar::Object;
sub set_modes
{
@@ -206,19 +247,34 @@ sub create
sub isLink() { 1 }
sub isSymLink() { 1 }
-package OpenBSD::Ustar::File;
-our @ISA=qw(OpenBSD::Ustar::Object);
+package OpenBSD::CompactWriter;
-my $bs;
-my $zeroes;
-sub print_compact
+use constant {
+ FH => 0,
+ BS => 1,
+ ZEROES => 2,
+ UNFINISHED => 3,
+};
+
+sub new
{
- my ($fh, $buffer) = @_;
- my $newbs = (stat $fh)[11];
- if (!defined $bs or $newbs != $bs) {
- $bs = $newbs;
+ my ($class, $fname) = @_;
+ open (my $out, '>', $fname);
+ if (!defined $out) {
+ return undef;
+ }
+ my $bs = (stat $out)[11];
+ my $zeroes;
+ if (defined $bs) {
$zeroes = "\x00"x$bs;
}
+ bless [ $out, $bs, $zeroes, 0 ], $class;
+}
+
+sub write
+{
+ my ($self, $buffer) = @_;
+ my ($fh, $bs, $zeroes, $e) = @$self;
START:
if (defined $bs) {
for (my $i = 0; $i + $bs <= length($buffer); $i+= $bs) {
@@ -233,23 +289,41 @@ START:
defined(sysseek($fh, $seek_forward, 1))
or return 0;
$buffer = substr($buffer, $i);
+ if (length $buffer == 0) {
+ $self->[UNFINISHED] = 1;
+ return 1;
+ }
goto START;
}
}
}
+ $self->[UNFINISHED] = 0;
defined(syswrite($fh, $buffer)) or return 0;
return 1;
}
+sub close
+{
+ my ($self) = @_;
+ if ($self->[UNFINISHED]) {
+ defined(sysseek($self->[FH], -1, 1)) or return 0;
+ defined(syswrite($self->[FH], "\0")) or return 0;
+ }
+ return 1;
+}
+
+package OpenBSD::Ustar::File;
+our @ISA=qw(OpenBSD::Ustar::Object);
+
sub create
{
my $self = shift;
$self->make_basedir($self->{name});
- open (my $out, '>', $self->{destdir}.$self->{name});
+ my $buffer;
+ my $out = OpenBSD::CompactWriter->new($self->{destdir}.$self->{name});
if (!defined $out) {
die "Can't write to $self->{destdir}$self->{name}: $!";
}
- my $buffer;
my $toread = $self->{size};
while ($toread > 0) {
my $maxread = $buffsize;
@@ -258,7 +332,7 @@ sub create
die "Error reading from archive: $!";
}
$self->{archive}->{swallow} -= $maxread;
- unless (print_compact($out, $buffer)) {
+ unless ($out->write($buffer)) {
die "Error writing to $self->{destdir}$self->{name}: $!";
}