diff options
Diffstat (limited to '')
-rw-r--r-- | compress.cc | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/compress.cc b/compress.cc index ad3f151..4e74efa 100644 --- a/compress.cc +++ b/compress.cc @@ -78,9 +78,18 @@ const char * ne_output_filename() // non-empty output file name } +bool check_tty_in( const char * const input_filename, const int infd ) + { + if( isatty( infd ) ) // for example /dev/tty + { show_file_error( input_filename, + "I won't read archive data from a terminal." ); + close( infd ); return false; } + return true; + } + bool check_tty_out() { - if( isatty( outfd ) ) + if( isatty( outfd ) ) // for example /dev/tty { show_file_error( ne_output_filename(), "I won't write compressed data to a terminal." ); return false; } @@ -145,8 +154,7 @@ bool archive_write( const uint8_t * const buf, const long long size, if( rd < 0 ) internal_error( "library error (LZ_compress_read)." ); if( rd == 0 && sz >= size ) break; if( writeblock( outfd, obuf, rd ) != rd ) - { show_file_error( ne_output_filename(), "Write error", errno ); - return false; } + { show_file_error( ne_output_filename(), werr_msg, errno ); return false; } } if( LZ_compress_finished( encoder ) == 1 && LZ_compress_restart_member( encoder, LLONG_MAX ) < 0 ) @@ -160,9 +168,9 @@ bool tail_compress( const Cl_options & cl_opts, LZ_Encoder * const encoder ) { if( cl_opts.solidity != solid && !archive_write( 0, 0, encoder ) ) - return false; // flush encoder before EOF blocks + return false; // flush encoder before compressing EOA blocks int size = header_size; - bool zero = true; // true until non-zero data found after EOF blocks + bool zero = true; // true until non-zero data found after EOA blocks while( true ) { if( size > 0 && !archive_write( header, size, encoder ) ) @@ -171,7 +179,7 @@ bool tail_compress( const Cl_options & cl_opts, size = readblock( infd, header, header_size ); if( errno ) return false; if( zero && !block_is_zero( header, size ) ) - { zero = false; // flush encoder after EOF blocks + { zero = false; // flush encoder after compressing EOA blocks if( cl_opts.solidity != solid && !archive_write( 0, 0, encoder ) ) return false; } } @@ -188,7 +196,7 @@ int compress_archive( const Cl_options & cl_opts, const bool from_stdin = input_filename == "-"; const char * const filename = from_stdin ? "(stdin)" : input_filename.c_str(); const int infd = from_stdin ? STDIN_FILENO : open_instream( filename ); - if( infd < 0 ) return 1; + if( infd < 0 || !check_tty_in( filename, infd ) ) return 1; if( one_to_one ) { if( from_stdin ) { outfd = STDOUT_FILENO; output_filename.clear(); } @@ -206,14 +214,16 @@ int compress_archive( const Cl_options & cl_opts, unsigned long long partial_data_size = 0; // size of current block Extended extended; // metadata from extended records Resizable_buffer rbuf; // headers and extended records buffer + if( !rbuf.size() ) { show_error( mem_msg ); return 1; } + const char * const rderr_msg = "Read error"; + while( true ) // process one tar member per iteration { int total_header_size = header_size; // size of header(s) read const int rd = readblock( infd, rbuf.u8(), header_size ); - if( rd == 0 && errno == 0 ) break; // missing EOF blocks + if( rd == 0 && errno == 0 ) break; // missing EOA blocks if( rd != header_size ) - { show_file_error( filename, "Read error", errno ); - close( infd ); return 1; } + { show_file_error( filename, rderr_msg, errno ); close( infd ); return 1; } if( to_file && outfd < 0 ) // open outfd after verifying infd { @@ -223,9 +233,9 @@ int compress_archive( const Cl_options & cl_opts, delete_output_on_interrupt = true; } - if( !verify_ustar_chksum( rbuf.u8() ) ) // maybe EOF + if( !verify_ustar_chksum( rbuf.u8() ) ) // maybe EOA block { - if( block_is_zero( rbuf.u8(), header_size ) ) // first EOF block + if( block_is_zero( rbuf.u8(), header_size ) ) // first EOA block { tail_compress( cl_opts, infd, rbuf.u8(), encoder ); break; } show_file_error( filename, bad_hdr_msg ); close( infd ); return 2; } @@ -241,8 +251,7 @@ int compress_archive( const Cl_options & cl_opts, if( !rbuf.resize( total_header_size + bufsize ) ) { show_file_error( filename, mem_msg ); close( infd ); return 1; } if( readblock( infd, rbuf.u8() + total_header_size, bufsize ) != bufsize ) - { show_file_error( filename, "Read error", errno ); - close( infd ); return 1; } + { show_file_error( filename, rderr_msg, errno ); close( infd ); return 1; } total_header_size += bufsize; if( typeflag == tf_extended ) // do not parse global headers { @@ -252,7 +261,7 @@ int compress_archive( const Cl_options & cl_opts, if( !rbuf.resize( total_header_size + header_size ) ) { show_file_error( filename, mem_msg ); close( infd ); return 1; } if( readblock( infd, rbuf.u8() + total_header_size, header_size ) != header_size ) - { show_file_error( filename, errno ? "Read error" : end_msg, errno ); + { show_file_error( filename, errno ? rderr_msg : end_msg, errno ); close( infd ); return errno ? 1 : 2; } if( !verify_ustar_chksum( rbuf.u8() ) ) { show_file_error( filename, bad_hdr_msg ); close( infd ); return 2; } @@ -304,7 +313,7 @@ int compress_archive( const Cl_options & cl_opts, const struct stat * const in_statsp = ( need_close && fstat( infd, &in_stats ) == 0 ) ? &in_stats : 0; if( close( infd ) != 0 ) - { show_file_error( filename, "Error closing file", errno ); return 1; } + { show_file_error( filename, eclosf_msg, errno ); return 1; } if( need_close ) close_and_set_permissions( in_statsp ); return 0; } @@ -312,7 +321,7 @@ int compress_archive( const Cl_options & cl_opts, } // end namespace -int compress( Cl_options & cl_opts ) +int compress( const Cl_options & cl_opts ) { if( cl_opts.num_files > 1 && cl_opts.output_filename.size() ) { show_file_error( cl_opts.output_filename.c_str(), @@ -326,14 +335,9 @@ int compress( Cl_options & cl_opts ) if( !to_stdout && ( cl_opts.filenames_given || to_file ) ) set_signals( signal_handler ); - const int dictionary_size = option_mapping[cl_opts.level].dictionary_size; - if( cl_opts.data_size <= 0 ) - { - if( cl_opts.level == 0 ) cl_opts.data_size = 1 << 20; - else cl_opts.data_size = 2 * dictionary_size; - } - LZ_Encoder * encoder = LZ_compress_open( dictionary_size, - option_mapping[cl_opts.level].match_len_limit, LLONG_MAX ); + LZ_Encoder * encoder = LZ_compress_open( + option_mapping[cl_opts.level].dictionary_size, + option_mapping[cl_opts.level].match_len_limit, LLONG_MAX ); if( !encoder || LZ_compress_errno( encoder ) != LZ_ok ) { if( !encoder || LZ_compress_errno( encoder ) == LZ_mem_error ) |