Blame


1 ff3adf60 2004-04-14 devnull
2 ff3adf60 2004-04-14 devnull /*-----------------------------------------------------------*/
3 ff3adf60 2004-04-14 devnull /*--- Block recoverer program for bzip2 ---*/
4 ff3adf60 2004-04-14 devnull /*--- bzip2recover.c ---*/
5 ff3adf60 2004-04-14 devnull /*-----------------------------------------------------------*/
6 ff3adf60 2004-04-14 devnull
7 ff3adf60 2004-04-14 devnull /*--
8 ff3adf60 2004-04-14 devnull This program is bzip2recover, a program to attempt data
9 ff3adf60 2004-04-14 devnull salvage from damaged files created by the accompanying
10 ff3adf60 2004-04-14 devnull bzip2-1.0 program.
11 ff3adf60 2004-04-14 devnull
12 ff3adf60 2004-04-14 devnull Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
13 ff3adf60 2004-04-14 devnull
14 ff3adf60 2004-04-14 devnull Redistribution and use in source and binary forms, with or without
15 ff3adf60 2004-04-14 devnull modification, are permitted provided that the following conditions
16 ff3adf60 2004-04-14 devnull are met:
17 ff3adf60 2004-04-14 devnull
18 ff3adf60 2004-04-14 devnull 1. Redistributions of source code must retain the above copyright
19 ff3adf60 2004-04-14 devnull notice, this list of conditions and the following disclaimer.
20 ff3adf60 2004-04-14 devnull
21 ff3adf60 2004-04-14 devnull 2. The origin of this software must not be misrepresented; you must
22 ff3adf60 2004-04-14 devnull not claim that you wrote the original software. If you use this
23 ff3adf60 2004-04-14 devnull software in a product, an acknowledgment in the product
24 ff3adf60 2004-04-14 devnull documentation would be appreciated but is not required.
25 ff3adf60 2004-04-14 devnull
26 ff3adf60 2004-04-14 devnull 3. Altered source versions must be plainly marked as such, and must
27 ff3adf60 2004-04-14 devnull not be misrepresented as being the original software.
28 ff3adf60 2004-04-14 devnull
29 ff3adf60 2004-04-14 devnull 4. The name of the author may not be used to endorse or promote
30 ff3adf60 2004-04-14 devnull products derived from this software without specific prior written
31 ff3adf60 2004-04-14 devnull permission.
32 ff3adf60 2004-04-14 devnull
33 ff3adf60 2004-04-14 devnull THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
34 ff3adf60 2004-04-14 devnull OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35 ff3adf60 2004-04-14 devnull WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 ff3adf60 2004-04-14 devnull ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
37 ff3adf60 2004-04-14 devnull DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 ff3adf60 2004-04-14 devnull DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
39 ff3adf60 2004-04-14 devnull GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 ff3adf60 2004-04-14 devnull INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
41 ff3adf60 2004-04-14 devnull WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42 ff3adf60 2004-04-14 devnull NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43 ff3adf60 2004-04-14 devnull SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 ff3adf60 2004-04-14 devnull
45 ff3adf60 2004-04-14 devnull Julian Seward, Cambridge, UK.
46 ff3adf60 2004-04-14 devnull jseward@acm.org
47 ff3adf60 2004-04-14 devnull bzip2/libbzip2 version 1.0 of 21 March 2000
48 ff3adf60 2004-04-14 devnull --*/
49 ff3adf60 2004-04-14 devnull
50 ff3adf60 2004-04-14 devnull /*--
51 ff3adf60 2004-04-14 devnull This program is a complete hack and should be rewritten
52 ff3adf60 2004-04-14 devnull properly. It isn't very complicated.
53 ff3adf60 2004-04-14 devnull --*/
54 ff3adf60 2004-04-14 devnull
55 ff3adf60 2004-04-14 devnull #include <stdio.h>
56 ff3adf60 2004-04-14 devnull #include <errno.h>
57 ff3adf60 2004-04-14 devnull #include <stdlib.h>
58 ff3adf60 2004-04-14 devnull #include <string.h>
59 ff3adf60 2004-04-14 devnull
60 ff3adf60 2004-04-14 devnull typedef unsigned int UInt32;
61 ff3adf60 2004-04-14 devnull typedef int Int32;
62 ff3adf60 2004-04-14 devnull typedef unsigned char UChar;
63 ff3adf60 2004-04-14 devnull typedef char Char;
64 ff3adf60 2004-04-14 devnull typedef unsigned char Bool;
65 ff3adf60 2004-04-14 devnull #define True ((Bool)1)
66 ff3adf60 2004-04-14 devnull #define False ((Bool)0)
67 ff3adf60 2004-04-14 devnull
68 ff3adf60 2004-04-14 devnull
69 ff3adf60 2004-04-14 devnull Char inFileName[2000];
70 ff3adf60 2004-04-14 devnull Char outFileName[2000];
71 ff3adf60 2004-04-14 devnull Char progName[2000];
72 ff3adf60 2004-04-14 devnull
73 ff3adf60 2004-04-14 devnull UInt32 bytesOut = 0;
74 ff3adf60 2004-04-14 devnull UInt32 bytesIn = 0;
75 ff3adf60 2004-04-14 devnull
76 ff3adf60 2004-04-14 devnull
77 ff3adf60 2004-04-14 devnull /*---------------------------------------------------*/
78 ff3adf60 2004-04-14 devnull /*--- I/O errors ---*/
79 ff3adf60 2004-04-14 devnull /*---------------------------------------------------*/
80 ff3adf60 2004-04-14 devnull
81 ff3adf60 2004-04-14 devnull /*---------------------------------------------*/
82 ff3adf60 2004-04-14 devnull void readError ( void )
83 ff3adf60 2004-04-14 devnull {
84 ff3adf60 2004-04-14 devnull fprintf ( stderr,
85 ff3adf60 2004-04-14 devnull "%s: I/O error reading `%s', possible reason follows.\n",
86 ff3adf60 2004-04-14 devnull progName, inFileName );
87 ff3adf60 2004-04-14 devnull perror ( progName );
88 ff3adf60 2004-04-14 devnull fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
89 ff3adf60 2004-04-14 devnull progName );
90 ff3adf60 2004-04-14 devnull exit ( 1 );
91 ff3adf60 2004-04-14 devnull }
92 ff3adf60 2004-04-14 devnull
93 ff3adf60 2004-04-14 devnull
94 ff3adf60 2004-04-14 devnull /*---------------------------------------------*/
95 ff3adf60 2004-04-14 devnull void writeError ( void )
96 ff3adf60 2004-04-14 devnull {
97 ff3adf60 2004-04-14 devnull fprintf ( stderr,
98 ff3adf60 2004-04-14 devnull "%s: I/O error reading `%s', possible reason follows.\n",
99 ff3adf60 2004-04-14 devnull progName, inFileName );
100 ff3adf60 2004-04-14 devnull perror ( progName );
101 ff3adf60 2004-04-14 devnull fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
102 ff3adf60 2004-04-14 devnull progName );
103 ff3adf60 2004-04-14 devnull exit ( 1 );
104 ff3adf60 2004-04-14 devnull }
105 ff3adf60 2004-04-14 devnull
106 ff3adf60 2004-04-14 devnull
107 ff3adf60 2004-04-14 devnull /*---------------------------------------------*/
108 ff3adf60 2004-04-14 devnull void mallocFail ( Int32 n )
109 ff3adf60 2004-04-14 devnull {
110 ff3adf60 2004-04-14 devnull fprintf ( stderr,
111 ff3adf60 2004-04-14 devnull "%s: malloc failed on request for %d bytes.\n",
112 ff3adf60 2004-04-14 devnull progName, n );
113 ff3adf60 2004-04-14 devnull fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
114 ff3adf60 2004-04-14 devnull progName );
115 ff3adf60 2004-04-14 devnull exit ( 1 );
116 ff3adf60 2004-04-14 devnull }
117 ff3adf60 2004-04-14 devnull
118 ff3adf60 2004-04-14 devnull
119 ff3adf60 2004-04-14 devnull /*---------------------------------------------------*/
120 ff3adf60 2004-04-14 devnull /*--- Bit stream I/O ---*/
121 ff3adf60 2004-04-14 devnull /*---------------------------------------------------*/
122 ff3adf60 2004-04-14 devnull
123 ff3adf60 2004-04-14 devnull typedef
124 ff3adf60 2004-04-14 devnull struct {
125 ff3adf60 2004-04-14 devnull FILE* handle;
126 ff3adf60 2004-04-14 devnull Int32 buffer;
127 ff3adf60 2004-04-14 devnull Int32 buffLive;
128 ff3adf60 2004-04-14 devnull Char mode;
129 ff3adf60 2004-04-14 devnull }
130 ff3adf60 2004-04-14 devnull BitStream;
131 ff3adf60 2004-04-14 devnull
132 ff3adf60 2004-04-14 devnull
133 ff3adf60 2004-04-14 devnull /*---------------------------------------------*/
134 ff3adf60 2004-04-14 devnull BitStream* bsOpenReadStream ( FILE* stream )
135 ff3adf60 2004-04-14 devnull {
136 ff3adf60 2004-04-14 devnull BitStream *bs = malloc ( sizeof(BitStream) );
137 ff3adf60 2004-04-14 devnull if (bs == NULL) mallocFail ( sizeof(BitStream) );
138 ff3adf60 2004-04-14 devnull bs->handle = stream;
139 ff3adf60 2004-04-14 devnull bs->buffer = 0;
140 ff3adf60 2004-04-14 devnull bs->buffLive = 0;
141 ff3adf60 2004-04-14 devnull bs->mode = 'r';
142 ff3adf60 2004-04-14 devnull return bs;
143 ff3adf60 2004-04-14 devnull }
144 ff3adf60 2004-04-14 devnull
145 ff3adf60 2004-04-14 devnull
146 ff3adf60 2004-04-14 devnull /*---------------------------------------------*/
147 ff3adf60 2004-04-14 devnull BitStream* bsOpenWriteStream ( FILE* stream )
148 ff3adf60 2004-04-14 devnull {
149 ff3adf60 2004-04-14 devnull BitStream *bs = malloc ( sizeof(BitStream) );
150 ff3adf60 2004-04-14 devnull if (bs == NULL) mallocFail ( sizeof(BitStream) );
151 ff3adf60 2004-04-14 devnull bs->handle = stream;
152 ff3adf60 2004-04-14 devnull bs->buffer = 0;
153 ff3adf60 2004-04-14 devnull bs->buffLive = 0;
154 ff3adf60 2004-04-14 devnull bs->mode = 'w';
155 ff3adf60 2004-04-14 devnull return bs;
156 ff3adf60 2004-04-14 devnull }
157 ff3adf60 2004-04-14 devnull
158 ff3adf60 2004-04-14 devnull
159 ff3adf60 2004-04-14 devnull /*---------------------------------------------*/
160 ff3adf60 2004-04-14 devnull void bsPutBit ( BitStream* bs, Int32 bit )
161 ff3adf60 2004-04-14 devnull {
162 ff3adf60 2004-04-14 devnull if (bs->buffLive == 8) {
163 ff3adf60 2004-04-14 devnull Int32 retVal = putc ( (UChar) bs->buffer, bs->handle );
164 ff3adf60 2004-04-14 devnull if (retVal == EOF) writeError();
165 ff3adf60 2004-04-14 devnull bytesOut++;
166 ff3adf60 2004-04-14 devnull bs->buffLive = 1;
167 ff3adf60 2004-04-14 devnull bs->buffer = bit & 0x1;
168 ff3adf60 2004-04-14 devnull } else {
169 ff3adf60 2004-04-14 devnull bs->buffer = ( (bs->buffer << 1) | (bit & 0x1) );
170 ff3adf60 2004-04-14 devnull bs->buffLive++;
171 ff3adf60 2004-04-14 devnull };
172 ff3adf60 2004-04-14 devnull }
173 ff3adf60 2004-04-14 devnull
174 ff3adf60 2004-04-14 devnull
175 ff3adf60 2004-04-14 devnull /*---------------------------------------------*/
176 ff3adf60 2004-04-14 devnull /*--
177 ff3adf60 2004-04-14 devnull Returns 0 or 1, or 2 to indicate EOF.
178 ff3adf60 2004-04-14 devnull --*/
179 ff3adf60 2004-04-14 devnull Int32 bsGetBit ( BitStream* bs )
180 ff3adf60 2004-04-14 devnull {
181 ff3adf60 2004-04-14 devnull if (bs->buffLive > 0) {
182 ff3adf60 2004-04-14 devnull bs->buffLive --;
183 ff3adf60 2004-04-14 devnull return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
184 ff3adf60 2004-04-14 devnull } else {
185 ff3adf60 2004-04-14 devnull Int32 retVal = getc ( bs->handle );
186 ff3adf60 2004-04-14 devnull if ( retVal == EOF ) {
187 ff3adf60 2004-04-14 devnull if (errno != 0) readError();
188 ff3adf60 2004-04-14 devnull return 2;
189 ff3adf60 2004-04-14 devnull }
190 ff3adf60 2004-04-14 devnull bs->buffLive = 7;
191 ff3adf60 2004-04-14 devnull bs->buffer = retVal;
192 ff3adf60 2004-04-14 devnull return ( ((bs->buffer) >> 7) & 0x1 );
193 ff3adf60 2004-04-14 devnull }
194 ff3adf60 2004-04-14 devnull }
195 ff3adf60 2004-04-14 devnull
196 ff3adf60 2004-04-14 devnull
197 ff3adf60 2004-04-14 devnull /*---------------------------------------------*/
198 ff3adf60 2004-04-14 devnull void bsClose ( BitStream* bs )
199 ff3adf60 2004-04-14 devnull {
200 ff3adf60 2004-04-14 devnull Int32 retVal;
201 ff3adf60 2004-04-14 devnull
202 ff3adf60 2004-04-14 devnull if ( bs->mode == 'w' ) {
203 ff3adf60 2004-04-14 devnull while ( bs->buffLive < 8 ) {
204 ff3adf60 2004-04-14 devnull bs->buffLive++;
205 ff3adf60 2004-04-14 devnull bs->buffer <<= 1;
206 ff3adf60 2004-04-14 devnull };
207 ff3adf60 2004-04-14 devnull retVal = putc ( (UChar) (bs->buffer), bs->handle );
208 ff3adf60 2004-04-14 devnull if (retVal == EOF) writeError();
209 ff3adf60 2004-04-14 devnull bytesOut++;
210 ff3adf60 2004-04-14 devnull retVal = fflush ( bs->handle );
211 ff3adf60 2004-04-14 devnull if (retVal == EOF) writeError();
212 ff3adf60 2004-04-14 devnull }
213 ff3adf60 2004-04-14 devnull retVal = fclose ( bs->handle );
214 ff3adf60 2004-04-14 devnull if (retVal == EOF) {
215 ff3adf60 2004-04-14 devnull if (bs->mode == 'w') writeError(); else readError();
216 ff3adf60 2004-04-14 devnull }
217 ff3adf60 2004-04-14 devnull free ( bs );
218 ff3adf60 2004-04-14 devnull }
219 ff3adf60 2004-04-14 devnull
220 ff3adf60 2004-04-14 devnull
221 ff3adf60 2004-04-14 devnull /*---------------------------------------------*/
222 ff3adf60 2004-04-14 devnull void bsPutUChar ( BitStream* bs, UChar c )
223 ff3adf60 2004-04-14 devnull {
224 ff3adf60 2004-04-14 devnull Int32 i;
225 ff3adf60 2004-04-14 devnull for (i = 7; i >= 0; i--)
226 ff3adf60 2004-04-14 devnull bsPutBit ( bs, (((UInt32) c) >> i) & 0x1 );
227 ff3adf60 2004-04-14 devnull }
228 ff3adf60 2004-04-14 devnull
229 ff3adf60 2004-04-14 devnull
230 ff3adf60 2004-04-14 devnull /*---------------------------------------------*/
231 ff3adf60 2004-04-14 devnull void bsPutUInt32 ( BitStream* bs, UInt32 c )
232 ff3adf60 2004-04-14 devnull {
233 ff3adf60 2004-04-14 devnull Int32 i;
234 ff3adf60 2004-04-14 devnull
235 ff3adf60 2004-04-14 devnull for (i = 31; i >= 0; i--)
236 ff3adf60 2004-04-14 devnull bsPutBit ( bs, (c >> i) & 0x1 );
237 ff3adf60 2004-04-14 devnull }
238 ff3adf60 2004-04-14 devnull
239 ff3adf60 2004-04-14 devnull
240 ff3adf60 2004-04-14 devnull /*---------------------------------------------*/
241 ff3adf60 2004-04-14 devnull Bool endsInBz2 ( Char* name )
242 ff3adf60 2004-04-14 devnull {
243 ff3adf60 2004-04-14 devnull Int32 n = strlen ( name );
244 ff3adf60 2004-04-14 devnull if (n <= 4) return False;
245 ff3adf60 2004-04-14 devnull return
246 ff3adf60 2004-04-14 devnull (name[n-4] == '.' &&
247 ff3adf60 2004-04-14 devnull name[n-3] == 'b' &&
248 ff3adf60 2004-04-14 devnull name[n-2] == 'z' &&
249 ff3adf60 2004-04-14 devnull name[n-1] == '2');
250 ff3adf60 2004-04-14 devnull }
251 ff3adf60 2004-04-14 devnull
252 ff3adf60 2004-04-14 devnull
253 ff3adf60 2004-04-14 devnull /*---------------------------------------------------*/
254 ff3adf60 2004-04-14 devnull /*--- ---*/
255 ff3adf60 2004-04-14 devnull /*---------------------------------------------------*/
256 ff3adf60 2004-04-14 devnull
257 ff3adf60 2004-04-14 devnull #define BLOCK_HEADER_HI 0x00003141UL
258 ff3adf60 2004-04-14 devnull #define BLOCK_HEADER_LO 0x59265359UL
259 ff3adf60 2004-04-14 devnull
260 ff3adf60 2004-04-14 devnull #define BLOCK_ENDMARK_HI 0x00001772UL
261 ff3adf60 2004-04-14 devnull #define BLOCK_ENDMARK_LO 0x45385090UL
262 ff3adf60 2004-04-14 devnull
263 ff3adf60 2004-04-14 devnull
264 ff3adf60 2004-04-14 devnull UInt32 bStart[20000];
265 ff3adf60 2004-04-14 devnull UInt32 bEnd[20000];
266 ff3adf60 2004-04-14 devnull UInt32 rbStart[20000];
267 ff3adf60 2004-04-14 devnull UInt32 rbEnd[20000];
268 ff3adf60 2004-04-14 devnull
269 ff3adf60 2004-04-14 devnull Int32 main ( Int32 argc, Char** argv )
270 ff3adf60 2004-04-14 devnull {
271 ff3adf60 2004-04-14 devnull FILE* inFile;
272 ff3adf60 2004-04-14 devnull FILE* outFile;
273 ff3adf60 2004-04-14 devnull BitStream* bsIn, *bsWr;
274 ff3adf60 2004-04-14 devnull Int32 currBlock, b, wrBlock;
275 ff3adf60 2004-04-14 devnull UInt32 bitsRead;
276 ff3adf60 2004-04-14 devnull Int32 rbCtr;
277 ff3adf60 2004-04-14 devnull
278 ff3adf60 2004-04-14 devnull
279 ff3adf60 2004-04-14 devnull UInt32 buffHi, buffLo, blockCRC;
280 ff3adf60 2004-04-14 devnull Char* p;
281 ff3adf60 2004-04-14 devnull
282 ff3adf60 2004-04-14 devnull strcpy ( progName, argv[0] );
283 ff3adf60 2004-04-14 devnull inFileName[0] = outFileName[0] = 0;
284 ff3adf60 2004-04-14 devnull
285 ff3adf60 2004-04-14 devnull fprintf ( stderr, "bzip2recover 1.0: extracts blocks from damaged .bz2 files.\n" );
286 ff3adf60 2004-04-14 devnull
287 ff3adf60 2004-04-14 devnull if (argc != 2) {
288 ff3adf60 2004-04-14 devnull fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
289 ff3adf60 2004-04-14 devnull progName, progName );
290 ff3adf60 2004-04-14 devnull exit(1);
291 ff3adf60 2004-04-14 devnull }
292 ff3adf60 2004-04-14 devnull
293 ff3adf60 2004-04-14 devnull strcpy ( inFileName, argv[1] );
294 ff3adf60 2004-04-14 devnull
295 ff3adf60 2004-04-14 devnull inFile = fopen ( inFileName, "rb" );
296 ff3adf60 2004-04-14 devnull if (inFile == NULL) {
297 ff3adf60 2004-04-14 devnull fprintf ( stderr, "%s: can't read `%s'\n", progName, inFileName );
298 ff3adf60 2004-04-14 devnull exit(1);
299 ff3adf60 2004-04-14 devnull }
300 ff3adf60 2004-04-14 devnull
301 ff3adf60 2004-04-14 devnull bsIn = bsOpenReadStream ( inFile );
302 ff3adf60 2004-04-14 devnull fprintf ( stderr, "%s: searching for block boundaries ...\n", progName );
303 ff3adf60 2004-04-14 devnull
304 ff3adf60 2004-04-14 devnull bitsRead = 0;
305 ff3adf60 2004-04-14 devnull buffHi = buffLo = 0;
306 ff3adf60 2004-04-14 devnull currBlock = 0;
307 ff3adf60 2004-04-14 devnull bStart[currBlock] = 0;
308 ff3adf60 2004-04-14 devnull
309 ff3adf60 2004-04-14 devnull rbCtr = 0;
310 ff3adf60 2004-04-14 devnull
311 ff3adf60 2004-04-14 devnull while (True) {
312 ff3adf60 2004-04-14 devnull b = bsGetBit ( bsIn );
313 ff3adf60 2004-04-14 devnull bitsRead++;
314 ff3adf60 2004-04-14 devnull if (b == 2) {
315 ff3adf60 2004-04-14 devnull if (bitsRead >= bStart[currBlock] &&
316 ff3adf60 2004-04-14 devnull (bitsRead - bStart[currBlock]) >= 40) {
317 ff3adf60 2004-04-14 devnull bEnd[currBlock] = bitsRead-1;
318 ff3adf60 2004-04-14 devnull if (currBlock > 0)
319 ff3adf60 2004-04-14 devnull fprintf ( stderr, " block %d runs from %d to %d (incomplete)\n",
320 ff3adf60 2004-04-14 devnull currBlock, bStart[currBlock], bEnd[currBlock] );
321 ff3adf60 2004-04-14 devnull } else
322 ff3adf60 2004-04-14 devnull currBlock--;
323 ff3adf60 2004-04-14 devnull break;
324 ff3adf60 2004-04-14 devnull }
325 ff3adf60 2004-04-14 devnull buffHi = (buffHi << 1) | (buffLo >> 31);
326 ff3adf60 2004-04-14 devnull buffLo = (buffLo << 1) | (b & 1);
327 ff3adf60 2004-04-14 devnull if ( ( (buffHi & 0x0000ffff) == BLOCK_HEADER_HI
328 ff3adf60 2004-04-14 devnull && buffLo == BLOCK_HEADER_LO)
329 ff3adf60 2004-04-14 devnull ||
330 ff3adf60 2004-04-14 devnull ( (buffHi & 0x0000ffff) == BLOCK_ENDMARK_HI
331 ff3adf60 2004-04-14 devnull && buffLo == BLOCK_ENDMARK_LO)
332 ff3adf60 2004-04-14 devnull ) {
333 ff3adf60 2004-04-14 devnull if (bitsRead > 49)
334 ff3adf60 2004-04-14 devnull bEnd[currBlock] = bitsRead-49; else
335 ff3adf60 2004-04-14 devnull bEnd[currBlock] = 0;
336 ff3adf60 2004-04-14 devnull if (currBlock > 0 &&
337 ff3adf60 2004-04-14 devnull (bEnd[currBlock] - bStart[currBlock]) >= 130) {
338 ff3adf60 2004-04-14 devnull fprintf ( stderr, " block %d runs from %d to %d\n",
339 ff3adf60 2004-04-14 devnull rbCtr+1, bStart[currBlock], bEnd[currBlock] );
340 ff3adf60 2004-04-14 devnull rbStart[rbCtr] = bStart[currBlock];
341 ff3adf60 2004-04-14 devnull rbEnd[rbCtr] = bEnd[currBlock];
342 ff3adf60 2004-04-14 devnull rbCtr++;
343 ff3adf60 2004-04-14 devnull }
344 ff3adf60 2004-04-14 devnull currBlock++;
345 ff3adf60 2004-04-14 devnull
346 ff3adf60 2004-04-14 devnull bStart[currBlock] = bitsRead;
347 ff3adf60 2004-04-14 devnull }
348 ff3adf60 2004-04-14 devnull }
349 ff3adf60 2004-04-14 devnull
350 ff3adf60 2004-04-14 devnull bsClose ( bsIn );
351 ff3adf60 2004-04-14 devnull
352 ff3adf60 2004-04-14 devnull /*-- identified blocks run from 1 to rbCtr inclusive. --*/
353 ff3adf60 2004-04-14 devnull
354 ff3adf60 2004-04-14 devnull if (rbCtr < 1) {
355 ff3adf60 2004-04-14 devnull fprintf ( stderr,
356 ff3adf60 2004-04-14 devnull "%s: sorry, I couldn't find any block boundaries.\n",
357 ff3adf60 2004-04-14 devnull progName );
358 ff3adf60 2004-04-14 devnull exit(1);
359 ff3adf60 2004-04-14 devnull };
360 ff3adf60 2004-04-14 devnull
361 ff3adf60 2004-04-14 devnull fprintf ( stderr, "%s: splitting into blocks\n", progName );
362 ff3adf60 2004-04-14 devnull
363 ff3adf60 2004-04-14 devnull inFile = fopen ( inFileName, "rb" );
364 ff3adf60 2004-04-14 devnull if (inFile == NULL) {
365 ff3adf60 2004-04-14 devnull fprintf ( stderr, "%s: can't open `%s'\n", progName, inFileName );
366 ff3adf60 2004-04-14 devnull exit(1);
367 ff3adf60 2004-04-14 devnull }
368 ff3adf60 2004-04-14 devnull bsIn = bsOpenReadStream ( inFile );
369 ff3adf60 2004-04-14 devnull
370 ff3adf60 2004-04-14 devnull /*-- placate gcc's dataflow analyser --*/
371 ff3adf60 2004-04-14 devnull blockCRC = 0; bsWr = 0;
372 ff3adf60 2004-04-14 devnull
373 ff3adf60 2004-04-14 devnull bitsRead = 0;
374 ff3adf60 2004-04-14 devnull outFile = NULL;
375 ff3adf60 2004-04-14 devnull wrBlock = 0;
376 ff3adf60 2004-04-14 devnull while (True) {
377 ff3adf60 2004-04-14 devnull b = bsGetBit(bsIn);
378 ff3adf60 2004-04-14 devnull if (b == 2) break;
379 ff3adf60 2004-04-14 devnull buffHi = (buffHi << 1) | (buffLo >> 31);
380 ff3adf60 2004-04-14 devnull buffLo = (buffLo << 1) | (b & 1);
381 ff3adf60 2004-04-14 devnull if (bitsRead == 47+rbStart[wrBlock])
382 ff3adf60 2004-04-14 devnull blockCRC = (buffHi << 16) | (buffLo >> 16);
383 ff3adf60 2004-04-14 devnull
384 ff3adf60 2004-04-14 devnull if (outFile != NULL && bitsRead >= rbStart[wrBlock]
385 ff3adf60 2004-04-14 devnull && bitsRead <= rbEnd[wrBlock]) {
386 ff3adf60 2004-04-14 devnull bsPutBit ( bsWr, b );
387 ff3adf60 2004-04-14 devnull }
388 ff3adf60 2004-04-14 devnull
389 ff3adf60 2004-04-14 devnull bitsRead++;
390 ff3adf60 2004-04-14 devnull
391 ff3adf60 2004-04-14 devnull if (bitsRead == rbEnd[wrBlock]+1) {
392 ff3adf60 2004-04-14 devnull if (outFile != NULL) {
393 ff3adf60 2004-04-14 devnull bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
394 ff3adf60 2004-04-14 devnull bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
395 ff3adf60 2004-04-14 devnull bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
396 ff3adf60 2004-04-14 devnull bsPutUInt32 ( bsWr, blockCRC );
397 ff3adf60 2004-04-14 devnull bsClose ( bsWr );
398 ff3adf60 2004-04-14 devnull }
399 ff3adf60 2004-04-14 devnull if (wrBlock >= rbCtr) break;
400 ff3adf60 2004-04-14 devnull wrBlock++;
401 ff3adf60 2004-04-14 devnull } else
402 ff3adf60 2004-04-14 devnull if (bitsRead == rbStart[wrBlock]) {
403 ff3adf60 2004-04-14 devnull outFileName[0] = 0;
404 ff3adf60 2004-04-14 devnull sprintf ( outFileName, "rec%4d", wrBlock+1 );
405 ff3adf60 2004-04-14 devnull for (p = outFileName; *p != 0; p++) if (*p == ' ') *p = '0';
406 ff3adf60 2004-04-14 devnull strcat ( outFileName, inFileName );
407 ff3adf60 2004-04-14 devnull if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );
408 ff3adf60 2004-04-14 devnull
409 ff3adf60 2004-04-14 devnull fprintf ( stderr, " writing block %d to `%s' ...\n",
410 ff3adf60 2004-04-14 devnull wrBlock+1, outFileName );
411 ff3adf60 2004-04-14 devnull
412 ff3adf60 2004-04-14 devnull outFile = fopen ( outFileName, "wb" );
413 ff3adf60 2004-04-14 devnull if (outFile == NULL) {
414 ff3adf60 2004-04-14 devnull fprintf ( stderr, "%s: can't write `%s'\n",
415 ff3adf60 2004-04-14 devnull progName, outFileName );
416 ff3adf60 2004-04-14 devnull exit(1);
417 ff3adf60 2004-04-14 devnull }
418 ff3adf60 2004-04-14 devnull bsWr = bsOpenWriteStream ( outFile );
419 ff3adf60 2004-04-14 devnull bsPutUChar ( bsWr, 'B' ); bsPutUChar ( bsWr, 'Z' );
420 ff3adf60 2004-04-14 devnull bsPutUChar ( bsWr, 'h' ); bsPutUChar ( bsWr, '9' );
421 ff3adf60 2004-04-14 devnull bsPutUChar ( bsWr, 0x31 ); bsPutUChar ( bsWr, 0x41 );
422 ff3adf60 2004-04-14 devnull bsPutUChar ( bsWr, 0x59 ); bsPutUChar ( bsWr, 0x26 );
423 ff3adf60 2004-04-14 devnull bsPutUChar ( bsWr, 0x53 ); bsPutUChar ( bsWr, 0x59 );
424 ff3adf60 2004-04-14 devnull }
425 ff3adf60 2004-04-14 devnull }
426 ff3adf60 2004-04-14 devnull
427 ff3adf60 2004-04-14 devnull fprintf ( stderr, "%s: finished\n", progName );
428 ff3adf60 2004-04-14 devnull return 0;
429 ff3adf60 2004-04-14 devnull }
430 ff3adf60 2004-04-14 devnull
431 ff3adf60 2004-04-14 devnull
432 ff3adf60 2004-04-14 devnull
433 ff3adf60 2004-04-14 devnull /*-----------------------------------------------------------*/
434 ff3adf60 2004-04-14 devnull /*--- end bzip2recover.c ---*/
435 ff3adf60 2004-04-14 devnull /*-----------------------------------------------------------*/