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