19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* gzjoin -- command to join gzip files into one gzip file 29e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 304351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes Copyright (C) 2004, 2005, 2012 Mark Adler, all rights reserved 404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes version 1.2, 14 Aug 2012 59e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project This software is provided 'as-is', without any express or implied 79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project warranty. In no event will the author be held liable for any damages 89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project arising from the use of this software. 99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Permission is granted to anyone to use this software for any purpose, 119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project including commercial applications, and to alter it and redistribute it 129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project freely, subject to the following restrictions: 139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1. The origin of this software must not be misrepresented; you must not 159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project claim that you wrote the original software. If you use this software 169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in a product, an acknowledgment in the product documentation would be 179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project appreciated but is not required. 189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2. Altered source versions must be plainly marked as such, and must not be 199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project misrepresented as being the original software. 209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3. This notice may not be removed or altered from any source distribution. 219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Mark Adler madler@alumni.caltech.edu 239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Change history: 279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 1.0 11 Dec 2004 - First version 299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 1.1 12 Jun 2005 - Changed ssize_t to long for portability 3004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes * 1.2 14 Aug 2012 - Clean up for z_const usage 319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gzjoin takes one or more gzip files on the command line and writes out a 359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project single gzip file that will uncompress to the concatenation of the 369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project uncompressed data from the individual gzip files. gzjoin does this without 379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project having to recompress any of the data and without having to calculate a new 389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project crc32 for the concatenated uncompressed data. gzjoin does however have to 399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project decompress all of the input data in order to find the bits in the compressed 409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project data that need to be modified to concatenate the streams. 419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gzjoin does not do an integrity check on the input gzip files other than 439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project checking the gzip header and decompressing the compressed data. They are 449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project otherwise assumed to be complete and correct. 459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Each joint between gzip files removes at least 18 bytes of previous trailer 479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project and subsequent header, and inserts an average of about three bytes to the 489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project compressed data in order to connect the streams. The output gzip file 499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project has a minimal ten-byte gzip header with no file name or modification time. 509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project This program was written to illustrate the use of the Z_BLOCK option of 529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflate() and the crc32_combine() function. gzjoin will not compile with 539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project versions of zlib earlier than 1.2.3. 549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdio.h> /* fputs(), fprintf(), fwrite(), putc() */ 579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdlib.h> /* exit(), malloc(), free() */ 589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <fcntl.h> /* open() */ 599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <unistd.h> /* close(), read(), lseek() */ 609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "zlib.h" 619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* crc32(), crc32_combine(), inflateInit2(), inflate(), inflateEnd() */ 629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define local static 649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* exit with an error (return a value to allow use in an expression) */ 669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal int bail(char *why1, char *why2) 679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "gzjoin error: %s%s, output incomplete\n", why1, why2); 699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project exit(1); 709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 0; 719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* -- simple buffered file input with access to the buffer -- */ 749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define CHUNK 32768 /* must be a power of two and fit in unsigned */ 769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* bin buffered input file type */ 789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projecttypedef struct { 799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project char *name; /* name of file for error messages */ 809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int fd; /* file descriptor */ 819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned left; /* bytes remaining at next */ 829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char *next; /* next byte to read */ 839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char *buf; /* allocated buffer of length CHUNK */ 849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} bin; 859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* close a buffered file and free allocated memory */ 879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void bclose(bin *in) 889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (in != NULL) { 909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (in->fd != -1) 919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project close(in->fd); 929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (in->buf != NULL) 939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project free(in->buf); 949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project free(in); 959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* open a buffered file for input, return a pointer to type bin, or NULL on 999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project failure */ 1009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal bin *bopen(char *name) 1019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 1029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bin *in; 1039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in = malloc(sizeof(bin)); 1059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (in == NULL) 1069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return NULL; 1079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->buf = malloc(CHUNK); 1089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->fd = open(name, O_RDONLY, 0); 1099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (in->buf == NULL || in->fd == -1) { 1109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bclose(in); 1119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return NULL; 1129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->left = 0; 1149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->next = in->buf; 1159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->name = name; 1169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return in; 1179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 1189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* load buffer from file, return -1 on read error, 0 or 1 on success, with 1209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1 indicating that end-of-file was reached */ 1219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal int bload(bin *in) 1229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 1239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project long len; 1249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (in == NULL) 1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return -1; 1279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (in->left != 0) 1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 0; 1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->next = in->buf; 1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { 1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = (long)read(in->fd, in->buf + in->left, CHUNK - in->left); 1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (len < 0) 1339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return -1; 1349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->left += (unsigned)len; 1359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (len != 0 && in->left < CHUNK); 1369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return len == 0 ? 1 : 0; 1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* get a byte from the file, bail if end of file */ 1409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define bget(in) (in->left ? 0 : bload(in), \ 1419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->left ? (in->left--, *(in->next)++) : \ 1429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bail("unexpected end of file on ", in->name)) 1439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* get a four-byte little-endian unsigned integer from file */ 1459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal unsigned long bget4(bin *in) 1469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 1479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long val; 1489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project val = bget(in); 1509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project val += (unsigned long)(bget(in)) << 8; 1519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project val += (unsigned long)(bget(in)) << 16; 1529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project val += (unsigned long)(bget(in)) << 24; 1539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return val; 1549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 1559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* skip bytes in file */ 1579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void bskip(bin *in, unsigned skip) 1589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 1599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* check pointer */ 1609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (in == NULL) 1619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return; 1629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* easy case -- skip bytes in buffer */ 1649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (skip <= in->left) { 1659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->left -= skip; 1669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->next += skip; 1679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return; 1689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* skip what's in buffer, discard buffer contents */ 1719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project skip -= in->left; 1729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->left = 0; 1739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* seek past multiples of CHUNK bytes */ 1759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (skip > CHUNK) { 1769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned left; 1779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left = skip & (CHUNK - 1); 1799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (left == 0) { 1809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* exact number of chunks: seek all the way minus one byte to check 1819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for end-of-file with a read */ 1829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lseek(in->fd, skip - 1, SEEK_CUR); 1839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (read(in->fd, in->buf, 1) != 1) 1849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bail("unexpected end of file on ", in->name); 1859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return; 1869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* skip the integral chunks, update skip with remainder */ 1899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lseek(in->fd, skip - left, SEEK_CUR); 1909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project skip = left; 1919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* read more input and skip remainder */ 1949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bload(in); 1959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (skip > in->left) 1969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bail("unexpected end of file on ", in->name); 1979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->left -= skip; 1989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->next += skip; 1999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 2009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* -- end of buffered input functions -- */ 2029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* skip the gzip header from file in */ 2049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void gzhead(bin *in) 2059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 2069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int flags; 2079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* verify gzip magic header and compression method */ 2099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (bget(in) != 0x1f || bget(in) != 0x8b || bget(in) != 8) 2109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bail(in->name, " is not a valid gzip file"); 2119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* get and verify flags */ 2139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project flags = bget(in); 2149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((flags & 0xe0) != 0) 2159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bail("unknown reserved bits set in ", in->name); 2169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* skip modification time, extra flags, and os */ 2189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bskip(in, 6); 2199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* skip extra field if present */ 2219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (flags & 4) { 2229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned len; 2239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = bget(in); 2259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len += (unsigned)(bget(in)) << 8; 2269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bskip(in, len); 2279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* skip file name if present */ 2309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (flags & 8) 2319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (bget(in) != 0) 2329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ; 2339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* skip comment if present */ 2359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (flags & 16) 2369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (bget(in) != 0) 2379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ; 2389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* skip header crc if present */ 2409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (flags & 2) 2419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bskip(in, 2); 2429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 2439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* write a four-byte little-endian unsigned integer to out */ 2459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void put4(unsigned long val, FILE *out) 2469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 2479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putc(val & 0xff, out); 2489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putc((val >> 8) & 0xff, out); 2499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putc((val >> 16) & 0xff, out); 2509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putc((val >> 24) & 0xff, out); 2519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 2529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Load up zlib stream from buffered input, bail if end of file */ 2549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void zpull(z_streamp strm, bin *in) 2559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 2569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (in->left == 0) 2579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bload(in); 2589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (in->left == 0) 2599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bail("unexpected end of file on ", in->name); 2609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->avail_in = in->left; 2619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->next_in = in->next; 2629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 2639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Write header for gzip file to out and initialize trailer. */ 2659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void gzinit(unsigned long *crc, unsigned long *tot, FILE *out) 2669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 2679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out); 2689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *crc = crc32(0L, Z_NULL, 0); 2699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *tot = 0; 2709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 2719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Copy the compressed data from name, zeroing the last block bit of the last 2739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project block if clr is true, and adding empty blocks as needed to get to a byte 2749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project boundary. If clr is false, then the last block becomes the last block of 2759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project the output, and the gzip trailer is written. crc and tot maintains the 2769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project crc and length (modulo 2^32) of the output for the trailer. The resulting 2779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gzip file is written to out. gzinit() must be called before the first call 2789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project of gzcopy() to write the gzip header and to initialize crc and tot. */ 2799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot, 2809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project FILE *out) 2819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 2829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int ret; /* return value from zlib functions */ 2839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int pos; /* where the "last block" bit is in byte */ 2849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int last; /* true if processing the last block */ 2859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bin *in; /* buffered input file */ 2869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char *start; /* start of compressed data in buffer */ 2879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char *junk; /* buffer for uncompressed data -- discarded */ 2889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project z_off_t len; /* length of uncompressed data (support > 4 GB) */ 2899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project z_stream strm; /* zlib inflate stream */ 2909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* open gzip file and skip header */ 2929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in = bopen(name); 2939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (in == NULL) 2949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bail("could not open ", name); 2959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gzhead(in); 2969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* allocate buffer for uncompressed data and initialize raw inflate 2989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project stream */ 2999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project junk = malloc(CHUNK); 3009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm.zalloc = Z_NULL; 3019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm.zfree = Z_NULL; 3029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm.opaque = Z_NULL; 3039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm.avail_in = 0; 3049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm.next_in = Z_NULL; 3059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflateInit2(&strm, -15); 3069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (junk == NULL || ret != Z_OK) 3079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bail("out of memory", ""); 3089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* inflate and copy compressed data, clear last-block bit if requested */ 3109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = 0; 3119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project zpull(&strm, in); 31204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes start = in->next; 3139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project last = start[0] & 1; 3149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last && clr) 3159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project start[0] &= ~1; 3169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm.avail_out = 0; 3179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 3189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* if input used and output done, write used input and get more */ 3199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm.avail_in == 0 && strm.avail_out != 0) { 3209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fwrite(start, 1, strm.next_in - start, out); 3219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project start = in->buf; 3229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->left = 0; 3239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project zpull(&strm, in); 3249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* decompress -- return early when end-of-block reached */ 3279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm.avail_out = CHUNK; 3289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm.next_out = junk; 3299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflate(&strm, Z_BLOCK); 3309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project switch (ret) { 3319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case Z_MEM_ERROR: 3329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bail("out of memory", ""); 3339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case Z_DATA_ERROR: 3349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bail("invalid compressed data in ", in->name); 3359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* update length of uncompressed data */ 3389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len += CHUNK - strm.avail_out; 3399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* check for block boundary (only get this when block copied out) */ 3419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm.data_type & 128) { 3429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* if that was the last block, then done */ 3439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last) 3449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 3459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* number of unused bits in last byte */ 3479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project pos = strm.data_type & 7; 3489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* find the next last-block bit */ 3509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (pos != 0) { 3519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* next last-block bit is in last used byte */ 3529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project pos = 0x100 >> pos; 3539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project last = strm.next_in[-1] & pos; 3549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last && clr) 35504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes in->buf[strm.next_in - in->buf - 1] &= ~pos; 3569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 3589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* next last-block bit is in next unused byte */ 3599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm.avail_in == 0) { 3609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* don't have that byte yet -- get it */ 3619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fwrite(start, 1, strm.next_in - start, out); 3629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project start = in->buf; 3639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->left = 0; 3649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project zpull(&strm, in); 3659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project last = strm.next_in[0] & 1; 3679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (last && clr) 36804351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes in->buf[strm.next_in - in->buf] &= ~1; 3699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* update buffer with unused input */ 3749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in->left = strm.avail_in; 37504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes in->next = in->buf + (strm.next_in - in->buf); 3769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* copy used input, write empty blocks to get to byte boundary */ 3789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project pos = strm.data_type & 7; 3799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fwrite(start, 1, in->next - start - 1, out); 3809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project last = in->next[-1]; 3819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (pos == 0 || !clr) 3829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* already at byte boundary, or last file: write last byte */ 3839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putc(last, out); 3849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 3859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* append empty blocks to last byte */ 3869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project last &= ((0x100 >> pos) - 1); /* assure unused bits are zero */ 3879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (pos & 1) { 3889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* odd -- append an empty stored block */ 3899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putc(last, out); 3909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (pos == 1) 3919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putc(0, out); /* two more bits in block header */ 3929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fwrite("\0\0\xff\xff", 1, 4, out); 3939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 3959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* even -- append 1, 2, or 3 empty fixed blocks */ 3969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project switch (pos) { 3979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case 6: 3989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putc(last | 8, out); 3999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project last = 0; 4009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case 4: 4019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putc(last | 0x20, out); 4029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project last = 0; 4039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case 2: 4049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putc(last | 0x80, out); 4059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putc(0, out); 4069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* update crc and tot */ 4119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *crc = crc32_combine(*crc, bget4(in), len); 4129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *tot += (unsigned long)len; 4139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* clean up */ 4159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflateEnd(&strm); 4169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project free(junk); 4179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bclose(in); 4189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* write trailer if this is the last gzip file */ 4209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (!clr) { 4219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project put4(*crc, out); 4229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project put4(*tot, out); 4239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 4259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* join the gzip files on the command line, write result to stdout */ 4279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint main(int argc, char **argv) 4289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 4299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long crc, tot; /* running crc and total uncompressed length */ 4309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* skip command name */ 4329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project argc--; 4339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project argv++; 4349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* show usage if no arguments */ 4369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (argc == 0) { 4379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fputs("gzjoin usage: gzjoin f1.gz [f2.gz [f3.gz ...]] > fjoin.gz\n", 4389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project stderr); 4399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 0; 4409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* join gzip files on command line and write to stdout */ 4439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gzinit(&crc, &tot, stdout); 4449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (argc--) 4459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gzcopy(*argv++, argc, &crc, &tot, stdout); 4469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* done */ 4489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 0; 4499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 450