Merging upstream version 0.9.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
2ab7382c1c
commit
f787962ed2
25 changed files with 1761 additions and 353 deletions
55
create.cc
55
create.cc
|
@ -1,5 +1,5 @@
|
|||
/* Tarlz - Archiver with multimember lzip compression
|
||||
Copyright (C) 2013-2018 Antonio Diaz Diaz.
|
||||
Copyright (C) 2013-2019 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
|
||||
|
@ -46,7 +46,7 @@ const CRC32C crc32c;
|
|||
|
||||
int cl_owner = -1; // global vars needed by add_member
|
||||
int cl_group = -1;
|
||||
int cl_solid = 0; // 1 = dsolid, 2 = asolid, 3 = solid
|
||||
Solidity solidity = no_solid;
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -110,7 +110,7 @@ bool check_appendable( const int fd, const bool remove_eof )
|
|||
if( rd == 0 && errno == 0 ) return true; // append to empty archive
|
||||
if( rd < min_member_size || ( rd != bufsize && errno ) ) return false;
|
||||
const Lzip_header * const p = (const Lzip_header *)buf; // shut up gcc
|
||||
if( !p->verify_magic() ) return false;
|
||||
if( !p->verify_magic() || !p->verify_version() ) return false;
|
||||
LZ_Decoder * decoder = LZ_decompress_open(); // decompress first header
|
||||
if( !decoder || LZ_decompress_errno( decoder ) != LZ_ok ||
|
||||
LZ_decompress_write( decoder, buf, rd ) != rd ||
|
||||
|
@ -133,8 +133,8 @@ bool check_appendable( const int fd, const bool remove_eof )
|
|||
Lzip_header header;
|
||||
if( seek_read( fd, header.data, Lzip_header::size,
|
||||
end - member_size ) != Lzip_header::size ) return false;
|
||||
if( !header.verify_magic() || !isvalid_ds( header.dictionary_size() ) )
|
||||
return false;
|
||||
if( !header.verify_magic() || !header.verify_version() ||
|
||||
!isvalid_ds( header.dictionary_size() ) ) return false;
|
||||
|
||||
const unsigned long long data_size = trailer.data_size();
|
||||
if( data_size < header_size || data_size > 32256 ) return false;
|
||||
|
@ -218,7 +218,7 @@ void print_hex( char * const buf, int size, unsigned long long num )
|
|||
while( --size >= 0 ) { buf[size] = xdigit( num & 0x0F ); num >>= 4; }
|
||||
}
|
||||
|
||||
void print_octal( char * const buf, int size, unsigned long long num )
|
||||
void print_octal( uint8_t * const buf, int size, unsigned long long num )
|
||||
{
|
||||
while( --size >= 0 ) { buf[size] = '0' + ( num % 8 ); num /= 8; }
|
||||
}
|
||||
|
@ -230,13 +230,14 @@ unsigned decimal_digits( unsigned long long value )
|
|||
return digits;
|
||||
}
|
||||
|
||||
unsigned long long record_size( const unsigned keyword_size,
|
||||
const unsigned long long value_size )
|
||||
int record_size( const unsigned keyword_size, const unsigned long value_size )
|
||||
{
|
||||
// size = ' ' + keyword + '=' + value + '\n'
|
||||
const unsigned long long size = 1 + keyword_size + 1 + value_size + 1;
|
||||
unsigned long long size = 1 + keyword_size + 1 + value_size + 1;
|
||||
const unsigned d1 = decimal_digits( size );
|
||||
return decimal_digits( d1 + size ) + size;
|
||||
size += decimal_digits( d1 + size );
|
||||
if( size >= INT_MAX ) size = 0; // overflows snprintf size
|
||||
return size;
|
||||
}
|
||||
|
||||
bool write_extended( const Extended & extended )
|
||||
|
@ -274,9 +275,8 @@ bool write_extended( const Extended & extended )
|
|||
init_tar_header( header );
|
||||
header[typeflag_o] = tf_extended; // fill only required fields
|
||||
print_octal( header + size_o, size_l - 1, edsize );
|
||||
print_octal( header + chksum_o, chksum_l - 1,
|
||||
ustar_chksum( (const uint8_t *)header ) );
|
||||
if( !archive_write( (const uint8_t *)header, header_size ) ) goto error;
|
||||
print_octal( header + chksum_o, chksum_l - 1, ustar_chksum( header ) );
|
||||
if( !archive_write( header, header_size ) ) goto error;
|
||||
for( pos = 0; pos < bufsize; ) // write extended records to archive
|
||||
{
|
||||
int size = std::min( bufsize - pos, 1ULL << 20 );
|
||||
|
@ -387,7 +387,7 @@ int add_member( const char * const filename, const struct stat *,
|
|||
typeflag = tf_symlink;
|
||||
long len;
|
||||
if( st.st_size <= linkname_l )
|
||||
len = readlink( filename, header + linkname_o, linkname_l );
|
||||
len = readlink( filename, (char *)header + linkname_o, linkname_l );
|
||||
else
|
||||
{
|
||||
char * const buf = new char[st.st_size+1];
|
||||
|
@ -414,20 +414,19 @@ int add_member( const char * const filename, const struct stat *,
|
|||
header[typeflag_o] = typeflag;
|
||||
const struct passwd * const pw = getpwuid( uid );
|
||||
if( pw && pw->pw_name )
|
||||
std::strncpy( header + uname_o, pw->pw_name, uname_l - 1 );
|
||||
std::strncpy( (char *)header + uname_o, pw->pw_name, uname_l - 1 );
|
||||
const struct group * const gr = getgrgid( gid );
|
||||
if( gr && gr->gr_name )
|
||||
std::strncpy( header + gname_o, gr->gr_name, gname_l - 1 );
|
||||
std::strncpy( (char *)header + gname_o, gr->gr_name, gname_l - 1 );
|
||||
if( file_size >= 1ULL << 33 ) extended.size = file_size;
|
||||
else print_octal( header + size_o, size_l - 1, file_size );
|
||||
print_octal( header + chksum_o, chksum_l - 1,
|
||||
ustar_chksum( (const uint8_t *)header ) );
|
||||
print_octal( header + chksum_o, chksum_l - 1, ustar_chksum( header ) );
|
||||
|
||||
const int infd = file_size ? open_instream( filename ) : -1;
|
||||
if( file_size && infd < 0 ) { gretval = 1; return 0; }
|
||||
if( !extended.empty() && !write_extended( extended ) )
|
||||
{ show_error( "Error writing extended header", errno ); return 1; }
|
||||
if( !archive_write( (const uint8_t *)header, header_size ) )
|
||||
if( !archive_write( header, header_size ) )
|
||||
{ show_error( "Error writing ustar header", errno ); return 1; }
|
||||
if( file_size )
|
||||
{
|
||||
|
@ -460,7 +459,7 @@ int add_member( const char * const filename, const struct stat *,
|
|||
if( close( infd ) != 0 )
|
||||
{ show_file_error( filename, "Error closing file", errno ); return 1; }
|
||||
}
|
||||
if( encoder && cl_solid == 0 && !archive_write( 0, 0 ) ) // flush encoder
|
||||
if( encoder && solidity == no_solid && !archive_write( 0, 0 ) )
|
||||
{ show_error( "Error flushing encoder", errno ); return 1; }
|
||||
if( verbosity >= 1 ) std::fprintf( stderr, "%s\n", filename );
|
||||
return 0;
|
||||
|
@ -469,18 +468,18 @@ int add_member( const char * const filename, const struct stat *,
|
|||
} // end namespace
|
||||
|
||||
|
||||
unsigned ustar_chksum( const uint8_t * const buf )
|
||||
unsigned ustar_chksum( const uint8_t * const header )
|
||||
{
|
||||
unsigned chksum = chksum_l * 0x20; // treat chksum field as spaces
|
||||
for( int i = 0; i < chksum_o; ++i ) chksum += buf[i];
|
||||
for( int i = chksum_o + chksum_l; i < header_size; ++i ) chksum += buf[i];
|
||||
for( int i = 0; i < chksum_o; ++i ) chksum += header[i];
|
||||
for( int i = chksum_o + chksum_l; i < header_size; ++i ) chksum += header[i];
|
||||
return chksum;
|
||||
}
|
||||
|
||||
|
||||
bool verify_ustar_chksum( const uint8_t * const buf )
|
||||
{ return ( verify_ustar_magic( buf ) &&
|
||||
ustar_chksum( buf ) == strtoul( (const char *)buf + chksum_o, 0, 8 ) ); }
|
||||
bool verify_ustar_chksum( const uint8_t * const header )
|
||||
{ return ( verify_ustar_magic( header ) &&
|
||||
ustar_chksum( header ) == parse_octal( header + chksum_o, chksum_l ) ); }
|
||||
|
||||
|
||||
int concatenate( const std::string & archive_name, const Arg_parser & parser,
|
||||
|
@ -611,7 +610,7 @@ int encode( const std::string & archive_name, const Arg_parser & parser,
|
|||
if( gretval < 1 ) gretval = 1; }
|
||||
else if( ( retval = nftw( filename, add_member, 16, FTW_PHYS ) ) != 0 )
|
||||
break; // write error
|
||||
else if( encoder && cl_solid == 1 && !archive_write( 0, 0 ) ) // flush encoder
|
||||
else if( encoder && solidity == dsolid && !archive_write( 0, 0 ) )
|
||||
{ show_error( "Error flushing encoder", errno ); retval = 1; }
|
||||
}
|
||||
|
||||
|
@ -620,7 +619,7 @@ int encode( const std::string & archive_name, const Arg_parser & parser,
|
|||
enum { bufsize = 2 * header_size };
|
||||
uint8_t buf[bufsize];
|
||||
std::memset( buf, 0, bufsize );
|
||||
if( encoder && cl_solid == 2 && !archive_write( 0, 0 ) ) // flush encoder
|
||||
if( encoder && solidity == asolid && !archive_write( 0, 0 ) )
|
||||
{ show_error( "Error flushing encoder", errno ); retval = 1; }
|
||||
else if( !archive_write( buf, bufsize ) ||
|
||||
( encoder && !archive_write( 0, 0 ) ) ) // flush encoder
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue