summaryrefslogtreecommitdiffstats
path: root/create_lz.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2021-07-17 07:43:33 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2021-07-17 07:43:33 +0000
commit18525b97f1a4b60884962d8fb326e8e85d837686 (patch)
tree99125a3d130d197d38d03df460e7ec1634784b8f /create_lz.cc
parentReleasing debian version 0.19-2. (diff)
downloadtarlz-18525b97f1a4b60884962d8fb326e8e85d837686.tar.xz
tarlz-18525b97f1a4b60884962d8fb326e8e85d837686.zip
Merging upstream version 0.21.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'create_lz.cc')
-rw-r--r--create_lz.cc61
1 files changed, 31 insertions, 30 deletions
diff --git a/create_lz.cc b/create_lz.cc
index 52efb56..f942809 100644
--- a/create_lz.cc
+++ b/create_lz.cc
@@ -19,22 +19,19 @@
#include <algorithm>
#include <cerrno>
-#include <climits>
#include <cstdio>
#include <cstdlib>
-#include <cstring>
#include <queue>
-#include <string>
-#include <vector>
#include <pthread.h>
-#include <stdint.h>
+#include <stdint.h> // for lzlib.h
#include <unistd.h>
#include <sys/stat.h>
#include <ftw.h>
#include <lzlib.h>
-#include "arg_parser.h"
#include "tarlz.h"
+#include "arg_parser.h"
+#include "create.h"
namespace {
@@ -272,7 +269,8 @@ int add_member_lz( const char * const filename, const struct stat *,
{ delete[] header; delete extended; return 0; }
if( gcl_opts->solidity == bsolid &&
- block_is_full( *extended, file_size, partial_data_size ) )
+ block_is_full( extended->full_size(), file_size, gcl_opts->data_size,
+ partial_data_size ) )
courierp->receive_packet( new Ipacket ); // end of group
courierp->receive_packet( new Ipacket( filename, file_size, extended, header ) );
@@ -307,7 +305,7 @@ extern "C" void * grouper( void * arg )
const char * filename = arg.c_str();
if( code == 'C' && chdir( filename ) != 0 )
{ show_file_error( filename, "Error changing working directory", errno );
- cleanup_and_fail(); }
+ exit_fail_mt(); }
if( code ) continue; // skip options
if( cl_opts.parser.argument( i ).empty() ) continue; // skip empty names
std::string deslashed; // arg without trailing slashes
@@ -322,7 +320,7 @@ extern "C" void * grouper( void * arg )
set_error_status( 1 ); }
else if( nftw( filename, add_member_lz, 16,
cl_opts.dereference ? 0 : FTW_PHYS ) != 0 )
- cleanup_and_fail(); // write error or OOM
+ exit_fail_mt(); // write error or OOM
else if( cl_opts.solidity == dsolid ) // end of group
courier.receive_packet( new Ipacket );
}
@@ -363,7 +361,7 @@ void loop_encode( const uint8_t * const ibuf, const int isize,
if( verbosity >= 0 )
std::fprintf( stderr, "LZ_compress_read error: %s\n",
LZ_strerror( LZ_compress_errno( encoder ) ) );
- cleanup_and_fail();
+ exit_fail_mt();
}
opos += rd;
// obuf is full or last opacket in lzip member
@@ -373,11 +371,11 @@ void loop_encode( const uint8_t * const ibuf, const int isize,
internal_error( "opacket size exceeded in worker." );
courier.collect_packet( new Opacket( obuf, opos ), worker_id );
opos = 0; obuf = new( std::nothrow ) uint8_t[max_packet_size];
- if( !obuf ) { show_error( mem_msg2 ); cleanup_and_fail(); }
+ if( !obuf ) { show_error( mem_msg2 ); exit_fail_mt(); }
if( LZ_compress_finished( encoder ) == 1 )
{
if( LZ_compress_restart_member( encoder, LLONG_MAX ) >= 0 ) break;
- show_error( "LZ_compress_restart_member failed." ); cleanup_and_fail();
+ show_error( "LZ_compress_restart_member failed." ); exit_fail_mt();
}
}
}
@@ -409,7 +407,7 @@ extern "C" void * cworker( void * arg )
LZ_Encoder * encoder = 0;
uint8_t * data = 0;
Resizable_buffer rbuf; // extended header + data
- if( !rbuf.size() ) { show_error( mem_msg2 ); cleanup_and_fail(); }
+ if( !rbuf.size() ) { show_error( mem_msg2 ); exit_fail_mt(); }
int opos = 0;
bool flushed = true; // avoid producing empty lzip members
@@ -425,8 +423,9 @@ extern "C" void * cworker( void * arg )
flushed = true; delete ipacket; continue;
}
+ const char * const filename = ipacket->filename.c_str();
const int infd =
- ipacket->file_size ? open_instream( ipacket->filename.c_str() ) : -1;
+ ipacket->file_size ? open_instream( filename ) : -1;
if( ipacket->file_size && infd < 0 ) // can't read file data
{ delete[] ipacket->header; delete ipacket->extended; delete ipacket;
set_error_status( 1 ); continue; } // skip file
@@ -442,7 +441,7 @@ extern "C" void * cworker( void * arg )
show_error( mem_msg2 );
else
internal_error( "invalid argument to encoder." );
- cleanup_and_fail();
+ exit_fail_mt();
}
}
@@ -450,13 +449,12 @@ extern "C" void * cworker( void * arg )
{
const long long ebsize = ipacket->extended->format_block( rbuf );
if( ebsize < 0 )
- { show_error( "Error formatting extended records." ); cleanup_and_fail(); }
+ { show_error( "Error formatting extended records." ); exit_fail_mt(); }
/* Limit the size of the extended block to INT_MAX - 1 so that it can
be fed to lzlib as one buffer. */
if( ebsize >= INT_MAX )
- { show_error( "Extended records size >= INT_MAX." ); cleanup_and_fail(); }
- loop_encode( (const uint8_t *)rbuf(), ebsize, data, opos, courier,
- encoder, worker_id );
+ { show_error( "Extended records size >= INT_MAX." ); exit_fail_mt(); }
+ loop_encode( rbuf.u8(), ebsize, data, opos, courier, encoder, worker_id );
}
// compress ustar header
loop_encode( ipacket->header, header_size, data, opos, courier,
@@ -477,8 +475,8 @@ extern "C" void * cworker( void * arg )
{
if( verbosity >= 0 )
std::fprintf( stderr, "File '%s' ends unexpectedly at pos %llu\n",
- ipacket->filename.c_str(), ipacket->file_size - rest );
- close( infd ); cleanup_and_fail();
+ filename, ipacket->file_size - rest );
+ close( infd ); exit_fail_mt();
}
if( rest == 0 ) // last read
{
@@ -491,14 +489,17 @@ extern "C" void * cworker( void * arg )
loop_encode( buf, size, data, opos, courier, encoder, worker_id );
}
if( close( infd ) != 0 )
- { show_file_error( ipacket->filename.c_str(), "Error closing file", errno );
- cleanup_and_fail(); }
+ { show_file_error( filename, "Error closing file", errno );
+ exit_fail_mt(); }
}
+ if( gcl_opts->warn_newer && archive_attrs.is_newer( filename ) )
+ { show_file_error( filename, "File is newer than the archive." );
+ set_error_status( 1 ); }
delete ipacket;
}
if( data ) delete[] data;
if( encoder && LZ_compress_close( encoder ) < 0 )
- { show_error( "LZ_compress_close failed." ); cleanup_and_fail(); }
+ { show_error( "LZ_compress_close failed." ); exit_fail_mt(); }
return 0;
}
@@ -514,7 +515,7 @@ void muxer( Packet_courier & courier, const int outfd )
if( !opacket ) break; // queue is empty. all workers exited
if( !writeblock_wrapper( outfd, opacket->data, opacket->size ) )
- cleanup_and_fail();
+ exit_fail_mt();
delete[] opacket->data;
delete opacket;
}
@@ -546,12 +547,12 @@ int encode_lz( const Cl_options & cl_opts, const char * const archive_namep,
pthread_t grouper_thread;
int errcode = pthread_create( &grouper_thread, 0, grouper, &grouper_arg );
if( errcode )
- { show_error( "Can't create grouper thread", errcode ); cleanup_and_fail(); }
+ { show_error( "Can't create grouper thread", errcode ); exit_fail_mt(); }
Worker_arg * worker_args = new( std::nothrow ) Worker_arg[num_workers];
pthread_t * worker_threads = new( std::nothrow ) pthread_t[num_workers];
if( !worker_args || !worker_threads )
- { show_error( mem_msg ); cleanup_and_fail(); }
+ { show_error( mem_msg ); exit_fail_mt(); }
for( int i = 0; i < num_workers; ++i )
{
worker_args[i].courier = &courier;
@@ -560,7 +561,7 @@ int encode_lz( const Cl_options & cl_opts, const char * const archive_namep,
worker_args[i].worker_id = i;
errcode = pthread_create( &worker_threads[i], 0, cworker, &worker_args[i] );
if( errcode )
- { show_error( "Can't create worker threads", errcode ); cleanup_and_fail(); }
+ { show_error( "Can't create worker threads", errcode ); exit_fail_mt(); }
}
muxer( courier, outfd );
@@ -569,14 +570,14 @@ int encode_lz( const Cl_options & cl_opts, const char * const archive_namep,
{
errcode = pthread_join( worker_threads[i], 0 );
if( errcode )
- { show_error( "Can't join worker threads", errcode ); cleanup_and_fail(); }
+ { show_error( "Can't join worker threads", errcode ); exit_fail_mt(); }
}
delete[] worker_threads;
delete[] worker_args;
errcode = pthread_join( grouper_thread, 0 );
if( errcode )
- { show_error( "Can't join grouper thread", errcode ); cleanup_and_fail(); }
+ { show_error( "Can't join grouper thread", errcode ); exit_fail_mt(); }
// write End-Of-Archive records
int retval = !write_eof_records( outfd, true );