diff options
| author | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2002-01-02 13:52:26 +0000 |
|---|---|---|
| committer | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2002-01-02 13:52:26 +0000 |
| commit | 207c7487a7afc394d119d2ff13f7586bc126246c (patch) | |
| tree | 4f406c877f88a013c4e1dc650ac312640a95cb00 | |
| parent | d3d7a5045c61945e9772f3937f6b03b18d9560cd (diff) | |
| download | busybox-w32-207c7487a7afc394d119d2ff13f7586bc126246c.tar.gz busybox-w32-207c7487a7afc394d119d2ff13f7586bc126246c.tar.bz2 busybox-w32-207c7487a7afc394d119d2ff13f7586bc126246c.zip | |
unzip applet by Laurence Anderson
----------------------------------------------------------------------
git-svn-id: svn://busybox.net/trunk/busybox@3988 69ca8d6d-28ef-0310-b511-8ec308f3f277
| -rw-r--r-- | archival/Makefile | 1 | ||||
| -rw-r--r-- | archival/config.in | 1 | ||||
| -rw-r--r-- | archival/libunarchive/Makefile | 8 | ||||
| -rw-r--r-- | archival/libunarchive/decompress_unzip.c | 48 | ||||
| -rw-r--r-- | archival/libunarchive/get_header_zip.c | 110 | ||||
| -rw-r--r-- | archival/libunarchive/unarchive.c | 3 | ||||
| -rw-r--r-- | archival/libunarchive/unzip.c | 48 | ||||
| -rw-r--r-- | archival/unzip.c | 94 | ||||
| -rw-r--r-- | include/applets.h | 3 | ||||
| -rw-r--r-- | include/libbb.h | 1 | ||||
| -rw-r--r-- | include/unarchive.h | 2 | ||||
| -rw-r--r-- | include/usage.h | 13 | ||||
| -rw-r--r-- | libbb/unzip.c | 48 |
13 files changed, 302 insertions, 78 deletions
diff --git a/archival/Makefile b/archival/Makefile index 8787589ff..35ba02f3b 100644 --- a/archival/Makefile +++ b/archival/Makefile | |||
| @@ -34,6 +34,7 @@ obj-$(CONFIG_GUNZIP) += gunzip.o | |||
| 34 | obj-$(CONFIG_GZIP) += gzip.o | 34 | obj-$(CONFIG_GZIP) += gzip.o |
| 35 | obj-$(CONFIG_RPM2CPIO) += rpm2cpio.o | 35 | obj-$(CONFIG_RPM2CPIO) += rpm2cpio.o |
| 36 | obj-$(CONFIG_TAR) += tar.o | 36 | obj-$(CONFIG_TAR) += tar.o |
| 37 | obj-$(CONFIG_UNZIP) += unzip.o | ||
| 37 | 38 | ||
| 38 | 39 | ||
| 39 | # Hand off to toplevel Rules.mak | 40 | # Hand off to toplevel Rules.mak |
diff --git a/archival/config.in b/archival/config.in index 76a192e13..7b5644f01 100644 --- a/archival/config.in +++ b/archival/config.in | |||
| @@ -20,4 +20,5 @@ if [ "$CONFIG_TAR" = "y" ] ; then | |||
| 20 | bool ' Enable -X and --exclude options (exclude files)' CONFIG_FEATURE_TAR_EXCLUDE | 20 | bool ' Enable -X and --exclude options (exclude files)' CONFIG_FEATURE_TAR_EXCLUDE |
| 21 | bool ' Enable -z option (currently only for extracting)' CONFIG_FEATURE_TAR_GZIP | 21 | bool ' Enable -z option (currently only for extracting)' CONFIG_FEATURE_TAR_GZIP |
| 22 | fi | 22 | fi |
| 23 | bool 'unzip' CONFIG_UNZIP | ||
| 23 | endmenu | 24 | endmenu |
diff --git a/archival/libunarchive/Makefile b/archival/libunarchive/Makefile index 0c7219dcd..a8409a432 100644 --- a/archival/libunarchive/Makefile +++ b/archival/libunarchive/Makefile | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | TOPDIR :=../.. | 20 | TOPDIR :=../.. |
| 21 | L_TARGET := libunarchive.a | 21 | L_TARGET := libunarchive.a |
| 22 | 22 | ||
| 23 | obj-y := unarchive.o seek_sub_file.o | 23 | obj-y := unarchive.o seek_sub_file.o |
| 24 | obj-n := | 24 | obj-n := |
| 25 | obj- := | 25 | obj- := |
| 26 | 26 | ||
| @@ -41,13 +41,17 @@ ifeq ($(CONFIG_CPIO),y) | |||
| 41 | endif | 41 | endif |
| 42 | 42 | ||
| 43 | ifeq ($(CONFIG_RPM2CPIO),y) | 43 | ifeq ($(CONFIG_RPM2CPIO),y) |
| 44 | obj-y += get_header_cpio.o | 44 | obj-y += get_header_cpio.o |
| 45 | endif | 45 | endif |
| 46 | 46 | ||
| 47 | ifeq ($(CONFIG_TAR),y) | 47 | ifeq ($(CONFIG_TAR),y) |
| 48 | obj-y += get_header_tar.o | 48 | obj-y += get_header_tar.o |
| 49 | endif | 49 | endif |
| 50 | 50 | ||
| 51 | ifeq ($(CONFIG_UNZIP),y) | ||
| 52 | obj-y += get_header_zip.o | ||
| 53 | endif | ||
| 54 | |||
| 51 | 55 | ||
| 52 | # Hand off to toplevel Rules.mak | 56 | # Hand off to toplevel Rules.mak |
| 53 | include $(TOPDIR)/Rules.mak | 57 | include $(TOPDIR)/Rules.mak |
diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c index 6c28d181d..8075fd717 100644 --- a/archival/libunarchive/decompress_unzip.c +++ b/archival/libunarchive/decompress_unzip.c | |||
| @@ -80,7 +80,7 @@ static const int ERROR = 1; | |||
| 80 | 80 | ||
| 81 | /* | 81 | /* |
| 82 | * window size--must be a power of two, and | 82 | * window size--must be a power of two, and |
| 83 | * at least 32K for zip's deflate method | 83 | * at least 32K for zip's deflate method |
| 84 | */ | 84 | */ |
| 85 | static const int WSIZE = 0x8000; | 85 | static const int WSIZE = 0x8000; |
| 86 | 86 | ||
| @@ -846,7 +846,7 @@ static int inflate_block(int *e) | |||
| 846 | * | 846 | * |
| 847 | * GLOBAL VARIABLES: outcnt, bk, bb, hufts, inptr | 847 | * GLOBAL VARIABLES: outcnt, bk, bb, hufts, inptr |
| 848 | */ | 848 | */ |
| 849 | static int inflate(void) | 849 | extern int inflate(FILE *in, FILE *out) |
| 850 | { | 850 | { |
| 851 | int e; /* last block flag */ | 851 | int e; /* last block flag */ |
| 852 | int r; /* result code */ | 852 | int r; /* result code */ |
| @@ -857,6 +857,13 @@ static int inflate(void) | |||
| 857 | bk = 0; | 857 | bk = 0; |
| 858 | bb = 0; | 858 | bb = 0; |
| 859 | 859 | ||
| 860 | in_file = in; | ||
| 861 | out_file = out; | ||
| 862 | |||
| 863 | /* Allocate all global buffers (for DYN_ALLOC option) */ | ||
| 864 | window = xmalloc((size_t)(((2L*WSIZE)+1L)*sizeof(unsigned char))); | ||
| 865 | bytes_out = 0L; | ||
| 866 | |||
| 860 | /* Create the crc table */ | 867 | /* Create the crc table */ |
| 861 | make_crc_table(); | 868 | make_crc_table(); |
| 862 | 869 | ||
| @@ -881,13 +888,15 @@ static int inflate(void) | |||
| 881 | 888 | ||
| 882 | /* flush out window */ | 889 | /* flush out window */ |
| 883 | flush_window(); | 890 | flush_window(); |
| 891 | free(window); | ||
| 892 | free(crc_table); | ||
| 884 | 893 | ||
| 885 | /* return success */ | 894 | /* return success */ |
| 886 | return 0; | 895 | return 0; |
| 887 | } | 896 | } |
| 888 | 897 | ||
| 889 | /* =========================================================================== | 898 | /* =========================================================================== |
| 890 | * Unzip in to out. This routine works on both gzip and pkzip files. | 899 | * Unzip in to out. This routine works on gzip files only. |
| 891 | * | 900 | * |
| 892 | * IN assertions: the buffer inbuf contains already the beginning of | 901 | * IN assertions: the buffer inbuf contains already the beginning of |
| 893 | * the compressed data, from offsets inptr to insize-1 included. | 902 | * the compressed data, from offsets inptr to insize-1 included. |
| @@ -901,9 +910,6 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file) | |||
| 901 | typedef void (*sig_type) (int); | 910 | typedef void (*sig_type) (int); |
| 902 | unsigned short i; | 911 | unsigned short i; |
| 903 | 912 | ||
| 904 | in_file = l_in_file; | ||
| 905 | out_file = l_out_file; | ||
| 906 | |||
| 907 | if (signal(SIGINT, SIG_IGN) != SIG_IGN) { | 913 | if (signal(SIGINT, SIG_IGN) != SIG_IGN) { |
| 908 | (void) signal(SIGINT, (sig_type) abort_gzip); | 914 | (void) signal(SIGINT, (sig_type) abort_gzip); |
| 909 | } | 915 | } |
| @@ -918,53 +924,48 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file) | |||
| 918 | } | 924 | } |
| 919 | #endif | 925 | #endif |
| 920 | 926 | ||
| 921 | /* Allocate all global buffers (for DYN_ALLOC option) */ | ||
| 922 | window = xmalloc((size_t)(((2L*WSIZE)+1L)*sizeof(unsigned char))); | ||
| 923 | outcnt = 0; | ||
| 924 | bytes_out = 0L; | ||
| 925 | |||
| 926 | /* Magic header for gzip files, 1F 8B = \037\213 */ | 927 | /* Magic header for gzip files, 1F 8B = \037\213 */ |
| 927 | if ((fgetc(in_file) != 0x1F) || (fgetc(in_file) != 0x8b)) { | 928 | if ((fgetc(l_in_file) != 0x1F) || (fgetc(l_in_file) != 0x8b)) { |
| 928 | error_msg("Invalid gzip magic"); | 929 | error_msg("Invalid gzip magic"); |
| 929 | return EXIT_FAILURE; | 930 | return EXIT_FAILURE; |
| 930 | } | 931 | } |
| 931 | 932 | ||
| 932 | /* Check the compression method */ | 933 | /* Check the compression method */ |
| 933 | if (fgetc(in_file) != 8) { | 934 | if (fgetc(l_in_file) != 8) { |
| 934 | error_msg("Unknown compression method"); | 935 | error_msg("Unknown compression method"); |
| 935 | return(-1); | 936 | return(-1); |
| 936 | } | 937 | } |
| 937 | 938 | ||
| 938 | flags = (unsigned char) fgetc(in_file); | 939 | flags = (unsigned char) fgetc(l_in_file); |
| 939 | 940 | ||
| 940 | /* Ignore time stamp(4), extra flags(1), OS type(1) */ | 941 | /* Ignore time stamp(4), extra flags(1), OS type(1) */ |
| 941 | for (i = 0; i < 6; i++) { | 942 | for (i = 0; i < 6; i++) { |
| 942 | fgetc(in_file); | 943 | fgetc(l_in_file); |
| 943 | } | 944 | } |
| 944 | 945 | ||
| 945 | if (flags & 0x04) { | 946 | if (flags & 0x04) { |
| 946 | /* bit 2 set: extra field present */ | 947 | /* bit 2 set: extra field present */ |
| 947 | const unsigned short extra = fgetc(in_file) + (fgetc(in_file) << 8); | 948 | const unsigned short extra = fgetc(l_in_file) + (fgetc(l_in_file) << 8); |
| 948 | 949 | ||
| 949 | for (i = 0; i < extra; i++) { | 950 | for (i = 0; i < extra; i++) { |
| 950 | fgetc(in_file); | 951 | fgetc(l_in_file); |
| 951 | } | 952 | } |
| 952 | } | 953 | } |
| 953 | 954 | ||
| 954 | /* Discard original name if any */ | 955 | /* Discard original name if any */ |
| 955 | if (flags & 0x08) { | 956 | if (flags & 0x08) { |
| 956 | /* bit 3 set: original file name present */ | 957 | /* bit 3 set: original file name present */ |
| 957 | while (fgetc(in_file) != 0); /* null */ | 958 | while (fgetc(l_in_file) != 0); /* null */ |
| 958 | } | 959 | } |
| 959 | 960 | ||
| 960 | /* Discard file comment if any */ | 961 | /* Discard file comment if any */ |
| 961 | if (flags & 0x10) { | 962 | if (flags & 0x10) { |
| 962 | /* bit 4 set: file comment present */ | 963 | /* bit 4 set: file comment present */ |
| 963 | while (fgetc(in_file) != 0); /* null */ | 964 | while (fgetc(l_in_file) != 0); /* null */ |
| 964 | } | 965 | } |
| 965 | 966 | ||
| 966 | /* Decompress */ | 967 | /* Decompress */ |
| 967 | if (inflate() != 0) { | 968 | if (inflate(l_in_file, l_out_file) != 0) { |
| 968 | error_msg("invalid compressed data--format violated"); | 969 | error_msg("invalid compressed data--format violated"); |
| 969 | } | 970 | } |
| 970 | 971 | ||
| @@ -972,7 +973,7 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file) | |||
| 972 | * crc32 (see algorithm.doc) | 973 | * crc32 (see algorithm.doc) |
| 973 | * uncompressed input size modulo 2^32 | 974 | * uncompressed input size modulo 2^32 |
| 974 | */ | 975 | */ |
| 975 | fread(buf, 1, 8, in_file); | 976 | fread(buf, 1, 8, l_in_file); |
| 976 | 977 | ||
| 977 | /* Validate decompression - crc */ | 978 | /* Validate decompression - crc */ |
| 978 | if ((unsigned int)((buf[0] | (buf[1] << 8)) |((buf[2] | (buf[3] << 8)) << 16)) != (crc ^ 0xffffffffL)) { | 979 | if ((unsigned int)((buf[0] | (buf[1] << 8)) |((buf[2] | (buf[3] << 8)) << 16)) != (crc ^ 0xffffffffL)) { |
| @@ -983,14 +984,11 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file) | |||
| 983 | error_msg("invalid compressed data--length error"); | 984 | error_msg("invalid compressed data--length error"); |
| 984 | } | 985 | } |
| 985 | 986 | ||
| 986 | free(window); | ||
| 987 | free(crc_table); | ||
| 988 | |||
| 989 | return 0; | 987 | return 0; |
| 990 | } | 988 | } |
| 991 | 989 | ||
| 992 | /* | 990 | /* |
| 993 | * This needs access to global variables wondow and crc_table, so its not in its own file. | 991 | * This needs access to global variables window and crc_table, so its not in its own file. |
| 994 | */ | 992 | */ |
| 995 | extern void gz_close(int gunzip_pid) | 993 | extern void gz_close(int gunzip_pid) |
| 996 | { | 994 | { |
diff --git a/archival/libunarchive/get_header_zip.c b/archival/libunarchive/get_header_zip.c new file mode 100644 index 000000000..84f2a54f2 --- /dev/null +++ b/archival/libunarchive/get_header_zip.c | |||
| @@ -0,0 +1,110 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | ||
| 2 | /* | ||
| 3 | * get_header_zip for busybox | ||
| 4 | * | ||
| 5 | * Copyright (C) 2001 by Laurence Anderson | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <stdio.h> | ||
| 23 | #include <stdlib.h> | ||
| 24 | #include <string.h> | ||
| 25 | #include "unarchive.h" | ||
| 26 | #include "libbb.h" | ||
| 27 | |||
| 28 | #define ZIP_FILEHEADER_MAGIC 0x04034b50 | ||
| 29 | #define ZIP_CDS_MAGIC 0x02014b50 | ||
| 30 | #define ZIP_CDS_END_MAGIC 0x06054b50 | ||
| 31 | #define ZIP_DD_MAGIC 0x8074b50 | ||
| 32 | |||
| 33 | file_header_t *get_header_zip(FILE *zip_stream) | ||
| 34 | { | ||
| 35 | struct { | ||
| 36 | short version __attribute__ ((packed)); | ||
| 37 | short flags __attribute__ ((packed)); | ||
| 38 | short method __attribute__ ((packed)); | ||
| 39 | short modtime __attribute__ ((packed)); | ||
| 40 | short moddate __attribute__ ((packed)); | ||
| 41 | int crc32 __attribute__ ((packed)); | ||
| 42 | int cmpsize __attribute__ ((packed)); | ||
| 43 | int ucmpsize __attribute__ ((packed)); | ||
| 44 | short filename_len __attribute__ ((packed)); | ||
| 45 | short extra_len __attribute__ ((packed)); | ||
| 46 | } zip_header; | ||
| 47 | file_header_t *zip_entry = NULL; | ||
| 48 | int magic; | ||
| 49 | static int dd_ahead = 0; // If this is true, the we didn't know how long the last extraced file was | ||
| 50 | |||
| 51 | fread (&magic, 4, 1, zip_stream); | ||
| 52 | archive_offset += 4; | ||
| 53 | |||
| 54 | if (feof(zip_stream)) return(NULL); | ||
| 55 | checkmagic: | ||
| 56 | switch (magic) { | ||
| 57 | case ZIP_FILEHEADER_MAGIC: | ||
| 58 | zip_entry = xcalloc(1, sizeof(file_header_t)); | ||
| 59 | fread (&zip_header, sizeof(zip_header), 1, zip_stream); | ||
| 60 | archive_offset += sizeof(zip_header); | ||
| 61 | if (!(zip_header.method == 8 || zip_header.method == 0)) { printf("Unsupported compression method %d\n", zip_header.method); return(NULL); } | ||
| 62 | zip_entry->name = calloc(zip_header.filename_len + 1, sizeof(char)); | ||
| 63 | fread (zip_entry->name, sizeof(char), zip_header.filename_len, zip_stream); | ||
| 64 | archive_offset += zip_header.filename_len; | ||
| 65 | seek_sub_file(zip_stream, zip_header.extra_len); | ||
| 66 | zip_entry->size = zip_header.cmpsize; | ||
| 67 | if (zip_header.method == 8) zip_entry->extract_func = &inflate; | ||
| 68 | zip_entry->mode = S_IFREG | 0777; | ||
| 69 | // Time/Date? | ||
| 70 | if (*(zip_entry->name + strlen(zip_entry->name) - 1) == '/') { // Files that end in a / are directories | ||
| 71 | zip_entry->mode ^= S_IFREG; | ||
| 72 | zip_entry->mode |= S_IFDIR; | ||
| 73 | *(zip_entry->name + strlen(zip_entry->name) - 1) = '\0'; // Remove trailing / so unarchive doesn't get confused | ||
| 74 | } | ||
| 75 | //printf("cmpsize: %d, ucmpsize: %d, method: %d\n", zip_header.cmpsize, zip_header.ucmpsize, zip_header.method); | ||
| 76 | if (zip_header.flags & 0x8) { // crc32, and sizes are in the data description _after_ the file | ||
| 77 | if (zip_header.cmpsize == 0) dd_ahead = 1; // As we don't know how long this file it is difficult to skip! but it is compressed, so normally its ok | ||
| 78 | if (zip_header.ucmpsize != 0) dd_ahead = 2; // Humm... we would otherwise skip this twice - not good! | ||
| 79 | } | ||
| 80 | break; | ||
| 81 | case ZIP_CDS_MAGIC: /* FALLTHRU */ | ||
| 82 | case ZIP_CDS_END_MAGIC: | ||
| 83 | return(NULL); | ||
| 84 | break; | ||
| 85 | case ZIP_DD_MAGIC: { | ||
| 86 | int cmpsize; | ||
| 87 | seek_sub_file(zip_stream, 4); // Skip crc32 | ||
| 88 | fread(&cmpsize, 4, 1, zip_stream); | ||
| 89 | archive_offset += 4; | ||
| 90 | if (dd_ahead == 1) archive_offset += cmpsize; | ||
| 91 | seek_sub_file(zip_stream, 4); // Skip uncompressed size | ||
| 92 | dd_ahead = 0; | ||
| 93 | return (get_header_zip(zip_stream)); | ||
| 94 | break; } | ||
| 95 | default: | ||
| 96 | if (!dd_ahead) error_msg("Invalid magic (%#x): Trying to skip junk", magic); | ||
| 97 | dd_ahead = 0; | ||
| 98 | while (!feof(zip_stream)) { | ||
| 99 | int tmpmagic; | ||
| 100 | tmpmagic = fgetc(zip_stream); | ||
| 101 | archive_offset++; | ||
| 102 | magic = ((magic >> 8) & 0x00ffffff) | ((tmpmagic << 24) & 0xff000000); | ||
| 103 | if (magic == ZIP_FILEHEADER_MAGIC || magic == ZIP_CDS_MAGIC || magic == ZIP_CDS_END_MAGIC) goto checkmagic; | ||
| 104 | } | ||
| 105 | error_msg("End of archive reached: Bad archive"); | ||
| 106 | return(NULL); | ||
| 107 | } | ||
| 108 | //if (archive_offset != ftell(zip_stream)) printf("Archive offset out of sync (%d,%d)\n", (int) archive_offset, (int) ftell(zip_stream)); | ||
| 109 | return(zip_entry); | ||
| 110 | } | ||
diff --git a/archival/libunarchive/unarchive.c b/archival/libunarchive/unarchive.c index ff9b5876f..41be963ef 100644 --- a/archival/libunarchive/unarchive.c +++ b/archival/libunarchive/unarchive.c | |||
| @@ -120,7 +120,8 @@ char *extract_archive(FILE *src_stream, FILE *out_stream, const file_header_t *f | |||
| 120 | return NULL; | 120 | return NULL; |
| 121 | } | 121 | } |
| 122 | archive_offset += file_entry->size; | 122 | archive_offset += file_entry->size; |
| 123 | copy_file_chunk(src_stream, dst_stream, file_entry->size); | 123 | if (file_entry->extract_func) file_entry->extract_func(src_stream, dst_stream); |
| 124 | else copy_file_chunk(src_stream, dst_stream, file_entry->size); | ||
| 124 | fclose(dst_stream); | 125 | fclose(dst_stream); |
| 125 | } | 126 | } |
| 126 | break; | 127 | break; |
diff --git a/archival/libunarchive/unzip.c b/archival/libunarchive/unzip.c index 6c28d181d..8075fd717 100644 --- a/archival/libunarchive/unzip.c +++ b/archival/libunarchive/unzip.c | |||
| @@ -80,7 +80,7 @@ static const int ERROR = 1; | |||
| 80 | 80 | ||
| 81 | /* | 81 | /* |
| 82 | * window size--must be a power of two, and | 82 | * window size--must be a power of two, and |
| 83 | * at least 32K for zip's deflate method | 83 | * at least 32K for zip's deflate method |
| 84 | */ | 84 | */ |
| 85 | static const int WSIZE = 0x8000; | 85 | static const int WSIZE = 0x8000; |
| 86 | 86 | ||
| @@ -846,7 +846,7 @@ static int inflate_block(int *e) | |||
| 846 | * | 846 | * |
| 847 | * GLOBAL VARIABLES: outcnt, bk, bb, hufts, inptr | 847 | * GLOBAL VARIABLES: outcnt, bk, bb, hufts, inptr |
| 848 | */ | 848 | */ |
| 849 | static int inflate(void) | 849 | extern int inflate(FILE *in, FILE *out) |
| 850 | { | 850 | { |
| 851 | int e; /* last block flag */ | 851 | int e; /* last block flag */ |
| 852 | int r; /* result code */ | 852 | int r; /* result code */ |
| @@ -857,6 +857,13 @@ static int inflate(void) | |||
| 857 | bk = 0; | 857 | bk = 0; |
| 858 | bb = 0; | 858 | bb = 0; |
| 859 | 859 | ||
| 860 | in_file = in; | ||
| 861 | out_file = out; | ||
| 862 | |||
| 863 | /* Allocate all global buffers (for DYN_ALLOC option) */ | ||
| 864 | window = xmalloc((size_t)(((2L*WSIZE)+1L)*sizeof(unsigned char))); | ||
| 865 | bytes_out = 0L; | ||
| 866 | |||
| 860 | /* Create the crc table */ | 867 | /* Create the crc table */ |
| 861 | make_crc_table(); | 868 | make_crc_table(); |
| 862 | 869 | ||
| @@ -881,13 +888,15 @@ static int inflate(void) | |||
| 881 | 888 | ||
| 882 | /* flush out window */ | 889 | /* flush out window */ |
| 883 | flush_window(); | 890 | flush_window(); |
| 891 | free(window); | ||
| 892 | free(crc_table); | ||
| 884 | 893 | ||
| 885 | /* return success */ | 894 | /* return success */ |
| 886 | return 0; | 895 | return 0; |
| 887 | } | 896 | } |
| 888 | 897 | ||
| 889 | /* =========================================================================== | 898 | /* =========================================================================== |
| 890 | * Unzip in to out. This routine works on both gzip and pkzip files. | 899 | * Unzip in to out. This routine works on gzip files only. |
| 891 | * | 900 | * |
| 892 | * IN assertions: the buffer inbuf contains already the beginning of | 901 | * IN assertions: the buffer inbuf contains already the beginning of |
| 893 | * the compressed data, from offsets inptr to insize-1 included. | 902 | * the compressed data, from offsets inptr to insize-1 included. |
| @@ -901,9 +910,6 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file) | |||
| 901 | typedef void (*sig_type) (int); | 910 | typedef void (*sig_type) (int); |
| 902 | unsigned short i; | 911 | unsigned short i; |
| 903 | 912 | ||
| 904 | in_file = l_in_file; | ||
| 905 | out_file = l_out_file; | ||
| 906 | |||
| 907 | if (signal(SIGINT, SIG_IGN) != SIG_IGN) { | 913 | if (signal(SIGINT, SIG_IGN) != SIG_IGN) { |
| 908 | (void) signal(SIGINT, (sig_type) abort_gzip); | 914 | (void) signal(SIGINT, (sig_type) abort_gzip); |
| 909 | } | 915 | } |
| @@ -918,53 +924,48 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file) | |||
| 918 | } | 924 | } |
| 919 | #endif | 925 | #endif |
| 920 | 926 | ||
| 921 | /* Allocate all global buffers (for DYN_ALLOC option) */ | ||
| 922 | window = xmalloc((size_t)(((2L*WSIZE)+1L)*sizeof(unsigned char))); | ||
| 923 | outcnt = 0; | ||
| 924 | bytes_out = 0L; | ||
| 925 | |||
| 926 | /* Magic header for gzip files, 1F 8B = \037\213 */ | 927 | /* Magic header for gzip files, 1F 8B = \037\213 */ |
| 927 | if ((fgetc(in_file) != 0x1F) || (fgetc(in_file) != 0x8b)) { | 928 | if ((fgetc(l_in_file) != 0x1F) || (fgetc(l_in_file) != 0x8b)) { |
| 928 | error_msg("Invalid gzip magic"); | 929 | error_msg("Invalid gzip magic"); |
| 929 | return EXIT_FAILURE; | 930 | return EXIT_FAILURE; |
| 930 | } | 931 | } |
| 931 | 932 | ||
| 932 | /* Check the compression method */ | 933 | /* Check the compression method */ |
| 933 | if (fgetc(in_file) != 8) { | 934 | if (fgetc(l_in_file) != 8) { |
| 934 | error_msg("Unknown compression method"); | 935 | error_msg("Unknown compression method"); |
| 935 | return(-1); | 936 | return(-1); |
| 936 | } | 937 | } |
| 937 | 938 | ||
| 938 | flags = (unsigned char) fgetc(in_file); | 939 | flags = (unsigned char) fgetc(l_in_file); |
| 939 | 940 | ||
| 940 | /* Ignore time stamp(4), extra flags(1), OS type(1) */ | 941 | /* Ignore time stamp(4), extra flags(1), OS type(1) */ |
| 941 | for (i = 0; i < 6; i++) { | 942 | for (i = 0; i < 6; i++) { |
| 942 | fgetc(in_file); | 943 | fgetc(l_in_file); |
| 943 | } | 944 | } |
| 944 | 945 | ||
| 945 | if (flags & 0x04) { | 946 | if (flags & 0x04) { |
| 946 | /* bit 2 set: extra field present */ | 947 | /* bit 2 set: extra field present */ |
| 947 | const unsigned short extra = fgetc(in_file) + (fgetc(in_file) << 8); | 948 | const unsigned short extra = fgetc(l_in_file) + (fgetc(l_in_file) << 8); |
| 948 | 949 | ||
| 949 | for (i = 0; i < extra; i++) { | 950 | for (i = 0; i < extra; i++) { |
| 950 | fgetc(in_file); | 951 | fgetc(l_in_file); |
| 951 | } | 952 | } |
| 952 | } | 953 | } |
| 953 | 954 | ||
| 954 | /* Discard original name if any */ | 955 | /* Discard original name if any */ |
| 955 | if (flags & 0x08) { | 956 | if (flags & 0x08) { |
| 956 | /* bit 3 set: original file name present */ | 957 | /* bit 3 set: original file name present */ |
| 957 | while (fgetc(in_file) != 0); /* null */ | 958 | while (fgetc(l_in_file) != 0); /* null */ |
| 958 | } | 959 | } |
| 959 | 960 | ||
| 960 | /* Discard file comment if any */ | 961 | /* Discard file comment if any */ |
| 961 | if (flags & 0x10) { | 962 | if (flags & 0x10) { |
| 962 | /* bit 4 set: file comment present */ | 963 | /* bit 4 set: file comment present */ |
| 963 | while (fgetc(in_file) != 0); /* null */ | 964 | while (fgetc(l_in_file) != 0); /* null */ |
| 964 | } | 965 | } |
| 965 | 966 | ||
| 966 | /* Decompress */ | 967 | /* Decompress */ |
| 967 | if (inflate() != 0) { | 968 | if (inflate(l_in_file, l_out_file) != 0) { |
| 968 | error_msg("invalid compressed data--format violated"); | 969 | error_msg("invalid compressed data--format violated"); |
| 969 | } | 970 | } |
| 970 | 971 | ||
| @@ -972,7 +973,7 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file) | |||
| 972 | * crc32 (see algorithm.doc) | 973 | * crc32 (see algorithm.doc) |
| 973 | * uncompressed input size modulo 2^32 | 974 | * uncompressed input size modulo 2^32 |
| 974 | */ | 975 | */ |
| 975 | fread(buf, 1, 8, in_file); | 976 | fread(buf, 1, 8, l_in_file); |
| 976 | 977 | ||
| 977 | /* Validate decompression - crc */ | 978 | /* Validate decompression - crc */ |
| 978 | if ((unsigned int)((buf[0] | (buf[1] << 8)) |((buf[2] | (buf[3] << 8)) << 16)) != (crc ^ 0xffffffffL)) { | 979 | if ((unsigned int)((buf[0] | (buf[1] << 8)) |((buf[2] | (buf[3] << 8)) << 16)) != (crc ^ 0xffffffffL)) { |
| @@ -983,14 +984,11 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file) | |||
| 983 | error_msg("invalid compressed data--length error"); | 984 | error_msg("invalid compressed data--length error"); |
| 984 | } | 985 | } |
| 985 | 986 | ||
| 986 | free(window); | ||
| 987 | free(crc_table); | ||
| 988 | |||
| 989 | return 0; | 987 | return 0; |
| 990 | } | 988 | } |
| 991 | 989 | ||
| 992 | /* | 990 | /* |
| 993 | * This needs access to global variables wondow and crc_table, so its not in its own file. | 991 | * This needs access to global variables window and crc_table, so its not in its own file. |
| 994 | */ | 992 | */ |
| 995 | extern void gz_close(int gunzip_pid) | 993 | extern void gz_close(int gunzip_pid) |
| 996 | { | 994 | { |
diff --git a/archival/unzip.c b/archival/unzip.c new file mode 100644 index 000000000..ae0d7c1dc --- /dev/null +++ b/archival/unzip.c | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | ||
| 2 | /* | ||
| 3 | * Mini unzip implementation for busybox | ||
| 4 | * | ||
| 5 | * Copyright (C) 2001 by Laurence Anderson | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <fcntl.h> | ||
| 24 | #include <getopt.h> | ||
| 25 | #include <stdlib.h> | ||
| 26 | #include <string.h> | ||
| 27 | #include <unistd.h> | ||
| 28 | #include "unarchive.h" | ||
| 29 | #include "busybox.h" | ||
| 30 | |||
| 31 | extern int unzip_main(int argc, char **argv) | ||
| 32 | { | ||
| 33 | FILE *src_stream; | ||
| 34 | int extract_function = extract_all_to_fs | extract_create_leading_dirs; | ||
| 35 | char **extract_names = NULL; | ||
| 36 | char **exclude_names = NULL; | ||
| 37 | int opt = 0; | ||
| 38 | int num_of_entries = 0; | ||
| 39 | int exclude = 0; | ||
| 40 | char *outdir = "./"; | ||
| 41 | FILE *msgout = stdout; | ||
| 42 | |||
| 43 | while ((opt = getopt(argc, argv, "lnopqxd:")) != -1) { | ||
| 44 | switch (opt) { | ||
| 45 | case 'l': | ||
| 46 | extract_function |= extract_verbose_list; | ||
| 47 | extract_function ^= extract_all_to_fs; | ||
| 48 | break; | ||
| 49 | case 'n': | ||
| 50 | break; | ||
| 51 | case 'o': | ||
| 52 | extract_function |= extract_unconditional; | ||
| 53 | break; | ||
| 54 | case 'p': | ||
| 55 | extract_function |= extract_to_stdout; | ||
| 56 | extract_function ^= extract_all_to_fs; | ||
| 57 | /* FALLTHROUGH */ | ||
| 58 | case 'q': | ||
| 59 | msgout = xfopen("/dev/null", "w"); | ||
| 60 | break; | ||
| 61 | case 'd': | ||
| 62 | outdir = xstrdup(optarg); | ||
| 63 | strcat(outdir, "/"); | ||
| 64 | break; | ||
| 65 | case 'x': | ||
| 66 | exclude = 1; | ||
| 67 | break; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | if (optind == argc) { | ||
| 72 | show_usage(); | ||
| 73 | } | ||
| 74 | |||
| 75 | if (*argv[optind] == '-') src_stream = stdin; | ||
| 76 | else src_stream = xfopen(argv[optind++], "r"); | ||
| 77 | |||
| 78 | while (optind < argc) { | ||
| 79 | if (exclude) { | ||
| 80 | exclude_names = xrealloc(exclude_names, sizeof(char *) * (num_of_entries + 2)); | ||
| 81 | exclude_names[num_of_entries] = xstrdup(argv[optind]); | ||
| 82 | } else { | ||
| 83 | extract_names = xrealloc(extract_names, sizeof(char *) * (num_of_entries + 2)); | ||
| 84 | extract_names[num_of_entries] = xstrdup(argv[optind]); | ||
| 85 | } | ||
| 86 | num_of_entries++; | ||
| 87 | if (exclude) exclude_names[num_of_entries] = NULL; | ||
| 88 | else extract_names[num_of_entries] = NULL; | ||
| 89 | optind++; | ||
| 90 | } | ||
| 91 | |||
| 92 | unarchive(src_stream, msgout, &get_header_zip, extract_function, outdir, extract_names, exclude_names); | ||
| 93 | return EXIT_SUCCESS; | ||
| 94 | } | ||
diff --git a/include/applets.h b/include/applets.h index ba0a9aaa9..0d310bdc3 100644 --- a/include/applets.h +++ b/include/applets.h | |||
| @@ -470,6 +470,9 @@ | |||
| 470 | #ifdef CONFIG_UNIX2DOS | 470 | #ifdef CONFIG_UNIX2DOS |
| 471 | APPLET(unix2dos, dos2unix_main, _BB_DIR_USR_BIN) | 471 | APPLET(unix2dos, dos2unix_main, _BB_DIR_USR_BIN) |
| 472 | #endif | 472 | #endif |
| 473 | #ifdef CONFIG_UNZIP | ||
| 474 | APPLET(unzip, unzip_main, _BB_DIR_USR_BIN) | ||
| 475 | #endif | ||
| 473 | #ifdef CONFIG_UPDATE | 476 | #ifdef CONFIG_UPDATE |
| 474 | APPLET(update, update_main, _BB_DIR_SBIN) | 477 | APPLET(update, update_main, _BB_DIR_SBIN) |
| 475 | #endif | 478 | #endif |
diff --git a/include/libbb.h b/include/libbb.h index fccdf5fdf..8dadfd958 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -215,6 +215,7 @@ extern long arith (const char *startbuf, int *errcode); | |||
| 215 | int read_package_field(const char *package_buffer, char **field_name, char **field_value); | 215 | int read_package_field(const char *package_buffer, char **field_name, char **field_value); |
| 216 | char *fgets_str(FILE *file, const char *terminating_string); | 216 | char *fgets_str(FILE *file, const char *terminating_string); |
| 217 | 217 | ||
| 218 | extern int inflate(FILE *in, FILE *out); | ||
| 218 | extern int unzip(FILE *l_in_file, FILE *l_out_file); | 219 | extern int unzip(FILE *l_in_file, FILE *l_out_file); |
| 219 | extern void gz_close(int gunzip_pid); | 220 | extern void gz_close(int gunzip_pid); |
| 220 | extern FILE *gz_open(FILE *compressed_file, int *pid); | 221 | extern FILE *gz_open(FILE *compressed_file, int *pid); |
diff --git a/include/unarchive.h b/include/unarchive.h index be49f3d01..eada1c337 100644 --- a/include/unarchive.h +++ b/include/unarchive.h | |||
| @@ -26,11 +26,13 @@ typedef struct file_headers_s { | |||
| 26 | mode_t mode; | 26 | mode_t mode; |
| 27 | time_t mtime; | 27 | time_t mtime; |
| 28 | dev_t device; | 28 | dev_t device; |
| 29 | int (*extract_func)(FILE *, FILE *); | ||
| 29 | } file_header_t; | 30 | } file_header_t; |
| 30 | 31 | ||
| 31 | file_header_t *get_header_ar(FILE *in_file); | 32 | file_header_t *get_header_ar(FILE *in_file); |
| 32 | file_header_t *get_header_cpio(FILE *src_stream); | 33 | file_header_t *get_header_cpio(FILE *src_stream); |
| 33 | file_header_t *get_header_tar(FILE *tar_stream); | 34 | file_header_t *get_header_tar(FILE *tar_stream); |
| 35 | file_header_t *get_header_zip(FILE *zip_stream); | ||
| 34 | 36 | ||
| 35 | void seek_sub_file(FILE *src_stream, const int count); | 37 | void seek_sub_file(FILE *src_stream, const int count); |
| 36 | 38 | ||
diff --git a/include/usage.h b/include/usage.h index 20e2448fd..cd3af9c55 100644 --- a/include/usage.h +++ b/include/usage.h | |||
| @@ -1851,6 +1851,19 @@ | |||
| 1851 | "\t-u\toutput will be in UNIX format\n" \ | 1851 | "\t-u\toutput will be in UNIX format\n" \ |
| 1852 | "\t-d\toutput will be in DOS format" | 1852 | "\t-d\toutput will be in DOS format" |
| 1853 | 1853 | ||
| 1854 | #define unzip_trivial_usage \ | ||
| 1855 | "[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]" | ||
| 1856 | #define unzip_full_usage \ | ||
| 1857 | "Extracts files from ZIP archives\n" \ | ||
| 1858 | "Options:\n" \ | ||
| 1859 | "\t-l\tlist archive contents (short form)\n" \ | ||
| 1860 | "\t-n\tnever overwrite existing files (default)\n" \ | ||
| 1861 | "\t-o\toverwrite files without prompting\n" \ | ||
| 1862 | "\t-p\tsend output to stdout\n" \ | ||
| 1863 | "\t-q\tbe quiet\n" \ | ||
| 1864 | "\t-x\texclude these files\n" \ | ||
| 1865 | "\t-d\textract files into this directory" | ||
| 1866 | |||
| 1854 | #define update_trivial_usage \ | 1867 | #define update_trivial_usage \ |
| 1855 | "[options]" | 1868 | "[options]" |
| 1856 | #define update_full_usage \ | 1869 | #define update_full_usage \ |
diff --git a/libbb/unzip.c b/libbb/unzip.c index 6c28d181d..8075fd717 100644 --- a/libbb/unzip.c +++ b/libbb/unzip.c | |||
| @@ -80,7 +80,7 @@ static const int ERROR = 1; | |||
| 80 | 80 | ||
| 81 | /* | 81 | /* |
| 82 | * window size--must be a power of two, and | 82 | * window size--must be a power of two, and |
| 83 | * at least 32K for zip's deflate method | 83 | * at least 32K for zip's deflate method |
| 84 | */ | 84 | */ |
| 85 | static const int WSIZE = 0x8000; | 85 | static const int WSIZE = 0x8000; |
| 86 | 86 | ||
| @@ -846,7 +846,7 @@ static int inflate_block(int *e) | |||
| 846 | * | 846 | * |
| 847 | * GLOBAL VARIABLES: outcnt, bk, bb, hufts, inptr | 847 | * GLOBAL VARIABLES: outcnt, bk, bb, hufts, inptr |
| 848 | */ | 848 | */ |
| 849 | static int inflate(void) | 849 | extern int inflate(FILE *in, FILE *out) |
| 850 | { | 850 | { |
| 851 | int e; /* last block flag */ | 851 | int e; /* last block flag */ |
| 852 | int r; /* result code */ | 852 | int r; /* result code */ |
| @@ -857,6 +857,13 @@ static int inflate(void) | |||
| 857 | bk = 0; | 857 | bk = 0; |
| 858 | bb = 0; | 858 | bb = 0; |
| 859 | 859 | ||
| 860 | in_file = in; | ||
| 861 | out_file = out; | ||
| 862 | |||
| 863 | /* Allocate all global buffers (for DYN_ALLOC option) */ | ||
| 864 | window = xmalloc((size_t)(((2L*WSIZE)+1L)*sizeof(unsigned char))); | ||
| 865 | bytes_out = 0L; | ||
| 866 | |||
| 860 | /* Create the crc table */ | 867 | /* Create the crc table */ |
| 861 | make_crc_table(); | 868 | make_crc_table(); |
| 862 | 869 | ||
| @@ -881,13 +888,15 @@ static int inflate(void) | |||
| 881 | 888 | ||
| 882 | /* flush out window */ | 889 | /* flush out window */ |
| 883 | flush_window(); | 890 | flush_window(); |
| 891 | free(window); | ||
| 892 | free(crc_table); | ||
| 884 | 893 | ||
| 885 | /* return success */ | 894 | /* return success */ |
| 886 | return 0; | 895 | return 0; |
| 887 | } | 896 | } |
| 888 | 897 | ||
| 889 | /* =========================================================================== | 898 | /* =========================================================================== |
| 890 | * Unzip in to out. This routine works on both gzip and pkzip files. | 899 | * Unzip in to out. This routine works on gzip files only. |
| 891 | * | 900 | * |
| 892 | * IN assertions: the buffer inbuf contains already the beginning of | 901 | * IN assertions: the buffer inbuf contains already the beginning of |
| 893 | * the compressed data, from offsets inptr to insize-1 included. | 902 | * the compressed data, from offsets inptr to insize-1 included. |
| @@ -901,9 +910,6 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file) | |||
| 901 | typedef void (*sig_type) (int); | 910 | typedef void (*sig_type) (int); |
| 902 | unsigned short i; | 911 | unsigned short i; |
| 903 | 912 | ||
| 904 | in_file = l_in_file; | ||
| 905 | out_file = l_out_file; | ||
| 906 | |||
| 907 | if (signal(SIGINT, SIG_IGN) != SIG_IGN) { | 913 | if (signal(SIGINT, SIG_IGN) != SIG_IGN) { |
| 908 | (void) signal(SIGINT, (sig_type) abort_gzip); | 914 | (void) signal(SIGINT, (sig_type) abort_gzip); |
| 909 | } | 915 | } |
| @@ -918,53 +924,48 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file) | |||
| 918 | } | 924 | } |
| 919 | #endif | 925 | #endif |
| 920 | 926 | ||
| 921 | /* Allocate all global buffers (for DYN_ALLOC option) */ | ||
| 922 | window = xmalloc((size_t)(((2L*WSIZE)+1L)*sizeof(unsigned char))); | ||
| 923 | outcnt = 0; | ||
| 924 | bytes_out = 0L; | ||
| 925 | |||
| 926 | /* Magic header for gzip files, 1F 8B = \037\213 */ | 927 | /* Magic header for gzip files, 1F 8B = \037\213 */ |
| 927 | if ((fgetc(in_file) != 0x1F) || (fgetc(in_file) != 0x8b)) { | 928 | if ((fgetc(l_in_file) != 0x1F) || (fgetc(l_in_file) != 0x8b)) { |
| 928 | error_msg("Invalid gzip magic"); | 929 | error_msg("Invalid gzip magic"); |
| 929 | return EXIT_FAILURE; | 930 | return EXIT_FAILURE; |
| 930 | } | 931 | } |
| 931 | 932 | ||
| 932 | /* Check the compression method */ | 933 | /* Check the compression method */ |
| 933 | if (fgetc(in_file) != 8) { | 934 | if (fgetc(l_in_file) != 8) { |
| 934 | error_msg("Unknown compression method"); | 935 | error_msg("Unknown compression method"); |
| 935 | return(-1); | 936 | return(-1); |
| 936 | } | 937 | } |
| 937 | 938 | ||
| 938 | flags = (unsigned char) fgetc(in_file); | 939 | flags = (unsigned char) fgetc(l_in_file); |
| 939 | 940 | ||
| 940 | /* Ignore time stamp(4), extra flags(1), OS type(1) */ | 941 | /* Ignore time stamp(4), extra flags(1), OS type(1) */ |
| 941 | for (i = 0; i < 6; i++) { | 942 | for (i = 0; i < 6; i++) { |
| 942 | fgetc(in_file); | 943 | fgetc(l_in_file); |
| 943 | } | 944 | } |
| 944 | 945 | ||
| 945 | if (flags & 0x04) { | 946 | if (flags & 0x04) { |
| 946 | /* bit 2 set: extra field present */ | 947 | /* bit 2 set: extra field present */ |
| 947 | const unsigned short extra = fgetc(in_file) + (fgetc(in_file) << 8); | 948 | const unsigned short extra = fgetc(l_in_file) + (fgetc(l_in_file) << 8); |
| 948 | 949 | ||
| 949 | for (i = 0; i < extra; i++) { | 950 | for (i = 0; i < extra; i++) { |
| 950 | fgetc(in_file); | 951 | fgetc(l_in_file); |
| 951 | } | 952 | } |
| 952 | } | 953 | } |
| 953 | 954 | ||
| 954 | /* Discard original name if any */ | 955 | /* Discard original name if any */ |
| 955 | if (flags & 0x08) { | 956 | if (flags & 0x08) { |
| 956 | /* bit 3 set: original file name present */ | 957 | /* bit 3 set: original file name present */ |
| 957 | while (fgetc(in_file) != 0); /* null */ | 958 | while (fgetc(l_in_file) != 0); /* null */ |
| 958 | } | 959 | } |
| 959 | 960 | ||
| 960 | /* Discard file comment if any */ | 961 | /* Discard file comment if any */ |
| 961 | if (flags & 0x10) { | 962 | if (flags & 0x10) { |
| 962 | /* bit 4 set: file comment present */ | 963 | /* bit 4 set: file comment present */ |
| 963 | while (fgetc(in_file) != 0); /* null */ | 964 | while (fgetc(l_in_file) != 0); /* null */ |
| 964 | } | 965 | } |
| 965 | 966 | ||
| 966 | /* Decompress */ | 967 | /* Decompress */ |
| 967 | if (inflate() != 0) { | 968 | if (inflate(l_in_file, l_out_file) != 0) { |
| 968 | error_msg("invalid compressed data--format violated"); | 969 | error_msg("invalid compressed data--format violated"); |
| 969 | } | 970 | } |
| 970 | 971 | ||
| @@ -972,7 +973,7 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file) | |||
| 972 | * crc32 (see algorithm.doc) | 973 | * crc32 (see algorithm.doc) |
| 973 | * uncompressed input size modulo 2^32 | 974 | * uncompressed input size modulo 2^32 |
| 974 | */ | 975 | */ |
| 975 | fread(buf, 1, 8, in_file); | 976 | fread(buf, 1, 8, l_in_file); |
| 976 | 977 | ||
| 977 | /* Validate decompression - crc */ | 978 | /* Validate decompression - crc */ |
| 978 | if ((unsigned int)((buf[0] | (buf[1] << 8)) |((buf[2] | (buf[3] << 8)) << 16)) != (crc ^ 0xffffffffL)) { | 979 | if ((unsigned int)((buf[0] | (buf[1] << 8)) |((buf[2] | (buf[3] << 8)) << 16)) != (crc ^ 0xffffffffL)) { |
| @@ -983,14 +984,11 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file) | |||
| 983 | error_msg("invalid compressed data--length error"); | 984 | error_msg("invalid compressed data--length error"); |
| 984 | } | 985 | } |
| 985 | 986 | ||
| 986 | free(window); | ||
| 987 | free(crc_table); | ||
| 988 | |||
| 989 | return 0; | 987 | return 0; |
| 990 | } | 988 | } |
| 991 | 989 | ||
| 992 | /* | 990 | /* |
| 993 | * This needs access to global variables wondow and crc_table, so its not in its own file. | 991 | * This needs access to global variables window and crc_table, so its not in its own file. |
| 994 | */ | 992 | */ |
| 995 | extern void gz_close(int gunzip_pid) | 993 | extern void gz_close(int gunzip_pid) |
| 996 | { | 994 | { |
