Merging upstream version 0.12.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
8a1b7bb819
commit
fae36bf8d8
18 changed files with 427 additions and 212 deletions
75
create.cc
75
create.cc
|
@ -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; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue