summaryrefslogtreecommitdiffstats
path: root/main.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--main.cc94
1 files changed, 49 insertions, 45 deletions
diff --git a/main.cc b/main.cc
index 19d4324..e5b1cbc 100644
--- a/main.cc
+++ b/main.cc
@@ -1,5 +1,5 @@
/* Lziprecover - Data recovery tool for lzip files
- Copyright (C) 2009, 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
+ Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 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
@@ -56,6 +56,10 @@
#include "lzip.h"
#include "decoder.h"
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
#if CHAR_BIT != 8
#error "Environments where CHAR_BIT != 8 are not supported."
#endif
@@ -65,22 +69,16 @@ namespace {
const char * const Program_name = "Lziprecover";
const char * const program_name = "lziprecover";
-const char * const program_year = "2013";
+const char * const program_year = "2014";
const char * invocation_name = 0;
-#ifdef O_BINARY
-const int o_binary = O_BINARY;
-#else
-const int o_binary = 0;
-#endif
-
struct { const char * from; const char * to; } const known_extensions[] = {
{ ".lz", "" },
{ ".tlz", ".tar" },
{ 0, 0 } };
-enum Mode { m_none, m_decompress, m_generate, m_list, m_merge, m_range,
- m_recover, m_repair, m_split, m_test };
+enum Mode { m_none, m_decompress, m_list, m_merge, m_range, m_repair,
+ m_split, m_test };
std::string output_filename;
int outfd = -1;
@@ -102,14 +100,12 @@ void show_help()
" -d, --decompress decompress\n"
" -D, --range-decompress=<range> decompress only a range of bytes (N-M)\n"
" -f, --force overwrite existing output files\n"
-// " -g, --generate-recover-file generate a recover file\n"
" -i, --ignore-errors make '--range-decompress' ignore data errors\n"
" -k, --keep keep (don't delete) input files\n"
" -l, --list print total file sizes and ratios\n"
" -m, --merge correct errors in file using several copies\n"
" -o, --output=<file> place the output into <file>\n"
" -q, --quiet suppress all messages\n"
-// " -r, --recover correct errors in file using a recover file\n"
" -R, --repair try to repair a small error in file\n"
" -s, --split split multi-member file in single-member files\n"
" -t, --test test compressed file integrity\n"
@@ -127,7 +123,7 @@ void show_help()
void show_version()
{
- std::printf( "%s %s\n", Program_name, PROGVERSION );
+ std::printf( "%s %s\n", program_name, PROGVERSION );
std::printf( "Copyright (C) %s Antonio Diaz Diaz.\n", program_year );
std::printf( "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n"
"This is free software: you are free to change and redistribute it.\n"
@@ -189,15 +185,15 @@ int extension_index( const std::string & name )
} // end namespace
-int open_instream( const std::string & name, struct stat * const in_statsp,
+int open_instream( const char * const name, struct stat * const in_statsp,
const bool no_ofile, const bool reg_only )
{
- int infd = open( name.c_str(), O_RDONLY | o_binary );
+ int infd = open( name, O_RDONLY | O_BINARY );
if( infd < 0 )
{
if( verbosity >= 0 )
std::fprintf( stderr, "%s: Can't open input file '%s': %s.\n",
- program_name, name.c_str(), std::strerror( errno ) );
+ program_name, name, std::strerror( errno ) );
}
else
{
@@ -210,7 +206,7 @@ int open_instream( const std::string & name, struct stat * const in_statsp,
{
if( verbosity >= 0 )
std::fprintf( stderr, "%s: Input file '%s' is not a regular file%s.\n",
- program_name, name.c_str(),
+ program_name, name,
( can_read && !no_ofile ) ?
" and '--stdout' was not specified" : "" );
close( infd );
@@ -243,7 +239,7 @@ void set_d_outname( const std::string & name, const int i )
bool open_outstream( const bool force )
{
- int flags = O_CREAT | O_WRONLY | o_binary;
+ int flags = O_CREAT | O_WRONLY | O_BINARY;
if( force ) flags |= O_TRUNC; else flags |= O_EXCL;
outfd = open( output_filename.c_str(), flags, outfd_mode );
@@ -293,10 +289,14 @@ void close_and_set_permissions( const struct stat * const in_statsp )
bool warning = false;
if( in_statsp )
{
+ const mode_t mode = in_statsp->st_mode;
// fchown will in many cases return with EPERM, which can be safely ignored.
- if( ( fchown( outfd, in_statsp->st_uid, in_statsp->st_gid ) != 0 &&
- errno != EPERM ) ||
- fchmod( outfd, in_statsp->st_mode ) != 0 ) warning = true;
+ if( fchown( outfd, in_statsp->st_uid, in_statsp->st_gid ) == 0 )
+ { if( fchmod( outfd, mode ) != 0 ) warning = true; }
+ else
+ if( errno != EPERM ||
+ fchmod( outfd, mode & ~( S_ISUID | S_ISGID | S_ISVTX ) ) != 0 )
+ warning = true;
}
if( close( outfd ) != 0 ) cleanup_and_fail( 1 );
outfd = -1;
@@ -356,6 +356,7 @@ void show_trailing_garbage( const uint8_t * const data, const int size,
garbage_msg += xdigit( data[i] & 0x0F );
}
}
+ garbage_msg += '.';
pp( garbage_msg.c_str() );
}
@@ -375,7 +376,7 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
if( rdec.finished() ) // End Of File
{
if( first_member )
- { pp( "File ends unexpectedly at member header" ); retval = 2; }
+ { pp( "File ends unexpectedly at member header." ); retval = 2; }
else if( verbosity >= 4 && size > 0 )
show_trailing_garbage( header.data, size, pp, true );
break;
@@ -383,7 +384,7 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
if( !header.verify_magic() )
{
if( first_member )
- { pp( "Bad magic number (file not in lzip format)" ); retval = 2; }
+ { pp( "Bad magic number (file not in lzip format)." ); retval = 2; }
else if( verbosity >= 4 )
show_trailing_garbage( header.data, size, pp, false );
break;
@@ -398,7 +399,7 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
}
if( header.dictionary_size() < min_dictionary_size ||
header.dictionary_size() > max_dictionary_size )
- { pp( "Invalid dictionary size in member header" ); retval = 2; break; }
+ { pp( "Invalid dictionary size in member header." ); retval = 2; break; }
if( verbosity >= 2 || ( verbosity == 1 && first_member ) )
{ pp(); if( verbosity >= 3 ) show_header( header ); }
@@ -412,10 +413,10 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
{
pp();
if( result == 2 )
- std::fprintf( stderr, "File ends unexpectedly at pos %llu\n",
+ std::fprintf( stderr, "File ends unexpectedly at pos %llu.\n",
partial_file_pos );
else
- std::fprintf( stderr, "Decoder error at pos %llu\n",
+ std::fprintf( stderr, "Decoder error at pos %llu.\n",
partial_file_pos );
}
retval = 2; break;
@@ -424,11 +425,7 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
{ std::fprintf( stderr, testing ? "ok\n" : "done\n" ); pp.reset(); }
}
}
- catch( std::bad_alloc )
- {
- pp( "Not enough memory. Find a machine with more memory" );
- retval = 1;
- }
+ catch( std::bad_alloc ) { pp( "Not enough memory." ); retval = 1; }
catch( Error e ) { pp(); show_error( e.msg, errno ); retval = 1; }
if( verbosity == 1 && retval == 0 )
std::fprintf( stderr, testing ? "ok\n" : "done\n" );
@@ -455,7 +452,7 @@ void set_signals()
int open_outstream_rw( const std::string & output_filename, const bool force )
{
- int flags = O_CREAT | O_RDWR | o_binary;
+ int flags = O_CREAT | O_RDWR | O_BINARY;
if( force ) flags |= O_TRUNC; else flags |= O_EXCL;
int outfd = open( output_filename.c_str(), flags, all_rw );
@@ -481,7 +478,7 @@ void show_error( const char * const msg, const int errcode, const bool help )
{
std::fprintf( stderr, "%s: %s", program_name, msg );
if( errcode > 0 )
- std::fprintf( stderr, ": %s", std::strerror( errcode ) );
+ std::fprintf( stderr, ": %s.", std::strerror( errcode ) );
std::fprintf( stderr, "\n" );
}
if( help )
@@ -491,10 +488,18 @@ void show_error( const char * const msg, const int errcode, const bool help )
}
+void show_error2( const char * const msg1, const char * const name,
+ const char * const msg2 )
+ {
+ if( verbosity >= 0 )
+ std::fprintf( stderr, "%s: %s '%s' %s\n", program_name, msg1, name, msg2 );
+ }
+
+
void internal_error( const char * const msg )
{
if( verbosity >= 0 )
- std::fprintf( stderr, "%s: internal error: %s.\n", program_name, msg );
+ std::fprintf( stderr, "%s: internal error: %s\n", program_name, msg );
std::exit( 3 );
}
@@ -564,7 +569,7 @@ int main( const int argc, const char * const argv[] )
case 't': set_mode( program_mode, m_test ); break;
case 'v': if( verbosity < 4 ) ++verbosity; break;
case 'V': show_version(); return 0;
- default : internal_error( "uncaught option" );
+ default : internal_error( "uncaught option." );
}
} // end process options
@@ -588,9 +593,7 @@ int main( const int argc, const char * const argv[] )
switch( program_mode )
{
- case m_generate:
- case m_recover:
- case m_none: internal_error( "invalid operation" ); break;
+ case m_none: internal_error( "invalid operation." ); break;
case m_decompress: break;
case m_list:
if( filenames.size() < 1 )
@@ -599,7 +602,7 @@ int main( const int argc, const char * const argv[] )
case m_merge:
if( filenames.size() < 2 )
{ show_error( "You must specify at least 2 files.", 0, true ); return 1; }
- if( !default_output_filename.size() )
+ if( default_output_filename.empty() )
default_output_filename = insert_fixed( filenames[0] );
return merge_files( filenames, default_output_filename, verbosity, force );
case m_range:
@@ -608,9 +611,10 @@ int main( const int argc, const char * const argv[] )
range_string, verbosity, force, ignore, to_stdout );
case m_repair:
one_file( filenames.size() );
- if( !default_output_filename.size() )
+ if( default_output_filename.empty() )
default_output_filename = insert_fixed( filenames[0] );
- return repair_file( filenames[0], default_output_filename, verbosity, force );
+ return repair_file( filenames[0], default_output_filename,
+ verbosity, force );
case m_split:
one_file( filenames.size() );
return split_file( filenames[0], default_output_filename, verbosity, force );
@@ -620,7 +624,7 @@ int main( const int argc, const char * const argv[] )
if( program_mode == m_test )
outfd = -1;
else if( program_mode != m_decompress )
- internal_error( "invalid decompressor operation" );
+ internal_error( "invalid decompressor operation." );
if( filenames.empty() ) filenames.push_back("-");
if( !to_stdout && program_mode != m_test &&
@@ -635,13 +639,13 @@ int main( const int argc, const char * const argv[] )
struct stat in_stats;
output_filename.clear();
- if( !filenames[i].size() || filenames[i] == "-" )
+ if( filenames[i].empty() || filenames[i] == "-" )
{
input_filename.clear();
infd = STDIN_FILENO;
if( program_mode != m_test )
{
- if( to_stdout || !default_output_filename.size() )
+ if( to_stdout || default_output_filename.empty() )
outfd = STDOUT_FILENO;
else
{
@@ -659,7 +663,7 @@ int main( const int argc, const char * const argv[] )
else
{
input_filename = filenames[i];
- infd = open_instream( input_filename, &in_stats,
+ infd = open_instream( input_filename.c_str(), &in_stats,
to_stdout || program_mode == m_test );
if( infd < 0 ) { if( retval < 1 ) retval = 1; continue; }
if( program_mode != m_test )