bzip2recover.c revision cfb3b2780016b4e9ab4849e22d9c3acbaf535248
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 10cfb3b2780016b4e9ab4849e22d9c3acbaf535248The Android Open Source Project bzip2/libbzip2 version 1.0.5 of 10 December 2007 11cfb3b2780016b4e9ab4849e22d9c3acbaf535248The Android Open Source Project Copyright (C) 1996-2007 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, 316cfb3b2780016b4e9ab4849e22d9c3acbaf535248The Android Open Source Project "bzip2recover 1.0.5: 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