home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
- /* zmethod -- detect compressed tar files for on-the-fly decompression.
- *
- * Derived from GNU Zip program, Copyright (C) 1992-1993 Jean-loup Gailly
- * The unzip code was written and put in the public domain by Mark Adler.
- * Portions of the lzw code are derived from the public domain 'compress'
- * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
- * Ken Turkowski, Dave Mack and Peter Jannesen.
- *
- * Adaptation to DJTAR program: Eli Zaretskii, November 1995
- */
-
- /* This software is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY. No author or distributor accepts
- responsibility to anyone for the consequences of using it or for
- whether it serves any particular purpose or works at all, unless he
- says so in writing. Refer to the GNU General Public License
- for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- this software, but only under the conditions described in the GNU
- General Public License. A copy of this license is supposed to
- have been given to you along with this software so you can know your
- rights and responsibilities. It should be in a file named COPYING.
- Among other things, the copyright notice and this notice must be
- preserved on all copies. */
-
-
- #include "tailor.h"
- #include "zread.h"
- #include "lzw.h"
-
- /* global buffers */
-
- uch inbuf[INBUFSIZ + INBUF_EXTRA];
- uch outbuf[OUTBUFSIZ+OUTBUF_EXTRA];
- ush d_buf[DIST_BUFSIZE];
- uch window[2L*WSIZE];
- ush tab_prefix[1L<<BITS];
-
-
- /* local variables */
-
- int test = 0; /* test .gz file integrity */
- char *progname; /* program name */
- int maxbits = BITS; /* max bits per code for LZW */
- int method = DEFLATED;/* compression method */
- int level = 6; /* compression level */
- int exit_code = OK; /* program exit code */
- char *ifname; /* input file name */
- void *ifd; /* input file descriptor */
- unsigned insize; /* valid bytes in inbuf */
- unsigned inptr; /* index of next byte to be processed in inbuf */
- unsigned outcnt; /* bytes in output buffer */
- int (*decompressor)(void *) = unzip; /* function to call */
- long header_bytes, bytes_out;
-
- /* ========================================================================
- * Check the magic number of the input file and update ofname if an
- * original name was given and to_stdout is not set.
- * Return the compression method, -1 for error, -2 for warning.
- * Set inptr to the offset of the next byte to be processed.
- * Updates time_stamp if there is one and --no-time is not used.
- * This function may be called repeatedly for an input file consisting
- * of several contiguous gzip'ed members.
- * IN assertions: there is at least one remaining compressed member.
- * If the member is a zip file, it must be the only one.
- */
-
- int last_member;
-
- int
- get_method(void *in)
- {
- uch flags; /* compression flags */
- char magic[2]; /* magic header */
- ulg stamp; /* time stamp */
-
- ifd = in;
- magic[0] = (char)get_byte();
- magic[1] = (char)get_byte();
-
- method = -1; /* unknown yet */
- part_nb++; /* number of parts in gzip file */
- header_bytes = 0;
- last_member = RECORD_IO;
- /* assume multiple members in gzip file except for record oriented I/O */
-
- if (memcmp(magic, GZIP_MAGIC, 2) == 0
- || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) {
-
- method = (int)get_byte();
- if (method != DEFLATED) {
- fprintf(log_out,
- "%s: %s: unknown method %d -- get newer version of zread\n",
- progname, ifname, method);
- exit_code = ERROR;
- return -1;
- }
- decompressor = unzip;
- flags = (uch)get_byte();
-
- if ((flags & ENCRYPTED) != 0) {
- fprintf(log_out,
- "%s: %s is encrypted -- get newer version of zread\n",
- progname, ifname);
- exit_code = ERROR;
- return -1;
- }
- if ((flags & CONTINUATION) != 0) {
- fprintf(log_out,
- "%s: %s is a a multi-part gzip file -- get newer version of zread\n",
- progname, ifname);
- exit_code = ERROR;
- }
- if ((flags & RESERVED) != 0) {
- fprintf(log_out,
- "%s: %s has flags 0x%x -- get newer version of zread\n",
- progname, ifname, flags);
- exit_code = ERROR;
- }
- stamp = (ulg)get_byte();
- stamp |= ((ulg)get_byte()) << 8;
- stamp |= ((ulg)get_byte()) << 16;
- stamp |= ((ulg)get_byte()) << 24;
-
- (void)get_byte(); /* Ignore extra flags for the moment */
- (void)get_byte(); /* Ignore OS type for the moment */
-
- if ((flags & CONTINUATION) != 0) {
- unsigned part = (unsigned)get_byte();
- part |= ((unsigned)get_byte())<<8;
- if (v_switch) {
- fprintf(log_out,"%s: %s: part number %u\n",
- progname, ifname, part);
- }
- }
- if ((flags & EXTRA_FIELD) != 0) {
- unsigned len = (unsigned)get_byte();
- len |= ((unsigned)get_byte())<<8;
- if (v_switch) {
- fprintf(log_out,"%s: %s: extra field of %u bytes ignored\n",
- progname, ifname, len);
- }
- while (len--) (void)get_byte();
- }
-
- /* Get original file name if it was truncated */
- if ((flags & ORIG_NAME) != 0) {
- char orig_name[MAX_PATH_LEN], *p = orig_name;
- for (;;) {
- *p = (char)get_byte();
- if (*p++ == '\0') break;
- if (p >= orig_name + sizeof(orig_name)) {
- error("corrupted input -- file name too large");
- }
- }
- } /* ORIG_NAME */
-
- /* Discard file comment if any */
- if ((flags & COMMENT) != 0) {
- while (get_char() != 0) /* null */ ;
- }
- if (part_nb == 1) {
- header_bytes = inptr + 2*sizeof(long); /* include crc and size */
- }
-
- } else if (memcmp(magic, PKZIP_MAGIC, 2) == 0 && inptr == 2
- && memcmp((char*)inbuf, PKZIP_MAGIC, 4) == 0) {
- /* To simplify the code, we support a zip file when alone only.
- * We are thus guaranteed that the entire local header fits in inbuf.
- */
- inptr = 0;
- decompressor = unzip;
- if (check_zipfile() != OK) return -1;
- /* check_zipfile may get ofname from the local header */
- last_member = 1;
-
- } else if (memcmp(magic, PACK_MAGIC, 2) == 0) {
- decompressor = unpack;
- method = PACKED;
-
- } else if (memcmp(magic, LZW_MAGIC, 2) == 0) {
- decompressor = unlzw;
- method = COMPRESSED;
- last_member = 1;
-
- } else if (memcmp(magic, LZH_MAGIC, 2) == 0) {
- decompressor = unlzh;
- method = LZHED;
- last_member = 1;
-
- } else if (part_nb == 1) { /* pass input unchanged by default */
- method = STORED;
- decompressor = copy;
- inptr = 0;
- last_member = 1;
- }
- if (method >= 0) return method;
-
- if (part_nb == 1 && z_switch) {
- fprintf(log_out, "\n%s: %s: not in gzip format\n", progname, ifname);
- exit_code = ERROR;
- return -1;
- } else {
- WARN((log_out, "\n%s: %s: decompression OK, trailing garbage ignored\n",
- progname, ifname));
- return -2;
- }
- }
-
-