summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2011-03-08 12:55:32 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2011-03-08 12:55:32 +0100
commitfb0d17e832fc4a412e6ca291b6e71e25f1afb2ca (patch)
tree9f80357ffb7bb850818a8d6300b71e9940976cf2
parente42eb33113464796bbad3891ae05cbe1846c921e (diff)
downloadbarebox-fb0d17e832fc4a412e6ca291b6e71e25f1afb2ca.tar.gz
barebox-fb0d17e832fc4a412e6ca291b6e71e25f1afb2ca.tar.xz
Revert "lib/decompress_unlzo: use fill and full to read and write data"
As Eric reports this breaks unlzo support. This reverts commit a3463cc12877f6527624972c190a80ebb787a604.
-rw-r--r--lib/decompress_unlzo.c180
1 files changed, 88 insertions, 92 deletions
diff --git a/lib/decompress_unlzo.c b/lib/decompress_unlzo.c
index fc5c49f455..8f9cdcf27b 100644
--- a/lib/decompress_unlzo.c
+++ b/lib/decompress_unlzo.c
@@ -47,73 +47,98 @@ static const unsigned char lzop_magic[] = {
#define LZO_BLOCK_SIZE (256*1024l)
#define HEADER_HAS_FILTER 0x00000800L
-static inline int parse_header(u8 *input, u8 *skip)
+static inline int parse_header(int in_fd)
{
- int l;
- u8 *parse = input;
- u8 level = 0;
+ u8 l;
u16 version;
+ int ret;
+ unsigned char buf[256]; /* maximum filename length + 1 */
- /* read magic: 9 first bits */
+ /* read magic (9), library version (2), 'need to be extracted'
+ * version (2) and method (1)
+ */
+ ret = read(in_fd, buf, 9);
+ if (ret < 0)
+ return ret;
+
+ /* check magic */
for (l = 0; l < 9; l++) {
- if (*parse++ != lzop_magic[l])
- return 0;
+ if (buf[l] != lzop_magic[l])
+ return -EINVAL;
}
- /* get version (2bytes), skip library version (2),
- * 'need to be extracted' version (2) and
- * method (1) */
- version = get_unaligned_be16(parse);
- parse += 7;
+
+ ret = read(in_fd, buf, 4); /* version, lib_version */
+ if (ret < 0)
+ return ret;
+ version = get_unaligned_be16(buf);
+
+ if (version >= 0x0940) {
+ ret = read(in_fd, buf, 2); /* version to extract */
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = read(in_fd, buf, 1); /* method */
+ if (ret < 0)
+ return ret;
+
if (version >= 0x0940)
- level = *parse++;
- if (get_unaligned_be32(parse) & HEADER_HAS_FILTER)
- parse += 8; /* flags + filter info */
- else
- parse += 4; /* flags */
+ read(in_fd, buf, 1); /* level */
+
+ ret = read(in_fd, buf, 4); /* flags */
+ if (ret < 0)
+ return ret;
+
+ if (get_unaligned_be32(buf) & HEADER_HAS_FILTER) {
+ ret = read(in_fd, buf, 4); /* skip filter info */
+ if (ret < 0)
+ return ret;
+ }
/* skip mode and mtime_low */
- parse += 8;
- if (version >= 0x0940)
- parse += 4; /* skip mtime_high */
+ ret = read(in_fd, buf, 8);
+ if (ret < 0)
+ return ret;
- l = *parse++;
+ if (version >= 0x0940) {
+ ret = read(in_fd, buf, 4); /* skip mtime_high */
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = read(in_fd, &l, 1);
+ if (ret < 0)
+ return ret;
/* don't care about the file name, and skip checksum */
- parse += l + 4;
+ ret = read(in_fd, buf, l + 4);
+ if (ret < 0)
+ return ret;
- *skip = parse - input;
- return 1;
+ return 0;
}
-static int __unlzo(int *dest_len,
- int (*fill) (void *, unsigned int),
- int (*flush) (void *, unsigned int))
+int unlzo(int in_fd, int out_fd, int *dest_len)
{
- u8 skip = 0, r = 0;
+ u8 r = 0;
u32 src_len, dst_len;
size_t tmp;
- u8 *in_buf, *in_buf_save, *out_buf, *out_buf_save;
+ u8 *in_buf, *out_buf;
int obytes_processed = 0;
- int ret = -1;
-
- out_buf = xmalloc(LZO_BLOCK_SIZE);
- in_buf = xmalloc(lzo1x_worst_compress(LZO_BLOCK_SIZE));
+ unsigned char buf[8];
+ int ret;
- in_buf_save = in_buf;
- out_buf_save = out_buf;
-
- ret = fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE));
- if (ret < 0)
- goto exit_free;
-
- if (!parse_header(in_buf, &skip))
+ if (parse_header(in_fd))
return -EINVAL;
- in_buf += skip;
+ out_buf = xmalloc(LZO_BLOCK_SIZE);
+ in_buf = xmalloc(lzo1x_worst_compress(LZO_BLOCK_SIZE));
for (;;) {
/* read uncompressed block size */
- dst_len = get_unaligned_be32(in_buf);
- in_buf += 4;
+ ret = read(in_fd, buf, 4);
+ if (ret < 0)
+ goto exit_free;
+ dst_len = get_unaligned_be32(buf);
/* exit if last block */
if (dst_len == 0)
@@ -125,53 +150,43 @@ static int __unlzo(int *dest_len,
}
/* read compressed block size, and skip block checksum info */
- src_len = get_unaligned_be32(in_buf);
- in_buf += 8;
+ ret = read(in_fd, buf, 8);
+ if (ret < 0)
+ goto exit_free;
+
+ src_len = get_unaligned_be32(buf);
if (src_len <= 0 || src_len > dst_len) {
printf("file corrupted");
goto exit_free;
}
+ ret = read(in_fd, in_buf, src_len);
+ if (ret < 0)
+ goto exit_free;
/* decompress */
tmp = dst_len;
-
- /* When the input data is not compressed at all,
- * lzo1x_decompress_safe will fail, so call memcpy()
- * instead */
- if (unlikely(dst_len == src_len)) {
- if (src_len != dst_len) {
+ if (src_len < dst_len) {
+ r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
+ out_buf, &tmp);
+ if (r != LZO_E_OK || dst_len != tmp) {
printf("Compressed data violation");
goto exit_free;
}
- out_buf = in_buf;
+ ret = write(out_fd, out_buf, dst_len);
+ if (ret < 0)
+ goto exit_free;
} else {
- r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
- out_buf, &tmp);
-
- if (r != LZO_E_OK || dst_len != tmp) {
+ if (src_len != dst_len) {
printf("Compressed data violation");
goto exit_free;
}
+ ret = write(out_fd, in_buf, dst_len);
+ if (ret < 0)
+ goto exit_free;
}
- ret = flush(out_buf, dst_len);
- if (ret < 0)
- goto exit_free;
-
- out_buf = in_buf + src_len;
- in_buf = in_buf_save;
- ret = fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE));
- if (ret < 0)
- goto exit_free;
-
- if (ret == 0)
- in_buf = out_buf;
-
- out_buf = out_buf_save;
-
obytes_processed += dst_len;
-
}
exit_free:
@@ -182,22 +197,3 @@ exit_free:
return 0;
}
-static int in_fd;
-static int out_fd;
-
-static int unlzo_fill(void *buf, unsigned int len)
-{
- return read(in_fd, buf, len);
-}
-
-static int unlzo_flush(void *buf, unsigned int len)
-{
- return write(out_fd, buf, len);
-}
-
-int unlzo(int _in_fd, int _out_fd, int *dest_len)
-{
- in_fd = _in_fd;
- out_fd = _out_fd;
- return __unlzo(dest_len, unlzo_fill, unlzo_flush);
-}