summaryrefslogtreecommitdiffstats
path: root/archive_reader.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2021-01-27 16:07:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2021-01-27 16:08:24 +0000
commit2a00d366f34bfdfa7e5a3019b4753bc94a80748d (patch)
treefad13d976fa52e336b4bb0b85eff6de1350c9906 /archive_reader.cc
parentReleasing debian version 0.17-1. (diff)
downloadtarlz-2a00d366f34bfdfa7e5a3019b4753bc94a80748d.tar.xz
tarlz-2a00d366f34bfdfa7e5a3019b4753bc94a80748d.zip
Merging upstream version 0.19.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--archive_reader.cc57
1 files changed, 51 insertions, 6 deletions
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 <cstring>
#include <string>
#include <vector>
+#include <pthread.h> // for tarlz.h
#include <stdint.h>
#include <unistd.h>
#include <lzlib.h>
@@ -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