aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-07 19:37:42 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-07 19:37:42 +0000
commitad403413c776c36631da807b087f42aec1d4bdc9 (patch)
tree20210fd66571bd6b455a0846b4f303fd9c538754
parent88e2b1cb626761b1924305b761a5dfc723613c4e (diff)
downloadbusybox-w32-ad403413c776c36631da807b087f42aec1d4bdc9.tar.gz
busybox-w32-ad403413c776c36631da807b087f42aec1d4bdc9.tar.bz2
busybox-w32-ad403413c776c36631da807b087f42aec1d4bdc9.zip
a ton of gzip changes, split up in compiled and
run-tested pieces. Code was rather messy. It's not a bug fix, more like code cleanup. This is the first part.
-rw-r--r--archival/gzip.c333
1 files changed, 145 insertions, 188 deletions
diff --git a/archival/gzip.c b/archival/gzip.c
index b8a448435..c441942f3 100644
--- a/archival/gzip.c
+++ b/archival/gzip.c
@@ -25,45 +25,15 @@ aa: 85.1% -- replaced with aa.gz
25 25
26#define SMALL_MEM 26#define SMALL_MEM
27 27
28#include <stdlib.h> 28//#include <dirent.h>
29#include <stdio.h>
30#include <string.h>
31#include <unistd.h>
32#include <errno.h>
33#include <sys/types.h>
34#include <signal.h>
35#include <utime.h>
36#include <ctype.h>
37#include <sys/types.h>
38#include <unistd.h>
39#include <dirent.h>
40#include <fcntl.h>
41#include <time.h>
42#include "busybox.h" 29#include "busybox.h"
43 30
44typedef unsigned char uch;
45typedef unsigned short ush;
46typedef unsigned long ulg;
47
48/* Return codes from gzip */
49#define OK 0
50#define ERROR 1
51#define WARNING 2
52
53/* Compression methods (see algorithm.doc) */ 31/* Compression methods (see algorithm.doc) */
54/* Only STORED and DEFLATED are supported by this BusyBox module */ 32/* Only STORED and DEFLATED are supported by this BusyBox module */
55#define STORED 0 33#define STORED 0
56/* methods 4 to 7 reserved */ 34/* methods 4 to 7 reserved */
57#define DEFLATED 8 35#define DEFLATED 8
58 36
59/* To save memory for 16 bit systems, some arrays are overlaid between
60 * the various modules:
61 * deflate: prev+head window d_buf l_buf outbuf
62 * unlzw: tab_prefix tab_suffix stack inbuf outbuf
63 * For compression, input is done in window[]. For decompression, output
64 * is done in window except for unlzw.
65 */
66
67#ifndef INBUFSIZ 37#ifndef INBUFSIZ
68# ifdef SMALL_MEM 38# ifdef SMALL_MEM
69# define INBUFSIZ 0x2000 /* input buffer size */ 39# define INBUFSIZ 0x2000 /* input buffer size */
@@ -71,6 +41,7 @@ typedef unsigned long ulg;
71# define INBUFSIZ 0x8000 /* input buffer size */ 41# define INBUFSIZ 0x8000 /* input buffer size */
72# endif 42# endif
73#endif 43#endif
44
74#define INBUF_EXTRA 64 /* required by unlzw() */ 45#define INBUF_EXTRA 64 /* required by unlzw() */
75 46
76#ifndef OUTBUFSIZ 47#ifndef OUTBUFSIZ
@@ -90,21 +61,8 @@ typedef unsigned long ulg;
90# endif 61# endif
91#endif 62#endif
92 63
93# define DECLARE(type, array, size) static type * array
94# define ALLOC(type, array, size) { \
95 array = xzalloc((size_t)(((size)+1L)/2) * 2*sizeof(type)); \
96 }
97# define FREE(array) {free(array), array=NULL;}
98
99#define tab_suffix window
100#define tab_prefix prev /* hash link (see deflate.c) */
101#define head (prev+WSIZE) /* hash head (see deflate.c) */
102
103static long isize; /* number of input bytes */
104
105#define NO_FILE (-1) /* in memory compression */ 64#define NO_FILE (-1) /* in memory compression */
106 65
107
108#define PACK_MAGIC "\037\036" /* Magic header for packed files */ 66#define PACK_MAGIC "\037\036" /* Magic header for packed files */
109#define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */ 67#define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */
110#define OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */ 68#define OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */
@@ -142,37 +100,66 @@ static long isize; /* number of input bytes */
142 * distances are limited to MAX_DIST instead of WSIZE. 100 * distances are limited to MAX_DIST instead of WSIZE.
143 */ 101 */
144 102
145/* put_byte is used for the compressed output */ 103#ifndef MAX_PATH_LEN
146#define put_byte(c) {outbuf[outcnt++]=(uch)(c); if (outcnt==OUTBUFSIZ)\ 104# define MAX_PATH_LEN 1024 /* max pathname length */
147 flush_outbuf();} 105#endif
148 106
149#define seekable() 0 /* force sequential output */ 107#define seekable() 0 /* force sequential output */
150#define translate_eol 0 /* no option -a yet */ 108#define translate_eol 0 /* no option -a yet */
151 109
152/* Diagnostic functions */ 110#ifndef BITS
153#ifdef DEBUG 111# define BITS 16
154# define Assert(cond,msg) {if(!(cond)) bb_error_msg(msg);} 112#endif
155# define Trace(x) fprintf x 113#define INIT_BITS 9 /* Initial number of bits per code */
156# define Tracev(x) {if (verbose) fprintf x ;} 114
157# define Tracevv(x) {if (verbose>1) fprintf x ;} 115#define BIT_MASK 0x1f /* Mask for 'number of compression bits' */
158# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} 116/* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free.
159# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} 117 * It's a pity that old uncompress does not check bit 0x20. That makes
118 * extension of the format actually undesirable because old compress
119 * would just crash on the new format instead of giving a meaningful
120 * error message. It does check the number of bits, but it's more
121 * helpful to say "unsupported format, get a new version" than
122 * "can only handle 16 bits".
123 */
124
125#ifdef MAX_EXT_CHARS
126# define MAX_SUFFIX MAX_EXT_CHARS
160#else 127#else
161# define Assert(cond,msg) 128# define MAX_SUFFIX 30
162# define Trace(x)
163# define Tracev(x)
164# define Tracevv(x)
165# define Tracec(c,x)
166# define Tracecv(c,x)
167#endif 129#endif
168 130
169#define WARN(msg) {if (!quiet) fprintf msg ; \
170 if (exit_code == OK) exit_code = WARNING;}
171 131
172#ifndef MAX_PATH_LEN 132#define DECLARE(type, array, size)\
173# define MAX_PATH_LEN 1024 /* max pathname length */ 133 static type * array
134#define ALLOC(type, array, size) { \
135 array = xzalloc((size_t)(((size)+1L)/2) * 2*sizeof(type)); \
136}
137#define FREE(array) { \
138 free(array); \
139 array = NULL; \
140}
141
142/* Diagnostic functions */
143#ifdef DEBUG
144# define Assert(cond,msg) {if(!(cond)) bb_error_msg(msg);}
145# define Trace(x) fprintf x
146# define Tracev(x) {if (verbose) fprintf x ;}
147# define Tracevv(x) {if (verbose>1) fprintf x ;}
148# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
149# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
150#else
151# define Assert(cond,msg)
152# define Trace(x)
153# define Tracev(x)
154# define Tracevv(x)
155# define Tracec(c,x)
156# define Tracecv(c,x)
174#endif 157#endif
175 158
159typedef unsigned char uch;
160typedef unsigned short ush;
161typedef unsigned long ulg;
162
176 163
177 /* from zip.c: */ 164 /* from zip.c: */
178static int zip(int in, int out); 165static int zip(int in, int out);
@@ -195,66 +182,22 @@ static void bi_windup(void);
195static void copy_block(char *buf, unsigned len, int header); 182static void copy_block(char *buf, unsigned len, int header);
196static int (*read_buf) (char *buf, unsigned size); 183static int (*read_buf) (char *buf, unsigned size);
197 184
198 /* from util.c: */
199static void flush_outbuf(void); 185static void flush_outbuf(void);
200 186
201/* lzw.h -- define the lzw functions. 187/* global buffers */
202 * Copyright (C) 1992-1993 Jean-loup Gailly.
203 * This is free software; you can redistribute it and/or modify it under the
204 * terms of the GNU General Public License, see the file COPYING.
205 */
206 188
207#ifndef BITS 189/* To save memory for 16 bit systems, some arrays are overlaid between
208# define BITS 16 190 * the various modules:
209#endif 191 * deflate: prev+head window d_buf l_buf outbuf
210#define INIT_BITS 9 /* Initial number of bits per code */ 192 * unlzw: tab_prefix tab_suffix stack inbuf outbuf
211 193 * For compression, input is done in window[]. For decompression, output
212#define BIT_MASK 0x1f /* Mask for 'number of compression bits' */ 194 * is done in window except for unlzw.
213/* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free.
214 * It's a pity that old uncompress does not check bit 0x20. That makes
215 * extension of the format actually undesirable because old compress
216 * would just crash on the new format instead of giving a meaningful
217 * error message. It does check the number of bits, but it's more
218 * helpful to say "unsupported format, get a new version" than
219 * "can only handle 16 bits".
220 */
221
222/* tailor.h -- target dependent definitions
223 * Copyright (C) 1992-1993 Jean-loup Gailly.
224 * This is free software; you can redistribute it and/or modify it under the
225 * terms of the GNU General Public License, see the file COPYING.
226 */
227
228/* The target dependent definitions should be defined here only.
229 * The target dependent functions should be defined in tailor.c.
230 */ 195 */
231 196
232 197
233 /* Common defaults */ 198#define tab_suffix window
234 199#define tab_prefix prev /* hash link (see deflate.c) */
235#ifndef OS_CODE 200#define head (prev+WSIZE) /* hash head (see deflate.c) */
236# define OS_CODE 0x03 /* assume Unix */
237#endif
238
239#ifndef PATH_SEP
240# define PATH_SEP '/'
241#endif
242
243#ifndef OPTIONS_VAR
244# define OPTIONS_VAR "GZIP"
245#endif
246
247#ifndef Z_SUFFIX
248# define Z_SUFFIX ".gz"
249#endif
250
251#ifdef MAX_EXT_CHARS
252# define MAX_SUFFIX MAX_EXT_CHARS
253#else
254# define MAX_SUFFIX 30
255#endif
256
257 /* global buffers */
258 201
259DECLARE(uch, inbuf, INBUFSIZ + INBUF_EXTRA); 202DECLARE(uch, inbuf, INBUFSIZ + INBUF_EXTRA);
260DECLARE(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA); 203DECLARE(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA);
@@ -262,10 +205,12 @@ DECLARE(ush, d_buf, DIST_BUFSIZE);
262DECLARE(uch, window, 2L * WSIZE); 205DECLARE(uch, window, 2L * WSIZE);
263DECLARE(ush, tab_prefix, 1L << BITS); 206DECLARE(ush, tab_prefix, 1L << BITS);
264 207
265static int foreground; /* set if program run in foreground */ 208static long isize; /* number of input bytes */
209
210static int foreground; /* set if program run in foreground */
266static int method = DEFLATED; /* compression method */ 211static int method = DEFLATED; /* compression method */
267static int exit_code = OK; /* program exit code */ 212static int exit_code; /* program exit code */
268static long time_stamp; /* original time stamp (modification time) */ 213static long time_stamp; /* original time stamp (modification time) */
269static char z_suffix[MAX_SUFFIX + 1]; /* default suffix (can be set with --suffix) */ 214static char z_suffix[MAX_SUFFIX + 1]; /* default suffix (can be set with --suffix) */
270 215
271static int ifd; /* input file descriptor */ 216static int ifd; /* input file descriptor */
@@ -277,24 +222,67 @@ static unsigned outcnt; /* bytes in output buffer */
277 222
278static uint32_t *crc_32_tab; 223static uint32_t *crc_32_tab;
279 224
225
226/* ===========================================================================
227 * Local data used by the "bit string" routines.
228 */
229
230static int zfile; /* output gzip file */
231
232static unsigned short bi_buf;
233
234/* Output buffer. bits are inserted starting at the bottom (least significant
235 * bits).
236 */
237
238#undef BUF_SIZE
239#define BUF_SIZE (8 * sizeof(bi_buf))
240/* Number of bits used within bi_buf. (bi_buf might be implemented on
241 * more than 16 bits on some systems.)
242 */
243
244static int bi_valid;
245
246/* Current input function. Set to mem_read for in-memory compression */
247
248#ifdef DEBUG
249static ulg bits_sent; /* bit length of the compressed data */
250#endif
251
252
253/* ===========================================================================
254 */
255/* put_8bit is used for the compressed output */
256#define put_8bit(c) \
257{ \
258 outbuf[outcnt++] = (c); \
259 if (outcnt == OUTBUFSIZ) flush_outbuf(); \
260}
261
280/* Output a 16 bit value, lsb first */ 262/* Output a 16 bit value, lsb first */
281static void put_short(ush w) 263static void put_16bit(ush w)
282{ 264{
283 if (outcnt < OUTBUFSIZ - 2) { 265 if (outcnt < OUTBUFSIZ - 2) {
284 outbuf[outcnt++] = (uch) ((w) & 0xff); 266 outbuf[outcnt++] = w;
285 outbuf[outcnt++] = (uch) ((ush) (w) >> 8); 267 outbuf[outcnt++] = w >> 8;
286 } else { 268 } else {
287 put_byte((uch) ((w) & 0xff)); 269 put_8bit(w);
288 put_byte((uch) ((ush) (w) >> 8)); 270 put_8bit(w >> 8);
289 } 271 }
290} 272}
291 273
292/* ======================================================================== 274static void put_32bit(ulg n)
293 * Signal and error handler.
294 */
295static void abort_gzip(int ATTRIBUTE_UNUSED ignored)
296{ 275{
297 exit(ERROR); 276 put_16bit(n);
277 put_16bit(n >> 16);
278}
279
280/* put_header_byte is used for the compressed output
281 * - for the initial 4 bytes that can't overflow the buffer.
282 */
283#define put_header_byte(c) \
284{ \
285 outbuf[outcnt++] = (c); \
298} 286}
299 287
300/* =========================================================================== 288/* ===========================================================================
@@ -318,7 +306,8 @@ static void write_buf(int fd, void *buf, unsigned cnt)
318 unsigned n; 306 unsigned n;
319 307
320 while ((n = write(fd, buf, cnt)) != cnt) { 308 while ((n = write(fd, buf, cnt)) != cnt) {
321 if (n == (unsigned) (-1)) bb_error_msg_and_die(bb_msg_write_error); 309 if (n == (unsigned) (-1))
310 bb_error_msg_and_die(bb_msg_write_error);
322 cnt -= n; 311 cnt -= n;
323 buf = (void *) ((char *) buf + n); 312 buf = (void *) ((char *) buf + n);
324 } 313 }
@@ -401,31 +390,6 @@ static uint32_t updcrc(uch * s, unsigned n)
401 */ 390 */
402 391
403/* =========================================================================== 392/* ===========================================================================
404 * Local data used by the "bit string" routines.
405 */
406
407static int zfile; /* output gzip file */
408
409static unsigned short bi_buf;
410
411/* Output buffer. bits are inserted starting at the bottom (least significant
412 * bits).
413 */
414
415#define Buf_size (8 * 2*sizeof(char))
416/* Number of bits used within bi_buf. (bi_buf might be implemented on
417 * more than 16 bits on some systems.)
418 */
419
420static int bi_valid;
421
422/* Current input function. Set to mem_read for in-memory compression */
423
424#ifdef DEBUG
425ulg bits_sent; /* bit length of the compressed data */
426#endif
427
428/* ===========================================================================
429 * Initialize the bit string routines. 393 * Initialize the bit string routines.
430 */ 394 */
431static void bi_init(int zipfile) 395static void bi_init(int zipfile)
@@ -460,11 +424,11 @@ static void send_bits(int value, int length)
460 * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) 424 * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
461 * unused bits in value. 425 * unused bits in value.
462 */ 426 */
463 if (bi_valid > (int) Buf_size - length) { 427 if (bi_valid > (int) BUF_SIZE - length) {
464 bi_buf |= (value << bi_valid); 428 bi_buf |= (value << bi_valid);
465 put_short(bi_buf); 429 put_16bit(bi_buf);
466 bi_buf = (ush) value >> (Buf_size - bi_valid); 430 bi_buf = (ush) value >> (BUF_SIZE - bi_valid);
467 bi_valid += length - Buf_size; 431 bi_valid += length - BUF_SIZE;
468 } else { 432 } else {
469 bi_buf |= value << bi_valid; 433 bi_buf |= value << bi_valid;
470 bi_valid += length; 434 bi_valid += length;
@@ -493,9 +457,9 @@ static unsigned bi_reverse(unsigned code, int len)
493static void bi_windup(void) 457static void bi_windup(void)
494{ 458{
495 if (bi_valid > 8) { 459 if (bi_valid > 8) {
496 put_short(bi_buf); 460 put_16bit(bi_buf);
497 } else if (bi_valid > 0) { 461 } else if (bi_valid > 0) {
498 put_byte(bi_buf); 462 put_8bit(bi_buf);
499 } 463 }
500 bi_buf = 0; 464 bi_buf = 0;
501 bi_valid = 0; 465 bi_valid = 0;
@@ -513,8 +477,8 @@ static void copy_block(char *buf, unsigned len, int header)
513 bi_windup(); /* align on byte boundary */ 477 bi_windup(); /* align on byte boundary */
514 478
515 if (header) { 479 if (header) {
516 put_short((ush) len); 480 put_16bit((ush) len);
517 put_short((ush) ~ len); 481 put_16bit((ush) ~ len);
518#ifdef DEBUG 482#ifdef DEBUG
519 bits_sent += 2 * 16; 483 bits_sent += 2 * 16;
520#endif 484#endif
@@ -523,7 +487,7 @@ static void copy_block(char *buf, unsigned len, int header)
523 bits_sent += (ulg) len << 3; 487 bits_sent += (ulg) len << 3;
524#endif 488#endif
525 while (len--) { 489 while (len--) {
526 put_byte(*buf++); 490 put_8bit(*buf++);
527 } 491 }
528} 492}
529 493
@@ -1039,8 +1003,7 @@ static ulg deflate(void)
1039 1003
1040 check_match(strstart - 1, prev_match, prev_length); 1004 check_match(strstart - 1, prev_match, prev_length);
1041 1005
1042 flush = 1006 flush = ct_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
1043 ct_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
1044 1007
1045 /* Insert in hash table all strings up to the end of the match. 1008 /* Insert in hash table all strings up to the end of the match.
1046 * strstart-1 and strstart are already inserted. 1009 * strstart-1 and strstart are already inserted.
@@ -1122,6 +1085,11 @@ static ulg deflate(void)
1122typedef struct dirent dir_type; 1085typedef struct dirent dir_type;
1123 1086
1124/* ======================================================================== */ 1087/* ======================================================================== */
1088static void abort_gzip(int ATTRIBUTE_UNUSED ignored)
1089{
1090 exit(1);
1091}
1092
1125int gzip_main(int argc, char **argv) 1093int gzip_main(int argc, char **argv)
1126{ 1094{
1127 enum { 1095 enum {
@@ -1174,7 +1142,7 @@ int gzip_main(int argc, char **argv)
1174 } 1142 }
1175#endif 1143#endif
1176 1144
1177 strncpy(z_suffix, Z_SUFFIX, sizeof(z_suffix) - 1); 1145 strncpy(z_suffix, ".gz", sizeof(z_suffix) - 1);
1178 1146
1179 /* Allocate all global buffers (for DYN_ALLOC option) */ 1147 /* Allocate all global buffers (for DYN_ALLOC option) */
1180 ALLOC(uch, inbuf, INBUFSIZ + INBUF_EXTRA); 1148 ALLOC(uch, inbuf, INBUFSIZ + INBUF_EXTRA);
@@ -1244,7 +1212,7 @@ int gzip_main(int argc, char **argv)
1244 close(outFileNum); 1212 close(outFileNum);
1245 1213
1246 /* Delete the original file */ 1214 /* Delete the original file */
1247 if (result == OK) 1215 if (result == 0)
1248 delFileName = argv[i]; 1216 delFileName = argv[i];
1249 else 1217 else
1250 delFileName = path; 1218 delFileName = path;
@@ -2375,17 +2343,6 @@ static void set_file_type(void)
2375 2343
2376static uint32_t crc; /* crc on uncompressed file data */ 2344static uint32_t crc; /* crc on uncompressed file data */
2377 2345
2378static void put_long(ulg n)
2379{
2380 put_short((n) & 0xffff);
2381 put_short(((ulg) (n)) >> 16);
2382}
2383
2384/* put_header_byte is used for the compressed output
2385 * - for the initial 4 bytes that can't overflow the buffer.
2386 */
2387#define put_header_byte(c) {outbuf[outcnt++]=(uch)(c);}
2388
2389/* =========================================================================== 2346/* ===========================================================================
2390 * Deflate in to out. 2347 * Deflate in to out.
2391 * IN assertions: the input and output buffers are cleared. 2348 * IN assertions: the input and output buffers are cleared.
@@ -2409,7 +2366,7 @@ static int zip(int in, int out)
2409 put_header_byte(DEFLATED); /* compression method */ 2366 put_header_byte(DEFLATED); /* compression method */
2410 2367
2411 put_header_byte(my_flags); /* general flags */ 2368 put_header_byte(my_flags); /* general flags */
2412 put_long(time_stamp); 2369 put_32bit(time_stamp);
2413 2370
2414 /* Write deflated file to zip file */ 2371 /* Write deflated file to zip file */
2415 crc = updcrc(0, 0); 2372 crc = updcrc(0, 0);
@@ -2418,17 +2375,17 @@ static int zip(int in, int out)
2418 ct_init(&attr, &method); 2375 ct_init(&attr, &method);
2419 lm_init(&deflate_flags); 2376 lm_init(&deflate_flags);
2420 2377
2421 put_byte((uch) deflate_flags); /* extra flags */ 2378 put_8bit((uch) deflate_flags); /* extra flags */
2422 put_byte(OS_CODE); /* OS identifier */ 2379 put_8bit(3); /* OS identifier = 3 (Unix) */
2423 2380
2424 (void) deflate(); 2381 (void) deflate();
2425 2382
2426 /* Write the crc and uncompressed size */ 2383 /* Write the crc and uncompressed size */
2427 put_long(crc); 2384 put_32bit(crc);
2428 put_long(isize); 2385 put_32bit(isize);
2429 2386
2430 flush_outbuf(); 2387 flush_outbuf();
2431 return OK; 2388 return 0;
2432} 2389}
2433 2390
2434 2391