1
0
Fork 0

Adding upstream version 1.14~rc3.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-21 11:13:27 +01:00
parent 378b7b036f
commit 204cd23cae
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
17 changed files with 152 additions and 74 deletions

View file

@ -1,3 +1,10 @@
2013-04-26 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.14-rc3 released.
* Added new option '-i, --ignore-errors'.
* split.cc: Use as few digits as possible in file names.
* split.cc: In verbose mode show names of files being created.
2013-03-25 Antonio Diaz Diaz <ant_diaz@teleline.es> 2013-03-25 Antonio Diaz Diaz <ant_diaz@teleline.es>
* Version 1.14-rc2 released. * Version 1.14-rc2 released.

View file

@ -1,7 +1,7 @@
Requirements Requirements
------------ ------------
You will need a C++ compiler. You will need a C++ compiler.
I use gcc 4.7.2 and 3.3.6, but the code should compile with any I use gcc 4.8.0 and 3.3.6, but the code should compile with any
standards compliant compiler. standards compliant compiler.
Gcc is available at http://gcc.gnu.org. Gcc is available at http://gcc.gnu.org.

View file

@ -115,6 +115,8 @@ dist : doc
$(DISTNAME)/doc/$(pkgname).info \ $(DISTNAME)/doc/$(pkgname).info \
$(DISTNAME)/doc/$(pkgname).texinfo \ $(DISTNAME)/doc/$(pkgname).texinfo \
$(DISTNAME)/testsuite/check.sh \ $(DISTNAME)/testsuite/check.sh \
$(DISTNAME)/testsuite/fox5_bad.lz \
$(DISTNAME)/testsuite/fox5_bad.txt \
$(DISTNAME)/testsuite/test.txt \ $(DISTNAME)/testsuite/test.txt \
$(DISTNAME)/testsuite/test921-1921.txt \ $(DISTNAME)/testsuite/test921-1921.txt \
$(DISTNAME)/testsuite/test_bad[1-5].lz \ $(DISTNAME)/testsuite/test_bad[1-5].lz \

12
NEWS
View file

@ -1,10 +1,20 @@
Changes in version 1.14: Changes in version 1.14:
The new option "-i, --ignore-errors", which in conjunction with "-D"
decompresses all the recoverable data in all members of a file without
having to split it first, has been added.
Option "-l, --list" now accepts more than one file. Option "-l, --list" now accepts more than one file.
Decompression time has been reduced by 12%. Decompression time has been reduced by 12%.
File version is now shown only if verbosity >= 4. "--split" now uses as few digits as possible in the names of the files
produced, depending on the number of members in the input file.
"--split" in verbose mode now shows the names of files being created.
When decompressing or testing, file version is now shown only if
verbosity >= 4.
The target "install-as-lzip" has been added to the Makefile. The target "install-as-lzip" has been added to the Makefile.

2
configure vendored
View file

@ -8,7 +8,7 @@
args= args=
no_create= no_create=
pkgname=lziprecover pkgname=lziprecover
pkgversion=1.14-rc2 pkgversion=1.14-rc3
progname=lziprecover progname=lziprecover
srctrigger=doc/lziprecover.texinfo srctrigger=doc/lziprecover.texinfo

View file

@ -181,7 +181,7 @@ bool LZ_decoder::verify_trailer( const Pretty_print & pp ) const
trailer.member_size(), member_size, member_size ); trailer.member_size(), member_size, member_size );
} }
} }
if( !error && pp.verbosity() >= 3 && data_position() > 0 && member_size > 0 ) if( !error && pp.verbosity() >= 2 && data_position() > 0 && member_size > 0 )
std::fprintf( stderr, "%6.3f:1, %6.3f bits/byte, %5.2f%% saved. ", std::fprintf( stderr, "%6.3f:1, %6.3f bits/byte, %5.2f%% saved. ",
(double)data_position() / member_size, (double)data_position() / member_size,
( 8.0 * member_size ) / data_position(), ( 8.0 * member_size ) / data_position(),

View file

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
.TH LZIPRECOVER "1" "March 2013" "Lziprecover 1.14-rc2" "User Commands" .TH LZIPRECOVER "1" "April 2013" "Lziprecover 1.14-rc3" "User Commands"
.SH NAME .SH NAME
Lziprecover \- recovers data from damaged lzip files Lziprecover \- recovers data from damaged lzip files
.SH SYNOPSIS .SH SYNOPSIS
@ -27,6 +27,9 @@ decompress only a range of bytes (N\-M)
\fB\-f\fR, \fB\-\-force\fR \fB\-f\fR, \fB\-\-force\fR
overwrite existing output files overwrite existing output files
.TP .TP
\fB\-i\fR, \fB\-\-ignore\-errors\fR
make '\-\-range\-decompress' ignore data errors
.TP
\fB\-k\fR, \fB\-\-keep\fR \fB\-k\fR, \fB\-\-keep\fR
keep (don't delete) input files keep (don't delete) input files
.TP .TP

View file

@ -12,7 +12,7 @@ File: lziprecover.info, Node: Top, Next: Introduction, Up: (dir)
Lziprecover Manual Lziprecover Manual
****************** ******************
This manual is for Lziprecover (version 1.14-rc2, 25 March 2013). This manual is for Lziprecover (version 1.14-rc3, 23 April 2013).
* Menu: * Menu:
@ -66,7 +66,7 @@ from damaged members can be partially recovered writing it to stdout as
shown in the following example (the resulting file may contain some shown in the following example (the resulting file may contain some
garbage data at the end): garbage data at the end):
lziprecover -cd rec00001file.lz > rec00001file lziprecover -cd rec01file.lz > rec01file
If the cause of file corruption is damaged media, the combination If the cause of file corruption is damaged media, the combination
GNU ddrescue + lziprecover is the best option for recovering data from GNU ddrescue + lziprecover is the best option for recovering data from
@ -125,6 +125,14 @@ The format for running lziprecover is:
`--force' `--force'
Force overwrite of output files. Force overwrite of output files.
`-i'
`--ignore-errors'
Make `--range-decompress' ignore data errors and continue
decompressing the remaining members in the file. For example,
`lziprecover -i -D0 file.lz > file' decompresses all the
recoverable data in all members of `file.lz' without having to
split it first.
`-k' `-k'
`--keep' `--keep'
Keep (don't delete) input files during decompression. Keep (don't delete) input files during decompression.
@ -155,9 +163,9 @@ The format for running lziprecover is:
`--output=FILE' `--output=FILE'
Place the output into `FILE' instead of into `FILE_fixed.lz'. If Place the output into `FILE' instead of into `FILE_fixed.lz'. If
splitting, the names of the files produced are in the form splitting, the names of the files produced are in the form
`rec00001FILE', `rec00002FILE', etc. If decompressing from `rec01FILE', `rec02FILE', etc. If decompressing from standard
standard input and `--stdout' has not been specified, use `FILE' input and `--stdout' has not been specified, use `FILE' as the
as the name of the decompressed file. name of the decompressed file.
`-q' `-q'
`--quiet' `--quiet'
@ -178,11 +186,12 @@ The format for running lziprecover is:
undamaged, and try to repair or partially decompress those which undamaged, and try to repair or partially decompress those which
are damaged. are damaged.
The names of the files produced are in the form `rec00001FILE.lz', The names of the files produced are in the form `rec01FILE.lz',
`rec00002FILE.lz', etc, and are designed so that the use of `rec02FILE.lz', etc, and are designed so that the use of wildcards
wildcards in subsequent processing, for example, in subsequent processing, for example,
`lziprecover -cd rec*FILE.lz > recovered_data', processes the `lziprecover -cd rec*FILE.lz > recovered_data', processes the
files in the correct order. files in the correct order. The number of digits used in the names
varies depending on the number of members in `FILE'.
`-t' `-t'
`--test' `--test'
@ -353,24 +362,24 @@ error-checked merging of copies (*Note GNU ddrescue manual:
Example 8: Recover the first volume of those created with the command Example 8: Recover the first volume of those created with the command
`lzip -b 32MiB -S 650MB big_db' from two copies, `big_db1_00001.lz' and `lzip -b 32MiB -S 650MB big_db' from two copies, `big_db1_00001.lz' and
`big_db2_00001.lz', with member 00007 damaged in the first copy, member `big_db2_00001.lz', with member 07 damaged in the first copy, member 18
00018 damaged in the second copy, and member 00012 damaged in both damaged in the second copy, and member 12 damaged in both copies. Two
copies. Two correct copies are produced and compared. correct copies are produced and compared.
lziprecover -s big_db1_00001.lz lziprecover -s big_db1_00001.lz
lziprecover -s big_db2_00001.lz lziprecover -s big_db2_00001.lz
lziprecover -t rec*big_db1_00001.lz lziprecover -t rec*big_db1_00001.lz
rec00007big_db1_00001.lz: crc mismatch rec07big_db1_00001.lz: crc mismatch
rec00012big_db1_00001.lz: crc mismatch rec12big_db1_00001.lz: crc mismatch
lziprecover -t rec*big_db2_00001.lz lziprecover -t rec*big_db2_00001.lz
rec00012big_db2_00001.lz: crc mismatch rec12big_db2_00001.lz: crc mismatch
rec00018big_db2_00001.lz: crc mismatch rec18big_db2_00001.lz: crc mismatch
lziprecover -m -v rec00012big_db1_00001.lz rec00012big_db2_00001.lz lziprecover -m -v rec12big_db1_00001.lz rec12big_db2_00001.lz
Input files merged successfully Input files merged successfully
cp rec00007big_db2_00001.lz rec00007big_db1_00001.lz cp rec07big_db2_00001.lz rec07big_db1_00001.lz
cp rec00012big_db1_00001_fixed.lz rec00012big_db1_00001.lz cp rec12big_db1_00001_fixed.lz rec12big_db1_00001.lz
cp rec00012big_db1_00001_fixed.lz rec00012big_db2_00001.lz cp rec12big_db1_00001_fixed.lz rec12big_db2_00001.lz
cp rec00018big_db1_00001.lz rec00018big_db2_00001.lz cp rec18big_db1_00001.lz rec18big_db2_00001.lz
cat rec*big_db1_00001.lz > big_db3_00001.lz cat rec*big_db1_00001.lz > big_db3_00001.lz
cat rec*big_db2_00001.lz > big_db4_00001.lz cat rec*big_db2_00001.lz > big_db4_00001.lz
zcmp big_db3_00001.lz big_db4_00001.lz zcmp big_db3_00001.lz big_db4_00001.lz
@ -411,12 +420,12 @@ Concept Index
Tag Table: Tag Table:
Node: Top231 Node: Top231
Node: Introduction907 Node: Introduction907
Node: Invoking Lziprecover2944 Node: Invoking Lziprecover2938
Node: File Format8070 Node: File Format8454
Node: Examples10512 Node: Examples10896
Ref: ddrescue-example11730 Ref: ddrescue-example12114
Node: Problems13561 Node: Problems13894
Node: Concept Index14111 Node: Concept Index14444
 
End Tag Table End Tag Table

View file

@ -6,8 +6,8 @@
@finalout @finalout
@c %**end of header @c %**end of header
@set UPDATED 25 March 2013 @set UPDATED 23 April 2013
@set VERSION 1.14-rc2 @set VERSION 1.14-rc3
@dircategory Data Compression @dircategory Data Compression
@direntry @direntry
@ -86,7 +86,7 @@ in the following example (the resulting file may contain some garbage
data at the end): data at the end):
@example @example
lziprecover -cd rec00001file.lz > rec00001file lziprecover -cd rec01file.lz > rec01file
@end example @end example
If the cause of file corruption is damaged media, the combination If the cause of file corruption is damaged media, the combination
@ -148,6 +148,14 @@ containing the desired data.
@itemx --force @itemx --force
Force overwrite of output files. Force overwrite of output files.
@item -i
@itemx --ignore-errors
Make @samp{--range-decompress} ignore data errors and continue
decompressing the remaining members in the file. For example,
@w{@samp{lziprecover -i -D0 file.lz > file}} decompresses all the
recoverable data in all members of @samp{file.lz} without having to
split it first.
@item -k @item -k
@itemx --keep @itemx --keep
Keep (don't delete) input files during decompression. Keep (don't delete) input files during decompression.
@ -179,10 +187,10 @@ copies.
@itemx --output=@var{file} @itemx --output=@var{file}
Place the output into @samp{@var{file}} instead of into Place the output into @samp{@var{file}} instead of into
@samp{@var{file}_fixed.lz}. If splitting, the names of the files @samp{@var{file}_fixed.lz}. If splitting, the names of the files
produced are in the form @samp{rec00001@var{file}}, produced are in the form @samp{rec01@var{file}}, @samp{rec02@var{file}},
@samp{rec00002@var{file}}, etc. If decompressing from standard input and etc. If decompressing from standard input and @samp{--stdout} has not
@samp{--stdout} has not been specified, use @samp{@var{file}} as the been specified, use @samp{@var{file}} as the name of the decompressed
name of the decompressed file. file.
@item -q @item -q
@itemx --quiet @itemx --quiet
@ -203,10 +211,11 @@ integrity of the resulting files, decompress those which are undamaged,
and try to repair or partially decompress those which are damaged. and try to repair or partially decompress those which are damaged.
The names of the files produced are in the form The names of the files produced are in the form
@samp{rec00001@var{file}.lz}, @samp{rec00002@var{file}.lz}, etc, and are @samp{rec01@var{file}.lz}, @samp{rec02@var{file}.lz}, etc, and are
designed so that the use of wildcards in subsequent processing, for designed so that the use of wildcards in subsequent processing, for
example, @w{@samp{lziprecover -cd rec*@var{file}.lz > recovered_data}}, example, @w{@samp{lziprecover -cd rec*@var{file}.lz > recovered_data}},
processes the files in the correct order. processes the files in the correct order. The number of digits used in
the names varies depending on the number of members in @samp{@var{file}}.
@item -t @item -t
@itemx --test @itemx --test
@ -411,26 +420,26 @@ lziprecover -m -v -o rescued.tar.lz rescued1.tar.lz rescued2.tar.lz
@noindent @noindent
Example 8: Recover the first volume of those created with the command Example 8: Recover the first volume of those created with the command
@w{@code{lzip -b 32MiB -S 650MB big_db}} from two copies, @w{@code{lzip -b 32MiB -S 650MB big_db}} from two copies,
@samp{big_db1_00001.lz} and @samp{big_db2_00001.lz}, with member 00007 @samp{big_db1_00001.lz} and @samp{big_db2_00001.lz}, with member 07
damaged in the first copy, member 00018 damaged in the second copy, and damaged in the first copy, member 18 damaged in the second copy, and
member 00012 damaged in both copies. Two correct copies are produced and member 12 damaged in both copies. Two correct copies are produced and
compared. compared.
@example @example
lziprecover -s big_db1_00001.lz lziprecover -s big_db1_00001.lz
lziprecover -s big_db2_00001.lz lziprecover -s big_db2_00001.lz
lziprecover -t rec*big_db1_00001.lz lziprecover -t rec*big_db1_00001.lz
rec00007big_db1_00001.lz: crc mismatch rec07big_db1_00001.lz: crc mismatch
rec00012big_db1_00001.lz: crc mismatch rec12big_db1_00001.lz: crc mismatch
lziprecover -t rec*big_db2_00001.lz lziprecover -t rec*big_db2_00001.lz
rec00012big_db2_00001.lz: crc mismatch rec12big_db2_00001.lz: crc mismatch
rec00018big_db2_00001.lz: crc mismatch rec18big_db2_00001.lz: crc mismatch
lziprecover -m -v rec00012big_db1_00001.lz rec00012big_db2_00001.lz lziprecover -m -v rec12big_db1_00001.lz rec12big_db2_00001.lz
Input files merged successfully Input files merged successfully
cp rec00007big_db2_00001.lz rec00007big_db1_00001.lz cp rec07big_db2_00001.lz rec07big_db1_00001.lz
cp rec00012big_db1_00001_fixed.lz rec00012big_db1_00001.lz cp rec12big_db1_00001_fixed.lz rec12big_db1_00001.lz
cp rec00012big_db1_00001_fixed.lz rec00012big_db2_00001.lz cp rec12big_db1_00001_fixed.lz rec12big_db2_00001.lz
cp rec00018big_db1_00001.lz rec00018big_db2_00001.lz cp rec18big_db1_00001.lz rec18big_db2_00001.lz
cat rec*big_db1_00001.lz > big_db3_00001.lz cat rec*big_db1_00001.lz > big_db3_00001.lz
cat rec*big_db2_00001.lz > big_db4_00001.lz cat rec*big_db2_00001.lz > big_db4_00001.lz
zcmp big_db3_00001.lz big_db4_00001.lz zcmp big_db3_00001.lz big_db4_00001.lz

2
lzip.h
View file

@ -316,7 +316,7 @@ int list_files( const std::vector< std::string > & filenames,
int range_decompress( const std::string & input_filename, int range_decompress( const std::string & input_filename,
const std::string & default_output_filename, const std::string & default_output_filename,
const std::string & range_string, const int verbosity, const std::string & range_string, const int verbosity,
const bool force, const bool to_stdout ); const bool force, const bool ignore, const bool to_stdout );
// defined in repair.cc // defined in repair.cc
int seek_read( const int fd, uint8_t * const buf, const int size, int seek_read( const int fd, uint8_t * const buf, const int size,

10
main.cc
View file

@ -103,6 +103,7 @@ void show_help()
" -D, --range-decompress=<range> decompress only a range of bytes (N-M)\n" " -D, --range-decompress=<range> decompress only a range of bytes (N-M)\n"
" -f, --force overwrite existing output files\n" " -f, --force overwrite existing output files\n"
// " -g, --generate-recover-file generate a recover file\n" // " -g, --generate-recover-file generate a recover file\n"
" -i, --ignore-errors make '--range-decompress' ignore data errors\n"
" -k, --keep keep (don't delete) input files\n" " -k, --keep keep (don't delete) input files\n"
" -l, --list print total file sizes and ratios\n" " -l, --list print total file sizes and ratios\n"
" -m, --merge correct errors in file using several copies\n" " -m, --merge correct errors in file using several copies\n"
@ -399,7 +400,7 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
{ pp( "Invalid dictionary size in member header" ); retval = 2; break; } { pp( "Invalid dictionary size in member header" ); retval = 2; break; }
if( verbosity >= 2 || ( verbosity == 1 && first_member ) ) if( verbosity >= 2 || ( verbosity == 1 && first_member ) )
{ pp(); if( verbosity >= 2 ) show_header( header ); } { pp(); if( verbosity >= 3 ) show_header( header ); }
LZ_decoder decoder( header, rdec, outfd ); LZ_decoder decoder( header, rdec, outfd );
const int result = decoder.decode_member( pp ); const int result = decoder.decode_member( pp );
@ -507,6 +508,7 @@ int main( const int argc, const char * const argv[] )
int infd = -1; int infd = -1;
Mode program_mode = m_none; Mode program_mode = m_none;
bool force = false; bool force = false;
bool ignore = false;
bool keep_input_files = false; bool keep_input_files = false;
bool to_stdout = false; bool to_stdout = false;
invocation_name = argv[0]; invocation_name = argv[0];
@ -518,9 +520,11 @@ int main( const int argc, const char * const argv[] )
{ 'D', "range-decompress", Arg_parser::yes }, { 'D', "range-decompress", Arg_parser::yes },
{ 'f', "force", Arg_parser::no }, { 'f', "force", Arg_parser::no },
{ 'h', "help", Arg_parser::no }, { 'h', "help", Arg_parser::no },
{ 'i', "ignore-errors", Arg_parser::no },
{ 'k', "keep", Arg_parser::no }, { 'k', "keep", Arg_parser::no },
{ 'l', "list", Arg_parser::no }, { 'l', "list", Arg_parser::no },
{ 'm', "merge", Arg_parser::no }, { 'm', "merge", Arg_parser::no },
{ 'n', "threads", Arg_parser::yes },
{ 'o', "output", Arg_parser::yes }, { 'o', "output", Arg_parser::yes },
{ 'q', "quiet", Arg_parser::no }, { 'q', "quiet", Arg_parser::no },
{ 'R', "repair", Arg_parser::no }, { 'R', "repair", Arg_parser::no },
@ -548,9 +552,11 @@ int main( const int argc, const char * const argv[] )
range_string = arg; break; range_string = arg; break;
case 'f': force = true; break; case 'f': force = true; break;
case 'h': show_help(); return 0; case 'h': show_help(); return 0;
case 'i': ignore = true; break;
case 'k': keep_input_files = true; break; case 'k': keep_input_files = true; break;
case 'l': set_mode( program_mode, m_list ); break; case 'l': set_mode( program_mode, m_list ); break;
case 'm': set_mode( program_mode, m_merge ); break; case 'm': set_mode( program_mode, m_merge ); break;
case 'n': break;
case 'o': default_output_filename = arg; break; case 'o': default_output_filename = arg; break;
case 'q': verbosity = -1; break; case 'q': verbosity = -1; break;
case 'R': set_mode( program_mode, m_repair ); break; case 'R': set_mode( program_mode, m_repair ); break;
@ -600,7 +606,7 @@ int main( const int argc, const char * const argv[] )
case m_range: case m_range:
one_file( filenames.size() ); one_file( filenames.size() );
return range_decompress( filenames[0], default_output_filename, return range_decompress( filenames[0], default_output_filename,
range_string, verbosity, force, to_stdout ); range_string, verbosity, force, ignore, to_stdout );
case m_repair: case m_repair:
one_file( filenames.size() ); one_file( filenames.size() );
if( !default_output_filename.size() ) if( !default_output_filename.size() )

View file

@ -135,7 +135,7 @@ int open_input_files( const std::vector< std::string > & filenames,
else if( st_ino0 == in_stats.st_ino && st_dev0 == in_stats.st_dev ) else if( st_ino0 == in_stats.st_ino && st_dev0 == in_stats.st_dev )
{ identical = true; break; } { identical = true; break; }
} }
if( identical ) { show_error( "Two input files are the same." ); return 1; } if( identical ) { show_error( "Two input files are the same." ); return 2; }
isize = 0; isize = 0;
for( unsigned i = 0; i < filenames.size(); ++i ) for( unsigned i = 0; i < filenames.size(); ++i )
@ -154,7 +154,7 @@ int open_input_files( const std::vector< std::string > & filenames,
{ show_error( "Input file is too short." ); return 2; } { show_error( "Input file is too short." ); return 2; }
} }
else if( isize != tmp ) else if( isize != tmp )
{ show_error( "Sizes of input files are different." ); return 1; } { show_error( "Sizes of input files are different." ); return 2; }
} }
for( unsigned i = 0; i < filenames.size(); ++i ) for( unsigned i = 0; i < filenames.size(); ++i )

View file

@ -227,7 +227,7 @@ int list_files( const std::vector< std::string > & filenames,
int range_decompress( const std::string & input_filename, int range_decompress( const std::string & input_filename,
const std::string & output_filename, const std::string & output_filename,
const std::string & range_string, const int verbosity, const std::string & range_string, const int verbosity,
const bool force, const bool to_stdout ) const bool force, const bool ignore, const bool to_stdout )
{ {
Block range( 0, 0 ); Block range( 0, 0 );
parse_range( range_string.c_str(), range ); parse_range( range_string.c_str(), range );
@ -260,7 +260,7 @@ int range_decompress( const std::string & input_filename,
else else
{ outfd = open_outstream_rw( output_filename, force ); { outfd = open_outstream_rw( output_filename, force );
if( outfd < 0 ) return 1; } if( outfd < 0 ) return 1; }
Pretty_print pp( input_filename, 0 ); Pretty_print pp( input_filename, verbosity );
int retval = 0; int retval = 0;
for( int i = 0; i < file_index.members(); ++i ) for( int i = 0; i < file_index.members(); ++i )
{ {
@ -268,13 +268,15 @@ int range_decompress( const std::string & input_filename,
if( range.overlaps( db ) ) if( range.overlaps( db ) )
{ {
if( verbosity >= 3 ) if( verbosity >= 3 )
std::fprintf( stderr, "Decompressing member %3d\n", i ); std::fprintf( stderr, "Decompressing member %3d\n", i + 1 );
const long long outskip = std::max( 0LL, range.pos() - db.pos() ); const long long outskip = std::max( 0LL, range.pos() - db.pos() );
const long long outend = std::min( db.end(), range.end() - db.pos() ); const long long outend = std::min( db.size(), range.end() - db.pos() );
const long long mpos = file_index.mblock( i ).pos(); const long long mpos = file_index.mblock( i ).pos();
if( !safe_seek( infd, mpos ) ) { retval = 1; break; } if( !safe_seek( infd, mpos ) ) { retval = 1; break; }
retval = decompress_member( infd, outfd, pp, mpos, outskip, outend ); const int tmp = decompress_member( infd, outfd, pp, mpos, outskip, outend );
if( retval ) cleanup_and_fail( output_filename, outfd, retval ); if( tmp && ( tmp != 2 || !ignore ) )
cleanup_and_fail( output_filename, outfd, tmp );
if( tmp > retval ) retval = tmp;
pp.reset(); pp.reset();
} }
} }
@ -284,7 +286,7 @@ int range_decompress( const std::string & input_filename,
show_error( "Error closing output file", errno ); show_error( "Error closing output file", errno );
cleanup_and_fail( output_filename, -1, 1 ); cleanup_and_fail( output_filename, -1, 1 );
} }
if( verbosity >= 2 ) if( verbosity >= 2 && retval == 0 )
std::fprintf( stderr, "Byte range decompressed successfully.\n" ); std::fprintf( stderr, "Byte range decompressed successfully.\n" );
return retval; return retval;
} }

View file

@ -28,13 +28,14 @@
#include <sys/stat.h> #include <sys/stat.h>
#include "lzip.h" #include "lzip.h"
#include "file_index.h"
namespace { namespace {
void first_filename( const std::string & input_filename, void first_filename( const std::string & input_filename,
const std::string & default_output_filename, const std::string & default_output_filename,
std::string & output_filename ) std::string & output_filename, const int max_digits )
{ {
if( default_output_filename.size() ) if( default_output_filename.size() )
output_filename = default_output_filename; output_filename = default_output_filename;
@ -42,15 +43,17 @@ void first_filename( const std::string & input_filename,
output_filename = input_filename; output_filename = input_filename;
int b = output_filename.size(); int b = output_filename.size();
while( b > 0 && output_filename[b-1] != '/' ) --b; while( b > 0 && output_filename[b-1] != '/' ) --b;
output_filename.insert( b, "rec00001" ); output_filename.insert( b, 1, '1' );
if( max_digits > 1 ) output_filename.insert( b, max_digits - 1, '0' );
output_filename.insert( b, "rec" );
} }
bool next_filename( std::string & output_filename ) bool next_filename( std::string & output_filename, const int max_digits )
{ {
int b = output_filename.size(); int b = output_filename.size();
while( b > 0 && output_filename[b-1] != '/' ) --b; while( b > 0 && output_filename[b-1] != '/' ) --b;
for( int i = b + 7; i >= b + 3; --i ) // "rec00001" for( int i = b + max_digits + 2; i > b + 2; --i ) // "rec<max_digits>"
{ {
if( output_filename[i] < '9' ) { ++output_filename[i]; return true; } if( output_filename[i] < '9' ) { ++output_filename[i]; return true; }
else output_filename[i] = '0'; else output_filename[i] = '0';
@ -96,7 +99,12 @@ int do_split_file( const std::string & input_filename, uint8_t * & base_buffer,
struct stat in_stats; struct stat in_stats;
const int infd = open_instream( input_filename, &in_stats, true, true ); const int infd = open_instream( input_filename, &in_stats, true, true );
if( infd < 0 ) return 1; if( infd < 0 ) return 1;
int size = readblock( infd, buffer, buffer_size + hsize ) - hsize; File_index file_index( infd );
const int max_members = ( file_index.retval() ? 999999 : file_index.members() );
int max_digits = 1;
for( int i = max_members; i >= 10; i /= 10 ) ++max_digits;
int size = seek_read( infd, buffer, buffer_size + hsize, 0 ) - hsize;
bool at_stream_end = ( size < buffer_size ); bool at_stream_end = ( size < buffer_size );
if( size != buffer_size && errno ) if( size != buffer_size && errno )
{ show_error( "Read error", errno ); return 1; } { show_error( "Read error", errno ); return 1; }
@ -105,7 +113,8 @@ int do_split_file( const std::string & input_filename, uint8_t * & base_buffer,
if( !verify_header( *(File_header *)buffer, verbosity ) ) return 2; if( !verify_header( *(File_header *)buffer, verbosity ) ) return 2;
std::string output_filename; std::string output_filename;
first_filename( input_filename, default_output_filename, output_filename ); first_filename( input_filename, default_output_filename, output_filename,
max_digits );
int outfd = open_outstream_rw( output_filename, force ); int outfd = open_outstream_rw( output_filename, force );
if( outfd < 0 ) { close( infd ); return 1; } if( outfd < 0 ) { close( infd ); return 1; }
@ -126,7 +135,12 @@ int do_split_file( const std::string & input_filename, uint8_t * & base_buffer,
{ show_error( "Write error", errno ); return 1; } { show_error( "Write error", errno ); return 1; }
if( close( outfd ) != 0 ) if( close( outfd ) != 0 )
{ show_error( "Error closing output file", errno ); return 1; } { show_error( "Error closing output file", errno ); return 1; }
if( !next_filename( output_filename ) ) if( verbosity >= 1 )
{
std::printf( "Member '%s' done \r", output_filename.c_str() );
std::fflush( stdout );
}
if( !next_filename( output_filename, max_digits ) )
{ show_error( "Too many members in file." ); close( infd ); return 1; } { show_error( "Too many members in file." ); close( infd ); return 1; }
outfd = open_outstream_rw( output_filename, force ); outfd = open_outstream_rw( output_filename, force );
if( outfd < 0 ) { close( infd ); return 1; } if( outfd < 0 ) { close( infd ); return 1; }
@ -159,6 +173,11 @@ int do_split_file( const std::string & input_filename, uint8_t * & base_buffer,
close( infd ); close( infd );
if( close( outfd ) != 0 ) if( close( outfd ) != 0 )
{ show_error( "Error closing output file", errno ); return 1; } { show_error( "Error closing output file", errno ); return 1; }
if( verbosity >= 1 )
{
std::printf( "Member '%s' done \n", output_filename.c_str() );
std::fflush( stdout );
}
return 0; return 0;
} }

View file

@ -25,6 +25,8 @@ cd "${objdir}"/tmp
in="${testdir}"/test.txt in="${testdir}"/test.txt
in_lz="${testdir}"/test_v1.lz in_lz="${testdir}"/test_v1.lz
inD="${testdir}"/test921-1921.txt inD="${testdir}"/test921-1921.txt
fox5="${testdir}"/fox5_bad.txt
fox5_lz="${testdir}"/fox5_bad.lz
bad1_lz="${testdir}"/test_bad1.lz bad1_lz="${testdir}"/test_bad1.lz
bad2_lz="${testdir}"/test_bad2.lz bad2_lz="${testdir}"/test_bad2.lz
bad3_lz="${testdir}"/test_bad3.lz bad3_lz="${testdir}"/test_bad3.lz
@ -33,6 +35,7 @@ bad5_lz="${testdir}"/test_bad5.lz
fail=0 fail=0
# Description of test files for lziprecover: # Description of test files for lziprecover:
# fox5_bad.lz: byte at offset 188 changed from 0x34 to 0x33
# test_bad1.lz: byte at offset 67 changed from 0xCC to 0x33 # test_bad1.lz: byte at offset 67 changed from 0xCC to 0x33
# test_bad2.lz: [ 34- 66) --> copy of bytes [ 68- 100) # test_bad2.lz: [ 34- 66) --> copy of bytes [ 68- 100)
# test_bad3.lz: [ 512-1536) --> zeroed; [2560-3584) --> zeroed # test_bad3.lz: [ 512-1536) --> zeroed; [2560-3584) --> zeroed
@ -68,9 +71,13 @@ printf .
"${LZIPRECOVER}" -D 921,1000 "${in_lz}" > copy || fail=1 "${LZIPRECOVER}" -D 921,1000 "${in_lz}" > copy || fail=1
cmp "${inD}" copy || fail=1 cmp "${inD}" copy || fail=1
printf . printf .
"${LZIPRECOVER}" -D0 -iq -fo copy "${fox5_lz}"
if [ $? = 2 ] && cmp "${fox5}" copy ; then printf . ; else fail=1 ; printf - ; fi
"${LZIPRECOVER}" -D0 -iq "${fox5_lz}" > copy
if [ $? = 2 ] && cmp "${fox5}" copy ; then printf . ; else fail=1 ; printf - ; fi
"${LZIPRECOVER}" -m -o copy.lz "${bad1_lz}" "${bad2_lz}" "${bad1_lz}" -q "${LZIPRECOVER}" -m -o copy.lz "${bad1_lz}" "${bad2_lz}" "${bad1_lz}" -q
if [ $? != 1 ] ; then fail=1 ; printf - ; else printf . ; fi if [ $? != 2 ] ; then fail=1 ; printf - ; else printf . ; fi
"${LZIPRECOVER}" -m -o copy.lz "${bad1_lz}" "${bad2_lz}" || fail=1 "${LZIPRECOVER}" -m -o copy.lz "${bad1_lz}" "${bad2_lz}" || fail=1
"${LZIPRECOVER}" -df copy.lz || fail=1 "${LZIPRECOVER}" -df copy.lz || fail=1
cmp "${in}" copy || fail=1 cmp "${in}" copy || fail=1
@ -119,7 +126,7 @@ cat "${in_lz}" "${in_lz}" "${in_lz}" > copy || framework_failure
printf "garbage" >> copy || fail=1 printf "garbage" >> copy || fail=1
"${LZIPRECOVER}" -s -o copy.lz copy || fail=1 "${LZIPRECOVER}" -s -o copy.lz copy || fail=1
for i in 1 2 3 ; do for i in 1 2 3 ; do
"${LZIPRECOVER}" -cd rec0000${i}copy.lz > copy || fail=1 "${LZIPRECOVER}" -cd rec${i}copy.lz > copy || fail=1
cmp "${in}" copy || fail=1 cmp "${in}" copy || fail=1
printf . printf .
done done

BIN
testsuite/fox5_bad.lz Normal file

Binary file not shown.

4
testsuite/fox5_bad.txt Normal file
View file

@ -0,0 +1,4 @@
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox c††zzzzzzzzzzzzzzzzzzzzzzThe quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.