Merging upstream version 1.14~rc3.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
fab5d40dce
commit
090aac16e8
17 changed files with 152 additions and 74 deletions
|
@ -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.
|
||||||
|
|
2
INSTALL
2
INSTALL
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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
12
NEWS
|
@ -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
2
configure
vendored
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
2
lzip.h
|
@ -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
10
main.cc
|
@ -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() )
|
||||||
|
|
4
merge.cc
4
merge.cc
|
@ -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 )
|
||||||
|
|
16
range_dec.cc
16
range_dec.cc
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
33
split.cc
33
split.cc
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
BIN
testsuite/fox5_bad.lz
Normal file
Binary file not shown.
4
testsuite/fox5_bad.txt
Normal file
4
testsuite/fox5_bad.txt
Normal 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.
|
Loading…
Add table
Reference in a new issue