Blame bzip2recover.c.bzip2recover

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