1
0
Fork 0

Merging upstream version 1.9.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-24 05:59:37 +01:00
parent 3e7d50525b
commit 13941d3cbe
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
30 changed files with 1188 additions and 1060 deletions

View file

@ -1,18 +1,18 @@
/* Zupdate - recompress bzip2, gzip, xz files to lzip format
Copyright (C) 2013-2019 Antonio Diaz Diaz.
/* Zupdate - recompress bzip2, gzip, xz files to lzip format
Copyright (C) 2013-2020 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
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
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
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define _FILE_OFFSET_BITS 64
@ -51,7 +51,7 @@ namespace {
void show_help()
{
std::printf( "Zupdate recompresses files from bzip2, gzip, and xz formats to lzip\n"
std::printf( "zupdate recompresses files from bzip2, gzip, and xz formats to lzip\n"
"format. Each original is compared with the new file and then deleted.\n"
"Only regular files with standard file name extensions are recompressed,\n"
"other files are ignored. Compressed files are decompressed and then\n"
@ -61,21 +61,23 @@ void show_help()
"\nIf no files are specified, recursive searches examine the current\n"
"working directory, and nonrecursive searches do nothing.\n"
"\nIf the lzip compressed version of a file already exists, the file is\n"
"skipped unless the '--force' option is given. In this case, if the\n"
"skipped unless the option '--force' is given. In this case, if the\n"
"comparison with the existing lzip version fails, an error is returned\n"
"and the original file is not deleted. The operation of zupdate is meant\n"
"to be safe and not produce any data loss. Therefore, existing lzip\n"
"to be safe and not cause any data loss. Therefore, existing lzip\n"
"compressed files are never overwritten nor deleted.\n"
"\nThe names of the original files must have one of the following extensions:\n"
"'.bz2', '.gz', and '.xz' are recompressed to '.lz'.\n"
"'.tbz', '.tbz2', '.tgz', and '.txz' are recompressed to '.tlz'.\n"
"\nUsage: zupdate [options] [files]\n"
"\nExit status is 0 if all the compressed files were successfully\n"
"recompressed (if needed), compared and deleted (if requested). Non-zero\n"
"otherwise.\n"
"\nExit status is 0 if all the compressed files were successfully recompressed\n"
"(if needed), compared, and deleted (if requested). Non-zero otherwise.\n"
"\nOptions:\n"
" -h, --help display this help and exit\n"
" -V, --version output version information and exit\n"
" -f, --force don't skip a file even if the .lz exists\n"
" -k, --keep keep (don't delete) input files\n"
" -l, --lzip-verbose pass a -v option to the lzip compressor\n"
" -l, --lzip-verbose pass one option -v to the lzip compressor\n"
" -M, --format=<list> process only the formats in <list>\n"
" -N, --no-rcfile don't read runtime configuration file\n"
" -q, --quiet suppress all messages\n"
@ -106,7 +108,7 @@ int cant_execute( const std::string & command, const int status )
}
// Set permissions, owner and times.
// Set permissions, owner, and times.
void set_permissions( const char * const rname, const struct stat & in_stats )
{
bool warning = false;
@ -135,7 +137,7 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
{
static int disable_xz = -1; // tri-state bool
int format_index = -1;
std::string dname; // decompressed_name
std::string rname; // recompressed name
const int eindex = extension_index( name ); // search extension
if( eindex >= 0 )
@ -148,8 +150,9 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
program_name, name.c_str(), extension_from( eindex ) );
return 0; // ignore this file
}
dname.assign( name, 0, name.size() - std::strlen( extension_from( eindex ) ) );
dname += extension_to( eindex );
rname.assign( name, 0, name.size() - std::strlen( extension_from( eindex ) ) );
rname += ( std::strcmp( extension_to( eindex ), ".tar" ) == 0 ) ?
".tlz" : ".lz"; // keep combined extension
}
const char * const compressor_name = get_compressor_name( format_index );
if( !compressor_name )
@ -176,9 +179,11 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
return 1;
}
struct stat st;
std::string rname( dname ); rname += ".lz"; // recompressed_name
struct stat st; // not used
const std::string rname2( rname + ".lz" ); // produced by lzip < 1.20
const bool lz_exists = ( stat( rname.c_str(), &st ) == 0 );
// don't modify an existing 'rname.lz'
const bool lz_lz_exists = ( stat( rname2.c_str(), &st ) == 0 );
if( lz_exists && !force )
{
if( verbosity >= 0 )
@ -245,7 +250,7 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
for( int i = 0; i < size; ++i ) argv[i+2] = lzip_args[i].c_str();
for( int i = 0; i < size2; ++i ) argv[i+size+2] = lzip_args2[i].c_str();
argv[size+size2+2] = "-o";
argv[size+size2+3] = dname.c_str();
argv[size+size2+3] = rname.c_str();
argv[size+size2+4] = 0;
execvp( argv[0], (char **)argv );
}
@ -258,7 +263,14 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
close( fda[0] ); close( fda[1] );
int retval = wait_for_child( pid, compressor_name );
int retval2 = wait_for_child( pid2, lzip_name );
if( retval || retval2 ) { std::remove( rname.c_str() ); return 1; }
if( retval || retval2 )
{ if( !lz_lz_exists ) std::remove( rname2.c_str() ); // lzip < 1.20
std::remove( rname.c_str() ); return 1; }
if( stat( rname.c_str(), &st ) != 0 &&
( lz_lz_exists || stat( rname2.c_str(), &st ) != 0 ||
std::rename( rname2.c_str(), rname.c_str() ) != 0 ) )
{ show_file_error( rname.c_str(), "Error renaming output file", errno );
return 1; } // lzip < 1.11
set_permissions( rname.c_str(), in_stats );
}
@ -268,11 +280,12 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
std::string zcmp_command( invocation_name );
unsigned i = zcmp_command.size();
while( i > 0 && zcmp_command[i-1] != '/' ) --i;
zcmp_command.resize( i );
zcmp_command += "zcmp "; // ${bindir}zcmp
zcmp_command.resize( i ); zcmp_command.insert( 0U, 1, '\'' );
zcmp_command += "zcmp' "; // '[dir/]zcmp'
if( no_rcfile ) zcmp_command += "-N ";
if( verbosity < 0 ) zcmp_command += "-q ";
zcmp_command += name; zcmp_command += ' '; zcmp_command += rname;
zcmp_command += '\''; zcmp_command += name;
zcmp_command += "' '"; zcmp_command += rname; zcmp_command += '\'';
int status = std::system( zcmp_command.c_str() );
if( status != 0 )
{ if( !lz_exists ) std::remove( rname.c_str() );
@ -301,8 +314,8 @@ int main( const int argc, const char * const argv[] )
bool force = false;
bool keep_input_files = false;
bool no_rcfile = false;
invocation_name = argv[0];
program_name = "zupdate";
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
const Arg_parser::Option options[] =
{