Merging upstream version 0.24.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
b3a4316df0
commit
d842f57fc5
33 changed files with 905 additions and 882 deletions
48
compress.cc
48
compress.cc
|
@ -1,5 +1,5 @@
|
|||
/* Tarlz - Archiver with multimember lzip compression
|
||||
Copyright (C) 2013-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2013-2023 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
|
||||
|
@ -20,7 +20,6 @@
|
|||
#include <cerrno>
|
||||
#include <csignal>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <stdint.h> // for lzlib.h
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
|
@ -131,7 +130,7 @@ void close_and_set_permissions( const struct stat * const in_statsp )
|
|||
}
|
||||
|
||||
|
||||
bool archive_write( const uint8_t * const buf, const long long size,
|
||||
bool archive_write( const uint8_t * const buf, const int size,
|
||||
LZ_Encoder * const encoder )
|
||||
{
|
||||
static bool flushed = true; // avoid flushing empty lzip members
|
||||
|
@ -140,13 +139,12 @@ bool archive_write( const uint8_t * const buf, const long long size,
|
|||
flushed = ( size <= 0 );
|
||||
enum { obuf_size = 65536 };
|
||||
uint8_t obuf[obuf_size];
|
||||
long long sz = 0;
|
||||
int sz = 0;
|
||||
if( flushed ) LZ_compress_finish( encoder ); // flush encoder
|
||||
while( sz < size || flushed )
|
||||
{
|
||||
if( sz < size )
|
||||
{ const int wr = LZ_compress_write( encoder, buf + sz,
|
||||
std::min( size - sz, (long long)max_dictionary_size ) );
|
||||
{ const int wr = LZ_compress_write( encoder, buf + sz, size - sz );
|
||||
if( wr < 0 ) internal_error( "library error (LZ_compress_write)." );
|
||||
sz += wr; }
|
||||
if( sz >= size && !flushed ) break; // minimize dictionary size
|
||||
|
@ -216,26 +214,34 @@ int compress_archive( const Cl_options & cl_opts,
|
|||
Resizable_buffer rbuf; // headers and extended records buffer
|
||||
if( !rbuf.size() ) { show_error( mem_msg ); return 1; }
|
||||
const char * const rderr_msg = "Read error";
|
||||
bool first_header = true;
|
||||
|
||||
while( true ) // process one tar member per iteration
|
||||
{
|
||||
int total_header_size = header_size; // size of header(s) read
|
||||
int total_header_size = header_size; // e_header + edata + u_header
|
||||
const int rd = readblock( infd, rbuf.u8(), header_size );
|
||||
if( rd == 0 && errno == 0 ) break; // missing EOA blocks
|
||||
if( rd == 0 && errno == 0 ) // missing EOA blocks
|
||||
{ if( !first_header ) break;
|
||||
show_file_error( filename, "Archive is empty." );
|
||||
close( infd ); return 2; }
|
||||
if( rd != header_size )
|
||||
{ show_file_error( filename, rderr_msg, errno ); close( infd ); return 1; }
|
||||
first_header = false;
|
||||
|
||||
if( to_file && outfd < 0 ) // open outfd after verifying infd
|
||||
const bool is_header = check_ustar_chksum( rbuf.u8() );
|
||||
const bool is_zero = !is_header && block_is_zero( rbuf.u8(), header_size );
|
||||
if( to_file && outfd < 0 && ( is_header || is_zero ) )
|
||||
{
|
||||
// open outfd after checking infd
|
||||
outfd = open_outstream( output_filename, true, 0, false );
|
||||
// check tty only once and don't try to delete a tty
|
||||
if( outfd < 0 || !check_tty_out() ) { close( infd ); return 1; }
|
||||
delete_output_on_interrupt = true;
|
||||
}
|
||||
|
||||
if( !verify_ustar_chksum( rbuf.u8() ) ) // maybe EOA block
|
||||
if( !is_header ) // maybe EOA block
|
||||
{
|
||||
if( block_is_zero( rbuf.u8(), header_size ) ) // first EOA block
|
||||
if( is_zero ) // first EOA block
|
||||
{ tail_compress( cl_opts, infd, rbuf.u8(), encoder ); break; }
|
||||
show_file_error( filename, bad_hdr_msg ); close( infd ); return 2;
|
||||
}
|
||||
|
@ -246,7 +252,7 @@ int compress_archive( const Cl_options & cl_opts,
|
|||
const long long edsize = parse_octal( rbuf.u8() + size_o, size_l );
|
||||
const long long bufsize = round_up( edsize );
|
||||
// overflow or no extended data
|
||||
if( edsize <= 0 || edsize >= 1LL << 33 || bufsize >= INT_MAX )
|
||||
if( edsize <= 0 || edsize >= 1LL << 33 || bufsize > max_edata_size )
|
||||
{ show_file_error( filename, bad_hdr_msg ); close( infd ); return 2; }
|
||||
if( !rbuf.resize( total_header_size + bufsize ) )
|
||||
{ show_file_error( filename, mem_msg ); close( infd ); return 1; }
|
||||
|
@ -263,7 +269,7 @@ int compress_archive( const Cl_options & cl_opts,
|
|||
if( readblock( infd, rbuf.u8() + total_header_size, header_size ) != header_size )
|
||||
{ show_file_error( filename, errno ? rderr_msg : end_msg, errno );
|
||||
close( infd ); return errno ? 1 : 2; }
|
||||
if( !verify_ustar_chksum( rbuf.u8() ) )
|
||||
if( !check_ustar_chksum( rbuf.u8() ) )
|
||||
{ show_file_error( filename, bad_hdr_msg ); close( infd ); return 2; }
|
||||
const Typeflag typeflag2 = (Typeflag)(rbuf() + total_header_size)[typeflag_o];
|
||||
if( typeflag2 == tf_extended || typeflag2 == tf_global )
|
||||
|
@ -294,9 +300,7 @@ int compress_archive( const Cl_options & cl_opts,
|
|||
rest -= rd;
|
||||
if( rd != size )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "'%s' ends unexpectedly at pos %llu\n",
|
||||
filename, file_size - rest );
|
||||
show_atpos_error( filename, file_size - rest, true );
|
||||
close( infd ); return 1;
|
||||
}
|
||||
if( !archive_write( buf, size, encoder ) ) { close( infd ); return 1; }
|
||||
|
@ -321,6 +325,18 @@ int compress_archive( const Cl_options & cl_opts,
|
|||
} // end namespace
|
||||
|
||||
|
||||
void show_atpos_error( const char * const filename, const long long pos,
|
||||
const bool isarchive )
|
||||
{
|
||||
if( verbosity < 0 ) return;
|
||||
std::fprintf( stderr, "%s: %s: %s %s at pos %llu%s%s\n", program_name,
|
||||
filename, isarchive ? "Archive" : "File",
|
||||
( errno > 0 ) ? "read error" : "ends unexpectedly", pos,
|
||||
( errno > 0 ) ? ": " : "",
|
||||
( errno > 0 ) ? std::strerror( errno ) : "" );
|
||||
}
|
||||
|
||||
|
||||
int compress( const Cl_options & cl_opts )
|
||||
{
|
||||
if( cl_opts.num_files > 1 && cl_opts.output_filename.size() )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue