summaryrefslogtreecommitdiffstats
path: root/main.cc
diff options
context:
space:
mode:
Diffstat (limited to 'main.cc')
-rw-r--r--main.cc69
1 files changed, 35 insertions, 34 deletions
diff --git a/main.cc b/main.cc
index eaa93fd..a012d73 100644
--- a/main.cc
+++ b/main.cc
@@ -1,5 +1,6 @@
/* Lzip - LZMA lossless data compressor
- Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
+ Copyright (C) 2008, 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
@@ -59,6 +60,10 @@
#include "encoder.h"
#include "fast_encoder.h"
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
#if CHAR_BIT != 8
#error "Environments where CHAR_BIT != 8 are not supported."
#endif
@@ -68,15 +73,9 @@ namespace {
const char * const Program_name = "Lzip";
const char * const program_name = "lzip";
-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" },
@@ -260,7 +259,8 @@ int open_instream( const char * const name, struct stat * const in_statsp,
}
else
{
- infd = open( name, O_RDONLY | o_binary );
+ do infd = open( name, O_RDONLY | O_BINARY );
+ while( infd < 0 && errno == EINTR );
if( infd < 0 )
{
if( verbosity >= 0 )
@@ -320,10 +320,11 @@ 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 );
+ do outfd = open( output_filename.c_str(), flags, outfd_mode );
+ while( outfd < 0 && errno == EINTR );
if( outfd < 0 && verbosity >= 0 )
{
if( errno == EEXIST )
@@ -376,10 +377,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;
@@ -414,6 +419,8 @@ int compress( const unsigned long long member_size,
const Lzma_options & encoder_options, const int infd,
const Pretty_print & pp, const struct stat * const in_statsp )
{
+ const unsigned long long cfile_size =
+ (in_statsp && S_ISREG( in_statsp->st_mode )) ? in_statsp->st_size / 100 : 0;
int retval = 0;
File_header header;
header.set_magic();
@@ -435,7 +442,8 @@ int compress( const unsigned long long member_size,
LZ_encoder encoder( matchfinder, header, outfd );
const unsigned long long size = ( volume_size > 0 ) ?
std::min( member_size, volume_size - partial_volume_size ) : member_size;
- show_progress( in_size, &matchfinder, &pp, in_statsp ); // init
+ if( verbosity >= 2 )
+ show_progress( in_size, &matchfinder, &pp, cfile_size ); // init
if( !encoder.encode_member( size ) )
{ pp( "Encoder error" ); retval = 1; break; }
in_size += matchfinder.data_position();
@@ -487,6 +495,8 @@ int fcompress( const unsigned long long member_size,
const unsigned long long volume_size, const int infd,
const Pretty_print & pp, const struct stat * const in_statsp )
{
+ const unsigned long long cfile_size =
+ (in_statsp && S_ISREG( in_statsp->st_mode )) ? in_statsp->st_size / 100 : 0;
int retval = 0;
File_header header;
header.set_magic();
@@ -503,7 +513,8 @@ int fcompress( const unsigned long long member_size,
FLZ_encoder encoder( fmatchfinder, header, outfd );
const unsigned long long size = ( volume_size > 0 ) ?
std::min( member_size, volume_size - partial_volume_size ) : member_size;
- show_progress( in_size, &fmatchfinder, &pp, in_statsp ); // init
+ if( verbosity >= 2 )
+ show_progress( in_size, &fmatchfinder, &pp, cfile_size ); // init
if( !encoder.encode_member( size ) )
{ pp( "Encoder error" ); retval = 1; break; }
in_size += fmatchfinder.data_position();
@@ -651,11 +662,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" );
@@ -712,25 +719,20 @@ void internal_error( const char * const msg )
void show_progress( const unsigned long long partial_size,
const Matchfinder_base * const m,
const Pretty_print * const p,
- const struct stat * const in_statsp )
+ const unsigned long long cfile_size )
{
- static unsigned long long cfile_size = 0; // file_size / 100
+ static unsigned long long csize = 0; // file_size / 100
static unsigned long long psize = 0;
static const Matchfinder_base * mb = 0;
static const Pretty_print * pp = 0;
if( m ) // initialize static vars
- {
- psize = partial_size; mb = m; pp = p;
- cfile_size = ( in_statsp && S_ISREG( in_statsp->st_mode ) ) ?
- in_statsp->st_size / 100 : 0;
- return;
- }
+ { csize = cfile_size; psize = partial_size; mb = m; pp = p; }
if( mb && pp )
{
const unsigned long long pos = psize + mb->data_position();
- if( cfile_size > 0 )
- std::fprintf( stderr, "%4llu%%", pos / cfile_size );
+ if( csize > 0 )
+ std::fprintf( stderr, "%4llu%%", pos / csize );
std::fprintf( stderr, " %.1f MB\r", pos / 1000000.0 );
pp->reset(); (*pp)(); // restore cursor position
}
@@ -812,10 +814,9 @@ int main( const int argc, const char * const argv[] )
const char * const arg = parser.argument( argind ).c_str();
switch( code )
{
- case '0': zero = true; break;
- case '1': case '2': case '3': case '4':
+ case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- zero = false;
+ zero = ( code == '0' );
encoder_options = option_mapping[code-'0']; break;
case 'b': member_size = getnum( arg, 100000, max_member_size ); break;
case 'c': to_stdout = true; break;