1
0
Fork 0

Merging upstream version 0.12.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-17 21:12:33 +01:00
parent 8a1b7bb819
commit fae36bf8d8
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
18 changed files with 427 additions and 212 deletions

View file

@ -25,6 +25,7 @@
#include <cstring>
#include <string>
#include <vector>
#include <pthread.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/stat.h>
@ -91,14 +92,15 @@ bool option_C_after_relative_filename( const Arg_parser & parser )
}
int seek_read( const int fd, uint8_t * const buf, const int size,
const long long pos )
bool writeblock_wrapper( const int outfd, const uint8_t * const buffer,
const int size )
{
if( lseek( fd, pos, SEEK_SET ) == pos )
return readblock( fd, buf, size );
return 0;
if( writeblock( outfd, buffer, size ) != size )
{ show_file_error( archive_namep, "Write error", errno ); return false; }
return true;
}
// infd and outfd can refer to the same file if copying to a lower file
// position or if source and destination blocks don't overlap.
// max_size < 0 means no size limit.
@ -120,10 +122,7 @@ bool copy_file( const int infd, const int outfd, const long long max_size = -1 )
{ show_error( "Error reading input file", errno ); error = true; break; }
if( rd > 0 )
{
const int wr = writeblock( outfd, buffer, rd );
if( wr != rd )
{ show_error( "Error writing output file", errno );
error = true; break; }
if( !writeblock_wrapper( outfd, buffer, rd ) ) { error = true; break; }
copied_size += rd;
}
if( rd < size ) break; // EOF
@ -193,7 +192,7 @@ bool archive_write( const uint8_t * const buf, const int size )
if( size <= 0 && flushed ) return true;
flushed = ( size <= 0 );
if( !encoder ) // uncompressed
return ( writeblock( goutfd, buf, size ) == size );
return writeblock_wrapper( goutfd, buf, size );
enum { obuf_size = 65536 };
uint8_t obuf[obuf_size];
int sz = 0;
@ -207,7 +206,7 @@ bool archive_write( const uint8_t * const buf, const int size )
const int rd = LZ_compress_read( encoder, obuf, obuf_size );
if( rd < 0 ) internal_error( "library error (LZ_compress_read)." );
if( rd == 0 && sz >= size ) break;
if( writeblock( goutfd, obuf, rd ) != rd ) return false;
if( !writeblock_wrapper( goutfd, obuf, rd ) ) return false;
}
if( LZ_compress_finished( encoder ) == 1 &&
LZ_compress_restart_member( encoder, LLONG_MAX ) < 0 )
@ -270,13 +269,10 @@ int add_member( const char * const filename, const struct stat *,
if( encoder && solidity == bsolid &&
block_is_full( extended, file_size, partial_data_size ) &&
!archive_write( 0, 0 ) )
{ show_error( "Error flushing encoder", errno ); return 1; }
!archive_write( 0, 0 ) ) return 1;
if( !write_extended( extended ) )
{ show_error( "Error writing extended header", errno ); return 1; }
if( !archive_write( header, header_size ) )
{ show_error( "Error writing ustar header", errno ); return 1; }
if( !write_extended( extended ) || !archive_write( header, header_size ) )
return 1;
if( file_size )
{
enum { bufsize = 32 * header_size };
@ -301,15 +297,12 @@ int add_member( const char * const filename, const struct stat *,
{ const int padding = header_size - rem;
std::memset( buf + size, 0, padding ); size += padding; }
}
if( !archive_write( buf, size ) )
{ show_error( "Error writing archive", errno ); close( infd );
return 1; }
if( !archive_write( buf, size ) ) { close( infd ); return 1; }
}
if( close( infd ) != 0 )
{ show_file_error( filename, "Error closing file", errno ); return 1; }
}
if( encoder && solidity == no_solid && !archive_write( 0, 0 ) )
{ show_error( "Error flushing encoder", errno ); return 1; }
if( encoder && solidity == no_solid && !archive_write( 0, 0 ) ) return 1;
if( verbosity >= 1 ) std::fprintf( stderr, "%s\n", filename );
return 0;
}
@ -378,7 +371,7 @@ bool fill_headers( const char * const filename, Extended & extended,
set_error_status( 1 ); return false; }
print_octal( header + uid_o, uid_l - 1, uid );
print_octal( header + gid_o, gid_l - 1, gid );
const long long mtime = st.st_mtime; // shut up gcc
const long long mtime = st.st_mtime; // shut up gcc about time_t
if( mtime < 0 || mtime >= 1LL << 33 )
{ show_file_error( filename, "mtime is out of ustar range [0, 8_589_934_591]." );
set_error_status( 1 ); return false; }
@ -413,28 +406,28 @@ bool fill_headers( const char * const filename, Extended & extended,
else if( S_ISCHR( mode ) || S_ISBLK( mode ) )
{
typeflag = S_ISCHR( mode ) ? tf_chardev : tf_blockdev;
if( major( st.st_dev ) >= 2 << 20 || minor( st.st_dev ) >= 2 << 20 )
if( major( st.st_rdev ) >= 2 << 20 || minor( st.st_rdev ) >= 2 << 20 )
{ show_file_error( filename, "devmajor or devminor is larger than 2_097_151." );
set_error_status( 1 ); return false; }
print_octal( header + devmajor_o, devmajor_l - 1, major( st.st_dev ) );
print_octal( header + devminor_o, devminor_l - 1, minor( st.st_dev ) );
print_octal( header + devmajor_o, devmajor_l - 1, major( st.st_rdev ) );
print_octal( header + devminor_o, devminor_l - 1, minor( st.st_rdev ) );
}
else if( S_ISFIFO( mode ) ) typeflag = tf_fifo;
else { show_file_error( filename, "Unknown file type." );
set_error_status( 2 ); return false; }
header[typeflag_o] = typeflag;
errno = 0;
// errno = 0;
const struct passwd * const pw = getpwuid( uid );
if( pw && pw->pw_name )
std::strncpy( (char *)header + uname_o, pw->pw_name, uname_l - 1 );
else { show_file_error( filename, "Can't read user name from database", errno );
set_error_status( 1 ); }
errno = 0;
/* else { show_file_error( filename, "Can't read user name from database", errno );
set_error_status( 1 ); } */ // numerical only
// errno = 0;
const struct group * const gr = getgrgid( gid );
if( gr && gr->gr_name )
std::strncpy( (char *)header + gname_o, gr->gr_name, gname_l - 1 );
else { show_file_error( filename, "Can't read group name from database", errno );
set_error_status( 1 ); }
/* else { show_file_error( filename, "Can't read group name from database", errno );
set_error_status( 1 ); } */ // numerical only
if( file_size >= 1ULL << 33 )
{ extended.file_size( file_size ); force_extended_name = true; }
else print_octal( header + size_o, size_l - 1, file_size );
@ -469,10 +462,11 @@ void set_error_status( const int retval )
xunlock( &mutex );
}
int final_exit_status( int retval )
int final_exit_status( int retval, const bool show_msg )
{
if( !retval && error_status )
{ show_error( "Exiting with failure status due to previous errors." );
{ if( show_msg )
show_error( "Exiting with failure status due to previous errors." );
retval = error_status; }
return retval;
}
@ -511,9 +505,7 @@ int concatenate( const std::string & archive_name, const Arg_parser & parser,
if( parser.argument( i ).empty() ) continue; // skip empty names
const char * const filename = parser.argument( i ).c_str();
const int infd = open_instream( filename );
if( infd < 0 )
{ show_file_error( filename, "Can't open input file", errno );
retval = 1; break; }
if( infd < 0 ) { retval = 1; break; }
if( !check_appendable( infd, false ) )
{ show_file_error( filename, "Not an appendable tar.lz archive." );
close( infd ); retval = 2; break; }
@ -640,7 +632,7 @@ int encode( const std::string & archive_name, const Arg_parser & parser,
else if( ( retval = nftw( filename, add_member, 16, FTW_PHYS ) ) != 0 )
break; // write error
else if( encoder && solidity == dsolid && !archive_write( 0, 0 ) )
{ show_error( "Error flushing encoder", errno ); retval = 1; }
retval = 1;
}
if( !retval ) // write End-Of-Archive records
@ -650,12 +642,9 @@ int encode( const std::string & archive_name, const Arg_parser & parser,
std::memset( buf, 0, bufsize );
if( encoder &&
( solidity == asolid || ( solidity == bsolid && partial_data_size ) ) &&
!archive_write( 0, 0 ) )
{ show_error( "Error flushing encoder", errno ); retval = 1; }
!archive_write( 0, 0 ) ) retval = 1; // flush encoder
else if( !archive_write( buf, bufsize ) ||
( encoder && !archive_write( 0, 0 ) ) ) // flush encoder
{ show_error( "Error writing end-of-archive blocks", errno );
retval = 1; }
( encoder && !archive_write( 0, 0 ) ) ) retval = 1;
}
if( encoder && LZ_compress_close( encoder ) < 0 )
{ show_error( "LZ_compress_close failed." ); retval = 1; }