19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* gun.c -- simple gunzip to give an example of the use of inflateBack() 2381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes * Copyright (C) 2003, 2005, 2008, 2010 Mark Adler 39e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * For conditions of distribution and use, see copyright notice in zlib.h 4381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes Version 1.6 17 January 2010 Mark Adler */ 59e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Version history: 79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1.0 16 Feb 2003 First version for testing of inflateBack() 89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1.1 21 Feb 2005 Decompress concatenated gzip streams 99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Remove use of "this" variable (C++ keyword) 109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Fix return value for in() 119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Improve allocation failure checking 129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Add typecasting for void * structures 139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Add -h option for command version and usage 149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Add a bunch of comments 159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1.2 20 Mar 2005 Add Unix compress (LZW) decompression 169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Copy file attributes from input file to output file 179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1.3 12 Jun 2005 Add casts for error messages [Oberhumer] 18381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 1.4 8 Dec 2006 LZW decompression speed improvements 19381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 1.5 9 Feb 2008 Avoid warning in latest version of gcc 20381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 1.6 17 Jan 2010 Avoid signed/unsigned comparison warnings 219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gun [ -t ] [ name ... ] 259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project decompresses the data in the named gzip files. If no arguments are given, 279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gun will decompress from stdin to stdout. The names must end in .gz, -gz, 289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project .z, -z, _z, or .Z. The uncompressed data will be written to a file name 299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project with the suffix stripped. On success, the original file is deleted. On 309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project failure, the output file is deleted. For most failures, the command will 319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project continue to process the remaining names on the command line. A memory 329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project allocation failure will abort the command. If -t is specified, then the 339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project listed files or stdin will be tested as gzip files for integrity (without 349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project checking for a proper suffix), no output will be written, and no files 359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project will be deleted. 369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Like gzip, gun allows concatenated gzip streams and will decompress them, 389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project writing all of the uncompressed data to the output. Unlike gzip, gun allows 399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project an empty file on input, and will produce no error writing an empty output 409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project file. 419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gun will also decompress files made by Unix compress, which uses LZW 439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project compression. These files are automatically detected by virtue of their 449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project magic header bytes. Since the end of Unix compress stream is marked by the 459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project end-of-file, they cannot be concantenated. If a Unix compress stream is 469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project encountered in an input file, it is the last stream in that file. 479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Like gunzip and uncompress, the file attributes of the orignal compressed 499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project file are maintained in the final uncompressed file, to the extent that the 509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project user permissions allow it. 519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project On my Mac OS X PowerPC G4, gun is almost twice as fast as gunzip (version 539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1.2.4) is on the same file, when gun is linked with zlib 1.2.2. Also the 549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project LZW decompression provided by gun is about twice as fast as the standard 559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Unix uncompress command. 569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* external functions and related types and constants */ 599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdio.h> /* fprintf() */ 609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdlib.h> /* malloc(), free() */ 619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <string.h> /* strerror(), strcmp(), strlen(), memcpy() */ 629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <errno.h> /* errno */ 639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <fcntl.h> /* open() */ 649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <unistd.h> /* read(), write(), close(), chown(), unlink() */ 659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <sys/types.h> 669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <sys/stat.h> /* stat(), chmod() */ 679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <utime.h> /* utime() */ 689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "zlib.h" /* inflateBackInit(), inflateBack(), */ 699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* inflateBackEnd(), crc32() */ 709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* function declaration */ 729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define local static 739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* buffer constants */ 759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define SIZE 32768U /* input and output buffer sizes */ 769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define PIECE 16384 /* limits i/o chunks for 16-bit int case */ 779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* structure for infback() to pass to input function in() -- it maintains the 799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project input file and a buffer of size SIZE */ 809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectstruct ind { 819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int infile; 829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char *inbuf; 839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}; 849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Load input buffer, assumed to be empty, and return bytes loaded and a 869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project pointer to them. read() is called until the buffer is full, or until it 879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project returns end-of-file or error. Return 0 on error. */ 889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal unsigned in(void *in_desc, unsigned char **buf) 899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int ret; 919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned len; 929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char *next; 939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct ind *me = (struct ind *)in_desc; 949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next = me->inbuf; 969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *buf = next; 979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = 0; 989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { 999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = PIECE; 1009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((unsigned)ret > SIZE - len) 1019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = (int)(SIZE - len); 1029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = (int)read(me->infile, next, ret); 1039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret == -1) { 1049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = 0; 1059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 1069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next += ret; 1089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len += ret; 1099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (ret != 0 && len < SIZE); 1109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return len; 1119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 1129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* structure for infback() to pass to output function out() -- it maintains the 1149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project output file, a running CRC-32 check on the output and the total number of 1159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bytes output, both for checking against the gzip trailer. (The length in 1169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project the gzip trailer is stored modulo 2^32, so it's ok if a long is 32 bits and 1179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project the output is greater than 4 GB.) */ 1189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectstruct outd { 1199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int outfile; 1209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int check; /* true if checking crc and total */ 1219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long crc; 1229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long total; 1239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}; 1249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Write output buffer and update the CRC-32 and total bytes written. write() 1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project is called until all of the output is written or an error is encountered. 1279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project On success out() returns 0. For a write failure, out() returns 1. If the 1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project output file descriptor is -1, then nothing is written. 1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal int out(void *out_desc, unsigned char *buf, unsigned len) 1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int ret; 1339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct outd *me = (struct outd *)out_desc; 1349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (me->check) { 1369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project me->crc = crc32(me->crc, buf, len); 1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project me->total += len; 1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (me->outfile != -1) 1409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { 1419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = PIECE; 1429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((unsigned)ret > len) 1439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = (int)len; 1449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = (int)write(me->outfile, buf, ret); 1459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret == -1) 1469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 1; 1479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project buf += ret; 1489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len -= ret; 1499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (len != 0); 1509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 0; 1519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 1529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* next input byte macro for use inside lunpipe() and gunpipe() */ 1549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define NEXT() (have ? 0 : (have = in(indp, &next)), \ 1559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project last = have ? (have--, (int)(*next++)) : -1) 1569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* memory for gunpipe() and lunpipe() -- 1589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project the first 256 entries of prefix[] and suffix[] are never used, could 1599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have offset the index, but it's faster to waste the memory */ 1609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectunsigned char inbuf[SIZE]; /* input buffer */ 1619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectunsigned char outbuf[SIZE]; /* output buffer */ 1629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectunsigned short prefix[65536]; /* index to LZW prefix string */ 1639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectunsigned char suffix[65536]; /* one-character LZW suffix */ 1649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectunsigned char match[65280 + 2]; /* buffer for reversed match or gzip 1659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 32K sliding window */ 1669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* throw out what's left in the current bits byte buffer (this is a vestigial 1689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project aspect of the compressed data format derived from an implementation that 1699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project made use of a special VAX machine instruction!) */ 1709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define FLUSHCODE() \ 1719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 1729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left = 0; \ 1739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project rem = 0; \ 1749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (chunk > have) { \ 1759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project chunk -= have; \ 1769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have = 0; \ 1779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (NEXT() == -1) \ 1789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; \ 1799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project chunk--; \ 1809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (chunk > have) { \ 1819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project chunk = have = 0; \ 1829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; \ 1839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } \ 1849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } \ 1859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have -= chunk; \ 1869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next += chunk; \ 1879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project chunk = 0; \ 1889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 1899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Decompress a compress (LZW) file from indp to outfile. The compress magic 1919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project header (two bytes) has already been read and verified. There are have bytes 1929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project of buffered input at next. strm is used for passing error information back 1939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project to gunpipe(). 1949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lunpipe() will return Z_OK on success, Z_BUF_ERROR for an unexpected end of 1969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project file, read error, or write error (a write error indicated by strm->next_in 1979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project not equal to Z_NULL), or Z_DATA_ERROR for invalid input. 1989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 1999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal int lunpipe(unsigned have, unsigned char *next, struct ind *indp, 2009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int outfile, z_stream *strm) 2019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 2029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int last; /* last byte read by NEXT(), or -1 if EOF */ 203381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned chunk; /* bytes left in current chunk */ 2049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int left; /* bits left in rem */ 2059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned rem; /* unused bits from input */ 2069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int bits; /* current bits per code */ 2079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned code; /* code, table traversal index */ 2089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned mask; /* mask for current bits codes */ 2099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int max; /* maximum bits per code for this stream */ 210381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned flags; /* compress flags, then block compress flag */ 2119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned end; /* last valid entry in prefix/suffix tables */ 2129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned temp; /* current code */ 2139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned prev; /* previous code */ 2149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned final; /* last character written for previous code */ 2159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned stack; /* next position for reversed string */ 2169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned outcnt; /* bytes in output buffer */ 2179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct outd outd; /* output structure */ 218381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned char *p; 2199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* set up output */ 2219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outd.outfile = outfile; 2229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outd.check = 0; 2239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* process remainder of compress header -- a flags byte */ 2259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project flags = NEXT(); 2269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last == -1) 2279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_BUF_ERROR; 2289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (flags & 0x60) { 2299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"unknown lzw flags set"; 2309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_DATA_ERROR; 2319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project max = flags & 0x1f; 2339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (max < 9 || max > 16) { 2349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"lzw bits out of range"; 2359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_DATA_ERROR; 2369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (max == 9) /* 9 doesn't really mean 9 */ 2389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project max = 10; 2399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project flags &= 0x80; /* true if block compress */ 2409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* clear table */ 2429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits = 9; 2439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mask = 0x1ff; 2449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project end = flags ? 256 : 255; 2459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* set up: get first 9-bit code, which is the first decompressed byte, but 2479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project don't create a table entry until the next code */ 2489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (NEXT() == -1) /* no compressed data is ok */ 2499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_OK; 2509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project final = prev = (unsigned)last; /* low 8 bits of code */ 2519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (NEXT() == -1) /* missing a bit */ 2529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_BUF_ERROR; 2539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last & 1) { /* code must be < 256 */ 2549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid lzw code"; 2559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_DATA_ERROR; 2569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project rem = (unsigned)last >> 1; /* remaining 7 bits */ 2589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left = 7; 2599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project chunk = bits - 2; /* 7 bytes left in this chunk */ 2609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outbuf[0] = (unsigned char)final; /* write first decompressed byte */ 2619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outcnt = 1; 2629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* decode codes */ 2649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project stack = 0; 2659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 2669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* if the table will be full after this, increment the code size */ 2679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (end >= mask && bits < max) { 2689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project FLUSHCODE(); 2699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits++; 2709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mask <<= 1; 2719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mask++; 2729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* get a code of length bits */ 2759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (chunk == 0) /* decrement chunk modulo bits */ 2769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project chunk = bits; 2779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code = rem; /* low bits of code */ 2789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (NEXT() == -1) { /* EOF is end of compressed data */ 2799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* write remaining buffered output */ 2809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (outcnt && out(&outd, outbuf, outcnt)) { 2819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->next_in = outbuf; /* signal write error */ 2829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_BUF_ERROR; 2839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_OK; 2859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code += (unsigned)last << left; /* middle (or high) bits of code */ 2879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left += 8; 2889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project chunk--; 2899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (bits > left) { /* need more bits */ 2909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (NEXT() == -1) /* can't end in middle of code */ 2919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_BUF_ERROR; 2929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code += (unsigned)last << left; /* high bits of code */ 2939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left += 8; 2949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project chunk--; 2959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code &= mask; /* mask to current code length */ 2979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left -= bits; /* number of unused bits */ 2989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project rem = (unsigned)last >> (8 - left); /* unused bits from last byte */ 2999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* process clear code (256) */ 3019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (code == 256 && flags) { 3029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project FLUSHCODE(); 3039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits = 9; /* initialize bits and mask */ 3049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mask = 0x1ff; 3059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project end = 255; /* empty table */ 3069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project continue; /* get next code */ 3079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* special code to reuse last match */ 3109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project temp = code; /* save the current code */ 3119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (code > end) { 3129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Be picky on the allowed code here, and make sure that the code 3139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project we drop through (prev) will be a valid index so that random 3149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project input does not cause an exception. The code != end + 1 check is 3159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project empirically derived, and not checked in the original uncompress 3169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code. If this ever causes a problem, that check could be safely 3179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project removed. Leaving this check in greatly improves gun's ability 3189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project to detect random or corrupted input after a compress header. 3199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project In any case, the prev > end check must be retained. */ 3209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (code != end + 1 || prev > end) { 3219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid lzw code"; 3229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_DATA_ERROR; 3239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project match[stack++] = (unsigned char)final; 3259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code = prev; 3269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* walk through linked list to generate output in reverse order */ 329381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes p = match + stack; 3309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (code >= 256) { 331381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes *p++ = suffix[code]; 3329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code = prefix[code]; 3339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 334381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes stack = p - match; 3359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project match[stack++] = (unsigned char)code; 3369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project final = code; 3379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* link new table entry */ 3399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (end < mask) { 3409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project end++; 3419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project prefix[end] = (unsigned short)prev; 3429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project suffix[end] = (unsigned char)final; 3439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* set previous code for next iteration */ 3469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project prev = temp; 3479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* write output in forward order */ 3499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (stack > SIZE - outcnt) { 3509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (outcnt < SIZE) 3519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outbuf[outcnt++] = match[--stack]; 3529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (out(&outd, outbuf, outcnt)) { 3539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->next_in = outbuf; /* signal write error */ 3549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_BUF_ERROR; 3559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outcnt = 0; 3579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 358381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes p = match + stack; 3599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { 360381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes outbuf[outcnt++] = *--p; 361381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } while (p > match); 362381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes stack = 0; 3639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* loop for next code with final and prev as the last match, rem and 3659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left provide the first 0..7 bits of the next code, end is the last 3669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project valid table entry */ 3679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 3699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Decompress a gzip file from infile to outfile. strm is assumed to have been 3719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project successfully initialized with inflateBackInit(). The input file may consist 3729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project of a series of gzip streams, in which case all of them will be decompressed 3739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project to the output file. If outfile is -1, then the gzip stream(s) integrity is 3749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project checked and nothing is written. 3759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project The return value is a zlib error code: Z_MEM_ERROR if out of memory, 3779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Z_DATA_ERROR if the header or the compressed data is invalid, or if the 3789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project trailer CRC-32 check or length doesn't match, Z_BUF_ERROR if the input ends 3799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project prematurely or a write error occurs, or Z_ERRNO if junk (not a another gzip 3809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project stream) follows a valid gzip stream. 3819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 3829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal int gunpipe(z_stream *strm, int infile, int outfile) 3839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 3849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int ret, first, last; 3859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned have, flags, len; 386381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned char *next = NULL; 3879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct ind ind, *indp; 3889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct outd outd; 3899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* setup input buffer */ 3919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ind.infile = infile; 3929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ind.inbuf = inbuf; 3939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project indp = &ind; 3949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* decompress concatenated gzip streams */ 3969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have = 0; /* no input data read in yet */ 3979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project first = 1; /* looking for first gzip header */ 3989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */ 3999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 4009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* look for the two magic header bytes for a gzip stream */ 4019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (NEXT() == -1) { 4029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_OK; 4039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; /* empty gzip stream is ok */ 4049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last != 31 || (NEXT() != 139 && last != 157)) { 4069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"incorrect header check"; 4079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = first ? Z_DATA_ERROR : Z_ERRNO; 4089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; /* not a gzip or compress header */ 4099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project first = 0; /* next non-header is junk */ 4119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* process a compress (LZW) file -- can't be concatenated after this */ 4139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last == 157) { 4149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = lunpipe(have, next, indp, outfile, strm); 4159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 4169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* process remainder of gzip header */ 4199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_BUF_ERROR; 4209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (NEXT() != 8) { /* only deflate method allowed */ 4219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last == -1) break; 4229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"unknown compression method"; 4239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_DATA_ERROR; 4249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 4259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project flags = NEXT(); /* header flags */ 4279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEXT(); /* discard mod time, xflgs, os */ 4289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEXT(); 4299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEXT(); 4309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEXT(); 4319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEXT(); 4329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEXT(); 4339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last == -1) break; 4349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (flags & 0xe0) { 4359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"unknown header flags set"; 4369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_DATA_ERROR; 4379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 4389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (flags & 4) { /* extra field */ 4409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = NEXT(); 4419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len += (unsigned)(NEXT()) << 8; 4429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last == -1) break; 4439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (len > have) { 4449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len -= have; 4459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have = 0; 4469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (NEXT() == -1) break; 4479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len--; 4489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last == -1) break; 4509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have -= len; 4519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next += len; 4529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (flags & 8) /* file name */ 4549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (NEXT() != 0 && last != -1) 4559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ; 4569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (flags & 16) /* comment */ 4579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (NEXT() != 0 && last != -1) 4589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ; 4599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (flags & 2) { /* header crc */ 4609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEXT(); 4619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEXT(); 4629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last == -1) break; 4649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* set up output */ 4669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outd.outfile = outfile; 4679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outd.check = 1; 4689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outd.crc = crc32(0L, Z_NULL, 0); 4699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outd.total = 0; 4709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* decompress data to output */ 4729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->next_in = next; 4739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->avail_in = have; 4749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflateBack(strm, in, indp, out, &outd); 4759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret != Z_STREAM_END) break; 4769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next = strm->next_in; 4779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have = strm->avail_in; 4789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */ 4799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* check trailer */ 4819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_BUF_ERROR; 482381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (NEXT() != (int)(outd.crc & 0xff) || 483381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NEXT() != (int)((outd.crc >> 8) & 0xff) || 484381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NEXT() != (int)((outd.crc >> 16) & 0xff) || 485381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NEXT() != (int)((outd.crc >> 24) & 0xff)) { 4869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* crc error */ 4879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last != -1) { 4889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"incorrect data check"; 4899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_DATA_ERROR; 4909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 4929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 493381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (NEXT() != (int)(outd.total & 0xff) || 494381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NEXT() != (int)((outd.total >> 8) & 0xff) || 495381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NEXT() != (int)((outd.total >> 16) & 0xff) || 496381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NEXT() != (int)((outd.total >> 24) & 0xff)) { 4979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* length error */ 4989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last != -1) { 4999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"incorrect length check"; 5009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_DATA_ERROR; 5019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 5039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* go back and look for another gzip stream */ 5069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* clean up and return */ 5099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return ret; 5109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 5119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Copy file attributes, from -> to, as best we can. This is best effort, so 5139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project no errors are reported. The mode bits, including suid, sgid, and the sticky 5149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bit are copied (if allowed), the owner's user id and group id are copied 5159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project (again if allowed), and the access and modify times are copied. */ 5169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void copymeta(char *from, char *to) 5179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 5189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct stat was; 5199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct utimbuf when; 5209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* get all of from's Unix meta data, return if not a regular file */ 5229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (stat(from, &was) != 0 || (was.st_mode & S_IFMT) != S_IFREG) 5239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return; 5249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* set to's mode bits, ignore errors */ 5269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project (void)chmod(to, was.st_mode & 07777); 5279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* copy owner's user and group, ignore errors */ 5299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project (void)chown(to, was.st_uid, was.st_gid); 5309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* copy access and modify times, ignore errors */ 5329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project when.actime = was.st_atime; 5339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project when.modtime = was.st_mtime; 5349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project (void)utime(to, &when); 5359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 5369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Decompress the file inname to the file outnname, of if test is true, just 5389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project decompress without writing and check the gzip trailer for integrity. If 5399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inname is NULL or an empty string, read from stdin. If outname is NULL or 5409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project an empty string, write to stdout. strm is a pre-initialized inflateBack 5419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project structure. When appropriate, copy the file attributes from inname to 5429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outname. 5439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gunzip() returns 1 if there is an out-of-memory error or an unexpected 5459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return code from gunpipe(). Otherwise it returns 0. 5469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 5479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal int gunzip(z_stream *strm, char *inname, char *outname, int test) 5489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 5499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int ret; 5509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int infile, outfile; 5519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* open files */ 5539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (inname == NULL || *inname == 0) { 5549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inname = "-"; 5559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project infile = 0; /* stdin */ 5569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 5589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project infile = open(inname, O_RDONLY, 0); 5599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (infile == -1) { 5609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "gun cannot open %s\n", inname); 5619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 0; 5629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (test) 5659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outfile = -1; 5669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else if (outname == NULL || *outname == 0) { 5679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outname = "-"; 5689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outfile = 1; /* stdout */ 5699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 5719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outfile = open(outname, O_CREAT | O_TRUNC | O_WRONLY, 0666); 5729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (outfile == -1) { 5739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project close(infile); 5749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "gun cannot create %s\n", outname); 5759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 0; 5769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project errno = 0; 5799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* decompress */ 5819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = gunpipe(strm, infile, outfile); 5829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (outfile > 2) close(outfile); 5839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (infile > 2) close(infile); 5849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* interpret result */ 5869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project switch (ret) { 5879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case Z_OK: 5889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case Z_ERRNO: 5899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (infile > 2 && outfile > 2) { 5909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copymeta(inname, outname); /* copy attributes */ 5919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unlink(inname); 5929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret == Z_ERRNO) 5949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "gun warning: trailing garbage ignored in %s\n", 5959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inname); 5969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 5979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case Z_DATA_ERROR: 5989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (outfile > 2) unlink(outname); 5999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "gun data error on %s: %s\n", inname, strm->msg); 6009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 6019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case Z_MEM_ERROR: 6029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (outfile > 2) unlink(outname); 6039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "gun out of memory error--aborting\n"); 6049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 1; 6059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case Z_BUF_ERROR: 6069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (outfile > 2) unlink(outname); 6079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm->next_in != Z_NULL) { 6089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "gun write error on %s: %s\n", 6099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outname, strerror(errno)); 6109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else if (errno) { 6129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "gun read error on %s: %s\n", 6139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inname, strerror(errno)); 6149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 6169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "gun unexpected end of file on %s\n", 6179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inname); 6189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 6209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project default: 6219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (outfile > 2) unlink(outname); 6229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "gun internal error--aborting\n"); 6239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 1; 6249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 0; 6269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 6279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 6289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Process the gun command line arguments. See the command syntax near the 6299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project beginning of this source file. */ 6309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint main(int argc, char **argv) 6319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 6329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int ret, len, test; 6339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project char *outname; 6349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char *window; 6359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project z_stream strm; 6369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 6379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* initialize inflateBack state for repeated use */ 6389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project window = match; /* reuse LZW match buffer */ 6399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm.zalloc = Z_NULL; 6409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm.zfree = Z_NULL; 6419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm.opaque = Z_NULL; 6429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflateBackInit(&strm, 15, window); 6439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret != Z_OK) { 6449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "gun out of memory error--aborting\n"); 6459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 1; 6469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 6489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* decompress each file to the same name with the suffix removed */ 6499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project argc--; 6509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project argv++; 6519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project test = 0; 6529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (argc && strcmp(*argv, "-h") == 0) { 653381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes fprintf(stderr, "gun 1.6 (17 Jan 2010)\n"); 654381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes fprintf(stderr, "Copyright (C) 2003-2010 Mark Adler\n"); 6559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "usage: gun [-t] [file1.gz [file2.Z ...]]\n"); 6569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 0; 6579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (argc && strcmp(*argv, "-t") == 0) { 6599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project test = 1; 6609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project argc--; 6619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project argv++; 6629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (argc) 6649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { 6659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (test) 6669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outname = NULL; 6679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 6689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = (int)strlen(*argv); 6699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strcmp(*argv + len - 3, ".gz") == 0 || 6709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strcmp(*argv + len - 3, "-gz") == 0) 6719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len -= 3; 6729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else if (strcmp(*argv + len - 2, ".z") == 0 || 6739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strcmp(*argv + len - 2, "-z") == 0 || 6749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strcmp(*argv + len - 2, "_z") == 0 || 6759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strcmp(*argv + len - 2, ".Z") == 0) 6769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len -= 2; 6779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 6789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "gun error: no gz type on %s--skipping\n", 6799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *argv); 6809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project continue; 6819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outname = malloc(len + 1); 6839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (outname == NULL) { 6849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "gun out of memory error--aborting\n"); 6859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = 1; 6869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 6879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project memcpy(outname, *argv, len); 6899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project outname[len] = 0; 6909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = gunzip(&strm, *argv, outname, test); 6929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (outname != NULL) free(outname); 6939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret) break; 6949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (argv++, --argc); 6959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else 6969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = gunzip(&strm, NULL, NULL, test); 6979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 6989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* clean up */ 6999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflateBackEnd(&strm); 7009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return ret; 7019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 702