1
0
Fork 0

Merging upstream version 1.9.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-24 05:59:37 +01:00
parent 3e7d50525b
commit 13941d3cbe
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
30 changed files with 1188 additions and 1060 deletions

104
zcat.cc
View file

@ -1,18 +1,18 @@
/* Zcat - decompress and concatenate files to standard output
Copyright (C) 2010-2019 Antonio Diaz Diaz.
/* Zcat - decompress and concatenate files to standard output
Copyright (C) 2010-2020 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
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
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
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define _FILE_OFFSET_BITS 64
@ -90,19 +90,21 @@ Line_number line_number;
void show_help()
{
std::printf( "Zcat copies each given file to standard output. If any given file is\n"
"compressed, its decompressed content is used. If a given file does not\n"
"exist, and its name does not end with one of the known extensions, zcat\n"
"tries the compressed file names corresponding to the formats supported.\n"
std::printf( "zcat copies each file argument to standard output in sequence. If any\n"
"file given is compressed, its decompressed content is copied. If a file\n"
"given does not exist, and its name does not end with one of the known\n"
"extensions, zcat tries the compressed file names corresponding to the\n"
"formats supported. If a file fails to decompress, zcat continues copying the\n"
"rest of the files.\n"
"\nIf a file is specified as '-', data are read from standard input,\n"
"decompressed if needed, and sent to standard output. Data read from\n"
"standard input must be of the same type; all uncompressed or all in the\n"
"same compression format.\n"
"same compressed format.\n"
"\nIf no files are specified, recursive searches examine the current\n"
"working directory, and nonrecursive searches read standard input.\n"
"\nThe formats supported are bzip2, gzip, lzip and xz.\n"
"\nThe formats supported are bzip2, gzip, lzip, and xz.\n"
"\nUsage: zcat [options] [files]\n"
"\nExit status is 0 if no errors occurred, non-zero otherwise.\n"
"\nExit status is 0 if no errors occurred, 1 otherwise.\n"
"\nOptions:\n"
" -h, --help display this help and exit\n"
" -V, --version output version information and exit\n"
@ -113,7 +115,7 @@ void show_help()
" -M, --format=<list> process only the formats in <list>\n"
" -n, --number number all output lines\n"
" -N, --no-rcfile don't read runtime configuration file\n"
" -O, --force-format=<fmt> force given format (bz2, gz, lz, xz)\n"
" -O, --force-format=<fmt> force the format given (bz2, gz, lz, xz)\n"
" -q, --quiet suppress all messages\n"
" -r, --recursive operate recursively on directories\n"
" -R, --dereference-recursive recursively follow symbolic links\n"
@ -130,10 +132,10 @@ void show_help()
}
int do_cat( const int infd, const int buffer_size,
uint8_t * const inbuf, uint8_t * const outbuf,
const std::string & input_filename,
const Cat_options & cat_options )
bool do_cat( const int infd, const int buffer_size,
uint8_t * const inbuf, uint8_t * const outbuf,
const std::string & input_filename,
const Cat_options & cat_options )
{
static int at_bol = 1; // at begin of line. 0 = false, 1 = true,
// 2 = at begin of second blank line.
@ -148,7 +150,7 @@ int do_cat( const int infd, const int buffer_size,
if( outpos >= buffer_size )
{
if( writeblock( STDOUT_FILENO, outbuf, outpos ) != outpos )
{ show_error( "Write error", errno ); return 1; }
{ show_error( "Write error", errno ); return false; }
outpos = 0;
}
if( inpos > rd ) // inbuf is empty
@ -157,14 +159,14 @@ int do_cat( const int infd, const int buffer_size,
if( rd != buffer_size && errno )
{
show_file_error( input_filename.c_str(), "Read error", errno );
return 1;
return false;
}
if( rd == 0 )
{
if( writeblock( STDOUT_FILENO, outbuf, outpos ) != outpos )
{ show_error( "Write error", errno ); return 1; }
{ show_error( "Write error", errno ); return false; }
outpos = 0;
return 0;
return true;
}
inpos = 0;
inbuf[rd] = '\n'; // sentinel newline
@ -226,32 +228,27 @@ int do_cat( const int infd, const int buffer_size,
}
int cat( int infd, const int format_index, const std::string & input_filename,
const Cat_options & cat_options )
bool cat( int infd, const int format_index, const std::string & input_filename,
const Cat_options & cat_options )
{
enum { buffer_size = 4096, outbuf_size = (5 * buffer_size) + 256 + 1 };
// buffer with space for sentinel newline at the end
// input buffer with space for sentinel newline at the end
uint8_t * const inbuf = new uint8_t[buffer_size+1];
// buffer with space for character quoting, 255-digit line number,
// output buffer with space for character quoting, 255-digit line number,
// worst case flushing respect to inbuf, and a canary byte.
uint8_t * const outbuf = new uint8_t[outbuf_size];
outbuf[outbuf_size-1] = 0;
int retval = 0;
Children children;
if( !set_data_feeder( input_filename, &infd, children, format_index ) )
retval = 1;
else
retval = do_cat( infd, buffer_size, inbuf, outbuf,
input_filename, cat_options );
bool error = false;
if( !good_status( children, retval == 0 ) ) retval = 1;
if( retval == 0 && close( infd ) != 0 )
{ show_close_error(); retval = 1; }
if( outbuf[outbuf_size-1] != 0 )
internal_error( "buffer overflow." );
if( !set_data_feeder( input_filename, &infd, children, format_index ) ||
!do_cat( infd, buffer_size, inbuf, outbuf, input_filename, cat_options ) )
error = true;
if( !good_status( children, !error ) ) error = true;
if( !error && close( infd ) != 0 ) { show_close_error(); error = true; }
if( outbuf[outbuf_size-1] != 0 ) internal_error( "buffer overflow." );
delete[] outbuf; delete[] inbuf;
return retval;
return !error;
}
} // end namespace
@ -264,8 +261,8 @@ int main( const int argc, const char * const argv[] )
int recursive = 0; // 1 = '-r', 2 = '-R'
std::list< std::string > filenames;
Cat_options cat_options;
invocation_name = argv[0];
program_name = "zcat";
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
const Arg_parser::Option options[] =
{
@ -357,16 +354,15 @@ int main( const int argc, const char * const argv[] )
if( filenames.empty() ) filenames.push_back( recursive ? "." : "-" );
std::string input_filename;
int retval = 0;
bool error = false;
bool stdin_used = false;
while( next_filename( filenames, input_filename, error, recursive ) )
{
int infd;
if( input_filename.empty() )
if( input_filename == "." )
{
if( stdin_used ) continue; else stdin_used = true;
infd = STDIN_FILENO;
infd = STDIN_FILENO; input_filename = "-";
}
else
{
@ -374,10 +370,11 @@ int main( const int argc, const char * const argv[] )
if( infd < 0 ) { error = true; continue; }
}
const int tmp = cat( infd, format_index, input_filename, cat_options );
if( tmp > retval ) retval = tmp;
if( !cat( infd, format_index, input_filename, cat_options ) ) error = true;
if( input_filename.size() ) close( infd );
if( close( infd ) != 0 )
{ show_file_error( input_filename.c_str(), "Error closing input file",
errno ); error = true; }
}
if( std::fclose( stdout ) != 0 )
@ -385,6 +382,5 @@ int main( const int argc, const char * const argv[] )
show_error( "Error closing stdout", errno );
error = true;
}
if( error && retval == 0 ) retval = 1;
return retval;
return error;
}