diff options
Diffstat (limited to '')
-rw-r--r-- | ztest.cc | 145 |
1 files changed, 143 insertions, 2 deletions
@@ -15,7 +15,40 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -void show_ztest_help() +#define _FILE_OFFSET_BITS 64 + +#include <cerrno> +#include <climits> +#include <csignal> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <list> +#include <string> +#include <vector> +#include <dirent.h> +#include <fcntl.h> +#include <stdint.h> +#include <unistd.h> +#include <sys/stat.h> +#if defined(__MSVCRT__) || defined(__OS2__) +#include <io.h> +#endif + +#include "arg_parser.h" +#include "rc.h" +#include "zutils.h" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + + +namespace { + +#include "recursive.cc" + +void show_help() { std::printf( "Ztest verifies the integrity of the specified compressed files.\n" "Uncompressed files are ignored. If no files are specified, the integrity\n" @@ -44,6 +77,15 @@ void show_ztest_help() } +int open_instream( std::string & input_filename ) + { + int infd = open( input_filename.c_str(), O_RDONLY | O_BINARY ); + if( infd < 0 ) + show_error2( "Can't open input file", input_filename.c_str() ); + return infd; + } + + int ztest_stdin( const int infd, int format_index, const std::vector< const char * > & ztest_args ) { @@ -65,7 +107,7 @@ int ztest_stdin( const int infd, int format_index, !feed_data( infd, fda[1], magic_data, magic_size ) ) _exit( 1 ); if( close( fda[1] ) != 0 ) - { show_close_error( "data feeder" ); _exit( 1 ); } + { show_close_error(); _exit( 1 ); } _exit( 0 ); } if( pid < 0 ) // parent @@ -145,3 +187,102 @@ int ztest_file( const int infd, int format_index, const bool isgzxz = ( format_index == fmt_gz || format_index == fmt_xz ); return wait_for_child( pid, compressor_name, 1, isgzxz ); } + +} // end namespace + + +int main( const int argc, const char * const argv[] ) + { + enum { format_opt = 256, bz2_opt, gz_opt, lz_opt, xz_opt }; + int infd = -1; + int format_index = -1; + bool recursive = false; + std::string input_filename; + std::list< std::string > filenames; + std::vector< const char * > ztest_args; // args to ztest, maybe empty + invocation_name = argv[0]; + program_name = "ztest"; + + const Arg_parser::Option options[] = + { + { 'h', "help", Arg_parser::no }, + { 'N', "no-rcfile", Arg_parser::no }, + { 'q', "quiet", Arg_parser::no }, + { 'r', "recursive", Arg_parser::no }, + { 'v', "verbose", Arg_parser::no }, + { 'V', "version", Arg_parser::no }, + { format_opt, "format", Arg_parser::yes }, + { 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 } }; + + const Arg_parser parser( argc, argv, options ); + if( parser.error().size() ) // bad option + { show_error( parser.error().c_str(), 0, true ); return 1; } + + maybe_process_config_file( parser ); + + int argind = 0; + for( ; argind < parser.arguments(); ++argind ) + { + const int code = parser.code( argind ); + if( !code ) break; // no more options + const char * const arg = parser.argument( argind ).c_str(); + switch( code ) + { + case 'h': show_help(); return 0; + case 'N': break; + case 'q': verbosity = -1; ztest_args.push_back( "-q" ); break; + case 'r': recursive = true; break; + case 'v': if( verbosity < 4 ) ++verbosity; + ztest_args.push_back( "-v" ); break; + case 'V': show_version( "Ztest" ); return 0; + case format_opt: format_index = parse_format_type( arg ); break; + case bz2_opt: parse_compressor( arg, fmt_bz2, 1 ); break; + 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; + default : internal_error( "uncaught option" ); + } + } // end process options + +#if defined(__MSVCRT__) || defined(__OS2__) + setmode( STDIN_FILENO, O_BINARY ); + setmode( STDOUT_FILENO, O_BINARY ); +#endif + + for( ; argind < parser.arguments(); ++argind ) + filenames.push_back( parser.argument( argind ) ); + + if( filenames.empty() ) filenames.push_back("-"); + + int retval = 0; + bool error = false; + while( next_filename( filenames, input_filename, error, recursive ) ) + { + if( input_filename.empty() ) infd = STDIN_FILENO; + else + { + infd = open_instream( input_filename ); + if( infd < 0 ) { error = true; continue; } + } + + int tmp; + if( infd == STDIN_FILENO ) + tmp = ztest_stdin( infd, format_index, ztest_args ); + else tmp = ztest_file( infd, format_index, input_filename, ztest_args ); + if( tmp > retval ) retval = tmp; + + if( input_filename.size() ) { close( infd ); infd = -1; } + } + + if( std::fclose( stdout ) != 0 ) + { + show_error( "Can't close stdout", errno ); + error = true; + } + if( error && retval == 0 ) retval = 1; + return retval; + } |