summaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c105
1 files changed, 58 insertions, 47 deletions
diff --git a/main.c b/main.c
index 9a14137..2ff4a15 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,5 @@
/* Lunzip - Decompressor for the lzip format
- Copyright (C) 2010-2018 Antonio Diaz Diaz.
+ Copyright (C) 2010-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
@@ -36,19 +36,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"
@@ -65,9 +70,8 @@
int verbosity = 0;
-const char * const Program_name = "Lunzip";
const char * const program_name = "lunzip";
-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[] = {
@@ -77,6 +81,8 @@ const struct { const char * from; const char * to; } known_extensions[] = {
enum Mode { m_compress, m_decompress, m_list, 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;
@@ -260,7 +266,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 && *tail == 0 )
- return ( 1 << bits );
+ return 1 << bits;
return getnum( arg, min_dictionary_size, max_dictionary_size );
}
@@ -368,8 +374,17 @@ static bool open_outstream( const bool force, const bool from_stdin )
}
+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;
@@ -384,6 +399,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 )
{
@@ -455,9 +478,9 @@ static bool show_trailing_data( const uint8_t * const data, const int size,
static int decompress( const unsigned long long cfile_size, const int infd,
- struct Pretty_print * const pp, const unsigned buffer_size,
- const bool ignore_trailing, const bool loose_trailing,
- const bool testing )
+ struct Pretty_print * const pp, const unsigned buffer_size,
+ const bool ignore_trailing, const bool loose_trailing,
+ const bool testing )
{
unsigned long long partial_file_pos = 0;
struct Range_decoder rdec;
@@ -473,16 +496,16 @@ static int decompress( const unsigned long long cfile_size, const int infd,
{
int result, size;
unsigned dictionary_size;
- File_header header;
+ Lzip_header header;
struct LZ_decoder decoder;
Rd_reset_member_position( &rdec );
- size = Rd_read_data( &rdec, header, Fh_size );
+ size = Rd_read_data( &rdec, header, Lh_size );
if( Rd_finished( &rdec ) ) /* 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." );
show_trailing_data( header, size, pp, true, -1 );
retval = 2; }
@@ -491,11 +514,11 @@ static int decompress( const unsigned long long cfile_size, const int infd,
retval = 2;
break;
}
- if( !Fh_verify_magic( header ) )
+ if( !Lh_verify_magic( header ) )
{
if( first_member )
{ show_file_error( pp->name, bad_magic_msg, 0 ); retval = 2; }
- else if( !loose_trailing && Fh_verify_corrupt( header ) )
+ else if( !loose_trailing && Lh_verify_corrupt( header ) )
{ Pp_show_msg( pp, corrupt_mm_msg );
show_trailing_data( header, size, pp, false, -1 );
retval = 2; }
@@ -503,10 +526,10 @@ static int decompress( const unsigned long long cfile_size, const int infd,
retval = 2;
break;
}
- if( !Fh_verify_version( header ) )
- { Pp_show_msg( pp, bad_version( Fh_version( header ) ) );
+ if( !Lh_verify_version( header ) )
+ { Pp_show_msg( pp, bad_version( 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, bad_dict_msg ); retval = 2; break; }
@@ -528,7 +551,8 @@ static int decompress( const unsigned long long cfile_size, const int infd,
{
Pp_show_msg( pp, 0 );
fprintf( stderr, "%s at pos %llu\n", ( result == 2 ) ?
- "File ends unexpectedly" : "Decoder error", partial_file_pos );
+ "File ends unexpectedly" : "Decoder error",
+ partial_file_pos );
}
retval = 2; break;
}
@@ -542,31 +566,13 @@ static int decompress( const unsigned long long cfile_size, const int infd,
}
-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 );
- }
-
-
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 );
@@ -576,10 +582,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 ) : "" );
}
@@ -698,7 +704,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
@@ -737,7 +743,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 );
@@ -825,6 +831,12 @@ int main( const int argc, const char * const argv[] )
( in_statsp->st_size + 99 ) / 100 : 0;
tmp = decompress( cfile_size, infd, &pp, buffer_size, 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 );
@@ -834,7 +846,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 );
}