summaryrefslogtreecommitdiffstats
path: root/main.cc
diff options
context:
space:
mode:
Diffstat (limited to 'main.cc')
-rw-r--r--main.cc83
1 files changed, 60 insertions, 23 deletions
diff --git a/main.cc b/main.cc
index 402e3b5..90230a9 100644
--- a/main.cc
+++ b/main.cc
@@ -1,5 +1,5 @@
/* Tarlz - Archiver with multimember lzip compression
- Copyright (C) 2013-2020 Antonio Diaz Diaz.
+ Copyright (C) 2013-2021 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
@@ -60,20 +60,21 @@ int verbosity = 0;
namespace {
const char * const program_name = "tarlz";
-const char * const program_year = "2020";
+const char * const program_year = "2021";
const char * invocation_name = program_name; // default value
void show_help( const long num_online )
{
std::printf( "Tarlz is a massively parallel (multi-threaded) combined implementation of\n"
- "the tar archiver and the lzip compressor. Tarlz creates, lists and extracts\n"
- "archives in a simplified and safer variant of the POSIX pax format\n"
- "compressed with lzip, keeping the alignment between tar members and lzip\n"
- "members. The resulting multimember tar.lz archive is fully backward\n"
- "compatible with standard tar tools like GNU tar, which treat it like any\n"
- "other tar.lz archive. Tarlz can append files to the end of such compressed\n"
- "archives.\n"
+ "the tar archiver and the lzip compressor. Tarlz uses the compression library\n"
+ "lzlib.\n"
+ "\nTarlz creates, lists, and extracts archives in a simplified and safer\n"
+ "variant of the POSIX pax format compressed in lzip format, keeping the\n"
+ "alignment between tar members and lzip members. The resulting multimember\n"
+ "tar.lz archive is fully backward compatible with standard tar tools like GNU\n"
+ "tar, which treat it like any other tar.lz archive. Tarlz can append files to\n"
+ "the end of such compressed archives.\n"
"\nKeeping the alignment between tar members and lzip members has two\n"
"advantages. It adds an indexed lzip layer on top of the tar archive, making\n"
"it possible to decode the archive safely in parallel. It also minimizes the\n"
@@ -119,6 +120,7 @@ void show_help( const long num_online )
" --keep-damaged don't delete partially extracted files\n"
" --missing-crc exit with error status if missing extended CRC\n"
" --out-slots=<n> number of 1 MiB output packets buffered [64]\n"
+ " --check-lib compare version of lzlib.h with liblz.{a,so}\n"
/* " --permissive allow repeated extended headers and records\n"*/,
num_online );
if( verbosity >= 1 )
@@ -145,6 +147,37 @@ void show_version()
}
+int check_lib()
+ {
+ bool warning = false;
+ if( std::strcmp( LZ_version_string, LZ_version() ) != 0 )
+ { warning = true;
+ if( verbosity >= 0 )
+ std::printf( "warning: LZ_version_string != LZ_version() (%s vs %s)\n",
+ LZ_version_string, LZ_version() ); }
+#if defined LZ_API_VERSION && LZ_API_VERSION >= 1012
+ if( LZ_API_VERSION != LZ_api_version() )
+ { warning = true;
+ if( verbosity >= 0 )
+ std::printf( "warning: LZ_API_VERSION != LZ_api_version() (%u vs %u)\n",
+ LZ_API_VERSION, LZ_api_version() ); }
+#endif
+ if( verbosity >= 1 )
+ {
+ std::printf( "Using lzlib %s\n", LZ_version() );
+#if !defined LZ_API_VERSION
+ std::fputs( "LZ_API_VERSION is not defined.\n", stdout );
+#elif LZ_API_VERSION >= 1012
+ std::printf( "Using LZ_API_VERSION = %u\n", LZ_api_version() );
+#else
+ std::printf( "Compiled with LZ_API_VERSION = %u. "
+ "Using an unknown LZ_API_VERSION\n", LZ_API_VERSION );
+#endif
+ }
+ return warning;
+ }
+
+
unsigned long long getnum( const char * const ptr,
const unsigned long long llimit,
const unsigned long long ulimit )
@@ -281,15 +314,21 @@ int open_instream( const std::string & name )
}
-int open_outstream( const std::string & name, const bool create )
+int open_outstream( const std::string & name, const bool create,
+ Resizable_buffer * const rbufp )
{
const int flags = (create ? O_CREAT | O_WRONLY | O_TRUNC : O_RDWR) | O_BINARY;
const mode_t outfd_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
const int outfd = open( name.c_str(), flags, outfd_mode );
if( outfd < 0 )
- show_file_error( name.c_str(), create ?
- "Can't create file" : "Error opening file", errno );
+ {
+ const char * msg = create ? "Can't create file" : "Error opening file";
+ if( !rbufp ) show_file_error( name.c_str(), msg, errno );
+ else
+ snprintf( (*rbufp)(), (*rbufp).size(), "%s: %s: %s\n", name.c_str(),
+ msg, std::strerror( errno ) );
+ }
return outfd;
}
@@ -354,17 +393,9 @@ int main( const int argc, const char * const argv[] )
{
if( argc > 0 ) invocation_name = argv[0];
-#if !defined LZ_API_VERSION || LZ_API_VERSION < 1 // compile-time test
-#error "lzlib 1.8 or newer needed."
-#elif LZ_API_VERSION >= 2
- if( LZ_api_version() < 1 ) // runtime test
- { show_error( "Wrong library version. At least lzlib 1.8 is required." );
- return 1; }
-#endif
-
- enum { opt_ano = 256, opt_aso, opt_bso, opt_crc, opt_dbg, opt_del, opt_dso,
- opt_exc, opt_grp, opt_hlp, opt_id, opt_kd, opt_mti, opt_nso, opt_out,
- opt_own, opt_per, opt_sol, opt_un };
+ enum { opt_ano = 256, opt_aso, opt_bso, opt_chk, opt_crc, opt_dbg, opt_del,
+ opt_dso, opt_exc, opt_grp, opt_hlp, opt_id, opt_kd, opt_mti, opt_nso,
+ opt_out, opt_own, opt_per, opt_sol, opt_un };
const Arg_parser::Option options[] =
{
{ '0', 0, Arg_parser::no },
@@ -396,6 +427,7 @@ int main( const int argc, const char * const argv[] )
{ opt_ano, "anonymous", Arg_parser::no },
{ opt_aso, "asolid", Arg_parser::no },
{ opt_bso, "bsolid", Arg_parser::no },
+ { opt_chk, "check-lib", Arg_parser::no },
{ opt_dbg, "debug", Arg_parser::yes },
{ opt_del, "delete", Arg_parser::no },
{ opt_dso, "dsolid", Arg_parser::no },
@@ -462,6 +494,7 @@ int main( const int argc, const char * const argv[] )
case opt_aso: cl_opts.solidity = asolid; break;
case opt_bso: cl_opts.solidity = bsolid; break;
case opt_crc: cl_opts.missing_crc = true; break;
+ case opt_chk: return check_lib();
case opt_dbg: cl_opts.debug_level = getnum( arg, 0, 3 ); break;
case opt_del: set_mode( cl_opts.program_mode, m_delete ); break;
case opt_dso: cl_opts.solidity = dsolid; break;
@@ -481,6 +514,10 @@ int main( const int argc, const char * const argv[] )
}
} // end process options
+#if !defined LZ_API_VERSION || LZ_API_VERSION < 1 // compile-time test
+#error "lzlib 1.8 or newer needed."
+#endif
+
#if defined(__MSVCRT__) || defined(__OS2__)
setmode( STDIN_FILENO, O_BINARY );
setmode( STDOUT_FILENO, O_BINARY );