summaryrefslogtreecommitdiffstats
path: root/create.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2019-01-23 17:42:07 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2019-01-23 17:42:07 +0000
commit2f15376ba464cf08e710c3353bdacc4f503e11b4 (patch)
tree646663261d4ebf123dd0bb167d626b6c448dc3b8 /create.cc
parentReleasing debian version 0.8-2. (diff)
downloadtarlz-2f15376ba464cf08e710c3353bdacc4f503e11b4.tar.xz
tarlz-2f15376ba464cf08e710c3353bdacc4f503e11b4.zip
Merging upstream version 0.9.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'create.cc')
-rw-r--r--create.cc55
1 files changed, 27 insertions, 28 deletions
diff --git a/create.cc b/create.cc
index ba7d10a..7310aee 100644
--- a/create.cc
+++ b/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