diff options
Diffstat (limited to '')
-rw-r--r-- | ztest.cc | 49 |
1 files changed, 35 insertions, 14 deletions
@@ -1,5 +1,5 @@ /* Ztest - verify the integrity of compressed files - Copyright (C) 2010-2021 Antonio Diaz Diaz. + Copyright (C) 2010-2022 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 @@ -31,7 +31,7 @@ #include <stdint.h> #include <unistd.h> #include <sys/stat.h> -#if defined(__MSVCRT__) || defined(__OS2__) +#if defined __MSVCRT__ || defined __OS2__ #include <io.h> #endif @@ -60,7 +60,7 @@ void show_help() "test when testing multiple files.\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, xz, and zstd.\n" "\nNote that error detection in the xz format is broken. First, some xz\n" "files lack integrity information. Second, not all xz decompressors can\n" "verify the integrity of all xz files. Third, section 2.1.1.2 'Stream\n" @@ -76,7 +76,7 @@ void show_help() " -V, --version output version information and exit\n" " -M, --format=<list> process only the formats in <list>\n" " -N, --no-rcfile don't read runtime configuration file\n" - " -O, --force-format=<fmt> force the format given (bz2, gz, lz, xz)\n" + " -O, --force-format=<fmt> force the format given (bz2, gz, lz, xz, zst)\n" " -q, --quiet suppress all messages\n" " -r, --recursive operate recursively on directories\n" " -R, --dereference-recursive recursively follow symbolic links\n" @@ -84,7 +84,8 @@ void show_help() " --bz2=<command> set compressor and options for bzip2 format\n" " --gz=<command> set compressor and options for gzip format\n" " --lz=<command> set compressor and options for lzip format\n" - " --xz=<command> set compressor and options for xz format\n" ); + " --xz=<command> set compressor and options for xz format\n" + " --zst=<command> set compressor and options for zstd format\n" ); show_help_addr(); } @@ -164,7 +165,9 @@ int ztest_file( const int infd, int format_index, const std::string & input_filename, const std::vector< const char * > & ztest_args ) { + // bzip2, gzip, and lzip are the primary formats. xz and zstd are optional. static int disable_xz = -1; // tri-state bool + static int disable_zst = -1; // tri-state bool uint8_t magic_data[magic_buf_size]; int magic_size = 0; if( format_index < 0 ) @@ -178,9 +181,24 @@ int ztest_file( const int infd, int format_index, { std::string command( compressor_name ); command += " -V > /dev/null 2>&1"; disable_xz = ( std::system( command.c_str() ) != 0 ); + if( disable_xz && verbosity >= 2 ) + std::fprintf( stderr, "%s: '%s' not found. Ignoring xz files.\n", + program_name, compressor_name ); } if( disable_xz ) return 0; // ignore this file if no xz installed } + else if( format_index == fmt_zst ) + { + if( disable_zst < 0 ) + { + std::string command( compressor_name ); command += " -V > /dev/null 2>&1"; + disable_zst = ( std::system( command.c_str() ) != 0 ); + if( disable_zst && verbosity >= 2 ) + std::fprintf( stderr, "%s: '%s' not found. Ignoring zstd files.\n", + program_name, compressor_name ); + } + if( disable_zst ) return 0; // ignore this file if no zstd installed + } const pid_t pid = fork(); @@ -216,7 +234,7 @@ int ztest_file( const int infd, int format_index, int main( const int argc, const char * const argv[] ) { - enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt }; + enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt, zst_opt }; int format_index = -1; int recursive = 0; // 1 = '-r', 2 = '-R' std::list< std::string > filenames; @@ -235,11 +253,12 @@ int main( const int argc, const char * const argv[] ) { 'R', "dereference-recursive", Arg_parser::no }, { 'v', "verbose", Arg_parser::no }, { 'V', "version", Arg_parser::no }, - { bz2_opt, "bz2", Arg_parser::yes }, - { gz_opt, "gz", Arg_parser::yes }, - { lz_opt, "lz", Arg_parser::yes }, - { xz_opt, "xz", Arg_parser::yes }, - { 0 , 0, Arg_parser::no } }; + { bz2_opt, "bz2", Arg_parser::yes }, + { gz_opt, "gz", Arg_parser::yes }, + { lz_opt, "lz", Arg_parser::yes }, + { xz_opt, "xz", Arg_parser::yes }, + { zst_opt, "zst", Arg_parser::yes }, + { 0, 0, Arg_parser::no } }; const Arg_parser parser( argc, argv, options ); if( parser.error().size() ) // bad option @@ -252,13 +271,14 @@ int main( const int argc, const char * const argv[] ) { const int code = parser.code( argind ); if( !code ) break; // no more options + const char * const pn = parser.parsed_name( argind ).c_str(); const std::string & arg = parser.argument( argind ); switch( code ) { case 'h': show_help(); return 0; - case 'M': parse_format_list( arg ); break; + case 'M': parse_format_list( arg, pn ); break; case 'N': break; - case 'O': format_index = parse_format_type( arg ); break; + case 'O': format_index = parse_format_type( arg, pn ); break; case 'q': verbosity = -1; ztest_args.push_back( "-q" ); break; case 'r': recursive = 1; break; case 'R': recursive = 2; break; @@ -269,11 +289,12 @@ int main( const int argc, const char * const argv[] ) case gz_opt: parse_compressor( arg, fmt_gz, 1 ); break; case lz_opt: parse_compressor( arg, fmt_lz, 1 ); break; case xz_opt: parse_compressor( arg, fmt_xz, 1 ); break; + case zst_opt: parse_compressor( arg, fmt_zst, 1 ); break; default : internal_error( "uncaught option." ); } } // end process options -#if defined(__MSVCRT__) || defined(__OS2__) +#if defined __MSVCRT__ || defined __OS2__ setmode( STDIN_FILENO, O_BINARY ); setmode( STDOUT_FILENO, O_BINARY ); #endif |