X-Git-Url: http://git.rot13.org/?p=BackupPC.git;a=blobdiff_plain;f=lib%2FBackupPC%2FFileZIO.pm;h=a894bab8851e251747b6bc88bb6376972013b61b;hp=48554b86b604876d98df1e3a93c3a83706066309;hb=9cf3998c4ef71332dea96ff3115daf8b9f722acb;hpb=7dee89bfce659051d486cc66515bb7f22bbc4f09 diff --git a/lib/BackupPC/FileZIO.pm b/lib/BackupPC/FileZIO.pm index 48554b8..a894bab 100644 --- a/lib/BackupPC/FileZIO.pm +++ b/lib/BackupPC/FileZIO.pm @@ -11,7 +11,7 @@ # Craig Barratt # # COPYRIGHT -# Copyright (C) 2001 Craig Barratt +# Copyright (C) 2001-2009 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 @@ -29,7 +29,7 @@ # #======================================================================== # -# Version 2.0.0beta1, released 30 Mar 2003. +# Version 3.2.0beta0, released 5 April 2009. # # See http://backuppc.sourceforge.net. # @@ -43,6 +43,7 @@ use vars qw( $CompZlibOK ); use Carp; use File::Path; use File::Copy; +use Encode; # # For compressed files we have a to careful about running out of memory @@ -99,9 +100,10 @@ sub open } else { open(FH, "<", $fileName) || return; } + binmode(FH); $fh = *FH; } - $compLevel = 0 if ( !$CompZlibOK ); + $compLevel = 0 if ( !$CompZlibOK ); my $self = bless { fh => $fh, name => $fileName, @@ -114,6 +116,7 @@ sub open $self->{deflate} = $self->myDeflateInit; } else { $self->{inflate} = $self->myInflateInit; + $self->{inflateStart} = 1; } } return $self; @@ -124,6 +127,16 @@ sub compOk return $CompZlibOK; } +# +# Request utf8 strings with readLine interface +# +sub utf8 +{ + my($self, $mode) = @_; + + $self->{utf8} = $mode; +} + sub myDeflateInit { my $self = shift; @@ -156,11 +169,42 @@ sub read 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; @@ -187,11 +231,13 @@ sub readLine 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); @@ -201,7 +247,13 @@ sub readLine $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 @@ -214,6 +266,7 @@ sub rewind $self->{dataIn} = ''; $self->{eof} = 0; $self->{inflate} = $self->myInflateInit; + $self->{inflateStart} = 1; return sysseek($self->{fh}, 0, 0); } @@ -246,7 +299,7 @@ sub write 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} ) { # @@ -304,12 +357,12 @@ sub name 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 @@ -353,6 +406,7 @@ sub compressCopy my $fh = BackupPC::FileZIO->open($destFileZ, 1, $compress); my $data; if ( defined($fh) && open(LOG, "<", $srcFile) ) { + binmode(LOG); while ( sysread(LOG, $data, 65536) > 0 ) { $fh->write(\$data); }