| /* | |
| 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 */ | |
| #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[]) { | |
| 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; | |
| } |