1
0
Fork 0

Merging upstream version 1.17~rc2.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-21 11:24:05 +01:00
parent 93ad4e56ce
commit 36c7129c83
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
12 changed files with 126 additions and 100 deletions

View file

@ -1,3 +1,8 @@
2015-04-08 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.17-rc2 released.
* Minor changes.
2015-01-21 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.17-rc1 released.

2
configure vendored
View file

@ -6,7 +6,7 @@
# to copy, distribute and modify it.
pkgname=lziprecover
pkgversion=1.17-rc1
pkgversion=1.17-rc2
progname=lziprecover
srctrigger=doc/${pkgname}.texi

View file

@ -62,7 +62,7 @@ long readblock( const int fd, uint8_t * const buf, const long size )
{
const int n = read( fd, buf + sz, std::min( 1L << 20, size - sz ) );
if( n > 0 ) sz += n;
else if( n == 0 ) break; // EOF
else if( n == 0 ) break; /* EOF */
else if( errno != EINTR ) break;
errno = 0;
}
@ -206,9 +206,9 @@ int LZ_decoder::decode_member( const Pretty_print & pp )
Bit_model bm_align[dis_align_size];
Len_model match_len_model;
Len_model rep_len_model;
unsigned rep0 = 0; // rep[0-3] latest four distances
unsigned rep1 = 0; // used for efficient coding of
unsigned rep2 = 0; // repeated distances
unsigned rep0 = 0; /* rep[0-3] latest four distances */
unsigned rep1 = 0; /* used for efficient coding of */
unsigned rep2 = 0; /* repeated distances */
unsigned rep3 = 0;
State state;
@ -218,7 +218,7 @@ int LZ_decoder::decode_member( const Pretty_print & pp )
const int pos_state = data_position() & pos_state_mask;
if( rdec.decode_bit( bm_match[state()][pos_state] ) == 0 ) // 1st bit
{
const uint8_t prev_byte = get_prev_byte();
const uint8_t prev_byte = peek_prev();
if( state.is_char() )
{
state.set_char1();
@ -228,7 +228,7 @@ int LZ_decoder::decode_member( const Pretty_print & pp )
{
state.set_char2();
put_byte( rdec.decode_matched( bm_literal[get_lit_state(prev_byte)],
get_byte( rep0 ) ) );
peek( rep0 ) ) );
}
}
else
@ -255,7 +255,7 @@ int LZ_decoder::decode_member( const Pretty_print & pp )
else
{
if( rdec.decode_bit( bm_len[state()][pos_state] ) == 0 ) // 4th bit
{ state.set_short_rep(); put_byte( get_byte( rep0 ) ); continue; }
{ state.set_short_rep(); put_byte( peek( rep0 ) ); continue; }
}
state.set_rep();
len = min_match_len + rdec.decode_len( rep_len_model, pos_state );
@ -277,16 +277,16 @@ int LZ_decoder::decode_member( const Pretty_print & pp )
{
rep0 += rdec.decode( direct_bits - dis_align_bits ) << dis_align_bits;
rep0 += rdec.decode_tree_reversed4( bm_align );
if( rep0 == 0xFFFFFFFFU ) // marker found
if( rep0 == 0xFFFFFFFFU ) /* marker found */
{
rep0 = rep0_saved;
rdec.normalize();
flush_data();
if( len == min_match_len ) // End Of Stream marker
if( len == min_match_len ) /* End Of Stream marker */
{
if( verify_trailer( pp ) ) return 0; else return 3;
}
if( len == min_match_len + 1 ) // Sync Flush marker
if( len == min_match_len + 1 ) /* Sync Flush marker */
{
rdec.load(); continue;
}

View file

@ -19,12 +19,12 @@ class Range_decoder
{
enum { buffer_size = 16384 };
unsigned long long partial_member_pos;
uint8_t * const buffer; // input buffer
int pos; // current pos in buffer
int stream_pos; // when reached, a new block must be read
uint8_t * const buffer; /* input buffer */
int pos; /* current pos in buffer */
int stream_pos; /* when reached, a new block must be read */
uint32_t code;
uint32_t range;
const int infd; // input file descriptor
const int infd; /* input file descriptor */
bool at_stream_end;
bool read_block();
@ -215,24 +215,24 @@ class LZ_decoder
Range_decoder & rdec;
const unsigned dictionary_size;
const int buffer_size;
uint8_t * const buffer; // output buffer
int pos; // current pos in buffer
int stream_pos; // first byte not yet written to file
uint8_t * const buffer; /* output buffer */
int pos; /* current pos in buffer */
int stream_pos; /* first byte not yet written to file */
uint32_t crc_;
const int outfd; // output file descriptor
const int outfd; /* output file descriptor */
unsigned long long stream_position() const
{ return partial_data_pos + stream_pos; }
void flush_data();
bool verify_trailer( const Pretty_print & pp ) const;
uint8_t get_prev_byte() const
uint8_t peek_prev() const
{
const int i = ( ( pos > 0 ) ? pos : buffer_size ) - 1;
return buffer[i];
}
uint8_t get_byte( const int distance ) const
uint8_t peek( const int distance ) const
{
int i = pos - distance - 1;
if( i < 0 ) i += buffer_size;

View file

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
.TH LZIPRECOVER "1" "January 2015" "lziprecover 1.17-rc1" "User Commands"
.TH LZIPRECOVER "1" "April 2015" "lziprecover 1.17-rc2" "User Commands"
.SH NAME
lziprecover \- recovers data from damaged lzip files
.SH SYNOPSIS

View file

@ -12,7 +12,7 @@ File: lziprecover.info, Node: Top, Next: Introduction, Up: (dir)
Lziprecover Manual
******************
This manual is for Lziprecover (version 1.17-rc1, 21 January 2015).
This manual is for Lziprecover (version 1.17-rc2, 8 April 2015).
* Menu:
@ -283,10 +283,11 @@ data stream, even if it is just one altered bit, the original data can't
be recovered.
If you used bzip2, and if the file is large enough to contain more
than one compressed data block (usually larger than 900 kB), and if no
block is damaged in both files, then the data can be manually recovered
by splitting the files with bzip2recover, verifying every block and then
copying the right blocks in the right order in another file.
than one compressed data block (usually larger than 900 kB
uncompressed), and if no block is damaged in both files, then the data
can be manually recovered by splitting the files with bzip2recover,
verifying every block and then copying the right blocks in the right
order in another file.
But if you used lzip, the data can be automatically recovered as
long as no byte is damaged in both files.
@ -429,21 +430,19 @@ additional information before, between, or after them.
now.
'DS (coded dictionary size, 1 byte)'
Lzip divides the distance between any two powers of 2 into 8
equally spaced intervals, named "wedges". The dictionary size is
calculated by taking a power of 2 (the base size) and substracting
from it a number of wedges between 0 and 7. The size of a wedge is
(base_size / 16).
The dictionary size is calculated by taking a power of 2 (the base
size) and substracting from it a fraction between 0/16 and 7/16 of
the base size.
Bits 4-0 contain the base 2 logarithm of the base size (12 to 29).
Bits 7-5 contain the number of wedges (0 to 7) to substract from
the base size to obtain the dictionary size.
Bits 7-5 contain the numerator of the fraction (0 to 7) to
substract from the base size to obtain the dictionary size.
Example: 0xD3 = 2^19 - 6 * 2^15 = 512 KiB - 6 * 32 KiB = 320 KiB
Valid values for dictionary size range from 4 KiB to 512 MiB.
'Lzma stream'
The lzma stream, finished by an end of stream marker. Uses default
values for encoder properties. See the lzip manual for a full
description.
values for encoder properties. *Note Stream format: (lzip)Stream
format, for a complete description.
'CRC32 (4 bytes)'
CRC of the uncompressed original data.
@ -493,6 +492,8 @@ are abridged diagnostic messages from lziprecover).
lziprecover -v -R file.lz
Copy of input file repaired successfully.
lziprecover -tv file_fixed.lz
ok
mv file_fixed.lz file.lz
@ -518,6 +519,9 @@ error-checked merging of copies (*Note GNU ddrescue manual:
cp /mnt/cdimage/backup.tar.lz rescued2.tar.lz
umount /mnt/cdimage
lziprecover -m -v -o backup.tar.lz rescued1.tar.lz rescued2.tar.lz
Input files merged successfully.
lziprecover -tv backup.tar.lz
ok
Example 8: Recover the first volume of those created with the command
@ -527,7 +531,9 @@ damaged in the second copy, and member 12 damaged in both copies. The
correct file produced is saved in 'big_db_00001.lz'.
lziprecover -m -v -o big_db_00001.lz big_db1_00001.lz big_db2_00001.lz
Input files merged successfully
Input files merged successfully.
lziprecover -tv big_db_00001.lz
ok

File: lziprecover.info, Node: Unzcrash, Next: Problems, Prev: Examples, Up: Top
@ -646,18 +652,18 @@ Concept index

Tag Table:
Node: Top231
Node: Introduction1216
Node: Invoking lziprecover4312
Node: Data safety9745
Node: Repairing files11661
Node: Merging files13563
Node: File names15404
Node: File format15868
Node: Examples18375
Ref: ddrescue-example19576
Node: Unzcrash20685
Node: Problems23239
Node: Concept index23791
Node: Introduction1213
Node: Invoking lziprecover4309
Node: Data safety9742
Node: Repairing files11671
Node: Merging files13573
Node: File names15414
Node: File format15878
Node: Examples18282
Ref: ddrescue-example19528
Node: Unzcrash20770
Node: Problems23324
Node: Concept index23876

End Tag Table

View file

@ -6,8 +6,8 @@
@finalout
@c %**end of header
@set UPDATED 21 January 2015
@set VERSION 1.17-rc1
@set UPDATED 8 April 2015
@set VERSION 1.17-rc2
@dircategory Data Compression
@direntry
@ -311,10 +311,11 @@ data stream, even if it is just one altered bit, the original data can't
be recovered.
If you used bzip2, and if the file is large enough to contain more than
one compressed data block (usually larger than 900 kB), and if no block
is damaged in both files, then the data can be manually recovered by
splitting the files with bzip2recover, verifying every block and then
copying the right blocks in the right order in another file.
one compressed data block (usually larger than 900 kB uncompressed), and
if no block is damaged in both files, then the data can be manually
recovered by splitting the files with bzip2recover, verifying every
block and then copying the right blocks in the right order in another
file.
But if you used lzip, the data can be automatically recovered as long as
no byte is damaged in both files.
@ -463,19 +464,26 @@ A four byte string, identifying the lzip format, with the value "LZIP"
Just in case something needs to be modified in the future. 1 for now.
@item DS (coded dictionary size, 1 byte)
Lzip divides the distance between any two powers of 2 into 8 equally
spaced intervals, named "wedges". The dictionary size is calculated by
taking a power of 2 (the base size) and substracting from it a number of
wedges between 0 and 7. The size of a wedge is (base_size / 16).@*
The dictionary size is calculated by taking a power of 2 (the base size)
and substracting from it a fraction between 0/16 and 7/16 of the base
size.@*
Bits 4-0 contain the base 2 logarithm of the base size (12 to 29).@*
Bits 7-5 contain the number of wedges (0 to 7) to substract from the
base size to obtain the dictionary size.@*
Bits 7-5 contain the numerator of the fraction (0 to 7) to substract
from the base size to obtain the dictionary size.@*
Example: 0xD3 = 2^19 - 6 * 2^15 = 512 KiB - 6 * 32 KiB = 320 KiB@*
Valid values for dictionary size range from 4 KiB to 512 MiB.
@item Lzma stream
The lzma stream, finished by an end of stream marker. Uses default values
for encoder properties. See the lzip manual for a full description.
The lzma stream, finished by an end of stream marker. Uses default
values for encoder properties.
@ifnothtml
@xref{Stream format,,,lzip},
@end ifnothtml
@ifhtml
See
@uref{http://www.nongnu.org/lzip/manual/lzip_manual.html#Stream-format,,Stream format}
@end ifhtml
for a complete description.
@item CRC32 (4 bytes)
CRC of the uncompressed original data.
@ -538,6 +546,8 @@ lines are abridged diagnostic messages from lziprecover).
@example
lziprecover -v -R file.lz
Copy of input file repaired successfully.
lziprecover -tv file_fixed.lz
ok
mv file_fixed.lz file.lz
@end example
@ -577,6 +587,9 @@ mount -t iso9660 -o loop,ro cdimage2 /mnt/cdimage
cp /mnt/cdimage/backup.tar.lz rescued2.tar.lz
umount /mnt/cdimage
lziprecover -m -v -o backup.tar.lz rescued1.tar.lz rescued2.tar.lz
Input files merged successfully.
lziprecover -tv backup.tar.lz
ok
@end example
@sp 1
@ -590,7 +603,9 @@ member 12 damaged in both copies. The correct file produced is saved in
@example
lziprecover -m -v -o big_db_00001.lz big_db1_00001.lz big_db2_00001.lz
Input files merged successfully
Input files merged successfully.
lziprecover -tv big_db_00001.lz
ok
@end example

View file

@ -85,8 +85,8 @@ File_index::File_index( const int infd )
const long long member_size = trailer.member_size();
if( member_size < min_member_size || member_size > pos )
{
if( member_vector.empty() ) // maybe trailing garbage
{ --pos; continue; }
if( member_vector.empty() )
{ --pos; continue; } // maybe trailing garbage
set_num_error( "Member size in trailer is corrupt at pos ", pos - 8 );
break;
}
@ -95,8 +95,8 @@ File_index::File_index( const int infd )
{ set_errno_error( "Error reading member header: " ); break; }
if( !header.verify_magic() || !header.verify_version() )
{
if( member_vector.empty() ) // maybe trailing garbage
{ --pos; continue; }
if( member_vector.empty() )
{ --pos; continue; } // maybe trailing garbage
set_num_error( "Bad header at pos ", pos - member_size );
break;
}

24
lzip.h
View file

@ -40,7 +40,7 @@ public:
enum {
min_dictionary_bits = 12,
min_dictionary_size = 1 << min_dictionary_bits, // >= modeled_distances
min_dictionary_size = 1 << min_dictionary_bits, /* >= modeled_distances */
max_dictionary_bits = 29,
max_dictionary_size = 1 << max_dictionary_bits,
min_member_size = 36,
@ -53,7 +53,7 @@ enum {
dis_slot_bits = 6,
start_dis_model = 4,
end_dis_model = 14,
modeled_distances = 1 << (end_dis_model / 2), // 128
modeled_distances = 1 << (end_dis_model / 2), /* 128 */
dis_align_bits = 4,
dis_align_size = 1 << dis_align_bits,
@ -65,8 +65,8 @@ enum {
len_high_symbols = 1 << len_high_bits,
max_len_symbols = len_low_symbols + len_mid_symbols + len_high_symbols,
min_match_len = 2, // must be 2
max_match_len = min_match_len + max_len_symbols - 1, // 273
min_match_len = 2, /* must be 2 */
max_match_len = min_match_len + max_len_symbols - 1, /* 273 */
min_match_len_limit = 5 };
inline int get_len_state( const int len )
@ -186,9 +186,9 @@ const uint8_t magic_string[4] = { 0x4C, 0x5A, 0x49, 0x50 }; // "LZIP"
struct File_header
{
uint8_t data[6]; // 0-3 magic bytes
// 4 version
// 5 coded_dict_size
uint8_t data[6]; /* 0-3 magic bytes */
/* 4 version */
/* 5 coded_dict_size */
enum { size = 6 };
void set_magic() { std::memcpy( data, magic_string, 4 ); data[4] = 1; }
@ -214,9 +214,9 @@ struct File_header
if( sz > min_dictionary_size )
{
const unsigned base_size = 1 << data[5];
const unsigned wedge = base_size / 16;
const unsigned fraction = base_size / 16;
for( int i = 7; i >= 1; --i )
if( base_size - ( i * wedge ) >= sz )
if( base_size - ( i * fraction ) >= sz )
{ data[5] |= ( i << 5 ); break; }
}
return true;
@ -228,9 +228,9 @@ struct File_header
struct File_trailer
{
uint8_t data[20]; // 0-3 CRC32 of the uncompressed data
// 4-11 size of the uncompressed data
// 12-19 member size including header and trailer
uint8_t data[20]; /* 0-3 CRC32 of the uncompressed data */
/* 4-11 size of the uncompressed data */
/* 12-19 member size including header and trailer */
enum { size = 20 };

24
main.cc
View file

@ -372,14 +372,14 @@ void cleanup_and_fail( const int retval )
}
// Set permissions, owner and times.
/* Set permissions, owner and times. */
void close_and_set_permissions( const struct stat * const in_statsp )
{
bool warning = false;
if( in_statsp )
{
const mode_t mode = in_statsp->st_mode;
// fchown will in many cases return with EPERM, which can be safely ignored.
/* fchown will in many cases return with EPERM, which can be safely ignored. */
if( fchown( outfd, in_statsp->st_uid, in_statsp->st_gid ) == 0 )
{ if( fchmod( outfd, mode ) != 0 ) warning = true; }
else
@ -579,14 +579,6 @@ void show_error( const char * const msg, const int errcode, const bool help )
}
void show_error2( const char * const msg1, const char * const name,
const char * const msg2 )
{
if( verbosity >= 0 )
std::fprintf( stderr, "%s: %s '%s' %s\n", program_name, msg1, name, msg2 );
}
void internal_error( const char * const msg )
{
if( verbosity >= 0 )
@ -595,6 +587,14 @@ void internal_error( const char * const msg )
}
void show_error2( const char * const msg1, const char * const name,
const char * const msg2 )
{
if( verbosity >= 0 )
std::fprintf( stderr, "%s: %s '%s' %s\n", program_name, msg1, name, msg2 );
}
int main( const int argc, const char * const argv[] )
{
Block range( 0, 0 );
@ -642,7 +642,7 @@ int main( const int argc, const char * const argv[] )
for( ; argind < parser.arguments(); ++argind )
{
const int code = parser.code( argind );
if( !code ) break; // no more options
if( !code ) break; /* no more options */
const std::string & arg = parser.argument( argind );
switch( code )
{
@ -670,7 +670,7 @@ int main( const int argc, const char * const argv[] )
parse_pos_value( arg.c_str(), bad_pos, bad_value ); break;
default : internal_error( "uncaught option." );
}
} // end process options
} /* end process options */
#if defined(__MSVCRT__) || defined(__OS2__)
setmode( STDIN_FILENO, O_BINARY );

View file

@ -471,7 +471,7 @@ int merge_files( const std::vector< std::string > & filenames,
if( verbosity >= 1 && file_index.members() > 1 )
{
std::printf( "Merging member %ld of %ld\n",
j + 1, (long)file_index.members() );
j + 1, file_index.members() );
std::fflush( stdout );
}

View file

@ -77,7 +77,7 @@ int repair_file( const std::string & input_filename,
if( verbosity >= 1 ) // damaged member found
{
std::printf( "Repairing member %ld of %ld (failure pos = %llu)\n",
i + 1, (long)file_index.members(), mpos + failure_pos );
i + 1, file_index.members(), mpos + failure_pos );
std::fflush( stdout );
}
uint8_t * const mbuffer = read_member( infd, mpos, msize );
@ -173,8 +173,8 @@ int debug_delay( const std::string & input_filename, Block range,
const long long msize = file_index.mblock( i ).size();
if( verbosity >= 1 ) // damaged member found
{
std::printf( "Finding max delay in member %ld of %ld (member pos = %llu)\n",
i + 1, (long)file_index.members(), mpos );
std::printf( "Finding max delay in member %ld of %ld (mpos = %llu, msize = %llu)\n",
i + 1, file_index.members(), mpos, msize );
std::fflush( stdout );
}
uint8_t * const mbuffer = read_member( infd, mpos, msize );
@ -253,7 +253,7 @@ int debug_repair( const std::string & input_filename, const long long bad_pos,
{
if( verbosity >= 0 )
std::printf( "Member %ld of %ld already damaged (failure pos = %llu)\n",
idx + 1, (long)file_index.members(), mpos + failure_pos );
idx + 1, file_index.members(), mpos + failure_pos );
return 1;
}
}
@ -275,10 +275,10 @@ int debug_repair( const std::string & input_filename, const long long bad_pos,
}
if( verbosity >= 1 )
{
std::printf( "Test repairing member %ld of %ld\n"
std::printf( "Test repairing member %ld of %ld (mpos = %llu, msize = %llu)\n"
" (damage pos = %llu (0x%02X->0x%02X), failure pos = %llu)\n",
idx + 1, (long)file_index.members(), mpos + bad_pos,
good_value, bad_value, mpos + failure_pos );
idx + 1, file_index.members(), mpos, msize,
mpos + bad_pos, good_value, bad_value, mpos + failure_pos );
std::fflush( stdout );
}
}