Adding upstream version 0.21.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
7bf1f2e322
commit
cc1b855cb3
27 changed files with 961 additions and 324 deletions
84
create.cc
84
create.cc
|
@ -19,14 +19,10 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
#include <climits>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdint.h> // for lzlib.h
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#if !defined __FreeBSD__ && !defined __OpenBSD__ && !defined __NetBSD__ && \
|
||||
|
@ -38,8 +34,12 @@
|
|||
#include <pwd.h>
|
||||
#include <lzlib.h>
|
||||
|
||||
#include "arg_parser.h"
|
||||
#include "tarlz.h"
|
||||
#include "arg_parser.h"
|
||||
#include "create.h"
|
||||
|
||||
|
||||
Archive_attrs archive_attrs; // archive attributes at time of creation
|
||||
|
||||
|
||||
namespace {
|
||||
|
@ -52,28 +52,6 @@ Resizable_buffer grbuf; // extended header + data
|
|||
int goutfd = -1;
|
||||
int error_status = 0;
|
||||
|
||||
class File_is_the_archive
|
||||
{
|
||||
dev_t archive_dev;
|
||||
ino_t archive_ino;
|
||||
bool initialized;
|
||||
|
||||
public:
|
||||
File_is_the_archive() : initialized( false ) {}
|
||||
bool init( const int fd )
|
||||
{
|
||||
struct stat st;
|
||||
if( fstat( fd, &st ) != 0 ) return false;
|
||||
if( S_ISREG( st.st_mode ) )
|
||||
{ archive_dev = st.st_dev; archive_ino = st.st_ino; initialized = true; }
|
||||
return true;
|
||||
}
|
||||
bool operator()( const struct stat & st ) const
|
||||
{
|
||||
return initialized && archive_dev == st.st_dev && archive_ino == st.st_ino;
|
||||
}
|
||||
} file_is_the_archive;
|
||||
|
||||
|
||||
bool option_C_after_relative_filename( const Arg_parser & parser )
|
||||
{
|
||||
|
@ -171,7 +149,7 @@ long long check_uncompressed_appendable( const int fd, const bool remove_eof )
|
|||
if( edsize <= 0 || edsize >= 1LL << 33 || bufsize >= INT_MAX )
|
||||
return -1; // overflow or no extended data
|
||||
if( !rbuf.resize( bufsize ) ) return -1;
|
||||
if( readblock( fd, (uint8_t *)rbuf(), bufsize ) != bufsize )
|
||||
if( readblock( fd, rbuf.u8(), bufsize ) != bufsize )
|
||||
return -1;
|
||||
if( typeflag == tf_extended )
|
||||
{ if( !extended.parse( rbuf(), edsize, false ) ) return -1;
|
||||
|
@ -229,7 +207,7 @@ bool write_extended( const Extended & extended )
|
|||
for( long long pos = 0; pos < ebsize; ) // write extended block to archive
|
||||
{
|
||||
int size = std::min( ebsize - pos, 1LL << 20 );
|
||||
if( !archive_write( (const uint8_t *)grbuf() + pos, size ) ) return false;
|
||||
if( !archive_write( grbuf.u8() + pos, size ) ) return false;
|
||||
pos += size;
|
||||
}
|
||||
return true;
|
||||
|
@ -276,8 +254,8 @@ int add_member( const char * const filename, const struct stat *,
|
|||
if( file_size && infd < 0 ) { set_error_status( 1 ); return 0; }
|
||||
|
||||
if( encoder && gcl_opts->solidity == bsolid &&
|
||||
block_is_full( extended, file_size, partial_data_size ) &&
|
||||
!archive_write( 0, 0 ) ) return 1;
|
||||
block_is_full( extended.full_size(), file_size, gcl_opts->data_size,
|
||||
partial_data_size ) && !archive_write( 0, 0 ) ) return 1;
|
||||
|
||||
if( !write_extended( extended ) || !archive_write( header, header_size ) )
|
||||
return 1;
|
||||
|
@ -312,6 +290,9 @@ int add_member( const char * const filename, const struct stat *,
|
|||
}
|
||||
if( encoder && gcl_opts->solidity == no_solid && !archive_write( 0, 0 ) )
|
||||
return 1;
|
||||
if( gcl_opts->warn_newer && archive_attrs.is_newer( filename ) )
|
||||
{ show_file_error( filename, "File is newer than the archive." );
|
||||
set_error_status( 1 ); }
|
||||
if( verbosity >= 1 ) std::fprintf( stderr, "%s\n", filename );
|
||||
return 0;
|
||||
}
|
||||
|
@ -420,7 +401,7 @@ bool fill_headers( const char * const filename, Extended & extended,
|
|||
if( hstat( filename, &st, gcl_opts->dereference ) != 0 )
|
||||
{ show_file_error( filename, "Can't stat input file", errno );
|
||||
set_error_status( 1 ); return false; }
|
||||
if( file_is_the_archive( st ) )
|
||||
if( archive_attrs.is_the_archive( st ) )
|
||||
{ show_file_error( archive_namep, "File is the archive; not dumped." );
|
||||
return false; }
|
||||
init_tar_header( header );
|
||||
|
@ -516,13 +497,13 @@ bool fill_headers( const char * const filename, Extended & extended,
|
|||
}
|
||||
|
||||
|
||||
bool block_is_full( const Extended & extended,
|
||||
bool block_is_full( const long long extended_size,
|
||||
const unsigned long long file_size,
|
||||
const unsigned long long target_size,
|
||||
unsigned long long & partial_data_size )
|
||||
{
|
||||
const unsigned long long member_size = // may overflow 'long long'
|
||||
header_size + extended.full_size() + round_up( file_size );
|
||||
const unsigned long long target_size = gcl_opts->data_size;
|
||||
header_size + extended_size + round_up( file_size );
|
||||
if( partial_data_size >= target_size ||
|
||||
( partial_data_size >= min_data_size &&
|
||||
partial_data_size + member_size / 2 > target_size ) )
|
||||
|
@ -550,7 +531,7 @@ int final_exit_status( int retval, const bool show_msg )
|
|||
return retval;
|
||||
}
|
||||
|
||||
unsigned ustar_chksum( const uint8_t * const header )
|
||||
unsigned ustar_chksum( const Tar_header header )
|
||||
{
|
||||
unsigned chksum = chksum_l * 0x20; // treat chksum field as spaces
|
||||
for( int i = 0; i < chksum_o; ++i ) chksum += header[i];
|
||||
|
@ -559,7 +540,7 @@ unsigned ustar_chksum( const uint8_t * const header )
|
|||
}
|
||||
|
||||
|
||||
bool verify_ustar_chksum( const uint8_t * const header )
|
||||
bool verify_ustar_chksum( const Tar_header header )
|
||||
{ return ( verify_ustar_magic( header ) &&
|
||||
ustar_chksum( header ) == parse_octal( header + chksum_o, chksum_l ) ); }
|
||||
|
||||
|
@ -575,14 +556,14 @@ bool has_lz_ext( const std::string & name )
|
|||
|
||||
int concatenate( const Cl_options & cl_opts )
|
||||
{
|
||||
if( cl_opts.filenames <= 0 )
|
||||
if( cl_opts.num_files <= 0 )
|
||||
{ if( verbosity >= 1 ) show_error( "Nothing to concatenate." ); return 0; }
|
||||
const bool to_stdout = cl_opts.archive_name.empty();
|
||||
archive_namep = to_stdout ? "(stdout)" : cl_opts.archive_name.c_str();
|
||||
const int outfd =
|
||||
to_stdout ? STDOUT_FILENO : open_outstream( cl_opts.archive_name, false );
|
||||
if( outfd < 0 ) return 1;
|
||||
if( !to_stdout && !file_is_the_archive.init( outfd ) )
|
||||
if( !to_stdout && !archive_attrs.init( outfd ) )
|
||||
{ show_file_error( archive_namep, "Can't stat", errno ); return 1; }
|
||||
int compressed; // tri-state bool
|
||||
if( to_stdout ) compressed = -1; // unknown
|
||||
|
@ -613,7 +594,7 @@ int concatenate( const Cl_options & cl_opts )
|
|||
const int infd = open_instream( filename );
|
||||
if( infd < 0 ) { retval = 1; break; }
|
||||
struct stat st;
|
||||
if( !to_stdout && fstat( infd, &st ) == 0 && file_is_the_archive( st ) )
|
||||
if( !to_stdout && fstat( infd, &st ) == 0 && archive_attrs.is_the_archive( st ) )
|
||||
{ show_file_error( filename, "File is the archive; not concatenated." );
|
||||
close( infd ); continue; }
|
||||
long long size;
|
||||
|
@ -649,23 +630,6 @@ int concatenate( const Cl_options & cl_opts )
|
|||
|
||||
int encode( Cl_options & cl_opts )
|
||||
{
|
||||
struct Lzma_options
|
||||
{
|
||||
int dictionary_size; // 4 KiB .. 512 MiB
|
||||
int match_len_limit; // 5 .. 273
|
||||
};
|
||||
const Lzma_options option_mapping[] =
|
||||
{
|
||||
{ 65535, 16 }, // -0
|
||||
{ 1 << 20, 5 }, // -1
|
||||
{ 3 << 19, 6 }, // -2
|
||||
{ 1 << 21, 8 }, // -3
|
||||
{ 3 << 20, 12 }, // -4
|
||||
{ 1 << 22, 20 }, // -5
|
||||
{ 1 << 23, 36 }, // -6
|
||||
{ 1 << 24, 68 }, // -7
|
||||
{ 3 << 23, 132 }, // -8
|
||||
{ 1 << 25, 273 } }; // -9
|
||||
const bool compressed = ( cl_opts.level >= 0 && cl_opts.level <= 9 );
|
||||
const bool to_stdout = cl_opts.archive_name.empty();
|
||||
archive_namep = to_stdout ? "(stdout)" : cl_opts.archive_name.c_str();
|
||||
|
@ -676,7 +640,7 @@ int encode( Cl_options & cl_opts )
|
|||
"Uncompressed mode incompatible with .lz extension." ); return 2; }
|
||||
|
||||
const bool append = cl_opts.program_mode == m_append;
|
||||
if( cl_opts.filenames <= 0 )
|
||||
if( cl_opts.num_files <= 0 )
|
||||
{
|
||||
if( !append && !to_stdout ) // create archive
|
||||
{ show_error( "Cowardly refusing to create an empty archive.", 0, true );
|
||||
|
@ -701,7 +665,7 @@ int encode( Cl_options & cl_opts )
|
|||
"This does not look like an appendable tar archive." ); return 2; }
|
||||
}
|
||||
|
||||
if( !file_is_the_archive.init( goutfd ) )
|
||||
if( !archive_attrs.init( goutfd ) )
|
||||
{ show_file_error( archive_namep, "Can't stat", errno ); return 1; }
|
||||
|
||||
if( compressed )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue