summaryrefslogtreecommitdiff
path: root/usr.sbin/pkg_add/OpenBSD/Ustar.pm
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2004-12-11 14:05:14 +0000
committerMarc Espie <espie@cvs.openbsd.org>2004-12-11 14:05:14 +0000
commitc8f9f8f01b0474052b6abaaa267102e80576ce9d (patch)
tree3ba160990ac983188b053bfac7af469f4fa1987b /usr.sbin/pkg_add/OpenBSD/Ustar.pm
parentc385ba7c13c5d6c66464a0dafe0ff06780709d43 (diff)
implement zeroes blocks detection
Diffstat (limited to 'usr.sbin/pkg_add/OpenBSD/Ustar.pm')
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Ustar.pm36
1 files changed, 34 insertions, 2 deletions
diff --git a/usr.sbin/pkg_add/OpenBSD/Ustar.pm b/usr.sbin/pkg_add/OpenBSD/Ustar.pm
index 1dc73f4f22c..ab56ceef598 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.12 2004/11/01 15:44:11 espie Exp $
+# $OpenBSD: Ustar.pm,v 1.13 2004/12/11 14:05:13 espie Exp $
#
# Copyright (c) 2002-2004 Marc Espie <espie@openbsd.org>
#
@@ -37,6 +37,8 @@ use OpenBSD::IdCache;
my $uidcache = new OpenBSD::UidCache;
my $gidcache = new OpenBSD::GidCache;
+
+# This is a multiple of st_blksize everywhere....
my $buffsize = 2 * 1024 * 1024;
sub new
@@ -207,6 +209,36 @@ sub isSymLink() { 1 }
package OpenBSD::Ustar::File;
our @ISA=qw(OpenBSD::Ustar::Object);
+my $bs;
+my $zeroes;
+sub print_compact
+{
+ my ($fh, $buffer) = @_;
+ my $newbs = (stat $fh)[11];
+ if (!defined $bs or $newbs != $bs) {
+ $bs = $newbs;
+ $zeroes = "\x00"x$bs;
+ }
+START:
+ if (defined $bs) {
+ for (my $i = 0; $i + $bs <= length($buffer); $i+= $bs) {
+ if (substr($buffer, $i, $bs) eq $zeroes) {
+ syswrite($fh, $buffer, $i) or return 0;
+ $i+=$bs;
+ my $seek_forward = $bs;
+ while (substr($buffer, $i, $bs) eq $zeroes) {
+ $i += $bs;
+ $seek_forward += $bs;
+ }
+ sysseek($fh, $seek_forward, 1) or return 0;
+ $buffer = substr($buffer, $i);
+ goto START;
+ }
+ }
+ }
+ syswrite($fh, $buffer) or return 0;
+}
+
sub create
{
my $self = shift;
@@ -224,7 +256,7 @@ sub create
die "Error reading from archive: $!";
}
$self->{archive}->{swallow} -= $maxread;
- unless (print $out $buffer) {
+ unless (print_compact($out, $buffer)) {
die "Error writing to $self->{destdir}$self->{name}: $!";
}