diff options
Diffstat (limited to 'main.cc')
-rw-r--r-- | main.cc | 115 |
1 files changed, 0 insertions, 115 deletions
diff --git a/main.cc b/main.cc deleted file mode 100644 index bba5c6a..0000000 --- a/main.cc +++ /dev/null @@ -1,115 +0,0 @@ -/* Lzd - Educational decompressor for lzip files - Copyright (C) 2013 Antonio Diaz Diaz. - - This program is free software: you have unlimited permission - to copy, distribute and modify it. - - 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. -*/ -/* - Exit status: 0 for a normal exit, 1 for environmental problems - (file not found, invalid flags, I/O errors, etc), 2 to indicate a - corrupt or invalid input file. -*/ - -#include <algorithm> -#include <cerrno> -#include <cstdio> -#include <cstdlib> -#include <cstring> -#include <stdint.h> -#include <unistd.h> -#if defined(__MSVCRT__) || defined(__OS2__) -#include <fcntl.h> -#include <io.h> -#endif - -#include "decoder.cc" - - -enum { min_dictionary_size = 1 << 12, - max_dictionary_size = 1 << 29 }; - -typedef uint8_t File_header[6]; // 0-3 magic, 4 version, 5 coded_dict_size - -typedef uint8_t File_trailer[20]; - // 0-3 CRC32 of the uncompressed data - // 4-11 size of the uncompressed data - // 12-19 member size including header and trailer - - -int main( const int argc, const char * const argv[] ) - { - if( argc > 1 ) - { - std::printf( "Lzd %s - Educational decompressor for lzip files.\n", - PROGVERSION ); - std::printf( "Study the source to learn how a simple lzip decompressor works.\n" - "It is not safe to use it for any real work.\n" - "\nUsage: %s < file.lz > file\n", argv[0] ); - std::printf( "Lzd decompresses from standard input to standard output.\n" - "\nCopyright (C) 2013 Antonio Diaz Diaz.\n" - "This is free software: you are free to change and redistribute it.\n" - "There is NO WARRANTY, to the extent permitted by law.\n" - "Report bugs to lzip-bug@nongnu.org\n" - "Lzip home page: http://www.nongnu.org/lzip/lzip.html\n" ); - return 0; - } - -#if defined(__MSVCRT__) || defined(__OS2__) - setmode( STDIN_FILENO, O_BINARY ); - setmode( STDOUT_FILENO, O_BINARY ); -#endif - - if( isatty( STDIN_FILENO ) ) - { - std::fprintf( stderr, "I won't read compressed data from a terminal.\n" - "Try '%s --help' for more information.\n", argv[0] ); - return 1; - } - - for( bool first_member = true; ; first_member = false ) - { - File_header header; - for( int i = 0; i < 6; ++i ) - header[i] = std::getc( stdin ); - if( std::feof( stdin ) || std::memcmp( header, "LZIP", 4 ) != 0 ) - { - if( first_member ) - { std::fprintf( stderr, "Bad magic number (file not in lzip format)\n" ); - return 2; } - break; - } - if( header[4] != 1 ) - { - std::fprintf( stderr, "Version %d member format not supported.\n", - header[4] ); - return 2; - } - unsigned dict_size = 1 << ( header[5] & 0x1F ); - dict_size -= ( dict_size / 16 ) * ( ( header[5] >> 5 ) & 7 ); - if( dict_size < min_dictionary_size || dict_size > max_dictionary_size ) - { std::fprintf( stderr, "Invalid dictionary size in member header\n" ); - return 2; } - - LZ_decoder decoder( dict_size ); - if( !decoder.decode_member() ) - { std::fprintf( stderr, "Data error\n" ); return 2; } - - File_trailer trailer; - for( int i = 0; i < 20; ++i ) trailer[i] = std::getc( stdin ); - unsigned crc = 0; - for( int i = 3; i >= 0; --i ) { crc <<= 8; crc += trailer[i]; } - unsigned long long data_size = 0; - for( int i = 11; i >= 4; --i ) { data_size <<= 8; data_size += trailer[i]; } - if( crc != decoder.crc() || data_size != decoder.data_position() ) - { std::fprintf( stderr, "CRC error\n" ); return 2; } - } - - if( std::fclose( stdout ) != 0 ) - { std::fprintf( stderr, "Can't close stdout: %s\n", std::strerror( errno ) ); - return 1; } - return 0; - } |