aboutsummaryrefslogtreecommitdiff
path: root/bzip2recover.c
diff options
context:
space:
mode:
Diffstat (limited to 'bzip2recover.c')
-rw-r--r--bzip2recover.c125
1 files changed, 80 insertions, 45 deletions
diff --git a/bzip2recover.c b/bzip2recover.c
index 0eef0e6..0e2822b 100644
--- a/bzip2recover.c
+++ b/bzip2recover.c
@@ -7,43 +7,63 @@
7/*-- 7/*--
8 This program is bzip2recover, a program to attempt data 8 This program is bzip2recover, a program to attempt data
9 salvage from damaged files created by the accompanying 9 salvage from damaged files created by the accompanying
10 bzip2-0.1 program. 10 bzip2-0.9.0c program.
11 11
12 Copyright (C) 1996, 1997 by Julian Seward. 12 Copyright (C) 1996-1998 Julian R Seward. All rights reserved.
13 Guildford, Surrey, UK 13
14 email: jseward@acm.org 14 Redistribution and use in source and binary forms, with or without
15 15 modification, are permitted provided that the following conditions
16 This program is free software; you can redistribute it and/or modify 16 are met:
17 it under the terms of the GNU General Public License as published by 17
18 the Free Software Foundation; either version 2 of the License, or 18 1. Redistributions of source code must retain the above copyright
19 (at your option) any later version. 19 notice, this list of conditions and the following disclaimer.
20 20
21 This program is distributed in the hope that it will be useful, 21 2. The origin of this software must not be misrepresented; you must
22 but WITHOUT ANY WARRANTY; without even the implied warranty of 22 not claim that you wrote the original software. If you use this
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 software in a product, an acknowledgment in the product
24 GNU General Public License for more details. 24 documentation would be appreciated but is not required.
25 25
26 You should have received a copy of the GNU General Public License 26 3. Altered source versions must be plainly marked as such, and must
27 along with this program; if not, write to the Free Software 27 not be misrepresented as being the original software.
28 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 28
29 29 4. The name of the author may not be used to endorse or promote
30 The GNU General Public License is contained in the file LICENSE. 30 products derived from this software without specific prior written
31 permission.
32
33 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
34 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
37 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
39 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
41 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44
45 Julian Seward, Guildford, Surrey, UK.
46 jseward@acm.org
47 bzip2/libbzip2 version 0.9.0c of 18 October 1998
31--*/ 48--*/
32 49
50/*--
51 This program is a complete hack and should be rewritten
52 properly. It isn't very complicated.
53--*/
33 54
34#include <stdio.h> 55#include <stdio.h>
35#include <errno.h> 56#include <errno.h>
36#include <malloc.h>
37#include <stdlib.h> 57#include <stdlib.h>
38#include <strings.h> /*-- or try string.h --*/ 58#include <string.h>
39 59
40#define UInt32 unsigned int 60typedef unsigned int UInt32;
41#define Int32 int 61typedef int Int32;
42#define UChar unsigned char 62typedef unsigned char UChar;
43#define Char char 63typedef char Char;
44#define Bool unsigned char 64typedef unsigned char Bool;
45#define True 1 65#define True ((Bool)1)
46#define False 0 66#define False ((Bool)0)
47 67
48 68
49Char inFileName[2000]; 69Char inFileName[2000];
@@ -191,8 +211,9 @@ void bsClose ( BitStream* bs )
191 if (retVal == EOF) writeError(); 211 if (retVal == EOF) writeError();
192 } 212 }
193 retVal = fclose ( bs->handle ); 213 retVal = fclose ( bs->handle );
194 if (retVal == EOF) 214 if (retVal == EOF) {
195 if (bs->mode == 'w') writeError(); else readError(); 215 if (bs->mode == 'w') writeError(); else readError();
216 }
196 free ( bs ); 217 free ( bs );
197} 218}
198 219
@@ -248,13 +269,19 @@ Int32 main ( Int32 argc, Char** argv )
248 UInt32 bitsRead; 269 UInt32 bitsRead;
249 UInt32 bStart[20000]; 270 UInt32 bStart[20000];
250 UInt32 bEnd[20000]; 271 UInt32 bEnd[20000];
272
273 UInt32 rbStart[20000];
274 UInt32 rbEnd[20000];
275 Int32 rbCtr;
276
277
251 UInt32 buffHi, buffLo, blockCRC; 278 UInt32 buffHi, buffLo, blockCRC;
252 Char* p; 279 Char* p;
253 280
254 strcpy ( progName, argv[0] ); 281 strcpy ( progName, argv[0] );
255 inFileName[0] = outFileName[0] = 0; 282 inFileName[0] = outFileName[0] = 0;
256 283
257 fprintf ( stderr, "bzip2recover: extracts blocks from damaged .bz2 files.\n" ); 284 fprintf ( stderr, "bzip2recover v0.9.0c: extracts blocks from damaged .bz2 files.\n" );
258 285
259 if (argc != 2) { 286 if (argc != 2) {
260 fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n", 287 fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
@@ -278,6 +305,8 @@ Int32 main ( Int32 argc, Char** argv )
278 currBlock = 0; 305 currBlock = 0;
279 bStart[currBlock] = 0; 306 bStart[currBlock] = 0;
280 307
308 rbCtr = 0;
309
281 while (True) { 310 while (True) {
282 b = bsGetBit ( bsIn ); 311 b = bsGetBit ( bsIn );
283 bitsRead++; 312 bitsRead++;
@@ -303,19 +332,25 @@ Int32 main ( Int32 argc, Char** argv )
303 if (bitsRead > 49) 332 if (bitsRead > 49)
304 bEnd[currBlock] = bitsRead-49; else 333 bEnd[currBlock] = bitsRead-49; else
305 bEnd[currBlock] = 0; 334 bEnd[currBlock] = 0;
306 if (currBlock > 0) 335 if (currBlock > 0 &&
336 (bEnd[currBlock] - bStart[currBlock]) >= 130) {
307 fprintf ( stderr, " block %d runs from %d to %d\n", 337 fprintf ( stderr, " block %d runs from %d to %d\n",
308 currBlock, bStart[currBlock], bEnd[currBlock] ); 338 rbCtr+1, bStart[currBlock], bEnd[currBlock] );
339 rbStart[rbCtr] = bStart[currBlock];
340 rbEnd[rbCtr] = bEnd[currBlock];
341 rbCtr++;
342 }
309 currBlock++; 343 currBlock++;
344
310 bStart[currBlock] = bitsRead; 345 bStart[currBlock] = bitsRead;
311 } 346 }
312 } 347 }
313 348
314 bsClose ( bsIn ); 349 bsClose ( bsIn );
315 350
316 /*-- identified blocks run from 1 to currBlock inclusive. --*/ 351 /*-- identified blocks run from 1 to rbCtr inclusive. --*/
317 352
318 if (currBlock < 1) { 353 if (rbCtr < 1) {
319 fprintf ( stderr, 354 fprintf ( stderr,
320 "%s: sorry, I couldn't find any block boundaries.\n", 355 "%s: sorry, I couldn't find any block boundaries.\n",
321 progName ); 356 progName );
@@ -336,23 +371,23 @@ Int32 main ( Int32 argc, Char** argv )
336 371
337 bitsRead = 0; 372 bitsRead = 0;
338 outFile = NULL; 373 outFile = NULL;
339 wrBlock = 1; 374 wrBlock = 0;
340 while (True) { 375 while (True) {
341 b = bsGetBit(bsIn); 376 b = bsGetBit(bsIn);
342 if (b == 2) break; 377 if (b == 2) break;
343 buffHi = (buffHi << 1) | (buffLo >> 31); 378 buffHi = (buffHi << 1) | (buffLo >> 31);
344 buffLo = (buffLo << 1) | (b & 1); 379 buffLo = (buffLo << 1) | (b & 1);
345 if (bitsRead == 47+bStart[wrBlock]) 380 if (bitsRead == 47+rbStart[wrBlock])
346 blockCRC = (buffHi << 16) | (buffLo >> 16); 381 blockCRC = (buffHi << 16) | (buffLo >> 16);
347 382
348 if (outFile != NULL && bitsRead >= bStart[wrBlock] 383 if (outFile != NULL && bitsRead >= rbStart[wrBlock]
349 && bitsRead <= bEnd[wrBlock]) { 384 && bitsRead <= rbEnd[wrBlock]) {
350 bsPutBit ( bsWr, b ); 385 bsPutBit ( bsWr, b );
351 } 386 }
352 387
353 bitsRead++; 388 bitsRead++;
354 389
355 if (bitsRead == bEnd[wrBlock]+1) { 390 if (bitsRead == rbEnd[wrBlock]+1) {
356 if (outFile != NULL) { 391 if (outFile != NULL) {
357 bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 ); 392 bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
358 bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 ); 393 bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
@@ -360,18 +395,18 @@ Int32 main ( Int32 argc, Char** argv )
360 bsPutUInt32 ( bsWr, blockCRC ); 395 bsPutUInt32 ( bsWr, blockCRC );
361 bsClose ( bsWr ); 396 bsClose ( bsWr );
362 } 397 }
363 if (wrBlock >= currBlock) break; 398 if (wrBlock >= rbCtr) break;
364 wrBlock++; 399 wrBlock++;
365 } else 400 } else
366 if (bitsRead == bStart[wrBlock]) { 401 if (bitsRead == rbStart[wrBlock]) {
367 outFileName[0] = 0; 402 outFileName[0] = 0;
368 sprintf ( outFileName, "rec%4d", wrBlock ); 403 sprintf ( outFileName, "rec%4d", wrBlock+1 );
369 for (p = outFileName; *p != 0; p++) if (*p == ' ') *p = '0'; 404 for (p = outFileName; *p != 0; p++) if (*p == ' ') *p = '0';
370 strcat ( outFileName, inFileName ); 405 strcat ( outFileName, inFileName );
371 if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" ); 406 if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );
372 407
373 fprintf ( stderr, " writing block %d to `%s' ...\n", 408 fprintf ( stderr, " writing block %d to `%s' ...\n",
374 wrBlock, outFileName ); 409 wrBlock+1, outFileName );
375 410
376 outFile = fopen ( outFileName, "wb" ); 411 outFile = fopen ( outFileName, "wb" );
377 if (outFile == NULL) { 412 if (outFile == NULL) {