"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "zupdate.cc" between
zutils-1.8.tar.lz and zutils-1.9.tar.lz

About: Zutils is a collection of utilities able to deal with any combination of compressed and non-compressed files transparently. The utilities zcat, zcmp, zdiff, zgrep and ztest supports the compressors bzip2, gzip, lzip and xz.

zupdate.cc  (zutils-1.8.tar.lz):zupdate.cc  (zutils-1.9.tar.lz)
/* Zupdate - recompress bzip2, gzip, xz files to lzip format /* Zupdate - recompress bzip2, gzip, xz files to lzip format
Copyright (C) 2013-2019 Antonio Diaz Diaz. Copyright (C) 2013-2020 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#include <cerrno> #include <cerrno>
#include <climits> #include <climits>
#include <csignal> #include <csignal>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
skipping to change at line 53 skipping to change at line 53
#ifndef O_BINARY #ifndef O_BINARY
#define O_BINARY 0 #define O_BINARY 0
#endif #endif
namespace { namespace {
#include "recursive.cc" #include "recursive.cc"
void show_help() void show_help()
{ {
std::printf( "Zupdate recompresses files from bzip2, gzip, and xz formats to l zip\n" std::printf( "zupdate recompresses files from bzip2, gzip, and xz formats to l zip\n"
"format. Each original is compared with the new file and then del eted.\n" "format. Each original is compared with the new file and then del eted.\n"
"Only regular files with standard file name extensions are recomp ressed,\n" "Only regular files with standard file name extensions are recomp ressed,\n"
"other files are ignored. Compressed files are decompressed and t hen\n" "other files are ignored. Compressed files are decompressed and t hen\n"
"recompressed on the fly; no temporary files are created. The lzi p format\n" "recompressed on the fly; no temporary files are created. The lzi p format\n"
"is chosen as destination because it is the most appropriate for\ n" "is chosen as destination because it is the most appropriate for\ n"
"long-term data archiving.\n" "long-term data archiving.\n"
"\nIf no files are specified, recursive searches examine the curr ent\n" "\nIf no files are specified, recursive searches examine the curr ent\n"
"working directory, and nonrecursive searches do nothing.\n" "working directory, and nonrecursive searches do nothing.\n"
"\nIf the lzip compressed version of a file already exists, the f ile is\n" "\nIf the lzip compressed version of a file already exists, the f ile is\n"
"skipped unless the '--force' option is given. In this case, if t he\n" "skipped unless the option '--force' is given. In this case, if t he\n"
"comparison with the existing lzip version fails, an error is ret urned\n" "comparison with the existing lzip version fails, an error is ret urned\n"
"and the original file is not deleted. The operation of zupdate i s meant\n" "and the original file is not deleted. The operation of zupdate i s meant\n"
"to be safe and not produce any data loss. Therefore, existing lz ip\n" "to be safe and not cause any data loss. Therefore, existing lzip \n"
"compressed files are never overwritten nor deleted.\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" "\nUsage: zupdate [options] [files]\n"
"\nExit status is 0 if all the compressed files were successfully "\nExit status is 0 if all the compressed files were successfully
\n" recompressed\n"
"recompressed (if needed), compared and deleted (if requested). N "(if needed), compared, and deleted (if requested). Non-zero othe
on-zero\n" rwise.\n"
"otherwise.\n"
"\nOptions:\n" "\nOptions:\n"
" -h, --help display this help and exit\n" " -h, --help display this help and exit\n"
" -V, --version output version information and ex it\n" " -V, --version output version information and ex it\n"
" -f, --force don't skip a file even if the .lz exists\n" " -f, --force don't skip a file even if the .lz exists\n"
" -k, --keep keep (don't delete) input files\n " " -k, --keep keep (don't delete) input files\n "
" -l, --lzip-verbose pass a -v option to the lzip comp ressor\n" " -l, --lzip-verbose pass one option -v to the lzip co mpressor\n"
" -M, --format=<list> process only the formats in <list >\n" " -M, --format=<list> process only the formats in <list >\n"
" -N, --no-rcfile don't read runtime configuration file\n" " -N, --no-rcfile don't read runtime configuration file\n"
" -q, --quiet suppress all messages\n" " -q, --quiet suppress all messages\n"
" -r, --recursive operate recursively on directorie s\n" " -r, --recursive operate recursively on directorie s\n"
" -R, --dereference-recursive recursively follow symbolic links \n" " -R, --dereference-recursive recursively follow symbolic links \n"
" -v, --verbose be verbose (a 2nd -v gives more)\ n" " -v, --verbose be verbose (a 2nd -v gives more)\ n"
" -0 .. -9 set compression level [default 9] \n" " -0 .. -9 set compression level [default 9] \n"
" --bz2=<command> set compressor and options for bz ip2 format\n" " --bz2=<command> set compressor and options for bz ip2 format\n"
" --gz=<command> set compressor and options for gz ip format\n" " --gz=<command> set compressor and options for gz ip format\n"
" --lz=<command> set compressor and options for lz ip format\n" " --lz=<command> set compressor and options for lz ip format\n"
skipping to change at line 106 skipping to change at line 108
if( WIFEXITED( status ) ) if( WIFEXITED( status ) )
std::fprintf( stderr, "%s: Error executing '%s'. Exit status = %d\n", std::fprintf( stderr, "%s: Error executing '%s'. Exit status = %d\n",
program_name, command.c_str(), WEXITSTATUS( status ) ); program_name, command.c_str(), WEXITSTATUS( status ) );
else else
std::fprintf( stderr, "%s: Can't execute '%s'\n", std::fprintf( stderr, "%s: Can't execute '%s'\n",
program_name, command.c_str() ); program_name, command.c_str() );
} }
return 1; return 1;
} }
// Set permissions, owner and times. // Set permissions, owner, and times.
void set_permissions( const char * const rname, const struct stat & in_stats ) void set_permissions( const char * const rname, const struct stat & in_stats )
{ {
bool warning = false; bool warning = false;
const mode_t mode = in_stats.st_mode; const mode_t mode = in_stats.st_mode;
// chown will in many cases return with EPERM, which can be safely ignored. // chown will in many cases return with EPERM, which can be safely ignored.
if( chown( rname, in_stats.st_uid, in_stats.st_gid ) == 0 ) if( chown( rname, in_stats.st_uid, in_stats.st_gid ) == 0 )
{ if( chmod( rname, mode ) != 0 ) warning = true; } { if( chmod( rname, mode ) != 0 ) warning = true; }
else else
if( errno != EPERM || if( errno != EPERM ||
chmod( rname, mode & ~( S_ISUID | S_ISGID | S_ISVTX ) ) != 0 ) chmod( rname, mode & ~( S_ISUID | S_ISGID | S_ISVTX ) ) != 0 )
skipping to change at line 134 skipping to change at line 136
} }
// Returns 0 for success, -1 for file skipped, 1 for error. // Returns 0 for success, -1 for file skipped, 1 for error.
int zupdate_file( const std::string & name, const char * const lzip_name, int zupdate_file( const std::string & name, const char * const lzip_name,
const std::vector< std::string > & lzip_args2, const std::vector< std::string > & lzip_args2,
const bool force, const bool keep_input_files, const bool force, const bool keep_input_files,
const bool no_rcfile ) const bool no_rcfile )
{ {
static int disable_xz = -1; // tri-state bool static int disable_xz = -1; // tri-state bool
int format_index = -1; int format_index = -1;
std::string dname; // decompressed_name std::string rname; // recompressed name
const int eindex = extension_index( name ); // search extension const int eindex = extension_index( name ); // search extension
if( eindex >= 0 ) if( eindex >= 0 )
{ {
format_index = extension_format( eindex ); format_index = extension_format( eindex );
if( format_index == fmt_lz ) if( format_index == fmt_lz )
{ {
if( verbosity >= 2 ) if( verbosity >= 2 )
std::fprintf( stderr, "%s: Input file '%s' already has '%s' suffix.\n", std::fprintf( stderr, "%s: Input file '%s' already has '%s' suffix.\n",
program_name, name.c_str(), extension_from( eindex ) ); program_name, name.c_str(), extension_from( eindex ) );
return 0; // ignore this file return 0; // ignore this file
} }
dname.assign( name, 0, name.size() - std::strlen( extension_from( eindex ) ) rname.assign( name, 0, name.size() - std::strlen( extension_from( eindex ) )
); );
dname += extension_to( eindex ); rname += ( std::strcmp( extension_to( eindex ), ".tar" ) == 0 ) ?
".tlz" : ".lz"; // keep combined extension
} }
const char * const compressor_name = get_compressor_name( format_index ); const char * const compressor_name = get_compressor_name( format_index );
if( !compressor_name ) if( !compressor_name )
{ {
if( verbosity >= 2 ) if( verbosity >= 2 )
std::fprintf( stderr, "%s: Unknown extension in file name '%s' -- ignored. \n", std::fprintf( stderr, "%s: Unknown extension in file name '%s' -- ignored. \n",
program_name, name.c_str() ); program_name, name.c_str() );
return 0; // ignore this file return 0; // ignore this file
} }
skipping to change at line 175 skipping to change at line 178
return 1; return 1;
} }
if( !S_ISREG( in_stats.st_mode ) ) if( !S_ISREG( in_stats.st_mode ) )
{ {
if( verbosity >= 0 ) if( verbosity >= 0 )
std::fprintf( stderr, "%s: Input file '%s' is not a regular file.\n", std::fprintf( stderr, "%s: Input file '%s' is not a regular file.\n",
program_name, name.c_str() ); program_name, name.c_str() );
return 1; return 1;
} }
struct stat st; struct stat st; // not used
std::string rname( dname ); rname += ".lz"; // recompressed_name const std::string rname2( rname + ".lz" ); // produced by lzip < 1.20
const bool lz_exists = ( stat( rname.c_str(), &st ) == 0 ); 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( lz_exists && !force )
{ {
if( verbosity >= 0 ) if( verbosity >= 0 )
std::fprintf( stderr, "%s: Output file '%s' already exists, skipping.\n", std::fprintf( stderr, "%s: Output file '%s' already exists, skipping.\n",
program_name, rname.c_str() ); program_name, rname.c_str() );
return -1; return -1;
} }
if( format_index == fmt_xz ) if( format_index == fmt_xz )
{ {
skipping to change at line 244 skipping to change at line 249
const std::vector< std::string > & lzip_args = const std::vector< std::string > & lzip_args =
get_compressor_args( fmt_lz ); get_compressor_args( fmt_lz );
const int size = lzip_args.size(); const int size = lzip_args.size();
const int size2 = lzip_args2.size(); const int size2 = lzip_args2.size();
const char ** const argv = new const char *[size+size2+5]; const char ** const argv = new const char *[size+size2+5];
argv[0] = lzip_name; argv[0] = lzip_name;
argv[1] = "-9"; argv[1] = "-9";
for( int i = 0; i < size; ++i ) argv[i+2] = lzip_args[i].c_str(); 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(); for( int i = 0; i < size2; ++i ) argv[i+size+2] = lzip_args2[i].c_str();
argv[size+size2+2] = "-o"; argv[size+size2+2] = "-o";
argv[size+size2+3] = dname.c_str(); argv[size+size2+3] = rname.c_str();
argv[size+size2+4] = 0; argv[size+size2+4] = 0;
execvp( argv[0], (char **)argv ); execvp( argv[0], (char **)argv );
} }
show_exec_error( lzip_name ); show_exec_error( lzip_name );
_exit( 1 ); _exit( 1 );
} }
if( pid2 < 0 ) // parent if( pid2 < 0 ) // parent
{ show_fork_error( lzip_name ); return 1; } { show_fork_error( lzip_name ); return 1; }
close( fda[0] ); close( fda[1] ); close( fda[0] ); close( fda[1] );
int retval = wait_for_child( pid, compressor_name ); int retval = wait_for_child( pid, compressor_name );
int retval2 = wait_for_child( pid2, lzip_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 ); set_permissions( rname.c_str(), in_stats );
} }
{ {
if( lz_exists && verbosity >= 1 ) if( lz_exists && verbosity >= 1 )
std::fprintf( stderr, "Comparing file '%s'\n", name.c_str() ); std::fprintf( stderr, "Comparing file '%s'\n", name.c_str() );
std::string zcmp_command( invocation_name ); std::string zcmp_command( invocation_name );
unsigned i = zcmp_command.size(); unsigned i = zcmp_command.size();
while( i > 0 && zcmp_command[i-1] != '/' ) --i; while( i > 0 && zcmp_command[i-1] != '/' ) --i;
zcmp_command.resize( i ); zcmp_command.resize( i ); zcmp_command.insert( 0U, 1, '\'' );
zcmp_command += "zcmp "; // ${bindir}zcmp zcmp_command += "zcmp' "; // '[dir/]zcmp'
if( no_rcfile ) zcmp_command += "-N "; if( no_rcfile ) zcmp_command += "-N ";
if( verbosity < 0 ) zcmp_command += "-q "; 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() ); int status = std::system( zcmp_command.c_str() );
if( status != 0 ) if( status != 0 )
{ if( !lz_exists ) std::remove( rname.c_str() ); { if( !lz_exists ) std::remove( rname.c_str() );
return cant_execute( zcmp_command, status ); } return cant_execute( zcmp_command, status ); }
} }
if( !keep_input_files && std::remove( name.c_str() ) != 0 && errno != ENOENT ) if( !keep_input_files && std::remove( name.c_str() ) != 0 && errno != ENOENT )
{ {
if( verbosity >= 0 ) if( verbosity >= 0 )
std::fprintf( stderr, "%s: Can't delete input file '%s': %s\n", std::fprintf( stderr, "%s: Can't delete input file '%s': %s\n",
skipping to change at line 299 skipping to change at line 312
int main( const int argc, const char * const argv[] ) int main( const int argc, const char * const argv[] )
{ {
enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt }; enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt };
int recursive = 0; // 1 = '-r', 2 = '-R' int recursive = 0; // 1 = '-r', 2 = '-R'
std::list< std::string > filenames; std::list< std::string > filenames;
std::vector< std::string > lzip_args2; // args to lzip, maybe empty std::vector< std::string > lzip_args2; // args to lzip, maybe empty
bool force = false; bool force = false;
bool keep_input_files = false; bool keep_input_files = false;
bool no_rcfile = false; bool no_rcfile = false;
invocation_name = argv[0];
program_name = "zupdate"; program_name = "zupdate";
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
const Arg_parser::Option options[] = const Arg_parser::Option options[] =
{ {
{ '0', 0, Arg_parser::no }, { '0', 0, Arg_parser::no },
{ '1', 0, Arg_parser::no }, { '1', 0, Arg_parser::no },
{ '2', 0, Arg_parser::no }, { '2', 0, Arg_parser::no },
{ '3', 0, Arg_parser::no }, { '3', 0, Arg_parser::no },
{ '4', 0, Arg_parser::no }, { '4', 0, Arg_parser::no },
{ '5', 0, Arg_parser::no }, { '5', 0, Arg_parser::no },
{ '6', 0, Arg_parser::no }, { '6', 0, Arg_parser::no },
 End of changes. 20 change blocks. 
35 lines changed or deleted 50 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)