Adding upstream version 0.6.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
557010b363
commit
c2bdc739f1
14 changed files with 207 additions and 172 deletions
146
main.cc
146
main.cc
|
@ -134,6 +134,7 @@ void show_help() throw()
|
|||
// std::printf( " -d, --decompress decompress\n" );
|
||||
// std::printf( " -f, --force overwrite existing output files\n" );
|
||||
// std::printf( " -k, --keep keep (don't delete) input files\n" );
|
||||
std::printf( " -m, --magic=<type> output magic bytes for given file type\n" );
|
||||
// std::printf( " -o, --output=<file> if reading stdin, place the output into <file>\n" );
|
||||
std::printf( " -q, --quiet suppress all messages\n" );
|
||||
std::printf( " -t, --test test compressed file type\n" );
|
||||
|
@ -492,6 +493,129 @@ int decompress( const int inhandle, const Pretty_print & pp )
|
|||
}
|
||||
*/
|
||||
|
||||
unsigned char xdigit( const int value ) throw()
|
||||
{
|
||||
if( value >= 0 && value <= 9 ) return '0' + value;
|
||||
if( value >= 10 && value <= 15 ) return 'A' + value - 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int xtoi( const unsigned char ch ) throw()
|
||||
{
|
||||
switch( ch )
|
||||
{
|
||||
case '0': return 0;
|
||||
case '1': return 1;
|
||||
case '2': return 2;
|
||||
case '3': return 3;
|
||||
case '4': return 4;
|
||||
case '5': return 5;
|
||||
case '6': return 6;
|
||||
case '7': return 7;
|
||||
case '8': return 8;
|
||||
case '9': return 9;
|
||||
case 'a':
|
||||
case 'A': return 0x0A;
|
||||
case 'b':
|
||||
case 'B': return 0x0B;
|
||||
case 'c':
|
||||
case 'C': return 0x0C;
|
||||
case 'd':
|
||||
case 'D': return 0x0D;
|
||||
case 'e':
|
||||
case 'E': return 0x0E;
|
||||
case 'f':
|
||||
case 'F': return 0x0F;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool hex_to_data( const std::string & hex, std::string & data )
|
||||
{
|
||||
data.clear();
|
||||
if( hex.size() == 0 || hex.size() % 2 != 0 ) return false;
|
||||
for( unsigned int i = 0; 2 * i + 1 < hex.size(); ++i )
|
||||
{
|
||||
int uch = xtoi( hex[2*i] );
|
||||
int lch = xtoi( hex[2*i+1] );
|
||||
if( uch < 0 || lch < 0 ) return false;
|
||||
data.push_back( ( uch << 4 ) | lch );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int print_magic_type( const std::string & magic_type )
|
||||
{
|
||||
std::string data;
|
||||
|
||||
if( magic_type == "gzip" ) std::printf( "\x1F\x8B" );
|
||||
else if( magic_type == "bzip2" ) std::printf( "BZh" );
|
||||
else if( magic_type == "lzip" ) std::printf( "LZIP" );
|
||||
else if( magic_type == "xz" ) std::printf( "%c7zXZ", '\xFD' );
|
||||
else if( hex_to_data( magic_type, data ) ) std::printf( data.c_str() );
|
||||
else return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int test_stdin_type( const int inhandle, const Pretty_print & pp )
|
||||
{
|
||||
unsigned char buf[5];
|
||||
const char * msg = 0;
|
||||
int i = 0;
|
||||
if( readblock( inhandle, (char *)buf, 1 ) == 1 )
|
||||
{
|
||||
if( buf[0] == 0x1F )
|
||||
{
|
||||
if( readblock( inhandle, (char *)&buf[++i], 1 ) == 1 && buf[i] == 0x8B )
|
||||
msg = "gzip";
|
||||
}
|
||||
else if( buf[0] == 'B' )
|
||||
{
|
||||
if( readblock( inhandle, (char *)&buf[++i], 1 ) == 1 && buf[i] == 'Z' &&
|
||||
readblock( inhandle, (char *)&buf[++i], 1 ) == 1 && buf[i] == 'h' )
|
||||
msg = "bzip2";
|
||||
}
|
||||
else if( buf[0] == 'L' )
|
||||
{
|
||||
if( readblock( inhandle, (char *)&buf[++i], 1 ) == 1 && buf[i] == 'Z' &&
|
||||
readblock( inhandle, (char *)&buf[++i], 1 ) == 1 && buf[i] == 'I' &&
|
||||
readblock( inhandle, (char *)&buf[++i], 1 ) == 1 && buf[i] == 'P' )
|
||||
msg = "lzip";
|
||||
}
|
||||
else if( buf[0] == 0xFD )
|
||||
{
|
||||
if( readblock( inhandle, (char *)&buf[++i], 1 ) == 1 && buf[i] == '7' &&
|
||||
readblock( inhandle, (char *)&buf[++i], 1 ) == 1 && buf[i] == 'z' &&
|
||||
readblock( inhandle, (char *)&buf[++i], 1 ) == 1 && buf[i] == 'X' &&
|
||||
readblock( inhandle, (char *)&buf[++i], 1 ) == 1 && buf[i] == 'Z' )
|
||||
msg = "xz";
|
||||
}
|
||||
}
|
||||
const int retval = ( msg ? 0 : 1 );
|
||||
if( verbosity >= 0 )
|
||||
{
|
||||
if( verbosity >= 1 ) pp();
|
||||
if( !msg )
|
||||
{
|
||||
char hexmsg[(2*sizeof buf)+1];
|
||||
for( int j = 0; j <= i; ++j )
|
||||
{
|
||||
hexmsg[2*j] = xdigit( buf[j] >> 4 );
|
||||
hexmsg[2*j+1] = xdigit( buf[j] & 0x0F );
|
||||
}
|
||||
hexmsg[2*i+2] = 0;
|
||||
msg = hexmsg;
|
||||
}
|
||||
std::printf( "%s\n", msg );
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int test_type( const int inhandle, const Pretty_print & pp )
|
||||
{
|
||||
unsigned char buf[5];
|
||||
|
@ -505,7 +629,7 @@ int test_type( const int inhandle, const Pretty_print & pp )
|
|||
msg = "bzip2";
|
||||
else if( buf[0] == 'L' && buf[1] == 'Z' && buf[2] == 'I' && buf[3] == 'P' )
|
||||
msg = "lzip";
|
||||
else if( buf[1] == '7' && buf[2] == 'z' && buf[3] == 'X' && buf[4] == 'Z' )
|
||||
else if( buf[0] == 0xFD && buf[1] == '7' && buf[2] == 'z' && buf[3] == 'X' && buf[4] == 'Z' )
|
||||
msg = "xz";
|
||||
}
|
||||
const int retval = ( msg ? 0 : 1 );
|
||||
|
@ -546,6 +670,7 @@ int main( const int argc, const char * argv[] )
|
|||
std::string input_filename;
|
||||
std::string default_output_filename;
|
||||
std::vector< std::string > filenames;
|
||||
std::string magic_type;
|
||||
invocation_name = argv[0];
|
||||
|
||||
const Arg_parser::Option options[] =
|
||||
|
@ -555,6 +680,7 @@ int main( const int argc, const char * argv[] )
|
|||
{ 'f', "force", Arg_parser::no },
|
||||
{ 'h', "help", Arg_parser::no },
|
||||
{ 'k', "keep", Arg_parser::no },
|
||||
{ 'm', "magic", Arg_parser::yes },
|
||||
{ 'o', "output", Arg_parser::yes },
|
||||
{ 'q', "quiet", Arg_parser::no },
|
||||
{ 't', "test", Arg_parser::no },
|
||||
|
@ -571,7 +697,7 @@ int main( const int argc, const char * argv[] )
|
|||
{
|
||||
const int code = parser.code( argind );
|
||||
if( !code ) break; // no more options
|
||||
const char * arg = parser.argument( argind ).c_str();
|
||||
const std::string & arg = parser.argument( argind );
|
||||
switch( code )
|
||||
{
|
||||
case 'c': to_stdout = true; break;
|
||||
|
@ -579,6 +705,7 @@ int main( const int argc, const char * argv[] )
|
|||
case 'f': force = true; break;
|
||||
case 'h': show_help(); return 0;
|
||||
case 'k': keep_input_files = true; break;
|
||||
case 'm': magic_type = arg; break;
|
||||
case 'o': default_output_filename = arg; break;
|
||||
case 'q': verbosity = -1; break;
|
||||
case 't': program_mode = m_test; break;
|
||||
|
@ -588,6 +715,8 @@ int main( const int argc, const char * argv[] )
|
|||
}
|
||||
}
|
||||
|
||||
if( magic_type.size() ) return print_magic_type( magic_type );
|
||||
|
||||
bool filenames_given = false;
|
||||
for( ; argind < parser.arguments(); ++argind )
|
||||
{
|
||||
|
@ -669,19 +798,22 @@ int main( const int argc, const char * argv[] )
|
|||
case m_decompress:
|
||||
/*tmp = decompress( inhandle, pp );*/ break;
|
||||
case m_test:
|
||||
tmp = test_type( inhandle, pp ); break;
|
||||
if( inhandle == STDIN_FILENO )
|
||||
tmp = test_stdin_type( inhandle, pp );
|
||||
else tmp = test_type( inhandle, pp );
|
||||
break;
|
||||
}
|
||||
if( tmp > retval ) retval = tmp;
|
||||
if( tmp && program_mode != m_test ) cleanup_and_fail( retval );
|
||||
/*
|
||||
if( delete_output_on_interrupt )
|
||||
close_and_set_permissions( in_statsp, &retval );
|
||||
|
||||
// if( delete_output_on_interrupt )
|
||||
// close_and_set_permissions( in_statsp, &retval );
|
||||
if( input_filename.size() )
|
||||
{
|
||||
close( inhandle ); inhandle = -1;
|
||||
if( !keep_input_files && !to_stdout && program_mode != m_test )
|
||||
std::remove( input_filename.c_str() );
|
||||
}*/
|
||||
}
|
||||
}
|
||||
if( outhandle >= 0 ) close( outhandle );
|
||||
return retval;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue