From 2a00d366f34bfdfa7e5a3019b4753bc94a80748d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 27 Jan 2021 17:07:35 +0100 Subject: Merging upstream version 0.19. Signed-off-by: Daniel Baumann --- archive_reader.cc | 57 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 6 deletions(-) (limited to 'archive_reader.cc') diff --git a/archive_reader.cc b/archive_reader.cc index 496c33b..b7950ef 100644 --- a/archive_reader.cc +++ b/archive_reader.cc @@ -1,5 +1,5 @@ /* Tarlz - Archiver with multimember lzip compression - Copyright (C) 2013-2020 Antonio Diaz Diaz. + Copyright (C) 2013-2021 Antonio Diaz Diaz. 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 @@ -23,6 +23,7 @@ #include #include #include +#include // for tarlz.h #include #include #include @@ -32,6 +33,50 @@ #include "archive_reader.h" +namespace { + +/* Returns the number of bytes really read. + If (returned value < size) and (errno == 0), means EOF was reached. +*/ +int preadblock( const int fd, uint8_t * const buf, const int size, + const long long pos ) + { + int sz = 0; + errno = 0; + while( sz < size ) + { + const int n = pread( fd, buf + sz, size - sz, pos + sz ); + if( n > 0 ) sz += n; + else if( n == 0 ) break; // EOF + else if( errno != EINTR ) break; + errno = 0; + } + return sz; + } + + +/* Returns the number of bytes really written. + If (returned value < size), it is always an error. +*//* +int pwriteblock( const int fd, const uint8_t * const buf, const int size, + const long long pos ) + { + int sz = 0; + errno = 0; + while( sz < size ) + { + const int n = pwrite( fd, buf + sz, size - sz, pos + sz ); + if( n > 0 ) sz += n; + else if( n < 0 && errno != EINTR ) break; + errno = 0; + } + return sz; + } +*/ + +} // end namespace + + int Archive_reader_base::parse_records( Extended & extended, const Tar_header header, Resizable_buffer & rbuf, @@ -159,7 +204,7 @@ void Archive_reader_i::set_member( const long i ) { LZ_decompress_reset( decoder ); // prepare for new member data_pos_ = ad.lzip_index.dblock( i ).pos(); - mdata_end = ad.lzip_index.dblock( i ).end(); + mdata_end_ = ad.lzip_index.dblock( i ).end(); archive_pos = ad.lzip_index.mblock( i ).pos(); member_id = i; } @@ -175,9 +220,9 @@ int Archive_reader_i::read( uint8_t * const buf, const int size ) { const int rd = LZ_decompress_read( decoder, buf + sz, size - sz ); if( rd < 0 ) - return err( 1, LZ_strerror( LZ_decompress_errno( decoder ) ) ); + return err( 1, LZ_strerror( LZ_decompress_errno( decoder ) ), 0, sz ); if( rd == 0 && LZ_decompress_finished( decoder ) == 1 ) - return err( 2, end_msg ); + return err( 2, end_msg, 0, sz ); sz += rd; data_pos_ += rd; if( sz < size && LZ_decompress_write_size( decoder ) > 0 ) { @@ -198,7 +243,7 @@ int Archive_reader_i::read( uint8_t * const buf, const int size ) if( rd < rsize ) { LZ_decompress_finish( decoder ); - if( errno ) return err( 2, "Error reading archive" ); + if( errno ) return err( 2, "Error reading archive", 0, sz ); } } } @@ -210,7 +255,7 @@ int Archive_reader_i::read( uint8_t * const buf, const int size ) int Archive_reader_i::skip_member( const Extended & extended ) { long long rest = round_up( extended.file_size() ); // size + padding - if( data_pos_ + rest == mdata_end ) { data_pos_ = mdata_end; return 0; } + if( data_pos_ + rest == mdata_end_ ) { data_pos_ = mdata_end_; return 0; } const int bufsize = 32 * header_size; uint8_t buf[bufsize]; while( rest > 0 ) // skip tar member -- cgit v1.2.3