diff options
author | Daniel Baumann <mail@daniel-baumann.ch> | 2015-11-07 10:20:52 +0000 |
---|---|---|
committer | Daniel Baumann <mail@daniel-baumann.ch> | 2015-11-07 10:20:52 +0000 |
commit | 9e1481f1341f12a41b988d6dcb63e8256d1e54a3 (patch) | |
tree | 55304e8361dd48c9465c4670d9c5fa3747050e86 /repair.cc | |
parent | Adding upstream version 1.13. (diff) | |
download | lziprecover-9e1481f1341f12a41b988d6dcb63e8256d1e54a3.tar.xz lziprecover-9e1481f1341f12a41b988d6dcb63e8256d1e54a3.zip |
Adding upstream version 1.14~rc1.upstream/1.14_rc1
Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch>
Diffstat (limited to 'repair.cc')
-rw-r--r-- | repair.cc | 44 |
1 files changed, 28 insertions, 16 deletions
@@ -1,5 +1,5 @@ /* Lziprecover - Data recovery tool for lzipped files - Copyright (C) 2009, 2010, 2011, 2012 Antonio Diaz Diaz. + Copyright (C) 2009, 2010, 2011, 2012, 2013 Antonio Diaz Diaz. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,8 +30,27 @@ #include "lzip.h" +int seek_read( const int fd, uint8_t * const buf, const int size, + const long long pos ) + { + if( lseek( fd, pos, SEEK_SET ) == pos ) + return readblock( fd, buf, size ); + return 0; + } + + +int seek_write( const int fd, const uint8_t * const buf, const int size, + const long long pos ) + { + if( lseek( fd, pos, SEEK_SET ) == pos ) + return writeblock( fd, buf, size ); + return 0; + } + + int repair_file( const std::string & input_filename, - const std::string & output_filename, const bool force ) + const std::string & output_filename, const int verbosity, + const bool force ) { struct stat in_stats; const int infd = open_instream( input_filename, &in_stats, true, true ); @@ -41,7 +60,7 @@ int repair_file( const std::string & input_filename, { show_error( "Input file is not seekable", errno ); return 1; } if( isize < min_member_size ) { show_error( "Input file is too short." ); return 2; } - if( !verify_single_member( infd, isize ) ) return 2; + if( !verify_single_member( infd, isize, verbosity ) ) return 2; if( lseek( infd, 0, SEEK_SET ) < 0 ) { show_error( "Seek error in input file", errno ); return 1; } @@ -67,35 +86,28 @@ int repair_file( const std::string & input_filename, const long long min_pos = std::max( (long long)File_header::size, failure_pos - 1000 ); bool done = false; - for( long long pos = failure_pos; pos >= min_pos; --pos ) + for( long long pos = failure_pos; pos >= min_pos && !done ; --pos ) { if( verbosity >= 1 ) { - std::printf( "Trying position %lld \r", pos ); + std::printf( "Trying position %llu \r", pos ); std::fflush( stdout ); } uint8_t byte; - if( lseek( outfd, pos, SEEK_SET ) < 0 || - readblock( outfd, &byte, 1 ) != 1 ) + if( seek_read( outfd, &byte, 1, pos ) != 1 ) { show_error( "Error reading output file", errno ); cleanup_and_fail( output_filename, outfd, 1 ); } - for( int i = 0; i < 255; ++i ) + for( int i = 0; i < 256; ++i ) { ++byte; - if( lseek( outfd, pos, SEEK_SET ) < 0 || - writeblock( outfd, &byte, 1 ) != 1 || + if( seek_write( outfd, &byte, 1, pos ) != 1 || lseek( outfd, 0, SEEK_SET ) < 0 ) { show_error( "Error writing output file", errno ); cleanup_and_fail( output_filename, outfd, 1 ); } + if( i == 255 ) break; if( try_decompress( outfd, isize ) ) { done = true; break; } } - if( done ) break; - ++byte; - if( lseek( outfd, pos, SEEK_SET ) < 0 || - writeblock( outfd, &byte, 1 ) != 1 ) - { show_error( "Error writing output file", errno ); - cleanup_and_fail( output_filename, outfd, 1 ); } } if( verbosity >= 1 ) std::printf( "\n" ); |