-diff -urN busybox.snapshot/archival/Config.in busybox-lzmacat/archival/Config.in
---- busybox.snapshot/archival/Config.in 2005-05-03 21:43:40.000000000 +0200
-+++ busybox-lzmacat/archival/Config.in 2005-05-03 21:46:02.000000000 +0200
-@@ -121,6 +121,12 @@
- gzip is used to compress files.
- It's probably the most widely used UNIX compression program.
-
-+config CONFIG_LZMACAT
-+ bool "lzmacat"
-+ default n
-+ help
-+ lzmacat decompresses a given file to STUOUT
+--- busybox-20050614.orig/archival/libunarchive/lzmacat.c 1970-01-01 01:00:00.000000000 +0100
++++ busybox-20050614/archival/lzmacat.c 2005-06-15 02:13:51.000000000 +0200
+@@ -0,0 +1,190 @@
++/*
++ lzmacat.c
+
- config CONFIG_RPM2CPIO
- bool "rpm2cpio"
- default n
-diff -urN busybox.snapshot/archival/Makefile.in busybox-lzmacat/archival/Makefile.in
---- busybox.snapshot/archival/Makefile.in 2005-05-03 21:43:40.000000000 +0200
-+++ busybox-lzmacat/archival/Makefile.in 2005-05-03 21:46:02.000000000 +0200
-@@ -32,6 +32,7 @@
- ARCHIVAL-$(CONFIG_DPKG_DEB) += dpkg_deb.o
- ARCHIVAL-$(CONFIG_GUNZIP) += gunzip.o
- ARCHIVAL-$(CONFIG_GZIP) += gzip.o
-+ARCHIVAL-$(CONFIG_LZMACAT) += lzmacat.o
- ARCHIVAL-$(CONFIG_RPM2CPIO) += rpm2cpio.o
- ARCHIVAL-$(CONFIG_RPM) += rpm.o
- ARCHIVAL-$(CONFIG_TAR) += tar.o
-diff -urN busybox.snapshot/archival/libunarchive/LzmaDecode.c busybox-lzmacat/archival/libunarchive/LzmaDecode.c
---- busybox.snapshot/archival/libunarchive/LzmaDecode.c 1970-01-01 01:00:00.000000000 +0100
-+++ busybox-lzmacat/archival/libunarchive/LzmaDecode.c 2005-05-03 21:46:02.000000000 +0200
-@@ -0,0 +1,663 @@
++ Copyright (C) 1999-2004 Igor Pavlov (2005-03-18))
++ examplecode from the LZMA DSK
++ Copyright (C) 2005 Christian Leber
++ changed to lzmcacat functionality
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++ e-mail: christian@leber.de
++*/
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++#include "busybox.h"
++#include "libunarchive/LzmaDecode.h"
++
++#define _LZMA_READ_BUFFER_SIZE 0x10000
++#define _LZMA_WRITE_BUFFER_SIZE 0x10000
++
++#ifdef _LZMA_IN_CB
++typedef struct _CBuffer
++{
++ ILzmaInCallback InCallback;
++ unsigned char *Buffer;
++ FILE *fil;
++} CBuffer;
++
++int LzmaReadCompressed(void *object, unsigned char **buffer, unsigned int *size)
++{
++ CBuffer *bo = (CBuffer *)object;
++ /* try to read _LZMA_READ_SIZE bytes */
++ *size = fread(bo->Buffer,1,
++ _LZMA_READ_BUFFER_SIZE,bo->fil);
++ *buffer = bo->Buffer;
++ return LZMA_RESULT_OK;
++}
++#endif
++
++int lzmacat_main(int argc, char **argv)
++{
++ FILE *inputHandle;
++ unsigned int outSize, outSizeProcessed, lzmaInternalSize;
++ void *lzmaInternalData;
++ unsigned char header[13];
++ unsigned char prop0;
++ unsigned char *out_buffer;
++ int i, res;
++ int lc, lp, pb;
++ CBuffer bo;
++ UInt32 nowPos;
++ unsigned char *dictionary;
++ UInt32 dictionarySize = 0;
++
++ if (argc != 2) {
++ fprintf(stderr, "lzmacat\n");
++ fprintf(stderr, "Usage: lzmaDec file.lzma\n");
++ return 1;
++ }
++
++ inputHandle = fopen(argv[1], "rb");
++ if (inputHandle == 0) {
++ fprintf(stderr, "Open input file errori\n");
++ return 1;
++ }
++
++ if (!fread(header, 1, sizeof(header),inputHandle)) {
++ fprintf(stderr, "Can't read header\n");
++ return 1;
++ }
++
++ outSize = 0;
++ for (i = 0; i < 4; i++) {
++ outSize += (unsigned int)(header[5+i]) << (i * 8);
++ }
++
++ if (outSize == 0xFFFFFFFF) {
++ fprintf(stderr, "stream version is not supported\n");
++ return 1;
++ }
++
++ for (i = 0; i < 4; i++) {
++ if (header[9+i] != 0) {
++ fprintf(stderr, "file too big (bigger than 4 GB)\n");
++ return 1;
++ }
++ }
++
++ prop0 = header[0];
++ if (prop0 >= (9*5*5)) {
++ fprintf(stderr, "Properties error\n");
++ return 1;
++ }
++ pb = prop0 / 45;
++ prop0 = prop0 % 45;
++ lp = prop0 / 9;
++ lc = prop0 % 9;
++ lzmaInternalSize =
++ (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb);
++ /* because we a reusing _LZMA_OUT_READ */
++ lzmaInternalSize += 100;
++
++ lzmaInternalData = malloc(lzmaInternalSize);
++ if (lzmaInternalData == 0) {
++ fprintf(stderr, "malloc error!\n");
++ return 1;
++ }
++
++ bo.InCallback.Read = LzmaReadCompressed;
++ bo.Buffer = malloc(_LZMA_READ_BUFFER_SIZE);
++ if (bo.Buffer == 0) {
++ fprintf(stderr, "malloc error!\n");
++ free(lzmaInternalData);
++ return 1;
++ }
++ bo.fil = inputHandle;
++
++ for (i = 0; i < 4; i++) {
++ dictionarySize += (UInt32)(header[1 + i]) << (i * 8);
++ }
++
++ if (dictionarySize == 0) {
++ dictionarySize = 1;
++ /* LZMA decoder can not work with dictionarySize = 0 */
++ }
++
++ dictionary = (unsigned char *)malloc(dictionarySize);
++ if (dictionary == 0) {
++ fprintf(stderr, "malloc error!\n");
++ free(lzmaInternalData);
++ free(bo.Buffer);
++ return 1;
++ }
++ res = LzmaDecoderInit((unsigned char *)lzmaInternalData,
++ lzmaInternalSize,
++ lc, lp, pb,
++ dictionary, dictionarySize,
++ &bo.InCallback);
++ if (res == 0) {
++ out_buffer = malloc (_LZMA_WRITE_BUFFER_SIZE);
++ if(out_buffer==0) {
++ fprintf(stderr, "malloc error!\n");
++ free(lzmaInternalData);
++ free(bo.Buffer);
++ free(dictionary);
++ return 1;
++ }
++ for (nowPos = 0; nowPos < outSize;) {
++ UInt32 blockSize = outSize - nowPos;
++ if (blockSize > _LZMA_WRITE_BUFFER_SIZE)
++ blockSize = _LZMA_WRITE_BUFFER_SIZE;
++ res = LzmaDecode((unsigned char *)lzmaInternalData,
++ out_buffer, blockSize, &outSizeProcessed);
++ if (res != 0)
++ break;
++ if (outSizeProcessed == 0) {
++ outSize = nowPos;
++ break;
++ }
++ nowPos += outSizeProcessed;
++ write(fileno(stdout),out_buffer,outSizeProcessed);
++ }
++ }
++ free(lzmaInternalData);
++ free(bo.Buffer);
++ free(dictionary);
++ free(out_buffer);
++ if (res != 0) {
++ fprintf(stderr, "\nerror = %d\n", res);
++ return 1;
++ }
++ return 0;
++}
++
+--- busybox-20050614.orig/archival/libunarchive/LzmaDecode.c 1970-01-01 01:00:00.000000000 +0100
++++ busybox-20050614/archival/libunarchive/LzmaDecode.c 2005-06-15 02:13:59.000000000 +0200
+@@ -0,0 +1,586 @@
+/*
+ LzmaDecode.c
-+ LZMA Decoder
++ LZMA Decoder (optimized for Speed version)
+
-+ LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25)
++ LZMA SDK 4.17 Copyright (c) 1999-2005 Igor Pavlov (2005-04-05)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
-+ Igor Pavlov, as the author of this code, expressly permits you to
-+ statically or dynamically link your code (or bind by name) to the
-+ interfaces of this file without subjecting your linked code to the
++ Igor Pavlov, as the author of this Code, expressly permits you to
++ statically or dynamically link your Code (or bind by name) to the
++ interfaces of this file without subjecting your linked Code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
-+typedef struct _CRangeDecoder
-+{
-+ Byte *Buffer;
-+ Byte *BufferLim;
-+ UInt32 Range;
-+ UInt32 Code;
-+ #ifdef _LZMA_IN_CB
-+ ILzmaInCallback *InCallback;
-+ int Result;
-+ #endif
-+ int ExtraBytes;
-+} CRangeDecoder;
-+
-+Byte RangeDecoderReadByte(CRangeDecoder *rd)
-+{
-+ if (rd->Buffer == rd->BufferLim)
-+ {
-+ #ifdef _LZMA_IN_CB
-+ UInt32 size;
-+ rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size);
-+ rd->BufferLim = rd->Buffer + size;
-+ if (size == 0)
-+ #endif
-+ {
-+ rd->ExtraBytes = 1;
-+ return 0xFF;
-+ }
-+ }
-+ return (*rd->Buffer++);
-+}
++#define RC_READ_BYTE (*Buffer++)
+
-+/* #define ReadByte (*rd->Buffer++) */
-+#define ReadByte (RangeDecoderReadByte(rd))
++#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
++ { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
-+void RangeDecoderInit(CRangeDecoder *rd,
-+ #ifdef _LZMA_IN_CB
-+ ILzmaInCallback *inCallback
-+ #else
-+ Byte *stream, UInt32 bufferSize
-+ #endif
-+ )
-+{
-+ int i;
-+ #ifdef _LZMA_IN_CB
-+ rd->InCallback = inCallback;
-+ rd->Buffer = rd->BufferLim = 0;
-+ #else
-+ rd->Buffer = stream;
-+ rd->BufferLim = stream + bufferSize;
-+ #endif
-+ rd->ExtraBytes = 0;
-+ rd->Code = 0;
-+ rd->Range = (0xFFFFFFFF);
-+ for(i = 0; i < 5; i++)
-+ rd->Code = (rd->Code << 8) | ReadByte;
-+}
++#ifdef _LZMA_IN_CB
+
-+#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;
-+#define RC_FLUSH_VAR rd->Range = range; rd->Code = code;
-+#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; }
++#define RC_TEST { if (Buffer == BufferLim) \
++ { UInt32 size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
++ BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
+
-+UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits)
-+{
-+ RC_INIT_VAR
-+ UInt32 result = 0;
-+ int i;
-+ for (i = numTotalBits; i > 0; i--)
-+ {
-+ /* UInt32 t; */
-+ range >>= 1;
++#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
+
-+ result <<= 1;
-+ if (code >= range)
-+ {
-+ code -= range;
-+ result |= 1;
-+ }
-+ /*
-+ t = (code - range) >> 31;
-+ t &= 1;
-+ code -= range & (t - 1);
-+ result = (result + result) | (1 - t);
-+ */
-+ RC_NORMALIZE
-+ }
-+ RC_FLUSH_VAR
-+ return result;
-+}
++#else
+
-+int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd)
-+{
-+ UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob;
-+ if (rd->Code < bound)
-+ {
-+ rd->Range = bound;
-+ *prob += (kBitModelTotal - *prob) >> kNumMoveBits;
-+ if (rd->Range < kTopValue)
-+ {
-+ rd->Code = (rd->Code << 8) | ReadByte;
-+ rd->Range <<= 8;
-+ }
-+ return 0;
-+ }
-+ else
-+ {
-+ rd->Range -= bound;
-+ rd->Code -= bound;
-+ *prob -= (*prob) >> kNumMoveBits;
-+ if (rd->Range < kTopValue)
-+ {
-+ rd->Code = (rd->Code << 8) | ReadByte;
-+ rd->Range <<= 8;
-+ }
-+ return 1;
-+ }
-+}
++#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
+
-+#define RC_GET_BIT2(prob, mi, A0, A1) \
-+ UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
-+ if (code < bound) \
-+ { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
-+ else \
-+ { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
-+ RC_NORMALIZE
++#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
++
++#endif
+
-+#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)
++#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
-+int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
-+{
-+ int mi = 1;
-+ int i;
-+ #ifdef _LZMA_LOC_OPT
-+ RC_INIT_VAR
-+ #endif
-+ for(i = numLevels; i > 0; i--)
-+ {
-+ #ifdef _LZMA_LOC_OPT
-+ CProb *prob = probs + mi;
-+ RC_GET_BIT(prob, mi)
-+ #else
-+ mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd);
-+ #endif
-+ }
-+ #ifdef _LZMA_LOC_OPT
-+ RC_FLUSH_VAR
-+ #endif
-+ return mi - (1 << numLevels);
-+}
++#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
++#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
++#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
-+int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
-+{
-+ int mi = 1;
-+ int i;
-+ int symbol = 0;
-+ #ifdef _LZMA_LOC_OPT
-+ RC_INIT_VAR
-+ #endif
-+ for(i = 0; i < numLevels; i++)
-+ {
-+ #ifdef _LZMA_LOC_OPT
-+ CProb *prob = probs + mi;
-+ RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i))
-+ #else
-+ int bit = RangeDecoderBitDecode(probs + mi, rd);
-+ mi = mi + mi + bit;
-+ symbol |= (bit << i);
-+ #endif
-+ }
-+ #ifdef _LZMA_LOC_OPT
-+ RC_FLUSH_VAR
-+ #endif
-+ return symbol;
-+}
++#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
++ { UpdateBit0(p); mi <<= 1; A0; } else \
++ { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
++
++#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
+
-+Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd)
-+{
-+ int symbol = 1;
-+ #ifdef _LZMA_LOC_OPT
-+ RC_INIT_VAR
-+ #endif
-+ do
-+ {
-+ #ifdef _LZMA_LOC_OPT
-+ CProb *prob = probs + symbol;
-+ RC_GET_BIT(prob, symbol)
-+ #else
-+ symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
-+ #endif
-+ }
-+ while (symbol < 0x100);
-+ #ifdef _LZMA_LOC_OPT
-+ RC_FLUSH_VAR
-+ #endif
-+ return symbol;
-+}
++#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
++ { int i = numLevels; res = 1; \
++ do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
++ res -= (1 << numLevels); }
+
-+Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte)
-+{
-+ int symbol = 1;
-+ #ifdef _LZMA_LOC_OPT
-+ RC_INIT_VAR
-+ #endif
-+ do
-+ {
-+ int bit;
-+ int matchBit = (matchByte >> 7) & 1;
-+ matchByte <<= 1;
-+ #ifdef _LZMA_LOC_OPT
-+ {
-+ CProb *prob = probs + ((1 + matchBit) << 8) + symbol;
-+ RC_GET_BIT2(prob, symbol, bit = 0, bit = 1)
-+ }
-+ #else
-+ bit = RangeDecoderBitDecode(probs + ((1 + matchBit) << 8) + symbol, rd);
-+ symbol = (symbol << 1) | bit;
-+ #endif
-+ if (matchBit != bit)
-+ {
-+ while (symbol < 0x100)
-+ {
-+ #ifdef _LZMA_LOC_OPT
-+ CProb *prob = probs + symbol;
-+ RC_GET_BIT(prob, symbol)
-+ #else
-+ symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
-+ #endif
-+ }
-+ break;
-+ }
-+ }
-+ while (symbol < 0x100);
-+ #ifdef _LZMA_LOC_OPT
-+ RC_FLUSH_VAR
-+ #endif
-+ return symbol;
-+}
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
-+int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState)
-+{
-+ if(RangeDecoderBitDecode(p + LenChoice, rd) == 0)
-+ return RangeDecoderBitTreeDecode(p + LenLow +
-+ (posState << kLenNumLowBits), kLenNumLowBits, rd);
-+ if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0)
-+ return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid +
-+ (posState << kLenNumMidBits), kLenNumMidBits, rd);
-+ return kLenNumLowSymbols + kLenNumMidSymbols +
-+ RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd);
-+}
+
+#define kNumStates 12
++#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+
+typedef struct _LzmaVarState
+{
-+ CRangeDecoder RangeDecoder;
++ Byte *Buffer;
++ Byte *BufferLim;
++ UInt32 Range;
++ UInt32 Code;
++ #ifdef _LZMA_IN_CB
++ ILzmaInCallback *InCallback;
++ #endif
+ Byte *Dictionary;
+ UInt32 DictionarySize;
+ UInt32 DictionaryPos;
+ int lp;
+ int pb;
+ int State;
-+ int PreviousIsMatch;
+ int RemainLen;
++ Byte TempDictionary[4];
+} LzmaVarState;
+
+int LzmaDecoderInit(
+ int lc, int lp, int pb,
+ unsigned char *dictionary, UInt32 dictionarySize,
+ #ifdef _LZMA_IN_CB
-+ ILzmaInCallback *inCallback
++ ILzmaInCallback *InCallback
+ #else
+ unsigned char *inStream, UInt32 inSize
+ #endif
+ )
+{
++ Byte *Buffer;
++ Byte *BufferLim;
++ UInt32 Range;
++ UInt32 Code;
+ LzmaVarState *vs = (LzmaVarState *)buffer;
+ CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
+ vs->lp = lp;
+ vs->pb = pb;
+ vs->State = 0;
-+ vs->PreviousIsMatch = 0;
+ vs->RemainLen = 0;
+ dictionary[dictionarySize - 1] = 0;
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
-+ RangeDecoderInit(&vs->RangeDecoder,
-+ #ifdef _LZMA_IN_CB
-+ inCallback
-+ #else
-+ inStream, inSize
-+ #endif
-+ );
++
++ #ifdef _LZMA_IN_CB
++ RC_INIT;
++ #else
++ RC_INIT(inStream, inSize);
++ #endif
++ vs->Buffer = Buffer;
++ vs->BufferLim = BufferLim;
++ vs->Range = Range;
++ vs->Code = Code;
++ #ifdef _LZMA_IN_CB
++ vs->InCallback = InCallback;
++ #endif
++
+ return LZMA_RESULT_OK;
+}
+
+ UInt32 *outSizeProcessed)
+{
+ LzmaVarState *vs = (LzmaVarState *)buffer;
++ Byte *Buffer = vs->Buffer;
++ Byte *BufferLim = vs->BufferLim;
++ UInt32 Range = vs->Range;
++ UInt32 Code = vs->Code;
++ #ifdef _LZMA_IN_CB
++ ILzmaInCallback *InCallback = vs->InCallback;
++ #endif
+ CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
-+ CRangeDecoder rd = vs->RangeDecoder;
+ int state = vs->State;
-+ int previousIsMatch = vs->PreviousIsMatch;
+ Byte previousByte;
+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+ UInt32 nowPos = 0;
+ UInt32 dictionarySize = vs->DictionarySize;
+ UInt32 dictionaryPos = vs->DictionaryPos;
+
++ Byte tempDictionary[4];
++ if (dictionarySize == 0)
++ {
++ dictionary = tempDictionary;
++ dictionarySize = 1;
++ tempDictionary[0] = vs->TempDictionary[0];
++ }
++
+ if (len == -1)
+ {
+ *outSizeProcessed = 0;
+ return LZMA_RESULT_OK;
+ }
+
-+ while(len > 0 && nowPos < outSize)
++ while(len != 0 && nowPos < outSize)
+ {
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ Byte *buffer, UInt32 bufferSize,
+ int lc, int lp, int pb,
+ #ifdef _LZMA_IN_CB
-+ ILzmaInCallback *inCallback,
++ ILzmaInCallback *InCallback,
+ #else
+ unsigned char *inStream, UInt32 inSize,
+ #endif
+{
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
+ CProb *p = (CProb *)buffer;
-+ CRangeDecoder rd;
++
+ UInt32 i;
+ int state = 0;
-+ int previousIsMatch = 0;
+ Byte previousByte = 0;
+ UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+ UInt32 nowPos = 0;
+ UInt32 posStateMask = (1 << pb) - 1;
+ UInt32 literalPosMask = (1 << lp) - 1;
+ int len = 0;
++
++ Byte *Buffer;
++ Byte *BufferLim;
++ UInt32 Range;
++ UInt32 Code;
++
+ if (bufferSize < numProbs * sizeof(CProb))
+ return LZMA_RESULT_NOT_ENOUGH_MEM;
+ for (i = 0; i < numProbs; i++)
-+ p[i] = kBitModelTotal >> 1;
-+ RangeDecoderInit(&rd,
-+ #ifdef _LZMA_IN_CB
-+ inCallback
-+ #else
-+ inStream, inSize
-+ #endif
-+ );
++ p[i] = kBitModelTotal >> 1;
++
++
++ #ifdef _LZMA_IN_CB
++ RC_INIT;
++ #else
++ RC_INIT(inStream, inSize);
++ #endif
+#endif
+
+ *outSizeProcessed = 0;
+ while(nowPos < outSize)
+ {
++ CProb *prob;
++ UInt32 bound;
+ int posState = (int)(
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ #endif
+ )
+ & posStateMask);
-+ #ifdef _LZMA_IN_CB
-+ if (rd.Result != LZMA_RESULT_OK)
-+ return rd.Result;
-+ #endif
-+ if (rd.ExtraBytes != 0)
-+ return LZMA_RESULT_DATA_ERROR;
-+ if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0)
++
++ prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
++ IfBit0(prob)
+ {
-+ CProb *probs = p + Literal + (LZMA_LIT_SIZE *
++ int symbol = 1;
++ UpdateBit0(prob)
++ prob = p + Literal + (LZMA_LIT_SIZE *
+ (((
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ )
+ & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
-+ if (state < 4) state = 0;
-+ else if (state < 10) state -= 3;
-+ else state -= 6;
-+ if (previousIsMatch)
++ if (state >= kNumLitStates)
+ {
-+ Byte matchByte;
++ int matchByte;
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ #else
+ matchByte = outStream[nowPos - rep0];
+ #endif
-+ previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte);
-+ previousIsMatch = 0;
++ do
++ {
++ int bit;
++ CProb *probLit;
++ matchByte <<= 1;
++ bit = (matchByte & 0x100);
++ probLit = prob + 0x100 + bit + symbol;
++ RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
++ }
++ while (symbol < 0x100);
+ }
-+ else
-+ previousByte = LzmaLiteralDecode(probs, &rd);
++ while (symbol < 0x100)
++ {
++ CProb *probLit = prob + symbol;
++ RC_GET_BIT(probLit, symbol)
++ }
++ previousByte = (Byte)symbol;
++
+ outStream[nowPos++] = previousByte;
+ #ifdef _LZMA_OUT_READ
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #endif
++ if (state < 4) state = 0;
++ else if (state < 10) state -= 3;
++ else state -= 6;
+ }
+ else
+ {
-+ previousIsMatch = 1;
-+ if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1)
++ UpdateBit1(prob);
++ prob = p + IsRep + state;
++ IfBit0(prob)
+ {
-+ if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0)
++ UpdateBit0(prob);
++ rep3 = rep2;
++ rep2 = rep1;
++ rep1 = rep0;
++ state = state < kNumLitStates ? 0 : 3;
++ prob = p + LenCoder;
++ }
++ else
++ {
++ UpdateBit1(prob);
++ prob = p + IsRepG0 + state;
++ IfBit0(prob)
+ {
-+ if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0)
++ UpdateBit0(prob);
++ prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
++ IfBit0(prob)
+ {
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos;
+ #endif
-+ if (
-+ (nowPos
++ UpdateBit0(prob);
++ if (nowPos
+ #ifdef _LZMA_OUT_READ
+ + globalPos
+ #endif
-+ )
-+ == 0)
++ == 0)
+ return LZMA_RESULT_DATA_ERROR;
-+ state = state < 7 ? 9 : 11;
++ state = state < kNumLitStates ? 9 : 11;
+ #ifdef _LZMA_OUT_READ
+ pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ outStream[nowPos++] = previousByte;
+ continue;
+ }
++ else
++ {
++ UpdateBit1(prob);
++ }
+ }
+ else
+ {
+ UInt32 distance;
-+ if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0)
++ UpdateBit1(prob);
++ prob = p + IsRepG1 + state;
++ IfBit0(prob)
++ {
++ UpdateBit0(prob);
+ distance = rep1;
++ }
+ else
+ {
-+ if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0)
++ UpdateBit1(prob);
++ prob = p + IsRepG2 + state;
++ IfBit0(prob)
++ {
++ UpdateBit0(prob);
+ distance = rep2;
++ }
+ else
+ {
++ UpdateBit1(prob);
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
-+ len = LzmaLenDecode(p + RepLenCoder, &rd, posState);
-+ state = state < 7 ? 8 : 11;
++ state = state < kNumLitStates ? 8 : 11;
++ prob = p + RepLenCoder;
+ }
-+ else
++ {
++ int numBits, offset;
++ CProb *probLen = prob + LenChoice;
++ IfBit0(probLen)
++ {
++ UpdateBit0(probLen);
++ probLen = prob + LenLow + (posState << kLenNumLowBits);
++ offset = 0;
++ numBits = kLenNumLowBits;
++ }
++ else
++ {
++ UpdateBit1(probLen);
++ probLen = prob + LenChoice2;
++ IfBit0(probLen)
++ {
++ UpdateBit0(probLen);
++ probLen = prob + LenMid + (posState << kLenNumMidBits);
++ offset = kLenNumLowSymbols;
++ numBits = kLenNumMidBits;
++ }
++ else
++ {
++ UpdateBit1(probLen);
++ probLen = prob + LenHigh;
++ offset = kLenNumLowSymbols + kLenNumMidSymbols;
++ numBits = kLenNumHighBits;
++ }
++ }
++ RangeDecoderBitTreeDecode(probLen, numBits, len);
++ len += offset;
++ }
++
++ if (state < 4)
+ {
+ int posSlot;
-+ rep3 = rep2;
-+ rep2 = rep1;
-+ rep1 = rep0;
-+ state = state < 7 ? 7 : 10;
-+ len = LzmaLenDecode(p + LenCoder, &rd, posState);
-+ posSlot = RangeDecoderBitTreeDecode(p + PosSlot +
++ state += kNumLitStates;
++ prob = p + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
-+ kNumPosSlotBits), kNumPosSlotBits, &rd);
++ kNumPosSlotBits);
++ RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = ((posSlot >> 1) - 1);
-+ rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits);
++ rep0 = (2 | ((UInt32)posSlot & 1));
+ if (posSlot < kEndPosModelIndex)
+ {
-+ rep0 += RangeDecoderReverseBitTreeDecode(
-+ p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd);
++ rep0 <<= numDirectBits;
++ prob = p + SpecPos + rep0 - posSlot - 1;
+ }
+ else
+ {
-+ rep0 += RangeDecoderDecodeDirectBits(&rd,
-+ numDirectBits - kNumAlignBits) << kNumAlignBits;
-+ rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd);
++ numDirectBits -= kNumAlignBits;
++ do
++ {
++ RC_NORMALIZE
++ Range >>= 1;
++ rep0 <<= 1;
++ if (Code >= Range)
++ {
++ Code -= Range;
++ rep0 |= 1;
++ }
++ }
++ while (--numDirectBits != 0);
++ prob = p + Align;
++ rep0 <<= kNumAlignBits;
++ numDirectBits = kNumAlignBits;
++ }
++ {
++ int i = 1;
++ int mi = 1;
++ do
++ {
++ CProb *prob3 = prob + mi;
++ RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
++ i <<= 1;
++ }
++ while(--numDirectBits != 0);
+ }
+ }
+ else
+ rep0 = posSlot;
-+ rep0++;
-+ }
-+ if (rep0 == (UInt32)(0))
-+ {
-+ /* it's for stream version */
-+ len = -1;
-+ break;
++ if (++rep0 == (UInt32)(0))
++ {
++ /* it's for stream version */
++ len = -1;
++ break;
++ }
+ }
++
++ len += kMatchMinLen;
+ if (rep0 > nowPos
+ #ifdef _LZMA_OUT_READ
-+ + globalPos
++ + globalPos || rep0 > dictionarySize
+ #endif
-+ )
-+ {
++ )
+ return LZMA_RESULT_DATA_ERROR;
-+ }
-+ len += kMatchMinLen;
+ do
+ {
+ #ifdef _LZMA_OUT_READ
+ #else
+ previousByte = outStream[nowPos - rep0];
+ #endif
-+ outStream[nowPos++] = previousByte;
+ len--;
++ outStream[nowPos++] = previousByte;
+ }
-+ while(len > 0 && nowPos < outSize);
++ while(len != 0 && nowPos < outSize);
+ }
+ }
++ RC_NORMALIZE;
+
+ #ifdef _LZMA_OUT_READ
-+ vs->RangeDecoder = rd;
++ vs->Buffer = Buffer;
++ vs->BufferLim = BufferLim;
++ vs->Range = Range;
++ vs->Code = Code;
+ vs->DictionaryPos = dictionaryPos;
+ vs->GlobalPos = globalPos + nowPos;
+ vs->Reps[0] = rep0;
+ vs->Reps[2] = rep2;
+ vs->Reps[3] = rep3;
+ vs->State = state;
-+ vs->PreviousIsMatch = previousIsMatch;
+ vs->RemainLen = len;
++ vs->TempDictionary[0] = tempDictionary[0];
+ #endif
+
+ *outSizeProcessed = nowPos;
+ return LZMA_RESULT_OK;
+}
-diff -urN busybox.snapshot/archival/libunarchive/LzmaDecode.h busybox-lzmacat/archival/libunarchive/LzmaDecode.h
---- busybox.snapshot/archival/libunarchive/LzmaDecode.h 1970-01-01 01:00:00.000000000 +0100
-+++ busybox-lzmacat/archival/libunarchive/LzmaDecode.h 2005-05-03 21:46:02.000000000 +0200
+--- busybox-20050614.orig/archival/libunarchive/LzmaDecode.h 1970-01-01 01:00:00.000000000 +0100
++++ busybox-20050614/archival/libunarchive/LzmaDecode.h 2005-06-15 02:14:03.000000000 +0200
@@ -0,0 +1,100 @@
+/*
+ LzmaDecode.h
+ LZMA Decoder interface
+
-+ LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25)
++ LZMA SDK 4.16 Copyright (c) 1999-2005 Igor Pavlov (2005-03-18)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+#ifndef __LZMADECODE_H
+#define __LZMADECODE_H
+
-+/* #define _LZMA_IN_CB */
++#define _LZMA_IN_CB
+/* Use callback for input data */
+
-+/* #define _LZMA_OUT_READ */
++#define _LZMA_OUT_READ
+/* Use read function for output data */
+
-+/* #define _LZMA_PROB32 */
++#define _LZMA_PROB32
+/* It can increase speed on some 32-bit CPUs,
+ but memory usage will be doubled in that case */
+
-+/* #define _LZMA_LOC_OPT */
++#define _LZMA_LOC_OPT
+/* Enable local speed optimizations inside code */
+
+#ifndef UInt32
+ UInt32 *outSizeProcessed);
+
+#endif
-diff -urN busybox.snapshot/archival/libunarchive/Makefile.in busybox-lzmacat/archival/libunarchive/Makefile.in
---- busybox.snapshot/archival/libunarchive/Makefile.in 2005-05-03 21:43:40.000000000 +0200
-+++ busybox-lzmacat/archival/libunarchive/Makefile.in 2005-05-03 21:46:02.000000000 +0200
+--- busybox-20050614.orig/archival/Config.in 2005-06-14 08:20:08.000000000 +0200
++++ busybox-20050614/archival/Config.in 2005-06-15 01:31:10.000000000 +0200
+@@ -121,6 +121,12 @@
+ gzip is used to compress files.
+ It's probably the most widely used UNIX compression program.
+
++config CONFIG_LZMACAT
++ bool "lzmacat"
++ default n
++ help
++ lzmacat decompresses a given file to STUOUT
++
+ config CONFIG_RPM2CPIO
+ bool "rpm2cpio"
+ default n
+--- busybox-20050614.orig/archival/Makefile.in 2005-06-14 08:20:08.000000000 +0200
++++ busybox-20050614/archival/Makefile.in 2005-06-15 01:31:10.000000000 +0200
+@@ -32,6 +32,7 @@
+ ARCHIVAL-$(CONFIG_DPKG_DEB) += dpkg_deb.o
+ ARCHIVAL-$(CONFIG_GUNZIP) += gunzip.o
+ ARCHIVAL-$(CONFIG_GZIP) += gzip.o
++ARCHIVAL-$(CONFIG_LZMACAT) += lzmacat.o
+ ARCHIVAL-$(CONFIG_RPM2CPIO) += rpm2cpio.o
+ ARCHIVAL-$(CONFIG_RPM) += rpm.o
+ ARCHIVAL-$(CONFIG_TAR) += tar.o
+
+--- busybox-20050614.orig/archival/libunarchive/Makefile.in 2005-06-14 08:20:08.000000000 +0200
++++ busybox-20050614/archival/libunarchive/Makefile.in 2005-06-15 01:31:10.000000000 +0200
@@ -64,6 +64,7 @@
LIBUNARCHIVE-$(CONFIG_FEATURE_DEB_TAR_GZ) += $(GUNZIP_FILES) get_header_tar_gz.o
LIBUNARCHIVE-$(CONFIG_FEATURE_DEB_TAR_BZ2) += decompress_bunzip2.o get_header_tar_bz2.o
LIBUNARCHIVE-$(CONFIG_FEATURE_GUNZIP_UNCOMPRESS) += decompress_uncompress.o
LIBUNARCHIVE-$(CONFIG_RPM2CPIO) += $(GUNZIP_FILES) get_header_cpio.o
LIBUNARCHIVE-$(CONFIG_RPM) += $(GUNZIP_FILES) get_header_cpio.o
-diff -urN busybox.snapshot/archival/lzmacat.c busybox-lzmacat/archival/lzmacat.c
---- busybox.snapshot/archival/lzmacat.c 1970-01-01 01:00:00.000000000 +0100
-+++ busybox-lzmacat/archival/lzmacat.c 2005-05-03 22:45:20.000000000 +0200
-@@ -0,0 +1,130 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * Modified for busybox by Thomas Lundquist <thomasez@zelow.no>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ */
-+/*
-+ Ming-Ching Tiew mctiew@yahoo.com
-+ 9th March 2005
-+ GPL source
-+ */
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <getopt.h>
-+#include "busybox.h"
-+#include "libunarchive/LzmaDecode.h"
-+
-+int lzmacat(char *filename);
-+
-+int lzmacat_main(int argc, char **argv)
-+{
-+ char *filename;
-+ unsigned long opt;
-+
-+ opt = bb_getopt_ulflags(argc, argv, "");
-+
-+ filename = argv[optind];
-+
-+ if (!filename) {
-+ bb_error_msg_and_die("Need a filename, lzmacat -h for help.");
-+ }
-+
-+ lzmacat(filename);
-+
-+
-+ /* The lzmacat function is simple enough to error and die
-+ all by itself, so, if we are here, it all went well */
-+ return 0;
-+}
-+
-+int lzmacat(char *filename)
-+{
-+ FILE *fp;
-+ unsigned long size;
-+ unsigned int outsize;
-+ unsigned char prop0;
-+ unsigned int dictsize;
-+ unsigned int zero;
-+ int result, lzma_workspace_size;
-+ char *s, *d, *lzma_workspace;
-+ int lp, lc, pb;
-+
-+ fp = bb_xfopen(filename, "r");
-+
-+ if (fp == NULL) {
-+ bb_error_msg_and_die("No such file\n");
-+ }
-+ // to get the file size
-+ fseek(fp, 0L, SEEK_END);
-+
-+ // compressed data is file size - 13
-+ size = ftell(fp) - 13;
-+
-+ // allocate just enough memory
-+ s = (char *) malloc(size);
-+
-+ // move back up
-+ fseek(fp, 0L, SEEK_SET);
-+
-+ // read the property value
-+ fread(&prop0, 1, 1, fp);
-+
-+ if (prop0 > 5 * 9 * 5) {
-+ bb_error_msg_and_die("invalid file format!\n");
-+ }
-+ // read the dictionary size
-+ fread(&dictsize, 4, 1, fp);
-+
-+ // read the original file size
-+ fread(&outsize, 4, 1, fp);
-+ if (outsize < size) {
-+ bb_error_msg_and_die("invalid file size!\n");
-+ }
-+ // ignore file size greater than 4 bytes
-+ fread(&zero, 4, 1, fp);
-+ if (zero != 0) {
-+ bb_error_msg_and_die("invalid file or too big!\n");
-+ }
-+ // read the whole file
-+ fread(s, size, 1, fp);
-+ fclose(fp);
-+
-+ d = (char *) malloc(outsize);
-+
-+ // calculate the properties
-+ for (pb = 0; prop0 >= (9 * 5); pb++, prop0 -= (9 * 5));
-+ for (lp = 0; prop0 >= 9; lp++, prop0 -= 9);
-+ lc = prop0;
-+ lzma_workspace_size =
-+ (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb);
-+ lzma_workspace = (char *) malloc(lzma_workspace_size);
-+
-+ result = LzmaDecode(lzma_workspace, lzma_workspace_size, lc, lp, pb,
-+ s, size, d, outsize, &outsize);
-+
-+ if (result != 0) {
-+ bb_perror_msg_and_die("decode error=%d\n", result);
-+ }
-+
-+ fwrite(d, outsize, 1, stdout);
-+ free(s);
-+ free(d);
-+ free(lzma_workspace);
-+
-+ /* All ok */
-+ return 0;
-+
-+}
-diff -urN busybox.snapshot/include/applets.h busybox-lzmacat/include/applets.h
---- busybox.snapshot/include/applets.h 2005-05-03 21:43:58.000000000 +0200
-+++ busybox-lzmacat/include/applets.h 2005-05-03 21:46:02.000000000 +0200
-@@ -368,6 +368,9 @@
+
+--- busybox-20050614.orig/include/applets.h 2005-06-14 08:20:18.000000000 +0200
++++ busybox-20050614/include/applets.h 2005-06-15 01:31:11.000000000 +0200
+@@ -383,6 +383,9 @@
#ifdef CONFIG_LSMOD
APPLET(lsmod, lsmod_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
#endif
#ifdef CONFIG_MAKEDEVS
APPLET(makedevs, makedevs_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
#endif
-diff -urN busybox.snapshot/include/usage.h busybox-lzmacat/include/usage.h
---- busybox.snapshot/include/usage.h 2005-05-03 21:43:58.000000000 +0200
-+++ busybox-lzmacat/include/usage.h 2005-05-03 21:46:02.000000000 +0200
-@@ -1595,6 +1595,11 @@
+--- busybox-20050614.orig/include/usage.h 2005-06-14 08:20:18.000000000 +0200
++++ busybox-20050614/include/usage.h 2005-06-15 01:33:02.000000000 +0200
+@@ -1622,6 +1622,11 @@
#define lsmod_full_usage \
"List the currently loaded kernel modules."
+#define lzmacat_trivial_usage \
-+ "[FILE]"
++ "[FILE]"
+#define lzmacat_full_usage \
-+ "Decompresses [FILE] to STDOUT."
++ "Decompresses [FILE] to STDOUT."
+
#define makedevs_trivial_usage \
"NAME TYPE MAJOR MINOR FIRST LAST [s]"