aboutsummaryrefslogtreecommitdiff
path: root/archival/gzip.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-07 19:40:13 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-07 19:40:13 +0000
commit52933d47bd86d6d992f7290fad93d63b53f7a15f (patch)
tree1e7371ee6e4a7f8644e0d71c7987eff89ad9a43e /archival/gzip.c
parentef87d46b8c6ac3be21bcd6f1cad6533289e33f42 (diff)
downloadbusybox-w32-52933d47bd86d6d992f7290fad93d63b53f7a15f.tar.gz
busybox-w32-52933d47bd86d6d992f7290fad93d63b53f7a15f.tar.bz2
busybox-w32-52933d47bd86d6d992f7290fad93d63b53f7a15f.zip
gzip cleanup part #8
Diffstat (limited to 'archival/gzip.c')
-rw-r--r--archival/gzip.c346
1 files changed, 168 insertions, 178 deletions
diff --git a/archival/gzip.c b/archival/gzip.c
index 76836951f..2c8f69d91 100644
--- a/archival/gzip.c
+++ b/archival/gzip.c
@@ -311,11 +311,6 @@ static void check_match(IPos start, IPos match, int length);
311#endif 311#endif
312 312
313 313
314
315/* from zip.c: */
316static int zip(int in, int out);
317static unsigned file_read(void *buf, unsigned size);
318
319/* from deflate.c */ 314/* from deflate.c */
320static void lm_init(ush * flags); 315static void lm_init(ush * flags);
321static ulg deflate(void); 316static ulg deflate(void);
@@ -605,22 +600,8 @@ static void copy_block(char *buf, unsigned len, int header)
605 * input characters, so that a running hash key can be computed from the 600 * input characters, so that a running hash key can be computed from the
606 * previous key instead of complete recalculation each time. 601 * previous key instead of complete recalculation each time.
607 */ 602 */
608#define UPDATE_HASH(h,c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK) 603#define UPDATE_HASH(h, c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK)
609 604
610/* ===========================================================================
611 * Insert string s in the dictionary and set match_head to the previous head
612 * of the hash chain (the most recent string with same hash key). Return
613 * the previous length of the hash chain.
614 * IN assertion: all calls to to INSERT_STRING are made with consecutive
615 * input characters and the first MIN_MATCH bytes of s are valid
616 * (except for the last MIN_MATCH-1 bytes of the input file).
617 */
618#define INSERT_STRING(s, match_head) \
619{ \
620 UPDATE_HASH(ins_h, window[(s) + MIN_MATCH-1]); \
621 prev[(s) & WMASK] = match_head = head[ins_h]; \
622 head[ins_h] = (s); \
623}
624 605
625/* =========================================================================== 606/* ===========================================================================
626 * Initialize the "longest match" routines for a new file 607 * Initialize the "longest match" routines for a new file
@@ -834,9 +815,17 @@ static void fill_window(void)
834 815
835 816
836/* =========================================================================== 817/* ===========================================================================
837 * Flush the current block, with given end-of-file flag. 818 * Same as above, but achieves better compression. We use a lazy
838 * IN assertion: strstart is set to the end of the current match. 819 * evaluation for matches: a match is finally adopted only if there is
820 * no better match at the next window position.
821 *
822 * Processes a new input file and return its compressed length. Sets
823 * the compressed length, crc, deflate flags and internal file
824 * attributes.
839 */ 825 */
826
827/* Flush the current block, with given end-of-file flag.
828 * IN assertion: strstart is set to the end of the current match. */
840#define FLUSH_BLOCK(eof) \ 829#define FLUSH_BLOCK(eof) \
841 flush_block( \ 830 flush_block( \
842 block_start >= 0L \ 831 block_start >= 0L \
@@ -846,16 +835,19 @@ static void fill_window(void)
846 (eof) \ 835 (eof) \
847 ) 836 )
848 837
838/* Insert string s in the dictionary and set match_head to the previous head
839 * of the hash chain (the most recent string with same hash key). Return
840 * the previous length of the hash chain.
841 * IN assertion: all calls to to INSERT_STRING are made with consecutive
842 * input characters and the first MIN_MATCH bytes of s are valid
843 * (except for the last MIN_MATCH-1 bytes of the input file). */
844#define INSERT_STRING(s, match_head) \
845{ \
846 UPDATE_HASH(ins_h, window[(s) + MIN_MATCH-1]); \
847 prev[(s) & WMASK] = match_head = head[ins_h]; \
848 head[ins_h] = (s); \
849}
849 850
850/* ===========================================================================
851 * Same as above, but achieves better compression. We use a lazy
852 * evaluation for matches: a match is finally adopted only if there is
853 * no better match at the next window position.
854 *
855 * Processes a new input file and return its compressed length. Sets
856 * the compressed length, crc, deflate flags and internal file
857 * attributes.
858 */
859static ulg deflate(void) 851static ulg deflate(void)
860{ 852{
861 IPos hash_head; /* head of hash chain */ 853 IPos hash_head; /* head of hash chain */
@@ -959,152 +951,6 @@ static ulg deflate(void)
959 951
960 return FLUSH_BLOCK(1); /* eof */ 952 return FLUSH_BLOCK(1); /* eof */
961} 953}
962
963
964/* ======================================================================== */
965static void abort_gzip(int ATTRIBUTE_UNUSED ignored)
966{
967 exit(1);
968}
969
970int gzip_main(int argc, char **argv)
971{
972 enum {
973 OPT_tostdout = 0x1,
974 OPT_force = 0x2,
975 };
976
977 unsigned opt;
978 int result;
979 int inFileNum;
980 int outFileNum;
981 struct stat statBuf;
982 char *delFileName;
983
984 opt = getopt32(argc, argv, "cf123456789qv" USE_GUNZIP("d"));
985 //if (opt & 0x1) // -c
986 //if (opt & 0x2) // -f
987 /* Ignore 1-9 (compression level) options */
988 //if (opt & 0x4) // -1
989 //if (opt & 0x8) // -2
990 //if (opt & 0x10) // -3
991 //if (opt & 0x20) // -4
992 //if (opt & 0x40) // -5
993 //if (opt & 0x80) // -6
994 //if (opt & 0x100) // -7
995 //if (opt & 0x200) // -8
996 //if (opt & 0x400) // -9
997 //if (opt & 0x800) // -q
998 //if (opt & 0x1000) // -v
999#if ENABLE_GUNZIP /* gunzip_main may not be visible... */
1000 if (opt & 0x2000) { // -d
1001 /* FIXME: getopt32 should not depend on optind */
1002 optind = 1;
1003 return gunzip_main(argc, argv);
1004 }
1005#endif
1006
1007 foreground = signal(SIGINT, SIG_IGN) != SIG_IGN;
1008 if (foreground) {
1009 (void) signal(SIGINT, abort_gzip);
1010 }
1011#ifdef SIGTERM
1012 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
1013 (void) signal(SIGTERM, abort_gzip);
1014 }
1015#endif
1016#ifdef SIGHUP
1017 if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
1018 (void) signal(SIGHUP, abort_gzip);
1019 }
1020#endif
1021
1022 strncpy(z_suffix, ".gz", sizeof(z_suffix) - 1);
1023
1024 /* Allocate all global buffers (for DYN_ALLOC option) */
1025 ALLOC(uch, inbuf, INBUFSIZ + INBUF_EXTRA);
1026 ALLOC(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA);
1027 ALLOC(ush, d_buf, DIST_BUFSIZE);
1028 ALLOC(uch, window, 2L * WSIZE);
1029 ALLOC(ush, tab_prefix, 1L << BITS);
1030
1031 /* Initialise the CRC32 table */
1032 crc_32_tab = crc32_filltable(0);
1033
1034 clear_bufs();
1035
1036 if (optind == argc) {
1037 time_stamp = 0;
1038 zip(STDIN_FILENO, STDOUT_FILENO);
1039 } else {
1040 int i;
1041
1042 for (i = optind; i < argc; i++) {
1043 char *path = NULL;
1044
1045 clear_bufs();
1046 if (LONE_DASH(argv[i])) {
1047 time_stamp = 0;
1048 inFileNum = STDIN_FILENO;
1049 outFileNum = STDOUT_FILENO;
1050 } else {
1051 inFileNum = xopen(argv[i], O_RDONLY);
1052 if (fstat(inFileNum, &statBuf) < 0)
1053 bb_perror_msg_and_die("%s", argv[i]);
1054 time_stamp = statBuf.st_ctime;
1055
1056 if (!(opt & OPT_tostdout)) {
1057 path = xasprintf("%s.gz", argv[i]);
1058
1059 /* Open output file */
1060#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 && defined(O_NOFOLLOW)
1061 outFileNum =
1062 open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW);
1063#else
1064 outFileNum = open(path, O_RDWR | O_CREAT | O_EXCL);
1065#endif
1066 if (outFileNum < 0) {
1067 bb_perror_msg("%s", path);
1068 free(path);
1069 continue;
1070 }
1071
1072 /* Set permissions on the file */
1073 fchmod(outFileNum, statBuf.st_mode);
1074 } else
1075 outFileNum = STDOUT_FILENO;
1076 }
1077
1078 if (path == NULL && isatty(outFileNum) && !(opt & OPT_force)) {
1079 bb_error_msg
1080 ("compressed data not written to a terminal. Use -f to force compression.");
1081 free(path);
1082 continue;
1083 }
1084
1085 result = zip(inFileNum, outFileNum);
1086
1087 if (path != NULL) {
1088 close(inFileNum);
1089 close(outFileNum);
1090
1091 /* Delete the original file */
1092 if (result == 0)
1093 delFileName = argv[i];
1094 else
1095 delFileName = path;
1096
1097 if (unlink(delFileName) < 0)
1098 bb_perror_msg("%s", delFileName);
1099 }
1100
1101 free(path);
1102 }
1103 }
1104
1105 return exit_code;
1106}
1107
1108/* trees.c -- output deflated data using Huffman coding 954/* trees.c -- output deflated data using Huffman coding
1109 * Copyright (C) 1992-1993 Jean-loup Gailly 955 * Copyright (C) 1992-1993 Jean-loup Gailly
1110 * This is free software; you can redistribute it and/or modify it under the 956 * This is free software; you can redistribute it and/or modify it under the
@@ -2109,7 +1955,7 @@ static ulg flush_block(char *buf, ulg stored_len, int eof)
2109 */ 1955 */
2110static int ct_tally(int dist, int lc) 1956static int ct_tally(int dist, int lc)
2111{ 1957{
2112 l_buf[last_lit++] = (uch) lc; 1958 l_buf[last_lit++] = lc;
2113 if (dist == 0) { 1959 if (dist == 0) {
2114 /* lc is the unmatched char */ 1960 /* lc is the unmatched char */
2115 dyn_ltree[lc].Freq++; 1961 dyn_ltree[lc].Freq++;
@@ -2278,3 +2124,147 @@ static int zip(int in, int out)
2278 flush_outbuf(); 2124 flush_outbuf();
2279 return 0; 2125 return 0;
2280} 2126}
2127
2128
2129/* ======================================================================== */
2130static void abort_gzip(int ATTRIBUTE_UNUSED ignored)
2131{
2132 exit(1);
2133}
2134
2135int gzip_main(int argc, char **argv)
2136{
2137 enum {
2138 OPT_tostdout = 0x1,
2139 OPT_force = 0x2,
2140 };
2141
2142 unsigned opt;
2143 int result;
2144 int inFileNum;
2145 int outFileNum;
2146 int i;
2147 struct stat statBuf;
2148 char *delFileName;
2149
2150 opt = getopt32(argc, argv, "cf123456789qv" USE_GUNZIP("d"));
2151 //if (opt & 0x1) // -c
2152 //if (opt & 0x2) // -f
2153 /* Ignore 1-9 (compression level) options */
2154 //if (opt & 0x4) // -1
2155 //if (opt & 0x8) // -2
2156 //if (opt & 0x10) // -3
2157 //if (opt & 0x20) // -4
2158 //if (opt & 0x40) // -5
2159 //if (opt & 0x80) // -6
2160 //if (opt & 0x100) // -7
2161 //if (opt & 0x200) // -8
2162 //if (opt & 0x400) // -9
2163 //if (opt & 0x800) // -q
2164 //if (opt & 0x1000) // -v
2165#if ENABLE_GUNZIP /* gunzip_main may not be visible... */
2166 if (opt & 0x2000) { // -d
2167 /* FIXME: getopt32 should not depend on optind */
2168 optind = 1;
2169 return gunzip_main(argc, argv);
2170 }
2171#endif
2172
2173 foreground = signal(SIGINT, SIG_IGN) != SIG_IGN;
2174 if (foreground) {
2175 signal(SIGINT, abort_gzip);
2176 }
2177#ifdef SIGTERM
2178 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
2179 signal(SIGTERM, abort_gzip);
2180 }
2181#endif
2182#ifdef SIGHUP
2183 if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
2184 signal(SIGHUP, abort_gzip);
2185 }
2186#endif
2187
2188 strncpy(z_suffix, ".gz", sizeof(z_suffix) - 1);
2189
2190 /* Allocate all global buffers (for DYN_ALLOC option) */
2191 ALLOC(uch, inbuf, INBUFSIZ + INBUF_EXTRA);
2192 ALLOC(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA);
2193 ALLOC(ush, d_buf, DIST_BUFSIZE);
2194 ALLOC(uch, window, 2L * WSIZE);
2195 ALLOC(ush, tab_prefix, 1L << BITS);
2196
2197 /* Initialise the CRC32 table */
2198 crc_32_tab = crc32_filltable(0);
2199
2200 clear_bufs();
2201
2202 if (optind == argc) {
2203 time_stamp = 0;
2204 zip(STDIN_FILENO, STDOUT_FILENO);
2205 return exit_code;
2206 }
2207
2208 for (i = optind; i < argc; i++) {
2209 char *path = NULL;
2210
2211 clear_bufs();
2212 if (LONE_DASH(argv[i])) {
2213 time_stamp = 0;
2214 inFileNum = STDIN_FILENO;
2215 outFileNum = STDOUT_FILENO;
2216 } else {
2217 inFileNum = xopen(argv[i], O_RDONLY);
2218 if (fstat(inFileNum, &statBuf) < 0)
2219 bb_perror_msg_and_die("%s", argv[i]);
2220 time_stamp = statBuf.st_ctime;
2221
2222 if (!(opt & OPT_tostdout)) {
2223 path = xasprintf("%s.gz", argv[i]);
2224
2225 /* Open output file */
2226#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 && defined(O_NOFOLLOW)
2227 outFileNum = open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW);
2228#else
2229 outFileNum = open(path, O_RDWR | O_CREAT | O_EXCL);
2230#endif
2231 if (outFileNum < 0) {
2232 bb_perror_msg("%s", path);
2233 free(path);
2234 continue;
2235 }
2236
2237 /* Set permissions on the file */
2238 fchmod(outFileNum, statBuf.st_mode);
2239 } else
2240 outFileNum = STDOUT_FILENO;
2241 }
2242
2243 if (path == NULL && isatty(outFileNum) && !(opt & OPT_force)) {
2244 bb_error_msg("compressed data not written "
2245 "to a terminal. Use -f to force compression.");
2246 free(path);
2247 continue;
2248 }
2249
2250 result = zip(inFileNum, outFileNum);
2251
2252 if (path != NULL) {
2253 close(inFileNum);
2254 close(outFileNum);
2255
2256 /* Delete the original file */
2257 if (result == 0)
2258 delFileName = argv[i];
2259 else
2260 delFileName = path;
2261
2262 if (unlink(delFileName) < 0)
2263 bb_perror_msg("%s", delFileName);
2264 }
2265
2266 free(path);
2267 }
2268
2269 return exit_code;
2270}