# Craig Barratt <cbarratt@users.sourceforge.net>
#
# COPYRIGHT
-# Copyright (C) 2001-2003 Craig Barratt
+# Copyright (C) 2001-2007 Craig Barratt
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
#
#========================================================================
#
-# Version 2.1.0_CVS, released 3 Jul 2003.
+# Version 3.1.0beta0, released 3 Sep 2007.
#
# See http://backuppc.sourceforge.net.
#
use Carp;
use File::Path;
use File::Copy;
+use Encode;
#
# For compressed files we have a to careful about running out of memory
binmode(FH);
$fh = *FH;
}
- $compLevel = 0 if ( !$CompZlibOK );
+ $compLevel = 0 if ( !$CompZlibOK );
my $self = bless {
fh => $fh,
name => $fileName,
$self->{deflate} = $self->myDeflateInit;
} else {
$self->{inflate} = $self->myInflateInit;
+ $self->{inflateStart} = 1;
}
}
return $self;
return $CompZlibOK;
}
+#
+# Request utf8 strings with readLine interface
+#
+sub utf8
+{
+ my($self, $mode) = @_;
+
+ $self->{utf8} = $mode;
+}
+
sub myDeflateInit
{
my $self = shift;
return $n if ( $n < 0 );
$self->{eof} = 1 if ( $n == 0 );
}
+ if ( $self->{inflateStart} && $self->{dataIn} ne "" ) {
+ my $chr = substr($self->{dataIn}, 0, 1);
+
+ $self->{inflateStart} = 0;
+ if ( $chr eq chr(0xd6) || $chr eq chr(0xd7) ) {
+ #
+ # Flag 0xd6 or 0xd7 means this is a compressed file with
+ # appended md4 block checksums for rsync. Change
+ # the first byte back to 0x78 and proceed.
+ #
+ ##print("Got 0xd6/0xd7 block: normal\n");
+ substr($self->{dataIn}, 0, 1) = chr(0x78);
+ } elsif ( $chr eq chr(0xb3) ) {
+ #
+ # Flag 0xb3 means this is the start of the rsync
+ # block checksums, so consider this as EOF for
+ # the compressed file. Also seek the file so
+ # it is positioned at the 0xb3.
+ #
+ sysseek($self->{fh}, -length($self->{dataIn}), 1);
+ $self->{eof} = 1;
+ $self->{dataIn} = "";
+ ##print("Got 0xb3 block: considering eof\n");
+ last;
+ } else {
+ #
+ # normal case: nothing to do
+ #
+ }
+ }
my($data, $err) = $self->{inflate}->inflate($self->{dataIn});
$self->{dataOut} .= $data;
if ( $err == Z_STREAM_END ) {
#print("R");
$self->{inflate} = $self->myInflateInit;
+ $self->{inflateStart} = 1;
} elsif ( $err != Z_OK ) {
$$dataRef = "";
return -1;
my($self) = @_;
my $str;
- while ( defined($self->{readLineBuf}) && !@{$self->{readLineBuf}} ) {
+ $self->{readLineBuf} = [] if ( !defined($self->{readLineBuf}) );
+ while ( !@{$self->{readLineBuf}} ) {
$self->read(\$str, $CompMaxRead);
if ( $str eq "" ) {
$str = $self->{readLineFrag};
$self->{readLineFrag} = "";
+ $str = decode_utf8($str) if ( $self->{utf8} );
return $str;
}
@{$self->{readLineBuf}} = split(/\n/, $self->{readLineFrag} . $str);
$self->{readLineFrag} = "";
}
}
- return shift(@{$self->{readLineBuf}}) . "\n";
+ $str = shift(@{$self->{readLineBuf}}) . "\n";
+ if ( $self->{utf8} ) {
+ my $strUtf8 = decode_utf8($str, 0);
+ $strUtf8 = $str if ( length($strUtf8) == 0 );
+ return $strUtf8;
+ }
+ return $str;
}
sub rewind
$self->{dataIn} = '';
$self->{eof} = 0;
$self->{inflate} = $self->myInflateInit;
+ $self->{inflateStart} = 1;
return sysseek($self->{fh}, 0, 0);
}
my $n = length($$dataRef);
return if ( !$self->{write} );
- print($$dataRef) if ( $self->{writeTeeStdout} );
+ print(STDERR $$dataRef) if ( $self->{writeTeeStderr} );
return 0 if ( $n == 0 );
if ( !$self->{compress} ) {
#
return $self->{name};
}
-sub writeTeeStdout
+sub writeTeeStderr
{
my($self, $param) = @_;
- $self->{writeTeeStdout} = $param if ( defined($param) );
- return $self->{writeTeeStdout};
+ $self->{writeTeeStderr} = $param if ( defined($param) );
+ return $self->{writeTeeStderr};
}
sub close