aboutsummaryrefslogtreecommitdiff
path: root/extra/scanlzma/scanlzma.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--extra/scanlzma/scanlzma.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/extra/scanlzma/scanlzma.c b/extra/scanlzma/scanlzma.c
new file mode 100644
index 00000000..3612f9df
--- /dev/null
+++ b/extra/scanlzma/scanlzma.c
@@ -0,0 +1,85 @@
+/*
+ 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;
+}