diff options
Diffstat (limited to 'bzip2recover.c')
-rw-r--r-- | bzip2recover.c | 125 |
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 | 60 | typedef unsigned int UInt32; |
41 | #define Int32 int | 61 | typedef int Int32; |
42 | #define UChar unsigned char | 62 | typedef unsigned char UChar; |
43 | #define Char char | 63 | typedef char Char; |
44 | #define Bool unsigned char | 64 | typedef 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 | ||
49 | Char inFileName[2000]; | 69 | Char 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) { |