(root)/
xz-5.4.5/
extra/
scanlzma/
scanlzma.c
       1  /*
       2      scanlzma, scan for lzma compressed data in stdin and echo it to stdout.
       3      Copyright (C) 2006 Timo Lindfors
       4  
       5      This program is free software; you can redistribute it and/or modify
       6      it under the terms of the GNU General Public License as published by
       7      the Free Software Foundation; either version 2 of the License, or
       8      (at your option) any later version.
       9  
      10      This program is distributed in the hope that it will be useful,
      11      but WITHOUT ANY WARRANTY; without even the implied warranty of
      12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13      GNU General Public License for more details.
      14  */
      15  
      16  /* Usage example:
      17  
      18     $ wget http://www.wifi-shop.cz/Files/produkty/wa2204/wa2204av1.4.1.zip
      19     $ unzip wa2204av1.4.1.zip
      20     $ gcc scanlzma.c -o scanlzma -Wall
      21     $ ./scanlzma 0 < WA2204-FW1.4.1/linux-1.4.bin | lzma -c -d | strings | grep -i "copyright"
      22     UpdateDD version 2.5, Copyright (C) 2005 Philipp Benner.
      23     Copyright (C) 2005 Philipp Benner.
      24     Copyright (C) 2005 Philipp Benner.
      25     mawk 1.3%s%s %s, Copyright (C) Michael D. Brennan
      26     # Copyright (C) 1998, 1999, 2001  Henry Spencer.
      27     ...
      28  
      29  */
      30  
      31  
      32  /* LZMA compressed file format */
      33  /* --------------------------- */
      34  /* Offset Size Description */
      35  /*   0     1   Special LZMA properties for compressed data */
      36  /*   1     4   Dictionary size (little endian) */
      37  /*   5     8   Uncompressed size (little endian). -1 means unknown size */
      38  /*  13         Compressed data */
      39  
      40  #include <stdlib.h>
      41  #include <stdio.h>
      42  #include <string.h>
      43  
      44  #define BUFSIZE 4096
      45  
      46  int find_lzma_header(unsigned char *buf) {
      47  	return (buf[0] < 0xE1
      48  		&& buf[0] == 0x5d
      49  		&& buf[4] < 0x20
      50  		&& (memcmp (buf + 10 , "\x00\x00\x00", 3) == 0
      51  		    || (memcmp (buf + 5, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8) == 0)));
      52  }
      53  
      54  int main(int argc, char *argv[]) {
      55  	unsigned char buf[BUFSIZE];
      56  	int ret, i, numlzma, blocks=0;
      57  
      58  	if (argc != 2) {
      59  		printf("usage: %s numlzma < infile | lzma -c -d > outfile\n"
      60  		       "where numlzma is index of lzma file to extract, starting from zero.\n",
      61  		       argv[0]);
      62  		exit(1);
      63  	}
      64  	numlzma = atoi(argv[1]);
      65  
      66  	for (;;) {
      67  		/* Read data. */
      68  		ret = fread(buf, BUFSIZE, 1, stdin);
      69  		if (ret != 1)
      70  			break;
      71  
      72  		/* Scan for signature. */
      73  		for (i = 0; i<BUFSIZE-23; i++) {
      74  			if (find_lzma_header(buf+i) && numlzma-- <= 0) {
      75  				fwrite(buf+i, (BUFSIZE-i), 1, stdout);
      76  				for (;;) {
      77  					int ch;
      78  					ch = getchar();
      79  					if (ch == EOF)
      80  						exit(0);
      81  					putchar(ch);
      82  				}
      83  			}
      84  		}
      85  		blocks++;
      86  	}
      87  	return 1;
      88  }