Blame bzlib-src/bzip2recover.c

Packit 989e37
/*-----------------------------------------------------------*/
Packit 989e37
/*--- Block recoverer program for bzip2                   ---*/
Packit 989e37
/*---                                      bzip2recover.c ---*/
Packit 989e37
/*-----------------------------------------------------------*/
Packit 989e37
Packit 989e37
/* ------------------------------------------------------------------
Packit 989e37
   This file is part of bzip2/libbzip2, a program and library for
Packit 989e37
   lossless, block-sorting data compression.
Packit 989e37
Packit 989e37
   bzip2/libbzip2 version 1.0.6 of 6 September 2010
Packit 989e37
   Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Packit 989e37
Packit 989e37
   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
Packit 989e37
   README file.
Packit 989e37
Packit 989e37
   This program is released under the terms of the license contained
Packit 989e37
   in the file LICENSE.
Packit 989e37
   ------------------------------------------------------------------ */
Packit 989e37
Packit 989e37
/* This program is a complete hack and should be rewritten properly.
Packit 989e37
	 It isn't very complicated. */
Packit 989e37
Packit 989e37
#include <stdio.h>
Packit 989e37
#include <errno.h>
Packit 989e37
#include <stdlib.h>
Packit 989e37
#include <string.h>
Packit 989e37
Packit 989e37
Packit 989e37
/* This program records bit locations in the file to be recovered.
Packit 989e37
   That means that if 64-bit ints are not supported, we will not
Packit 989e37
   be able to recover .bz2 files over 512MB (2^32 bits) long.
Packit 989e37
   On GNU supported platforms, we take advantage of the 64-bit
Packit 989e37
   int support to circumvent this problem.  Ditto MSVC.
Packit 989e37
Packit 989e37
   This change occurred in version 1.0.2; all prior versions have
Packit 989e37
   the 512MB limitation.
Packit 989e37
*/
Packit 989e37
#ifdef __GNUC__
Packit 989e37
   typedef  unsigned long long int  MaybeUInt64;
Packit 989e37
#  define MaybeUInt64_FMT "%Lu"
Packit 989e37
#else
Packit 989e37
#ifdef _MSC_VER
Packit 989e37
   typedef  unsigned __int64  MaybeUInt64;
Packit 989e37
#  define MaybeUInt64_FMT "%I64u"
Packit 989e37
#else
Packit 989e37
   typedef  unsigned int   MaybeUInt64;
Packit 989e37
#  define MaybeUInt64_FMT "%u"
Packit 989e37
#endif
Packit 989e37
#endif
Packit 989e37
Packit 989e37
typedef  unsigned int   UInt32;
Packit 989e37
typedef  int            Int32;
Packit 989e37
typedef  unsigned char  UChar;
Packit 989e37
typedef  char           Char;
Packit 989e37
typedef  unsigned char  Bool;
Packit 989e37
#define True    ((Bool)1)
Packit 989e37
#define False   ((Bool)0)
Packit 989e37
Packit 989e37
Packit 989e37
#define BZ_MAX_FILENAME 2000
Packit 989e37
Packit 989e37
Char inFileName[BZ_MAX_FILENAME];
Packit 989e37
Char outFileName[BZ_MAX_FILENAME];
Packit 989e37
Char progName[BZ_MAX_FILENAME];
Packit 989e37
Packit 989e37
MaybeUInt64 bytesOut = 0;
Packit 989e37
MaybeUInt64 bytesIn  = 0;
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
/*--- Header bytes                                ---*/
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
Packit 989e37
#define BZ_HDR_B 0x42                         /* 'B' */
Packit 989e37
#define BZ_HDR_Z 0x5a                         /* 'Z' */
Packit 989e37
#define BZ_HDR_h 0x68                         /* 'h' */
Packit 989e37
#define BZ_HDR_0 0x30                         /* '0' */
Packit 989e37
 
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
/*--- I/O errors                                  ---*/
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
Packit 989e37
/*---------------------------------------------*/
Packit 989e37
static void readError ( void )
Packit 989e37
{
Packit 989e37
   fprintf ( stderr,
Packit 989e37
             "%s: I/O error reading `%s', possible reason follows.\n",
Packit 989e37
            progName, inFileName );
Packit 989e37
   perror ( progName );
Packit 989e37
   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
Packit 989e37
             progName );
Packit 989e37
   exit ( 1 );
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------*/
Packit 989e37
static void writeError ( void )
Packit 989e37
{
Packit 989e37
   fprintf ( stderr,
Packit 989e37
             "%s: I/O error reading `%s', possible reason follows.\n",
Packit 989e37
            progName, inFileName );
Packit 989e37
   perror ( progName );
Packit 989e37
   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
Packit 989e37
             progName );
Packit 989e37
   exit ( 1 );
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------*/
Packit 989e37
static void mallocFail ( Int32 n )
Packit 989e37
{
Packit 989e37
   fprintf ( stderr,
Packit 989e37
             "%s: malloc failed on request for %d bytes.\n",
Packit 989e37
            progName, n );
Packit 989e37
   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
Packit 989e37
             progName );
Packit 989e37
   exit ( 1 );
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------*/
Packit 989e37
static void tooManyBlocks ( Int32 max_handled_blocks )
Packit 989e37
{
Packit 989e37
   fprintf ( stderr,
Packit 989e37
             "%s: `%s' appears to contain more than %d blocks\n",
Packit 989e37
            progName, inFileName, max_handled_blocks );
Packit 989e37
   fprintf ( stderr,
Packit 989e37
             "%s: and cannot be handled.  To fix, increase\n",
Packit 989e37
             progName );
Packit 989e37
   fprintf ( stderr, 
Packit 989e37
             "%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n",
Packit 989e37
             progName );
Packit 989e37
   exit ( 1 );
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
/*--- Bit stream I/O                              ---*/
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
Packit 989e37
typedef
Packit 989e37
   struct {
Packit 989e37
      FILE*  handle;
Packit 989e37
      Int32  buffer;
Packit 989e37
      Int32  buffLive;
Packit 989e37
      Char   mode;
Packit 989e37
   }
Packit 989e37
   BitStream;
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------*/
Packit 989e37
static BitStream* bsOpenReadStream ( FILE* stream )
Packit 989e37
{
Packit 989e37
   BitStream *bs = malloc ( sizeof(BitStream) );
Packit 989e37
   if (bs == NULL) mallocFail ( sizeof(BitStream) );
Packit 989e37
   bs->handle = stream;
Packit 989e37
   bs->buffer = 0;
Packit 989e37
   bs->buffLive = 0;
Packit 989e37
   bs->mode = 'r';
Packit 989e37
   return bs;
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------*/
Packit 989e37
static BitStream* bsOpenWriteStream ( FILE* stream )
Packit 989e37
{
Packit 989e37
   BitStream *bs = malloc ( sizeof(BitStream) );
Packit 989e37
   if (bs == NULL) mallocFail ( sizeof(BitStream) );
Packit 989e37
   bs->handle = stream;
Packit 989e37
   bs->buffer = 0;
Packit 989e37
   bs->buffLive = 0;
Packit 989e37
   bs->mode = 'w';
Packit 989e37
   return bs;
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------*/
Packit 989e37
static void bsPutBit ( BitStream* bs, Int32 bit )
Packit 989e37
{
Packit 989e37
   if (bs->buffLive == 8) {
Packit 989e37
      Int32 retVal = putc ( (UChar) bs->buffer, bs->handle );
Packit 989e37
      if (retVal == EOF) writeError();
Packit 989e37
      bytesOut++;
Packit 989e37
      bs->buffLive = 1;
Packit 989e37
      bs->buffer = bit & 0x1;
Packit 989e37
   } else {
Packit 989e37
      bs->buffer = ( (bs->buffer << 1) | (bit & 0x1) );
Packit 989e37
      bs->buffLive++;
Packit 989e37
   };
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------*/
Packit 989e37
/*--
Packit 989e37
   Returns 0 or 1, or 2 to indicate EOF.
Packit 989e37
--*/
Packit 989e37
static Int32 bsGetBit ( BitStream* bs )
Packit 989e37
{
Packit 989e37
   if (bs->buffLive > 0) {
Packit 989e37
      bs->buffLive --;
Packit 989e37
      return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
Packit 989e37
   } else {
Packit 989e37
      Int32 retVal = getc ( bs->handle );
Packit 989e37
      if ( retVal == EOF ) {
Packit 989e37
         if (errno != 0) readError();
Packit 989e37
         return 2;
Packit 989e37
      }
Packit 989e37
      bs->buffLive = 7;
Packit 989e37
      bs->buffer = retVal;
Packit 989e37
      return ( ((bs->buffer) >> 7) & 0x1 );
Packit 989e37
   }
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------*/
Packit 989e37
static void bsClose ( BitStream* bs )
Packit 989e37
{
Packit 989e37
   Int32 retVal;
Packit 989e37
Packit 989e37
   if ( bs->mode == 'w' ) {
Packit 989e37
      while ( bs->buffLive < 8 ) {
Packit 989e37
         bs->buffLive++;
Packit 989e37
         bs->buffer <<= 1;
Packit 989e37
      };
Packit 989e37
      retVal = putc ( (UChar) (bs->buffer), bs->handle );
Packit 989e37
      if (retVal == EOF) writeError();
Packit 989e37
      bytesOut++;
Packit 989e37
      retVal = fflush ( bs->handle );
Packit 989e37
      if (retVal == EOF) writeError();
Packit 989e37
   }
Packit 989e37
   retVal = fclose ( bs->handle );
Packit 989e37
   if (retVal == EOF) {
Packit 989e37
      if (bs->mode == 'w') writeError(); else readError();
Packit 989e37
   }
Packit 989e37
   free ( bs );
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------*/
Packit 989e37
static void bsPutUChar ( BitStream* bs, UChar c )
Packit 989e37
{
Packit 989e37
   Int32 i;
Packit 989e37
   for (i = 7; i >= 0; i--)
Packit 989e37
      bsPutBit ( bs, (((UInt32) c) >> i) & 0x1 );
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------*/
Packit 989e37
static void bsPutUInt32 ( BitStream* bs, UInt32 c )
Packit 989e37
{
Packit 989e37
   Int32 i;
Packit 989e37
Packit 989e37
   for (i = 31; i >= 0; i--)
Packit 989e37
      bsPutBit ( bs, (c >> i) & 0x1 );
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------*/
Packit 989e37
static Bool endsInBz2 ( Char* name )
Packit 989e37
{
Packit 989e37
   Int32 n = strlen ( name );
Packit 989e37
   if (n <= 4) return False;
Packit 989e37
   return
Packit 989e37
      (name[n-4] == '.' &&
Packit 989e37
       name[n-3] == 'b' &&
Packit 989e37
       name[n-2] == 'z' &&
Packit 989e37
       name[n-1] == '2');
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
/*---                                             ---*/
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
Packit 989e37
/* This logic isn't really right when it comes to Cygwin. */
Packit 989e37
#ifdef _WIN32
Packit 989e37
#  define  BZ_SPLIT_SYM  '\\'  /* path splitter on Windows platform */
Packit 989e37
#else
Packit 989e37
#  define  BZ_SPLIT_SYM  '/'   /* path splitter on Unix platform */
Packit 989e37
#endif
Packit 989e37
Packit 989e37
#define BLOCK_HEADER_HI  0x00003141UL
Packit 989e37
#define BLOCK_HEADER_LO  0x59265359UL
Packit 989e37
Packit 989e37
#define BLOCK_ENDMARK_HI 0x00001772UL
Packit 989e37
#define BLOCK_ENDMARK_LO 0x45385090UL
Packit 989e37
Packit 989e37
/* Increase if necessary.  However, a .bz2 file with > 50000 blocks
Packit 989e37
   would have an uncompressed size of at least 40GB, so the chances
Packit 989e37
   are low you'll need to up this.
Packit 989e37
*/
Packit 989e37
#define BZ_MAX_HANDLED_BLOCKS 50000
Packit 989e37
Packit 989e37
MaybeUInt64 bStart [BZ_MAX_HANDLED_BLOCKS];
Packit 989e37
MaybeUInt64 bEnd   [BZ_MAX_HANDLED_BLOCKS];
Packit 989e37
MaybeUInt64 rbStart[BZ_MAX_HANDLED_BLOCKS];
Packit 989e37
MaybeUInt64 rbEnd  [BZ_MAX_HANDLED_BLOCKS];
Packit 989e37
Packit 989e37
Int32 main ( Int32 argc, Char** argv )
Packit 989e37
{
Packit 989e37
   FILE*       inFile;
Packit 989e37
   FILE*       outFile;
Packit 989e37
   BitStream*  bsIn, *bsWr;
Packit 989e37
   Int32       b, wrBlock, currBlock, rbCtr;
Packit 989e37
   MaybeUInt64 bitsRead;
Packit 989e37
Packit 989e37
   UInt32      buffHi, buffLo, blockCRC;
Packit 989e37
   Char*       p;
Packit 989e37
Packit 989e37
   strcpy ( progName, argv[0] );
Packit 989e37
   inFileName[0] = outFileName[0] = 0;
Packit 989e37
Packit 989e37
   fprintf ( stderr, 
Packit 989e37
             "bzip2recover 1.0.6: extracts blocks from damaged .bz2 files.\n" );
Packit 989e37
Packit 989e37
   if (argc != 2) {
Packit 989e37
      fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
Packit 989e37
                        progName, progName );
Packit 989e37
      switch (sizeof(MaybeUInt64)) {
Packit 989e37
         case 8:
Packit 989e37
            fprintf(stderr, 
Packit 989e37
                    "\trestrictions on size of recovered file: None\n");
Packit 989e37
            break;
Packit 989e37
         case 4:
Packit 989e37
            fprintf(stderr, 
Packit 989e37
                    "\trestrictions on size of recovered file: 512 MB\n");
Packit 989e37
            fprintf(stderr, 
Packit 989e37
                    "\tto circumvent, recompile with MaybeUInt64 as an\n"
Packit 989e37
                    "\tunsigned 64-bit int.\n");
Packit 989e37
            break;
Packit 989e37
         default:
Packit 989e37
            fprintf(stderr, 
Packit 989e37
                    "\tsizeof(MaybeUInt64) is not 4 or 8 -- "
Packit 989e37
                    "configuration error.\n");
Packit 989e37
            break;
Packit 989e37
      }
Packit 989e37
      exit(1);
Packit 989e37
   }
Packit 989e37
Packit 989e37
   if (strlen(argv[1]) >= BZ_MAX_FILENAME-20) {
Packit 989e37
      fprintf ( stderr, 
Packit 989e37
                "%s: supplied filename is suspiciously (>= %d chars) long.  Bye!\n",
Packit 989e37
                progName, (int)strlen(argv[1]) );
Packit 989e37
      exit(1);
Packit 989e37
   }
Packit 989e37
Packit 989e37
   strcpy ( inFileName, argv[1] );
Packit 989e37
Packit 989e37
   inFile = fopen ( inFileName, "rb" );
Packit 989e37
   if (inFile == NULL) {
Packit 989e37
      fprintf ( stderr, "%s: can't read `%s'\n", progName, inFileName );
Packit 989e37
      exit(1);
Packit 989e37
   }
Packit 989e37
Packit 989e37
   bsIn = bsOpenReadStream ( inFile );
Packit 989e37
   fprintf ( stderr, "%s: searching for block boundaries ...\n", progName );
Packit 989e37
Packit 989e37
   bitsRead = 0;
Packit 989e37
   buffHi = buffLo = 0;
Packit 989e37
   currBlock = 0;
Packit 989e37
   bStart[currBlock] = 0;
Packit 989e37
Packit 989e37
   rbCtr = 0;
Packit 989e37
Packit 989e37
   while (True) {
Packit 989e37
      b = bsGetBit ( bsIn );
Packit 989e37
      bitsRead++;
Packit 989e37
      if (b == 2) {
Packit 989e37
         if (bitsRead >= bStart[currBlock] &&
Packit 989e37
            (bitsRead - bStart[currBlock]) >= 40) {
Packit 989e37
            bEnd[currBlock] = bitsRead-1;
Packit 989e37
            if (currBlock > 0)
Packit 989e37
               fprintf ( stderr, "   block %d runs from " MaybeUInt64_FMT 
Packit 989e37
                                 " to " MaybeUInt64_FMT " (incomplete)\n",
Packit 989e37
                         currBlock,  bStart[currBlock], bEnd[currBlock] );
Packit 989e37
         } else
Packit 989e37
            currBlock--;
Packit 989e37
         break;
Packit 989e37
      }
Packit 989e37
      buffHi = (buffHi << 1) | (buffLo >> 31);
Packit 989e37
      buffLo = (buffLo << 1) | (b & 1);
Packit 989e37
      if ( ( (buffHi & 0x0000ffff) == BLOCK_HEADER_HI 
Packit 989e37
             && buffLo == BLOCK_HEADER_LO)
Packit 989e37
           || 
Packit 989e37
           ( (buffHi & 0x0000ffff) == BLOCK_ENDMARK_HI 
Packit 989e37
             && buffLo == BLOCK_ENDMARK_LO)
Packit 989e37
         ) {
Packit 989e37
         if (bitsRead > 49) {
Packit 989e37
            bEnd[currBlock] = bitsRead-49;
Packit 989e37
         } else {
Packit 989e37
            bEnd[currBlock] = 0;
Packit 989e37
         }
Packit 989e37
         if (currBlock > 0 &&
Packit 989e37
	     (bEnd[currBlock] - bStart[currBlock]) >= 130) {
Packit 989e37
            fprintf ( stderr, "   block %d runs from " MaybeUInt64_FMT 
Packit 989e37
                              " to " MaybeUInt64_FMT "\n",
Packit 989e37
                      rbCtr+1,  bStart[currBlock], bEnd[currBlock] );
Packit 989e37
            rbStart[rbCtr] = bStart[currBlock];
Packit 989e37
            rbEnd[rbCtr] = bEnd[currBlock];
Packit 989e37
            rbCtr++;
Packit 989e37
         }
Packit 989e37
         if (currBlock >= BZ_MAX_HANDLED_BLOCKS)
Packit 989e37
            tooManyBlocks(BZ_MAX_HANDLED_BLOCKS);
Packit 989e37
         currBlock++;
Packit 989e37
Packit 989e37
         bStart[currBlock] = bitsRead;
Packit 989e37
      }
Packit 989e37
   }
Packit 989e37
Packit 989e37
   bsClose ( bsIn );
Packit 989e37
Packit 989e37
   /*-- identified blocks run from 1 to rbCtr inclusive. --*/
Packit 989e37
Packit 989e37
   if (rbCtr < 1) {
Packit 989e37
      fprintf ( stderr,
Packit 989e37
                "%s: sorry, I couldn't find any block boundaries.\n",
Packit 989e37
                progName );
Packit 989e37
      exit(1);
Packit 989e37
   };
Packit 989e37
Packit 989e37
   fprintf ( stderr, "%s: splitting into blocks\n", progName );
Packit 989e37
Packit 989e37
   inFile = fopen ( inFileName, "rb" );
Packit 989e37
   if (inFile == NULL) {
Packit 989e37
      fprintf ( stderr, "%s: can't open `%s'\n", progName, inFileName );
Packit 989e37
      exit(1);
Packit 989e37
   }
Packit 989e37
   bsIn = bsOpenReadStream ( inFile );
Packit 989e37
Packit 989e37
   /*-- placate gcc's dataflow analyser --*/
Packit 989e37
   blockCRC = 0; bsWr = 0;
Packit 989e37
Packit 989e37
   bitsRead = 0;
Packit 989e37
   outFile = NULL;
Packit 989e37
   wrBlock = 0;
Packit 989e37
   while (True) {
Packit 989e37
      b = bsGetBit(bsIn);
Packit 989e37
      if (b == 2) break;
Packit 989e37
      buffHi = (buffHi << 1) | (buffLo >> 31);
Packit 989e37
      buffLo = (buffLo << 1) | (b & 1);
Packit 989e37
      if (bitsRead == 47+rbStart[wrBlock]) 
Packit 989e37
         blockCRC = (buffHi << 16) | (buffLo >> 16);
Packit 989e37
Packit 989e37
      if (outFile != NULL && bitsRead >= rbStart[wrBlock]
Packit 989e37
                          && bitsRead <= rbEnd[wrBlock]) {
Packit 989e37
         bsPutBit ( bsWr, b );
Packit 989e37
      }
Packit 989e37
Packit 989e37
      bitsRead++;
Packit 989e37
Packit 989e37
      if (bitsRead == rbEnd[wrBlock]+1) {
Packit 989e37
         if (outFile != NULL) {
Packit 989e37
            bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
Packit 989e37
            bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
Packit 989e37
            bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
Packit 989e37
            bsPutUInt32 ( bsWr, blockCRC );
Packit 989e37
            bsClose ( bsWr );
Packit 989e37
         }
Packit 989e37
         if (wrBlock >= rbCtr) break;
Packit 989e37
         wrBlock++;
Packit 989e37
      } else
Packit 989e37
      if (bitsRead == rbStart[wrBlock]) {
Packit 989e37
         /* Create the output file name, correctly handling leading paths. 
Packit 989e37
            (31.10.2001 by Sergey E. Kusikov) */
Packit 989e37
         Char* split;
Packit 989e37
         Int32 ofs, k;
Packit 989e37
         for (k = 0; k < BZ_MAX_FILENAME; k++) 
Packit 989e37
            outFileName[k] = 0;
Packit 989e37
         strcpy (outFileName, inFileName);
Packit 989e37
         split = strrchr (outFileName, BZ_SPLIT_SYM);
Packit 989e37
         if (split == NULL) {
Packit 989e37
            split = outFileName;
Packit 989e37
         } else {
Packit 989e37
            ++split;
Packit 989e37
	 }
Packit 989e37
	 /* Now split points to the start of the basename. */
Packit 989e37
         ofs  = split - outFileName;
Packit 989e37
         sprintf (split, "rec%5d", wrBlock+1);
Packit 989e37
         for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
Packit 989e37
         strcat (outFileName, inFileName + ofs);
Packit 989e37
Packit 989e37
         if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );
Packit 989e37
Packit 989e37
         fprintf ( stderr, "   writing block %d to `%s' ...\n",
Packit 989e37
                           wrBlock+1, outFileName );
Packit 989e37
Packit 989e37
         outFile = fopen ( outFileName, "wb" );
Packit 989e37
         if (outFile == NULL) {
Packit 989e37
            fprintf ( stderr, "%s: can't write `%s'\n",
Packit 989e37
                      progName, outFileName );
Packit 989e37
            exit(1);
Packit 989e37
         }
Packit 989e37
         bsWr = bsOpenWriteStream ( outFile );
Packit 989e37
         bsPutUChar ( bsWr, BZ_HDR_B );    
Packit 989e37
         bsPutUChar ( bsWr, BZ_HDR_Z );    
Packit 989e37
         bsPutUChar ( bsWr, BZ_HDR_h );    
Packit 989e37
         bsPutUChar ( bsWr, BZ_HDR_0 + 9 );
Packit 989e37
         bsPutUChar ( bsWr, 0x31 ); bsPutUChar ( bsWr, 0x41 );
Packit 989e37
         bsPutUChar ( bsWr, 0x59 ); bsPutUChar ( bsWr, 0x26 );
Packit 989e37
         bsPutUChar ( bsWr, 0x53 ); bsPutUChar ( bsWr, 0x59 );
Packit 989e37
      }
Packit 989e37
   }
Packit 989e37
Packit 989e37
   fprintf ( stderr, "%s: finished\n", progName );
Packit 989e37
   return 0;
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
Packit 989e37
/*-----------------------------------------------------------*/
Packit 989e37
/*--- end                                  bzip2recover.c ---*/
Packit 989e37
/*-----------------------------------------------------------*/