annotate src/bzip2-1.0.6/bzip2recover.c @ 23:619f715526df sv_v2.1

Update Vamp plugin SDK to 2.5
author Chris Cannam
date Thu, 09 May 2013 10:52:46 +0100
parents e13257ea84a4
children
rev   line source
Chris@4 1 /*-----------------------------------------------------------*/
Chris@4 2 /*--- Block recoverer program for bzip2 ---*/
Chris@4 3 /*--- bzip2recover.c ---*/
Chris@4 4 /*-----------------------------------------------------------*/
Chris@4 5
Chris@4 6 /* ------------------------------------------------------------------
Chris@4 7 This file is part of bzip2/libbzip2, a program and library for
Chris@4 8 lossless, block-sorting data compression.
Chris@4 9
Chris@4 10 bzip2/libbzip2 version 1.0.6 of 6 September 2010
Chris@4 11 Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Chris@4 12
Chris@4 13 Please read the WARNING, DISCLAIMER and PATENTS sections in the
Chris@4 14 README file.
Chris@4 15
Chris@4 16 This program is released under the terms of the license contained
Chris@4 17 in the file LICENSE.
Chris@4 18 ------------------------------------------------------------------ */
Chris@4 19
Chris@4 20 /* This program is a complete hack and should be rewritten properly.
Chris@4 21 It isn't very complicated. */
Chris@4 22
Chris@4 23 #include <stdio.h>
Chris@4 24 #include <errno.h>
Chris@4 25 #include <stdlib.h>
Chris@4 26 #include <string.h>
Chris@4 27
Chris@4 28
Chris@4 29 /* This program records bit locations in the file to be recovered.
Chris@4 30 That means that if 64-bit ints are not supported, we will not
Chris@4 31 be able to recover .bz2 files over 512MB (2^32 bits) long.
Chris@4 32 On GNU supported platforms, we take advantage of the 64-bit
Chris@4 33 int support to circumvent this problem. Ditto MSVC.
Chris@4 34
Chris@4 35 This change occurred in version 1.0.2; all prior versions have
Chris@4 36 the 512MB limitation.
Chris@4 37 */
Chris@4 38 #ifdef __GNUC__
Chris@4 39 typedef unsigned long long int MaybeUInt64;
Chris@4 40 # define MaybeUInt64_FMT "%Lu"
Chris@4 41 #else
Chris@4 42 #ifdef _MSC_VER
Chris@4 43 typedef unsigned __int64 MaybeUInt64;
Chris@4 44 # define MaybeUInt64_FMT "%I64u"
Chris@4 45 #else
Chris@4 46 typedef unsigned int MaybeUInt64;
Chris@4 47 # define MaybeUInt64_FMT "%u"
Chris@4 48 #endif
Chris@4 49 #endif
Chris@4 50
Chris@4 51 typedef unsigned int UInt32;
Chris@4 52 typedef int Int32;
Chris@4 53 typedef unsigned char UChar;
Chris@4 54 typedef char Char;
Chris@4 55 typedef unsigned char Bool;
Chris@4 56 #define True ((Bool)1)
Chris@4 57 #define False ((Bool)0)
Chris@4 58
Chris@4 59
Chris@4 60 #define BZ_MAX_FILENAME 2000
Chris@4 61
Chris@4 62 Char inFileName[BZ_MAX_FILENAME];
Chris@4 63 Char outFileName[BZ_MAX_FILENAME];
Chris@4 64 Char progName[BZ_MAX_FILENAME];
Chris@4 65
Chris@4 66 MaybeUInt64 bytesOut = 0;
Chris@4 67 MaybeUInt64 bytesIn = 0;
Chris@4 68
Chris@4 69
Chris@4 70 /*---------------------------------------------------*/
Chris@4 71 /*--- Header bytes ---*/
Chris@4 72 /*---------------------------------------------------*/
Chris@4 73
Chris@4 74 #define BZ_HDR_B 0x42 /* 'B' */
Chris@4 75 #define BZ_HDR_Z 0x5a /* 'Z' */
Chris@4 76 #define BZ_HDR_h 0x68 /* 'h' */
Chris@4 77 #define BZ_HDR_0 0x30 /* '0' */
Chris@4 78
Chris@4 79
Chris@4 80 /*---------------------------------------------------*/
Chris@4 81 /*--- I/O errors ---*/
Chris@4 82 /*---------------------------------------------------*/
Chris@4 83
Chris@4 84 /*---------------------------------------------*/
Chris@4 85 static void readError ( void )
Chris@4 86 {
Chris@4 87 fprintf ( stderr,
Chris@4 88 "%s: I/O error reading `%s', possible reason follows.\n",
Chris@4 89 progName, inFileName );
Chris@4 90 perror ( progName );
Chris@4 91 fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
Chris@4 92 progName );
Chris@4 93 exit ( 1 );
Chris@4 94 }
Chris@4 95
Chris@4 96
Chris@4 97 /*---------------------------------------------*/
Chris@4 98 static void writeError ( void )
Chris@4 99 {
Chris@4 100 fprintf ( stderr,
Chris@4 101 "%s: I/O error reading `%s', possible reason follows.\n",
Chris@4 102 progName, inFileName );
Chris@4 103 perror ( progName );
Chris@4 104 fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
Chris@4 105 progName );
Chris@4 106 exit ( 1 );
Chris@4 107 }
Chris@4 108
Chris@4 109
Chris@4 110 /*---------------------------------------------*/
Chris@4 111 static void mallocFail ( Int32 n )
Chris@4 112 {
Chris@4 113 fprintf ( stderr,
Chris@4 114 "%s: malloc failed on request for %d bytes.\n",
Chris@4 115 progName, n );
Chris@4 116 fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
Chris@4 117 progName );
Chris@4 118 exit ( 1 );
Chris@4 119 }
Chris@4 120
Chris@4 121
Chris@4 122 /*---------------------------------------------*/
Chris@4 123 static void tooManyBlocks ( Int32 max_handled_blocks )
Chris@4 124 {
Chris@4 125 fprintf ( stderr,
Chris@4 126 "%s: `%s' appears to contain more than %d blocks\n",
Chris@4 127 progName, inFileName, max_handled_blocks );
Chris@4 128 fprintf ( stderr,
Chris@4 129 "%s: and cannot be handled. To fix, increase\n",
Chris@4 130 progName );
Chris@4 131 fprintf ( stderr,
Chris@4 132 "%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n",
Chris@4 133 progName );
Chris@4 134 exit ( 1 );
Chris@4 135 }
Chris@4 136
Chris@4 137
Chris@4 138
Chris@4 139 /*---------------------------------------------------*/
Chris@4 140 /*--- Bit stream I/O ---*/
Chris@4 141 /*---------------------------------------------------*/
Chris@4 142
Chris@4 143 typedef
Chris@4 144 struct {
Chris@4 145 FILE* handle;
Chris@4 146 Int32 buffer;
Chris@4 147 Int32 buffLive;
Chris@4 148 Char mode;
Chris@4 149 }
Chris@4 150 BitStream;
Chris@4 151
Chris@4 152
Chris@4 153 /*---------------------------------------------*/
Chris@4 154 static BitStream* bsOpenReadStream ( FILE* stream )
Chris@4 155 {
Chris@4 156 BitStream *bs = malloc ( sizeof(BitStream) );
Chris@4 157 if (bs == NULL) mallocFail ( sizeof(BitStream) );
Chris@4 158 bs->handle = stream;
Chris@4 159 bs->buffer = 0;
Chris@4 160 bs->buffLive = 0;
Chris@4 161 bs->mode = 'r';
Chris@4 162 return bs;
Chris@4 163 }
Chris@4 164
Chris@4 165
Chris@4 166 /*---------------------------------------------*/
Chris@4 167 static BitStream* bsOpenWriteStream ( FILE* stream )
Chris@4 168 {
Chris@4 169 BitStream *bs = malloc ( sizeof(BitStream) );
Chris@4 170 if (bs == NULL) mallocFail ( sizeof(BitStream) );
Chris@4 171 bs->handle = stream;
Chris@4 172 bs->buffer = 0;
Chris@4 173 bs->buffLive = 0;
Chris@4 174 bs->mode = 'w';
Chris@4 175 return bs;
Chris@4 176 }
Chris@4 177
Chris@4 178
Chris@4 179 /*---------------------------------------------*/
Chris@4 180 static void bsPutBit ( BitStream* bs, Int32 bit )
Chris@4 181 {
Chris@4 182 if (bs->buffLive == 8) {
Chris@4 183 Int32 retVal = putc ( (UChar) bs->buffer, bs->handle );
Chris@4 184 if (retVal == EOF) writeError();
Chris@4 185 bytesOut++;
Chris@4 186 bs->buffLive = 1;
Chris@4 187 bs->buffer = bit & 0x1;
Chris@4 188 } else {
Chris@4 189 bs->buffer = ( (bs->buffer << 1) | (bit & 0x1) );
Chris@4 190 bs->buffLive++;
Chris@4 191 };
Chris@4 192 }
Chris@4 193
Chris@4 194
Chris@4 195 /*---------------------------------------------*/
Chris@4 196 /*--
Chris@4 197 Returns 0 or 1, or 2 to indicate EOF.
Chris@4 198 --*/
Chris@4 199 static Int32 bsGetBit ( BitStream* bs )
Chris@4 200 {
Chris@4 201 if (bs->buffLive > 0) {
Chris@4 202 bs->buffLive --;
Chris@4 203 return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
Chris@4 204 } else {
Chris@4 205 Int32 retVal = getc ( bs->handle );
Chris@4 206 if ( retVal == EOF ) {
Chris@4 207 if (errno != 0) readError();
Chris@4 208 return 2;
Chris@4 209 }
Chris@4 210 bs->buffLive = 7;
Chris@4 211 bs->buffer = retVal;
Chris@4 212 return ( ((bs->buffer) >> 7) & 0x1 );
Chris@4 213 }
Chris@4 214 }
Chris@4 215
Chris@4 216
Chris@4 217 /*---------------------------------------------*/
Chris@4 218 static void bsClose ( BitStream* bs )
Chris@4 219 {
Chris@4 220 Int32 retVal;
Chris@4 221
Chris@4 222 if ( bs->mode == 'w' ) {
Chris@4 223 while ( bs->buffLive < 8 ) {
Chris@4 224 bs->buffLive++;
Chris@4 225 bs->buffer <<= 1;
Chris@4 226 };
Chris@4 227 retVal = putc ( (UChar) (bs->buffer), bs->handle );
Chris@4 228 if (retVal == EOF) writeError();
Chris@4 229 bytesOut++;
Chris@4 230 retVal = fflush ( bs->handle );
Chris@4 231 if (retVal == EOF) writeError();
Chris@4 232 }
Chris@4 233 retVal = fclose ( bs->handle );
Chris@4 234 if (retVal == EOF) {
Chris@4 235 if (bs->mode == 'w') writeError(); else readError();
Chris@4 236 }
Chris@4 237 free ( bs );
Chris@4 238 }
Chris@4 239
Chris@4 240
Chris@4 241 /*---------------------------------------------*/
Chris@4 242 static void bsPutUChar ( BitStream* bs, UChar c )
Chris@4 243 {
Chris@4 244 Int32 i;
Chris@4 245 for (i = 7; i >= 0; i--)
Chris@4 246 bsPutBit ( bs, (((UInt32) c) >> i) & 0x1 );
Chris@4 247 }
Chris@4 248
Chris@4 249
Chris@4 250 /*---------------------------------------------*/
Chris@4 251 static void bsPutUInt32 ( BitStream* bs, UInt32 c )
Chris@4 252 {
Chris@4 253 Int32 i;
Chris@4 254
Chris@4 255 for (i = 31; i >= 0; i--)
Chris@4 256 bsPutBit ( bs, (c >> i) & 0x1 );
Chris@4 257 }
Chris@4 258
Chris@4 259
Chris@4 260 /*---------------------------------------------*/
Chris@4 261 static Bool endsInBz2 ( Char* name )
Chris@4 262 {
Chris@4 263 Int32 n = strlen ( name );
Chris@4 264 if (n <= 4) return False;
Chris@4 265 return
Chris@4 266 (name[n-4] == '.' &&
Chris@4 267 name[n-3] == 'b' &&
Chris@4 268 name[n-2] == 'z' &&
Chris@4 269 name[n-1] == '2');
Chris@4 270 }
Chris@4 271
Chris@4 272
Chris@4 273 /*---------------------------------------------------*/
Chris@4 274 /*--- ---*/
Chris@4 275 /*---------------------------------------------------*/
Chris@4 276
Chris@4 277 /* This logic isn't really right when it comes to Cygwin. */
Chris@4 278 #ifdef _WIN32
Chris@4 279 # define BZ_SPLIT_SYM '\\' /* path splitter on Windows platform */
Chris@4 280 #else
Chris@4 281 # define BZ_SPLIT_SYM '/' /* path splitter on Unix platform */
Chris@4 282 #endif
Chris@4 283
Chris@4 284 #define BLOCK_HEADER_HI 0x00003141UL
Chris@4 285 #define BLOCK_HEADER_LO 0x59265359UL
Chris@4 286
Chris@4 287 #define BLOCK_ENDMARK_HI 0x00001772UL
Chris@4 288 #define BLOCK_ENDMARK_LO 0x45385090UL
Chris@4 289
Chris@4 290 /* Increase if necessary. However, a .bz2 file with > 50000 blocks
Chris@4 291 would have an uncompressed size of at least 40GB, so the chances
Chris@4 292 are low you'll need to up this.
Chris@4 293 */
Chris@4 294 #define BZ_MAX_HANDLED_BLOCKS 50000
Chris@4 295
Chris@4 296 MaybeUInt64 bStart [BZ_MAX_HANDLED_BLOCKS];
Chris@4 297 MaybeUInt64 bEnd [BZ_MAX_HANDLED_BLOCKS];
Chris@4 298 MaybeUInt64 rbStart[BZ_MAX_HANDLED_BLOCKS];
Chris@4 299 MaybeUInt64 rbEnd [BZ_MAX_HANDLED_BLOCKS];
Chris@4 300
Chris@4 301 Int32 main ( Int32 argc, Char** argv )
Chris@4 302 {
Chris@4 303 FILE* inFile;
Chris@4 304 FILE* outFile;
Chris@4 305 BitStream* bsIn, *bsWr;
Chris@4 306 Int32 b, wrBlock, currBlock, rbCtr;
Chris@4 307 MaybeUInt64 bitsRead;
Chris@4 308
Chris@4 309 UInt32 buffHi, buffLo, blockCRC;
Chris@4 310 Char* p;
Chris@4 311
Chris@4 312 strcpy ( progName, argv[0] );
Chris@4 313 inFileName[0] = outFileName[0] = 0;
Chris@4 314
Chris@4 315 fprintf ( stderr,
Chris@4 316 "bzip2recover 1.0.6: extracts blocks from damaged .bz2 files.\n" );
Chris@4 317
Chris@4 318 if (argc != 2) {
Chris@4 319 fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
Chris@4 320 progName, progName );
Chris@4 321 switch (sizeof(MaybeUInt64)) {
Chris@4 322 case 8:
Chris@4 323 fprintf(stderr,
Chris@4 324 "\trestrictions on size of recovered file: None\n");
Chris@4 325 break;
Chris@4 326 case 4:
Chris@4 327 fprintf(stderr,
Chris@4 328 "\trestrictions on size of recovered file: 512 MB\n");
Chris@4 329 fprintf(stderr,
Chris@4 330 "\tto circumvent, recompile with MaybeUInt64 as an\n"
Chris@4 331 "\tunsigned 64-bit int.\n");
Chris@4 332 break;
Chris@4 333 default:
Chris@4 334 fprintf(stderr,
Chris@4 335 "\tsizeof(MaybeUInt64) is not 4 or 8 -- "
Chris@4 336 "configuration error.\n");
Chris@4 337 break;
Chris@4 338 }
Chris@4 339 exit(1);
Chris@4 340 }
Chris@4 341
Chris@4 342 if (strlen(argv[1]) >= BZ_MAX_FILENAME-20) {
Chris@4 343 fprintf ( stderr,
Chris@4 344 "%s: supplied filename is suspiciously (>= %d chars) long. Bye!\n",
Chris@4 345 progName, (int)strlen(argv[1]) );
Chris@4 346 exit(1);
Chris@4 347 }
Chris@4 348
Chris@4 349 strcpy ( inFileName, argv[1] );
Chris@4 350
Chris@4 351 inFile = fopen ( inFileName, "rb" );
Chris@4 352 if (inFile == NULL) {
Chris@4 353 fprintf ( stderr, "%s: can't read `%s'\n", progName, inFileName );
Chris@4 354 exit(1);
Chris@4 355 }
Chris@4 356
Chris@4 357 bsIn = bsOpenReadStream ( inFile );
Chris@4 358 fprintf ( stderr, "%s: searching for block boundaries ...\n", progName );
Chris@4 359
Chris@4 360 bitsRead = 0;
Chris@4 361 buffHi = buffLo = 0;
Chris@4 362 currBlock = 0;
Chris@4 363 bStart[currBlock] = 0;
Chris@4 364
Chris@4 365 rbCtr = 0;
Chris@4 366
Chris@4 367 while (True) {
Chris@4 368 b = bsGetBit ( bsIn );
Chris@4 369 bitsRead++;
Chris@4 370 if (b == 2) {
Chris@4 371 if (bitsRead >= bStart[currBlock] &&
Chris@4 372 (bitsRead - bStart[currBlock]) >= 40) {
Chris@4 373 bEnd[currBlock] = bitsRead-1;
Chris@4 374 if (currBlock > 0)
Chris@4 375 fprintf ( stderr, " block %d runs from " MaybeUInt64_FMT
Chris@4 376 " to " MaybeUInt64_FMT " (incomplete)\n",
Chris@4 377 currBlock, bStart[currBlock], bEnd[currBlock] );
Chris@4 378 } else
Chris@4 379 currBlock--;
Chris@4 380 break;
Chris@4 381 }
Chris@4 382 buffHi = (buffHi << 1) | (buffLo >> 31);
Chris@4 383 buffLo = (buffLo << 1) | (b & 1);
Chris@4 384 if ( ( (buffHi & 0x0000ffff) == BLOCK_HEADER_HI
Chris@4 385 && buffLo == BLOCK_HEADER_LO)
Chris@4 386 ||
Chris@4 387 ( (buffHi & 0x0000ffff) == BLOCK_ENDMARK_HI
Chris@4 388 && buffLo == BLOCK_ENDMARK_LO)
Chris@4 389 ) {
Chris@4 390 if (bitsRead > 49) {
Chris@4 391 bEnd[currBlock] = bitsRead-49;
Chris@4 392 } else {
Chris@4 393 bEnd[currBlock] = 0;
Chris@4 394 }
Chris@4 395 if (currBlock > 0 &&
Chris@4 396 (bEnd[currBlock] - bStart[currBlock]) >= 130) {
Chris@4 397 fprintf ( stderr, " block %d runs from " MaybeUInt64_FMT
Chris@4 398 " to " MaybeUInt64_FMT "\n",
Chris@4 399 rbCtr+1, bStart[currBlock], bEnd[currBlock] );
Chris@4 400 rbStart[rbCtr] = bStart[currBlock];
Chris@4 401 rbEnd[rbCtr] = bEnd[currBlock];
Chris@4 402 rbCtr++;
Chris@4 403 }
Chris@4 404 if (currBlock >= BZ_MAX_HANDLED_BLOCKS)
Chris@4 405 tooManyBlocks(BZ_MAX_HANDLED_BLOCKS);
Chris@4 406 currBlock++;
Chris@4 407
Chris@4 408 bStart[currBlock] = bitsRead;
Chris@4 409 }
Chris@4 410 }
Chris@4 411
Chris@4 412 bsClose ( bsIn );
Chris@4 413
Chris@4 414 /*-- identified blocks run from 1 to rbCtr inclusive. --*/
Chris@4 415
Chris@4 416 if (rbCtr < 1) {
Chris@4 417 fprintf ( stderr,
Chris@4 418 "%s: sorry, I couldn't find any block boundaries.\n",
Chris@4 419 progName );
Chris@4 420 exit(1);
Chris@4 421 };
Chris@4 422
Chris@4 423 fprintf ( stderr, "%s: splitting into blocks\n", progName );
Chris@4 424
Chris@4 425 inFile = fopen ( inFileName, "rb" );
Chris@4 426 if (inFile == NULL) {
Chris@4 427 fprintf ( stderr, "%s: can't open `%s'\n", progName, inFileName );
Chris@4 428 exit(1);
Chris@4 429 }
Chris@4 430 bsIn = bsOpenReadStream ( inFile );
Chris@4 431
Chris@4 432 /*-- placate gcc's dataflow analyser --*/
Chris@4 433 blockCRC = 0; bsWr = 0;
Chris@4 434
Chris@4 435 bitsRead = 0;
Chris@4 436 outFile = NULL;
Chris@4 437 wrBlock = 0;
Chris@4 438 while (True) {
Chris@4 439 b = bsGetBit(bsIn);
Chris@4 440 if (b == 2) break;
Chris@4 441 buffHi = (buffHi << 1) | (buffLo >> 31);
Chris@4 442 buffLo = (buffLo << 1) | (b & 1);
Chris@4 443 if (bitsRead == 47+rbStart[wrBlock])
Chris@4 444 blockCRC = (buffHi << 16) | (buffLo >> 16);
Chris@4 445
Chris@4 446 if (outFile != NULL && bitsRead >= rbStart[wrBlock]
Chris@4 447 && bitsRead <= rbEnd[wrBlock]) {
Chris@4 448 bsPutBit ( bsWr, b );
Chris@4 449 }
Chris@4 450
Chris@4 451 bitsRead++;
Chris@4 452
Chris@4 453 if (bitsRead == rbEnd[wrBlock]+1) {
Chris@4 454 if (outFile != NULL) {
Chris@4 455 bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
Chris@4 456 bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
Chris@4 457 bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
Chris@4 458 bsPutUInt32 ( bsWr, blockCRC );
Chris@4 459 bsClose ( bsWr );
Chris@4 460 }
Chris@4 461 if (wrBlock >= rbCtr) break;
Chris@4 462 wrBlock++;
Chris@4 463 } else
Chris@4 464 if (bitsRead == rbStart[wrBlock]) {
Chris@4 465 /* Create the output file name, correctly handling leading paths.
Chris@4 466 (31.10.2001 by Sergey E. Kusikov) */
Chris@4 467 Char* split;
Chris@4 468 Int32 ofs, k;
Chris@4 469 for (k = 0; k < BZ_MAX_FILENAME; k++)
Chris@4 470 outFileName[k] = 0;
Chris@4 471 strcpy (outFileName, inFileName);
Chris@4 472 split = strrchr (outFileName, BZ_SPLIT_SYM);
Chris@4 473 if (split == NULL) {
Chris@4 474 split = outFileName;
Chris@4 475 } else {
Chris@4 476 ++split;
Chris@4 477 }
Chris@4 478 /* Now split points to the start of the basename. */
Chris@4 479 ofs = split - outFileName;
Chris@4 480 sprintf (split, "rec%5d", wrBlock+1);
Chris@4 481 for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
Chris@4 482 strcat (outFileName, inFileName + ofs);
Chris@4 483
Chris@4 484 if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );
Chris@4 485
Chris@4 486 fprintf ( stderr, " writing block %d to `%s' ...\n",
Chris@4 487 wrBlock+1, outFileName );
Chris@4 488
Chris@4 489 outFile = fopen ( outFileName, "wb" );
Chris@4 490 if (outFile == NULL) {
Chris@4 491 fprintf ( stderr, "%s: can't write `%s'\n",
Chris@4 492 progName, outFileName );
Chris@4 493 exit(1);
Chris@4 494 }
Chris@4 495 bsWr = bsOpenWriteStream ( outFile );
Chris@4 496 bsPutUChar ( bsWr, BZ_HDR_B );
Chris@4 497 bsPutUChar ( bsWr, BZ_HDR_Z );
Chris@4 498 bsPutUChar ( bsWr, BZ_HDR_h );
Chris@4 499 bsPutUChar ( bsWr, BZ_HDR_0 + 9 );
Chris@4 500 bsPutUChar ( bsWr, 0x31 ); bsPutUChar ( bsWr, 0x41 );
Chris@4 501 bsPutUChar ( bsWr, 0x59 ); bsPutUChar ( bsWr, 0x26 );
Chris@4 502 bsPutUChar ( bsWr, 0x53 ); bsPutUChar ( bsWr, 0x59 );
Chris@4 503 }
Chris@4 504 }
Chris@4 505
Chris@4 506 fprintf ( stderr, "%s: finished\n", progName );
Chris@4 507 return 0;
Chris@4 508 }
Chris@4 509
Chris@4 510
Chris@4 511
Chris@4 512 /*-----------------------------------------------------------*/
Chris@4 513 /*--- end bzip2recover.c ---*/
Chris@4 514 /*-----------------------------------------------------------*/