annotate src/bzip2-1.0.6/bzip2recover.c @ 89:8a15ff55d9af

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