Merging upstream version 1.10.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
b2b52b515a
commit
9ad9f8e387
12 changed files with 276 additions and 193 deletions
153
main.c
153
main.c
|
@ -1,6 +1,6 @@
|
|||
/* Pdlzip - LZMA lossless data compressor
|
||||
2009-08-14 : Igor Pavlov : Public domain
|
||||
Copyright (C) 2010-2018 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010-2019 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
|
@ -38,19 +38,24 @@
|
|||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#include <sys/stat.h>
|
||||
#if defined(__MSVCRT__)
|
||||
#if defined(__MSVCRT__) || defined(__OS2__) || defined(__DJGPP__)
|
||||
#include <io.h>
|
||||
#if defined(__MSVCRT__)
|
||||
#define fchmod(x,y) 0
|
||||
#define fchown(x,y,z) 0
|
||||
#define SIGHUP SIGTERM
|
||||
#define S_ISSOCK(x) 0
|
||||
#ifndef S_IRGRP
|
||||
#define S_IRGRP 0
|
||||
#define S_IWGRP 0
|
||||
#define S_IROTH 0
|
||||
#define S_IWOTH 0
|
||||
#endif
|
||||
#if defined(__OS2__)
|
||||
#include <io.h>
|
||||
#endif
|
||||
#if defined(__DJGPP__)
|
||||
#define S_ISSOCK(x) 0
|
||||
#define S_ISVTX 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "carg_parser.h"
|
||||
|
@ -68,9 +73,8 @@
|
|||
|
||||
int verbosity = 0;
|
||||
|
||||
const char * const Program_name = "Pdlzip";
|
||||
const char * const program_name = "pdlzip";
|
||||
const char * const program_year = "2018";
|
||||
const char * const program_year = "2019";
|
||||
const char * invocation_name = 0;
|
||||
|
||||
const struct { const char * from; const char * to; } known_extensions[] = {
|
||||
|
@ -87,6 +91,8 @@ struct Lzma_options
|
|||
|
||||
enum Mode { m_compress, m_decompress, m_test };
|
||||
|
||||
/* Variables used in signal handler context.
|
||||
They are not declared volatile because the handler never returns. */
|
||||
char * output_filename = 0;
|
||||
int outfd = -1;
|
||||
bool delete_output_on_interrupt = false;
|
||||
|
@ -94,9 +100,20 @@ bool delete_output_on_interrupt = false;
|
|||
|
||||
static void show_help( void )
|
||||
{
|
||||
printf( "%s - A permissively licensed implementation of the lzip data\n", Program_name );
|
||||
printf( "compressor also able to decompress legacy lzma-alone (.lzma) files.\n"
|
||||
"\nLzma-alone is a very bad format; it is essentially a raw LZMA stream.\n"
|
||||
printf( "Pdlzip is a permissively licensed implementation of the lzip data\n"
|
||||
"compressor, intended for those who can't distribute (or even use) GPL\n"
|
||||
"licensed Free Software. (The name of pdlzip comes from 'public domain\n"
|
||||
"lzip'). Pdlzip is written in C and is (hope)fully compatible with lzip 1.4\n"
|
||||
"or newer.\n"
|
||||
"\nLzip is a lossless data compressor with a user interface similar to the\n"
|
||||
"one of gzip or bzip2. Lzip can compress about as fast as gzip (lzip -0)\n"
|
||||
"or compress most files more than bzip2 (lzip -9). Decompression speed is\n"
|
||||
"intermediate between gzip and bzip2. Lzip is better than gzip and bzip2\n"
|
||||
"from a data recovery perspective. Lzip has been designed, written and\n"
|
||||
"tested with great care to replace gzip and bzip2 as the standard\n"
|
||||
"general-purpose compressed format for unix-like systems.\n"
|
||||
"\nPdlzip is also able to decompress legacy lzma-alone (.lzma) files.\n"
|
||||
"Lzma-alone is a very bad format; it is essentially a raw LZMA stream.\n"
|
||||
"If you keep any lzma-alone files, it is advisable to recompress them to\n"
|
||||
"lzip format. Lziprecover can convert some lzma-alone files to lzip format\n"
|
||||
"without recompressing.\n"
|
||||
|
@ -116,8 +133,8 @@ static void show_help( void )
|
|||
" -s, --dictionary-size=<bytes> set dictionary size limit in bytes [8 MiB]\n"
|
||||
" -t, --test test compressed file integrity\n"
|
||||
" -v, --verbose be verbose (a 2nd -v gives more)\n"
|
||||
" -1 .. -9 set compression level [default 6]\n"
|
||||
" --fast alias for -1\n"
|
||||
" -0 .. -9 set compression level [default 6]\n"
|
||||
" --fast alias for -0\n"
|
||||
" --best alias for -9\n"
|
||||
" --loose-trailing allow trailing data seeming corrupt header\n"
|
||||
"If no file names are given, or if a file is '-', pdlzip compresses or\n"
|
||||
|
@ -255,7 +272,7 @@ static int get_dict_size( const char * const arg )
|
|||
const long bits = strtol( arg, &tail, 0 );
|
||||
if( bits >= min_dictionary_bits &&
|
||||
bits <= max_dictionary_bits_c && *tail == 0 )
|
||||
return ( 1 << bits );
|
||||
return 1 << bits;
|
||||
return getnum( arg, min_dictionary_size, max_dictionary_size_c );
|
||||
}
|
||||
|
||||
|
@ -393,8 +410,17 @@ static bool check_tty( const char * const input_filename, const int infd,
|
|||
}
|
||||
|
||||
|
||||
static void set_signals( void (*action)(int) )
|
||||
{
|
||||
signal( SIGHUP, action );
|
||||
signal( SIGINT, action );
|
||||
signal( SIGTERM, action );
|
||||
}
|
||||
|
||||
|
||||
void cleanup_and_fail( const int retval )
|
||||
{
|
||||
set_signals( SIG_IGN ); /* ignore signals */
|
||||
if( delete_output_on_interrupt )
|
||||
{
|
||||
delete_output_on_interrupt = false;
|
||||
|
@ -409,6 +435,14 @@ void cleanup_and_fail( const int retval )
|
|||
}
|
||||
|
||||
|
||||
void signal_handler( int sig )
|
||||
{
|
||||
if( sig ) {} /* keep compiler happy */
|
||||
show_error( "Control-C or similar caught, quitting.", 0, false );
|
||||
cleanup_and_fail( 1 );
|
||||
}
|
||||
|
||||
|
||||
/* Set permissions, owner and times. */
|
||||
static void close_and_set_permissions( const struct stat * const in_statsp )
|
||||
{
|
||||
|
@ -448,14 +482,14 @@ static int compress( const struct Lzma_options * const encoder_options,
|
|||
{
|
||||
int retval = 0;
|
||||
CLzmaEncHandle encoder = 0;
|
||||
File_header header;
|
||||
Fh_set_magic( header );
|
||||
Lzip_header header;
|
||||
Lh_set_magic( header );
|
||||
|
||||
if( verbosity >= 1 ) Pp_show_msg( pp, 0 );
|
||||
if( Fh_set_dictionary_size( header, encoder_options->dictionary_size ) &&
|
||||
if( Lh_set_dictionary_size( header, encoder_options->dictionary_size ) &&
|
||||
encoder_options->match_len_limit >= min_match_len_limit &&
|
||||
encoder_options->match_len_limit <= max_match_len )
|
||||
encoder = LzmaEnc_Init( Fh_get_dictionary_size( header ),
|
||||
encoder = LzmaEnc_Init( Lh_get_dictionary_size( header ),
|
||||
encoder_options->match_len_limit, infd, outfd );
|
||||
else internal_error( "invalid argument to encoder." );
|
||||
|
||||
|
@ -465,7 +499,7 @@ static int compress( const struct Lzma_options * const encoder_options,
|
|||
return 1;
|
||||
}
|
||||
|
||||
if( writeblock( outfd, header, Fh_size ) != Fh_size )
|
||||
if( writeblock( outfd, header, Lh_size ) != Lh_size )
|
||||
{ show_error( "Can't write output file", errno, false ); retval = 1; }
|
||||
else
|
||||
if( LzmaEnc_Encode( encoder ) != 0 )
|
||||
|
@ -578,7 +612,7 @@ static int lzip_decode( CLzmaDec *decoder, const int infd,
|
|||
int * const inPos, int * const inSize,
|
||||
const unsigned dictionary_size )
|
||||
{
|
||||
unsigned long long member_size = Fh_size, data_size = 0;
|
||||
unsigned long long member_size = Lh_size, data_size = 0;
|
||||
uint8_t outBuf[OUT_BUF_SIZE];
|
||||
int outPos = 0;
|
||||
uint32_t crc = 0xFFFFFFFFU;
|
||||
|
@ -612,7 +646,7 @@ static int lzip_decode( CLzmaDec *decoder, const int infd,
|
|||
|
||||
if (inProcessed == 0 && outProcessed == 0)
|
||||
{
|
||||
File_trailer trailer;
|
||||
Lzip_trailer trailer;
|
||||
int i;
|
||||
unsigned td_crc;
|
||||
unsigned long long td_size, tm_size;
|
||||
|
@ -620,9 +654,9 @@ static int lzip_decode( CLzmaDec *decoder, const int infd,
|
|||
|
||||
if( status != LZMA_STATUS_FINISHED_WITH_MARK )
|
||||
{ Pp_show_msg( pp, "Data error." ); return 2; }
|
||||
if( *inSize - *inPos < Ft_size &&
|
||||
if( *inSize - *inPos < Lt_size &&
|
||||
!read_inbuf( infd, inBuf, inPos, inSize ) ) return 1;
|
||||
if( *inSize - *inPos < Ft_size )
|
||||
if( *inSize - *inPos < Lt_size )
|
||||
{
|
||||
error = true;
|
||||
if( verbosity >= 0 )
|
||||
|
@ -632,12 +666,12 @@ static int lzip_decode( CLzmaDec *decoder, const int infd,
|
|||
" some checks may fail.\n", *inSize - *inPos );
|
||||
}
|
||||
}
|
||||
for( i = 0; i < Ft_size && *inPos < *inSize; ++i )
|
||||
for( i = 0; i < Lt_size && *inPos < *inSize; ++i )
|
||||
trailer[i] = inBuf[(*inPos)++];
|
||||
member_size += i;
|
||||
while( i < Ft_size ) trailer[i++] = 0;
|
||||
while( i < Lt_size ) trailer[i++] = 0;
|
||||
crc ^= 0xFFFFFFFFU;
|
||||
td_crc = Ft_get_data_crc( trailer );
|
||||
td_crc = Lt_get_data_crc( trailer );
|
||||
if( td_crc != crc )
|
||||
{
|
||||
error = true;
|
||||
|
@ -648,7 +682,7 @@ static int lzip_decode( CLzmaDec *decoder, const int infd,
|
|||
td_crc, crc );
|
||||
}
|
||||
}
|
||||
td_size = Ft_get_data_size( trailer );
|
||||
td_size = Lt_get_data_size( trailer );
|
||||
if( td_size != data_size )
|
||||
{
|
||||
error = true;
|
||||
|
@ -659,7 +693,7 @@ static int lzip_decode( CLzmaDec *decoder, const int infd,
|
|||
td_size, td_size, data_size, data_size );
|
||||
}
|
||||
}
|
||||
tm_size = Ft_get_member_size( trailer );
|
||||
tm_size = Lt_get_member_size( trailer );
|
||||
if( tm_size != member_size )
|
||||
{
|
||||
error = true;
|
||||
|
@ -709,38 +743,38 @@ static int decompress( const int infd, struct Pretty_print * const pp,
|
|||
{
|
||||
int i, size;
|
||||
unsigned dictionary_size;
|
||||
File_header header;
|
||||
Lzip_header header;
|
||||
if( inSize - inPos < lzma_header_size &&
|
||||
!read_inbuf( infd, inBuf, &inPos, &inSize ) ) return 1;
|
||||
size = inSize - inPos;
|
||||
for( i = 0; i < size && i < Fh_size; ++i )
|
||||
for( i = 0; i < size && i < Lh_size; ++i )
|
||||
raw_props[i] = header[i] = inBuf[inPos++];
|
||||
if( size <= Fh_size ) /* End Of File */
|
||||
if( size <= Lh_size ) /* End Of File */
|
||||
{
|
||||
if( first_member )
|
||||
{ show_file_error( pp->name, "File ends unexpectedly at member header.", 0 );
|
||||
retval = 2; }
|
||||
else if( Fh_verify_prefix( header, size ) )
|
||||
else if( Lh_verify_prefix( header, size ) )
|
||||
{ Pp_show_msg( pp, "Truncated header in multimember file." );
|
||||
retval = 2; }
|
||||
else if( size > 0 && !ignore_trailing )
|
||||
{ Pp_show_msg( pp, trailing_msg ); retval = 2; }
|
||||
break;
|
||||
}
|
||||
if( !Fh_verify_magic( header ) )
|
||||
if( !Lh_verify_magic( header ) )
|
||||
{
|
||||
if( !first_member )
|
||||
{
|
||||
if( !loose_trailing && Fh_verify_corrupt( header ) )
|
||||
if( !loose_trailing && Lh_verify_corrupt( header ) )
|
||||
{ Pp_show_msg( pp, "Corrupt header in multimember file." );
|
||||
retval = 2; }
|
||||
else if( !ignore_trailing )
|
||||
{ Pp_show_msg( pp, trailing_msg ); retval = 2; }
|
||||
break;
|
||||
}
|
||||
if( inSize - inPos >= lzma_header_size - Fh_size ) /* try lzma-alone */
|
||||
if( inSize - inPos >= lzma_header_size - Lh_size ) /* try lzma-alone */
|
||||
{
|
||||
for( i = Fh_size; i < lzma_header_size; ++i )
|
||||
for( i = Lh_size; i < lzma_header_size; ++i )
|
||||
raw_props[i] = inBuf[inPos++];
|
||||
if( ( raw_props[12] == 0 || raw_props[12] == 0xFF ) &&
|
||||
raw_props[12] == raw_props[11] && raw_props[0] < (9 * 5 * 5) )
|
||||
|
@ -763,15 +797,15 @@ static int decompress( const int infd, struct Pretty_print * const pp,
|
|||
if( lzip_mode )
|
||||
{
|
||||
int ds, i;
|
||||
if( !Fh_verify_version( header ) )
|
||||
if( !Lh_verify_version( header ) )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
{ Pp_show_msg( pp, 0 );
|
||||
fprintf( stderr, "Version %d member format not supported.\n",
|
||||
Fh_version( header ) ); }
|
||||
Lh_version( header ) ); }
|
||||
retval = 2; break;
|
||||
}
|
||||
dictionary_size = Fh_get_dictionary_size( header );
|
||||
dictionary_size = Lh_get_dictionary_size( header );
|
||||
if( !isvalid_ds( dictionary_size ) )
|
||||
{ Pp_show_msg( pp, "Invalid dictionary size in member header." );
|
||||
retval = 2; break; }
|
||||
|
@ -803,22 +837,6 @@ static int decompress( const int infd, struct Pretty_print * const pp,
|
|||
}
|
||||
|
||||
|
||||
void signal_handler( int sig )
|
||||
{
|
||||
if( sig ) {} /* keep compiler happy */
|
||||
show_error( "Control-C or similar caught, quitting.", 0, false );
|
||||
cleanup_and_fail( 1 );
|
||||
}
|
||||
|
||||
|
||||
static void set_signals( void )
|
||||
{
|
||||
signal( SIGHUP, signal_handler );
|
||||
signal( SIGINT, signal_handler );
|
||||
signal( SIGTERM, signal_handler );
|
||||
}
|
||||
|
||||
|
||||
CRC32 crc32;
|
||||
|
||||
|
||||
|
@ -863,11 +881,9 @@ void show_error( const char * const msg, const int errcode, const bool help )
|
|||
{
|
||||
if( verbosity < 0 ) return;
|
||||
if( msg && msg[0] )
|
||||
{
|
||||
fprintf( stderr, "%s: %s", program_name, msg );
|
||||
if( errcode > 0 ) fprintf( stderr, ": %s", strerror( errcode ) );
|
||||
fputc( '\n', stderr );
|
||||
}
|
||||
fprintf( stderr, "%s: %s%s%s\n", program_name, msg,
|
||||
( errcode > 0 ) ? ": " : "",
|
||||
( errcode > 0 ) ? strerror( errcode ) : "" );
|
||||
if( help )
|
||||
fprintf( stderr, "Try '%s --help' for more information.\n",
|
||||
invocation_name );
|
||||
|
@ -877,10 +893,10 @@ void show_error( const char * const msg, const int errcode, const bool help )
|
|||
void show_file_error( const char * const filename, const char * const msg,
|
||||
const int errcode )
|
||||
{
|
||||
if( verbosity < 0 ) return;
|
||||
fprintf( stderr, "%s: %s: %s", program_name, filename, msg );
|
||||
if( errcode > 0 ) fprintf( stderr, ": %s", strerror( errcode ) );
|
||||
fputc( '\n', stderr );
|
||||
if( verbosity >= 0 )
|
||||
fprintf( stderr, "%s: %s: %s%s%s\n", program_name, filename, msg,
|
||||
( errcode > 0 ) ? ": " : "",
|
||||
( errcode > 0 ) ? strerror( errcode ) : "" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -898,7 +914,7 @@ int main( const int argc, const char * const argv[] )
|
|||
to the corresponding LZMA compression modes. */
|
||||
const struct Lzma_options option_mapping[] =
|
||||
{
|
||||
{ 1 << 20, 5 }, /* -0 */
|
||||
{ 1 << 16, 5 }, /* -0 */
|
||||
{ 1 << 20, 5 }, /* -1 */
|
||||
{ 3 << 19, 6 }, /* -2 */
|
||||
{ 1 << 21, 8 }, /* -3 */
|
||||
|
@ -1004,7 +1020,7 @@ int main( const int argc, const char * const argv[] )
|
|||
}
|
||||
} /* end process options */
|
||||
|
||||
#if defined(__MSVCRT__) || defined(__OS2__)
|
||||
#if defined(__MSVCRT__) || defined(__OS2__) || defined(__DJGPP__)
|
||||
setmode( STDIN_FILENO, O_BINARY );
|
||||
setmode( STDOUT_FILENO, O_BINARY );
|
||||
#endif
|
||||
|
@ -1024,7 +1040,7 @@ int main( const int argc, const char * const argv[] )
|
|||
|
||||
if( !to_stdout && program_mode != m_test &&
|
||||
( filenames_given || default_output_filename[0] ) )
|
||||
set_signals();
|
||||
set_signals( signal_handler );
|
||||
|
||||
Pp_init( &pp, filenames, num_filenames );
|
||||
|
||||
|
@ -1103,6 +1119,12 @@ int main( const int argc, const char * const argv[] )
|
|||
else
|
||||
tmp = decompress( infd, &pp, ignore_trailing,
|
||||
loose_trailing, program_mode == m_test );
|
||||
if( close( infd ) != 0 )
|
||||
{
|
||||
show_error( input_filename[0] ? "Error closing input file" :
|
||||
"Error closing stdin", errno, false );
|
||||
if( tmp < 1 ) tmp = 1;
|
||||
}
|
||||
if( tmp > retval ) retval = tmp;
|
||||
if( tmp )
|
||||
{ if( program_mode != m_test ) cleanup_and_fail( retval );
|
||||
|
@ -1112,7 +1134,6 @@ int main( const int argc, const char * const argv[] )
|
|||
close_and_set_permissions( in_statsp );
|
||||
if( input_filename[0] )
|
||||
{
|
||||
close( infd );
|
||||
if( !keep_input_files && !to_stdout && program_mode != m_test )
|
||||
remove( input_filename );
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue