diff options
Diffstat (limited to '')
-rw-r--r-- | extra/scanlzma/scanlzma.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/extra/scanlzma/scanlzma.c b/extra/scanlzma/scanlzma.c new file mode 100644 index 0000000..110f822 --- /dev/null +++ b/extra/scanlzma/scanlzma.c @@ -0,0 +1,88 @@ +/* + scanlzma, scan for lzma compressed data in stdin and echo it to stdout. + Copyright (C) 2006 Timo Lindfors + + 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. +*/ + +/* Usage example: + + $ wget http://www.wifi-shop.cz/Files/produkty/wa2204/wa2204av1.4.1.zip + $ unzip wa2204av1.4.1.zip + $ gcc scanlzma.c -o scanlzma -Wall + $ ./scanlzma 0 < WA2204-FW1.4.1/linux-1.4.bin | lzma -c -d | strings | grep -i "copyright" + UpdateDD version 2.5, Copyright (C) 2005 Philipp Benner. + Copyright (C) 2005 Philipp Benner. + Copyright (C) 2005 Philipp Benner. + mawk 1.3%s%s %s, Copyright (C) Michael D. Brennan + # Copyright (C) 1998, 1999, 2001 Henry Spencer. + ... + +*/ + + +/* LZMA compressed file format */ +/* --------------------------- */ +/* Offset Size Description */ +/* 0 1 Special LZMA properties for compressed data */ +/* 1 4 Dictionary size (little endian) */ +/* 5 8 Uncompressed size (little endian). -1 means unknown size */ +/* 13 Compressed data */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#define BUFSIZE 4096 + +int find_lzma_header(unsigned char *buf) { + return (buf[0] < 0xE1 + && buf[0] == 0x5d + && buf[4] < 0x20 + && (memcmp (buf + 10 , "\x00\x00\x00", 3) == 0 + || (memcmp (buf + 5, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8) == 0))); +} + +int main(int argc, char *argv[]) { + unsigned char buf[BUFSIZE]; + int ret, i, numlzma, blocks=0; + + if (argc != 2) { + printf("usage: %s numlzma < infile | lzma -c -d > outfile\n" + "where numlzma is index of lzma file to extract, starting from zero.\n", + argv[0]); + exit(1); + } + numlzma = atoi(argv[1]); + + for (;;) { + /* Read data. */ + ret = fread(buf, BUFSIZE, 1, stdin); + if (ret != 1) + break; + + /* Scan for signature. */ + for (i = 0; i<BUFSIZE-23; i++) { + if (find_lzma_header(buf+i) && numlzma-- <= 0) { + fwrite(buf+i, (BUFSIZE-i), 1, stdout); + for (;;) { + int ch; + ch = getchar(); + if (ch == EOF) + exit(0); + putchar(ch); + } + } + } + blocks++; + } + return 1; +} |