diff options
Diffstat (limited to 'archival')
-rw-r--r-- | archival/gunzip.c | 2520 | ||||
-rw-r--r-- | archival/gzip.c | 3132 | ||||
-rw-r--r-- | archival/tar.c | 1857 |
3 files changed, 3835 insertions, 3674 deletions
diff --git a/archival/gunzip.c b/archival/gunzip.c index db7fa1dfe..2bc490e3e 100644 --- a/archival/gunzip.c +++ b/archival/gunzip.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* zcat : stripped version based on gzip sources | 2 | /* zcat : stripped version based on gzip sources |
2 | Sven Rudolph <sr1@inf.tu-dresden.de> | 3 | Sven Rudolph <sr1@inf.tu-dresden.de> |
3 | */ | 4 | */ |
@@ -8,11 +9,12 @@ | |||
8 | #include "messages.c" | 9 | #include "messages.c" |
9 | 10 | ||
10 | static const char gunzip_usage[] = | 11 | static const char gunzip_usage[] = |
11 | "gunzip [OPTION]... FILE\n\n" | 12 | "gunzip [OPTION]... FILE\n\n" |
12 | "Uncompress FILE (or standard input if FILE is '-').\n\n" | 13 | "Uncompress FILE (or standard input if FILE is '-').\n\n" |
13 | "Options:\n" | 14 | "Options:\n" |
14 | "\t-c\tWrite output to standard output\n" | 15 | |
15 | "\t-t\tTest compressed file integrity\n"; | 16 | "\t-c\tWrite output to standard output\n" |
17 | "\t-t\tTest compressed file integrity\n"; | ||
16 | 18 | ||
17 | /* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface | 19 | /* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface |
18 | * Copyright (C) 1992-1993 Jean-loup Gailly | 20 | * Copyright (C) 1992-1993 Jean-loup Gailly |
@@ -26,22 +28,23 @@ static const char gunzip_usage[] = | |||
26 | */ | 28 | */ |
27 | 29 | ||
28 | #if 0 | 30 | #if 0 |
29 | static char *license_msg[] = { | 31 | static char *license_msg[] = { |
30 | " Copyright (C) 1992-1993 Jean-loup Gailly", | 32 | " Copyright (C) 1992-1993 Jean-loup Gailly", |
31 | " This program is free software; you can redistribute it and/or modify", | 33 | " This program is free software; you can redistribute it and/or modify", |
32 | " it under the terms of the GNU General Public License as published by", | 34 | " it under the terms of the GNU General Public License as published by", |
33 | " the Free Software Foundation; either version 2, or (at your option)", | 35 | " the Free Software Foundation; either version 2, or (at your option)", |
34 | " any later version.", | 36 | " any later version.", |
35 | "", | 37 | "", |
36 | " This program is distributed in the hope that it will be useful,", | 38 | " This program is distributed in the hope that it will be useful,", |
37 | " but WITHOUT ANY WARRANTY; without even the implied warranty of", | 39 | " but WITHOUT ANY WARRANTY; without even the implied warranty of", |
38 | " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", | 40 | " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", |
39 | " GNU General Public License for more details.", | 41 | " GNU General Public License for more details.", |
40 | "", | 42 | "", |
41 | " You should have received a copy of the GNU General Public License", | 43 | " You should have received a copy of the GNU General Public License", |
42 | " along with this program; if not, write to the Free Software", | 44 | " along with this program; if not, write to the Free Software", |
43 | " Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.", | 45 | " Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.", |
44 | 0}; | 46 | 0 |
47 | }; | ||
45 | #endif | 48 | #endif |
46 | 49 | ||
47 | /* Compress files with zip algorithm and 'compress' interface. | 50 | /* Compress files with zip algorithm and 'compress' interface. |
@@ -67,7 +70,7 @@ static char *license_msg[] = { | |||
67 | #include <signal.h> | 70 | #include <signal.h> |
68 | #include <sys/stat.h> | 71 | #include <sys/stat.h> |
69 | #include <errno.h> | 72 | #include <errno.h> |
70 | #include <sys/param.h> /* for PATH_MAX */ | 73 | #include <sys/param.h> /* for PATH_MAX */ |
71 | 74 | ||
72 | /* #include "tailor.h" */ | 75 | /* #include "tailor.h" */ |
73 | 76 | ||
@@ -101,9 +104,9 @@ static char *license_msg[] = { | |||
101 | #endif | 104 | #endif |
102 | 105 | ||
103 | #ifdef __STDC__ | 106 | #ifdef __STDC__ |
104 | typedef void *voidp; | 107 | typedef void *voidp; |
105 | #else | 108 | #else |
106 | typedef char *voidp; | 109 | typedef char *voidp; |
107 | #endif | 110 | #endif |
108 | 111 | ||
109 | /* I don't like nested includes, but the string and io functions are used | 112 | /* I don't like nested includes, but the string and io functions are used |
@@ -118,10 +121,10 @@ static char *license_msg[] = { | |||
118 | # define memzero(s, n) memset ((voidp)(s), 0, (n)) | 121 | # define memzero(s, n) memset ((voidp)(s), 0, (n)) |
119 | #else | 122 | #else |
120 | # include <strings.h> | 123 | # include <strings.h> |
121 | # define strchr index | 124 | # define strchr index |
122 | # define strrchr rindex | 125 | # define strrchr rindex |
123 | # define memcpy(d, s, n) bcopy((s), (d), (n)) | 126 | # define memcpy(d, s, n) bcopy((s), (d), (n)) |
124 | # define memcmp(s1, s2, n) bcmp((s1), (s2), (n)) | 127 | # define memcmp(s1, s2, n) bcmp((s1), (s2), (n)) |
125 | # define memzero(s, n) bzero((s), (n)) | 128 | # define memzero(s, n) bzero((s), (n)) |
126 | #endif | 129 | #endif |
127 | 130 | ||
@@ -131,9 +134,9 @@ static char *license_msg[] = { | |||
131 | 134 | ||
132 | #define local static | 135 | #define local static |
133 | 136 | ||
134 | typedef unsigned char uch; | 137 | typedef unsigned char uch; |
135 | typedef unsigned short ush; | 138 | typedef unsigned short ush; |
136 | typedef unsigned long ulg; | 139 | typedef unsigned long ulg; |
137 | 140 | ||
138 | /* Return codes from gzip */ | 141 | /* Return codes from gzip */ |
139 | #define OK 0 | 142 | #define OK 0 |
@@ -143,7 +146,7 @@ typedef unsigned long ulg; | |||
143 | /* Compression methods (see algorithm.doc) */ | 146 | /* Compression methods (see algorithm.doc) */ |
144 | #define DEFLATED 8 | 147 | #define DEFLATED 8 |
145 | 148 | ||
146 | extern int method; /* compression method */ | 149 | extern int method; /* compression method */ |
147 | 150 | ||
148 | /* To save memory for 16 bit systems, some arrays are overlaid between | 151 | /* To save memory for 16 bit systems, some arrays are overlaid between |
149 | * the various modules: | 152 | * the various modules: |
@@ -158,29 +161,29 @@ extern int method; /* compression method */ | |||
158 | 161 | ||
159 | #ifndef INBUFSIZ | 162 | #ifndef INBUFSIZ |
160 | # ifdef SMALL_MEM | 163 | # ifdef SMALL_MEM |
161 | # define INBUFSIZ 0x2000 /* input buffer size */ | 164 | # define INBUFSIZ 0x2000 /* input buffer size */ |
162 | # else | 165 | # else |
163 | # define INBUFSIZ 0x8000 /* input buffer size */ | 166 | # define INBUFSIZ 0x8000 /* input buffer size */ |
164 | # endif | 167 | # endif |
165 | #endif | 168 | #endif |
166 | #define INBUF_EXTRA 64 /* required by unlzw() */ | 169 | #define INBUF_EXTRA 64 /* required by unlzw() */ |
167 | 170 | ||
168 | #ifndef OUTBUFSIZ | 171 | #ifndef OUTBUFSIZ |
169 | # ifdef SMALL_MEM | 172 | # ifdef SMALL_MEM |
170 | # define OUTBUFSIZ 8192 /* output buffer size */ | 173 | # define OUTBUFSIZ 8192 /* output buffer size */ |
171 | # else | 174 | # else |
172 | # define OUTBUFSIZ 16384 /* output buffer size */ | 175 | # define OUTBUFSIZ 16384 /* output buffer size */ |
173 | # endif | 176 | # endif |
174 | #endif | 177 | #endif |
175 | #define OUTBUF_EXTRA 2048 /* required by unlzw() */ | 178 | #define OUTBUF_EXTRA 2048 /* required by unlzw() */ |
176 | 179 | ||
177 | #define SMALL_MEM | 180 | #define SMALL_MEM |
178 | 181 | ||
179 | #ifndef DIST_BUFSIZE | 182 | #ifndef DIST_BUFSIZE |
180 | # ifdef SMALL_MEM | 183 | # ifdef SMALL_MEM |
181 | # define DIST_BUFSIZE 0x2000 /* buffer for distances, see trees.c */ | 184 | # define DIST_BUFSIZE 0x2000 /* buffer for distances, see trees.c */ |
182 | # else | 185 | # else |
183 | # define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */ | 186 | # define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */ |
184 | # endif | 187 | # endif |
185 | #endif | 188 | #endif |
186 | 189 | ||
@@ -201,50 +204,51 @@ extern int method; /* compression method */ | |||
201 | # define FREE(array) | 204 | # define FREE(array) |
202 | #endif | 205 | #endif |
203 | 206 | ||
204 | EXTERN(uch, inbuf); /* input buffer */ | 207 | EXTERN(uch, inbuf); /* input buffer */ |
205 | EXTERN(uch, outbuf); /* output buffer */ | 208 | EXTERN(uch, outbuf); /* output buffer */ |
206 | EXTERN(ush, d_buf); /* buffer for distances, see trees.c */ | 209 | EXTERN(ush, d_buf); /* buffer for distances, see trees.c */ |
207 | EXTERN(uch, window); /* Sliding window and suffix table (unlzw) */ | 210 | EXTERN(uch, window); /* Sliding window and suffix table (unlzw) */ |
208 | #define tab_suffix window | 211 | #define tab_suffix window |
209 | #ifndef MAXSEG_64K | 212 | #ifndef MAXSEG_64K |
210 | # define tab_prefix prev /* hash link (see deflate.c) */ | 213 | # define tab_prefix prev /* hash link (see deflate.c) */ |
211 | # define head (prev+WSIZE) /* hash head (see deflate.c) */ | 214 | # define head (prev+WSIZE) /* hash head (see deflate.c) */ |
212 | EXTERN(ush, tab_prefix); /* prefix code (see unlzw.c) */ | 215 | EXTERN(ush, tab_prefix); /* prefix code (see unlzw.c) */ |
213 | #else | 216 | #else |
214 | # define tab_prefix0 prev | 217 | # define tab_prefix0 prev |
215 | # define head tab_prefix1 | 218 | # define head tab_prefix1 |
216 | EXTERN(ush, tab_prefix0); /* prefix for even codes */ | 219 | EXTERN(ush, tab_prefix0); /* prefix for even codes */ |
217 | EXTERN(ush, tab_prefix1); /* prefix for odd codes */ | 220 | EXTERN(ush, tab_prefix1); /* prefix for odd codes */ |
218 | #endif | 221 | #endif |
219 | 222 | ||
220 | extern unsigned insize; /* valid bytes in inbuf */ | 223 | extern unsigned insize; /* valid bytes in inbuf */ |
221 | extern unsigned inptr; /* index of next byte to be processed in inbuf */ | 224 | extern unsigned inptr; /* index of next byte to be processed in inbuf */ |
222 | extern unsigned outcnt; /* bytes in output buffer */ | 225 | extern unsigned outcnt; /* bytes in output buffer */ |
226 | |||
227 | extern long bytes_in; /* number of input bytes */ | ||
228 | extern long bytes_out; /* number of output bytes */ | ||
229 | extern long header_bytes; /* number of bytes in gzip header */ | ||
223 | 230 | ||
224 | extern long bytes_in; /* number of input bytes */ | 231 | extern long ifile_size; /* input file size, -1 for devices (debug only) */ |
225 | extern long bytes_out; /* number of output bytes */ | ||
226 | extern long header_bytes;/* number of bytes in gzip header */ | ||
227 | 232 | ||
228 | extern long ifile_size; /* input file size, -1 for devices (debug only) */ | 233 | typedef int file_t; /* Do not use stdio */ |
229 | 234 | ||
230 | typedef int file_t; /* Do not use stdio */ | 235 | #define NO_FILE (-1) /* in memory compression */ |
231 | #define NO_FILE (-1) /* in memory compression */ | ||
232 | 236 | ||
233 | 237 | ||
234 | #define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */ | 238 | #define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */ |
235 | 239 | ||
236 | /* gzip flag byte */ | 240 | /* gzip flag byte */ |
237 | #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ | 241 | #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ |
238 | #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ | 242 | #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ |
239 | #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ | 243 | #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ |
240 | #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ | 244 | #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ |
241 | #define COMMENT 0x10 /* bit 4 set: file comment present */ | 245 | #define COMMENT 0x10 /* bit 4 set: file comment present */ |
242 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ | 246 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ |
243 | #define RESERVED 0xC0 /* bit 6,7: reserved */ | 247 | #define RESERVED 0xC0 /* bit 6,7: reserved */ |
244 | 248 | ||
245 | #ifndef WSIZE | 249 | #ifndef WSIZE |
246 | # define WSIZE 0x8000 /* window size--must be a power of two, and */ | 250 | # define WSIZE 0x8000 /* window size--must be a power of two, and */ |
247 | #endif /* at least 32K for zip's deflate method */ | 251 | #endif /* at least 32K for zip's deflate method */ |
248 | 252 | ||
249 | #define MIN_MATCH 3 | 253 | #define MIN_MATCH 3 |
250 | #define MAX_MATCH 258 | 254 | #define MAX_MATCH 258 |
@@ -260,11 +264,11 @@ typedef int file_t; /* Do not use stdio */ | |||
260 | * distances are limited to MAX_DIST instead of WSIZE. | 264 | * distances are limited to MAX_DIST instead of WSIZE. |
261 | */ | 265 | */ |
262 | 266 | ||
263 | extern int exit_code; /* program exit code */ | 267 | extern int exit_code; /* program exit code */ |
264 | extern int verbose; /* be verbose (-v) */ | 268 | extern int verbose; /* be verbose (-v) */ |
265 | extern int level; /* compression level */ | 269 | extern int level; /* compression level */ |
266 | extern int test; /* check .z file integrity */ | 270 | extern int test; /* check .z file integrity */ |
267 | extern int save_orig_name; /* set if original name must be saved */ | 271 | extern int save_orig_name; /* set if original name must be saved */ |
268 | 272 | ||
269 | #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(0)) | 273 | #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(0)) |
270 | #define try_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(1)) | 274 | #define try_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(1)) |
@@ -296,10 +300,10 @@ extern int save_orig_name; /* set if original name must be saved */ | |||
296 | put_short(((ulg)(n)) >> 16); \ | 300 | put_short(((ulg)(n)) >> 16); \ |
297 | } | 301 | } |
298 | 302 | ||
299 | #define seekable() 0 /* force sequential output */ | 303 | #define seekable() 0 /* force sequential output */ |
300 | #define translate_eol 0 /* no option -a yet */ | 304 | #define translate_eol 0 /* no option -a yet */ |
301 | 305 | ||
302 | #define tolow(c) (isupper(c) ? (c)-'A'+'a' : (c)) /* force to lower case */ | 306 | #define tolow(c) (isupper(c) ? (c)-'A'+'a' : (c)) /* force to lower case */ |
303 | 307 | ||
304 | /* Macros for getting two-byte and four-byte header values */ | 308 | /* Macros for getting two-byte and four-byte header values */ |
305 | #define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)) | 309 | #define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)) |
@@ -329,43 +333,44 @@ extern int save_orig_name; /* set if original name must be saved */ | |||
329 | 333 | ||
330 | 334 | ||
331 | /* in unzip.c */ | 335 | /* in unzip.c */ |
332 | extern int unzip OF((int in, int out)); | 336 | extern int unzip OF((int in, int out)); |
333 | 337 | ||
334 | /* in gzip.c */ | 338 | /* in gzip.c */ |
335 | RETSIGTYPE abort_gzip OF((void)); | 339 | RETSIGTYPE abort_gzip OF((void)); |
336 | 340 | ||
337 | /* in deflate.c */ | 341 | /* in deflate.c */ |
338 | void lm_init OF((int pack_level, ush *flags)); | 342 | void lm_init OF((int pack_level, ush * flags)); |
339 | ulg deflate OF((void)); | 343 | ulg deflate OF((void)); |
340 | 344 | ||
341 | /* in trees.c */ | 345 | /* in trees.c */ |
342 | void ct_init OF((ush *attr, int *method)); | 346 | void ct_init OF((ush * attr, int *method)); |
343 | int ct_tally OF((int dist, int lc)); | 347 | int ct_tally OF((int dist, int lc)); |
344 | ulg flush_block OF((char *buf, ulg stored_len, int eof)); | 348 | ulg flush_block OF((char *buf, ulg stored_len, int eof)); |
345 | 349 | ||
346 | /* in bits.c */ | 350 | /* in bits.c */ |
347 | void bi_init OF((file_t zipfile)); | 351 | void bi_init OF((file_t zipfile)); |
348 | void send_bits OF((int value, int length)); | 352 | void send_bits OF((int value, int length)); |
349 | unsigned bi_reverse OF((unsigned value, int length)); | 353 | unsigned bi_reverse OF((unsigned value, int length)); |
350 | void bi_windup OF((void)); | 354 | void bi_windup OF((void)); |
351 | void copy_block OF((char *buf, unsigned len, int header)); | 355 | void copy_block OF((char *buf, unsigned len, int header)); |
352 | extern int (*read_buf) OF((char *buf, unsigned size)); | 356 | extern int (*read_buf) OF((char *buf, unsigned size)); |
353 | 357 | ||
354 | /* in util.c: */ | 358 | /* in util.c: */ |
355 | extern int copy OF((int in, int out)); | 359 | extern int copy OF((int in, int out)); |
356 | extern ulg updcrc OF((uch *s, unsigned n)); | 360 | extern ulg updcrc OF((uch * s, unsigned n)); |
357 | extern void clear_bufs OF((void)); | 361 | extern void clear_bufs OF((void)); |
358 | extern int fill_inbuf OF((int eof_ok)); | 362 | extern int fill_inbuf OF((int eof_ok)); |
359 | extern void flush_outbuf OF((void)); | 363 | extern void flush_outbuf OF((void)); |
360 | extern void flush_window OF((void)); | 364 | extern void flush_window OF((void)); |
361 | extern void write_buf OF((int fd, voidp buf, unsigned cnt)); | 365 | extern void write_buf OF((int fd, voidp buf, unsigned cnt)); |
366 | |||
362 | #ifndef __linux__ | 367 | #ifndef __linux__ |
363 | extern char *basename OF((char *fname)); | 368 | extern char *basename OF((char *fname)); |
364 | #endif /* not __linux__ */ | 369 | #endif /* not __linux__ */ |
365 | extern void error OF((char *m)); | 370 | extern void error OF((char *m)); |
366 | extern void warn OF((char *a, char *b)); | 371 | extern void warn OF((char *a, char *b)); |
367 | extern void read_error OF((void)); | 372 | extern void read_error OF((void)); |
368 | extern void write_error OF((void)); | 373 | extern void write_error OF((void)); |
369 | 374 | ||
370 | /* in inflate.c */ | 375 | /* in inflate.c */ |
371 | extern int inflate OF((void)); | 376 | extern int inflate OF((void)); |
@@ -385,11 +390,11 @@ extern int inflate OF((void)); | |||
385 | #ifndef BITS | 390 | #ifndef BITS |
386 | # define BITS 16 | 391 | # define BITS 16 |
387 | #endif | 392 | #endif |
388 | #define INIT_BITS 9 /* Initial number of bits per code */ | 393 | #define INIT_BITS 9 /* Initial number of bits per code */ |
389 | 394 | ||
390 | #define LZW_MAGIC "\037\235" /* Magic header for lzw files, 1F 9D */ | 395 | #define LZW_MAGIC "\037\235" /* Magic header for lzw files, 1F 9D */ |
391 | 396 | ||
392 | #define BIT_MASK 0x1f /* Mask for 'number of compression bits' */ | 397 | #define BIT_MASK 0x1f /* Mask for 'number of compression bits' */ |
393 | /* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free. | 398 | /* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free. |
394 | * It's a pity that old uncompress does not check bit 0x20. That makes | 399 | * It's a pity that old uncompress does not check bit 0x20. That makes |
395 | * extension of the format actually undesirable because old compress | 400 | * extension of the format actually undesirable because old compress |
@@ -404,16 +409,16 @@ extern int inflate OF((void)); | |||
404 | * clear the dictionary. | 409 | * clear the dictionary. |
405 | */ | 410 | */ |
406 | 411 | ||
407 | #define LZW_RESERVED 0x60 /* reserved bits */ | 412 | #define LZW_RESERVED 0x60 /* reserved bits */ |
408 | 413 | ||
409 | #define CLEAR 256 /* flush the dictionary */ | 414 | #define CLEAR 256 /* flush the dictionary */ |
410 | #define FIRST (CLEAR+1) /* first free entry */ | 415 | #define FIRST (CLEAR+1) /* first free entry */ |
411 | 416 | ||
412 | extern int maxbits; /* max bits per code for LZW */ | 417 | extern int maxbits; /* max bits per code for LZW */ |
413 | extern int block_mode; /* block compress mode -C compatible with 2.0 */ | 418 | extern int block_mode; /* block compress mode -C compatible with 2.0 */ |
414 | 419 | ||
415 | extern int lzw OF((int in, int out)); | 420 | extern int lzw OF((int in, int out)); |
416 | extern int unlzw OF((int in, int out)); | 421 | extern int unlzw OF((int in, int out)); |
417 | 422 | ||
418 | 423 | ||
419 | /* #include "revision.h" */ | 424 | /* #include "revision.h" */ |
@@ -458,14 +463,12 @@ extern int unlzw OF((int in, int out)); | |||
458 | #ifdef __cplusplus | 463 | #ifdef __cplusplus |
459 | extern "C" { | 464 | extern "C" { |
460 | #endif | 465 | #endif |
461 | |||
462 | /* For communication from `getopt' to the caller. | 466 | /* For communication from `getopt' to the caller. |
463 | When `getopt' finds an option that takes an argument, | 467 | When `getopt' finds an option that takes an argument, |
464 | the argument value is returned here. | 468 | the argument value is returned here. |
465 | Also, when `ordering' is RETURN_IN_ORDER, | 469 | Also, when `ordering' is RETURN_IN_ORDER, |
466 | each non-option ARGV-element is returned here. */ | 470 | each non-option ARGV-element is returned here. */ |
467 | 471 | extern char *optarg; | |
468 | extern char *optarg; | ||
469 | 472 | ||
470 | /* Index in ARGV of the next element to be scanned. | 473 | /* Index in ARGV of the next element to be scanned. |
471 | This is used for communication to and from the caller | 474 | This is used for communication to and from the caller |
@@ -479,16 +482,16 @@ extern char *optarg; | |||
479 | Otherwise, `optind' communicates from one call to the next | 482 | Otherwise, `optind' communicates from one call to the next |
480 | how much of ARGV has been scanned so far. */ | 483 | how much of ARGV has been scanned so far. */ |
481 | 484 | ||
482 | extern int optind; | 485 | extern int optind; |
483 | 486 | ||
484 | /* Callers store zero here to inhibit the error message `getopt' prints | 487 | /* Callers store zero here to inhibit the error message `getopt' prints |
485 | for unrecognized options. */ | 488 | for unrecognized options. */ |
486 | 489 | ||
487 | extern int opterr; | 490 | extern int opterr; |
488 | 491 | ||
489 | /* Set to an option character which was unrecognized. */ | 492 | /* Set to an option character which was unrecognized. */ |
490 | 493 | ||
491 | extern int optopt; | 494 | extern int optopt; |
492 | 495 | ||
493 | /* Describe the long-named options requested by the application. | 496 | /* Describe the long-named options requested by the application. |
494 | The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector | 497 | The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector |
@@ -511,19 +514,18 @@ extern int optopt; | |||
511 | one). For long options that have a zero `flag' field, `getopt' | 514 | one). For long options that have a zero `flag' field, `getopt' |
512 | returns the contents of the `val' field. */ | 515 | returns the contents of the `val' field. */ |
513 | 516 | ||
514 | struct option | 517 | struct option { |
515 | { | ||
516 | #if __STDC__ | 518 | #if __STDC__ |
517 | const char *name; | 519 | const char *name; |
518 | #else | 520 | #else |
519 | char *name; | 521 | char *name; |
520 | #endif | 522 | #endif |
521 | /* has_arg can't be an enum because some compilers complain about | 523 | /* has_arg can't be an enum because some compilers complain about |
522 | type mismatches in all the code that assumes it is an int. */ | 524 | type mismatches in all the code that assumes it is an int. */ |
523 | int has_arg; | 525 | int has_arg; |
524 | int *flag; | 526 | int *flag; |
525 | int val; | 527 | int val; |
526 | }; | 528 | }; |
527 | 529 | ||
528 | /* Names for the values of the `has_arg' field of `struct option'. */ | 530 | /* Names for the values of the `has_arg' field of `struct option'. */ |
529 | 531 | ||
@@ -536,60 +538,61 @@ struct option | |||
536 | /* Many other libraries have conflicting prototypes for getopt, with | 538 | /* Many other libraries have conflicting prototypes for getopt, with |
537 | differences in the consts, in stdlib.h. To avoid compilation | 539 | differences in the consts, in stdlib.h. To avoid compilation |
538 | errors, only prototype getopt for the GNU C library. */ | 540 | errors, only prototype getopt for the GNU C library. */ |
539 | extern int getopt (int argc, char *const *argv, const char *shortopts); | 541 | extern int getopt(int argc, char *const *argv, const char *shortopts); |
540 | #endif /* not __GNU_LIBRARY__ */ | 542 | #endif /* not __GNU_LIBRARY__ */ |
541 | extern int getopt_long (int argc, char *const *argv, const char *shortopts, | 543 | extern int getopt_long(int argc, char *const *argv, |
542 | const struct option *longopts, int *longind); | 544 | const char *shortopts, |
543 | extern int getopt_long_only (int argc, char *const *argv, | 545 | const struct option *longopts, int *longind); |
544 | const char *shortopts, | 546 | extern int getopt_long_only(int argc, char *const *argv, |
545 | const struct option *longopts, int *longind); | 547 | const char *shortopts, |
548 | const struct option *longopts, | ||
549 | int *longind); | ||
546 | 550 | ||
547 | /* Internal only. Users should not call this directly. */ | 551 | /* Internal only. Users should not call this directly. */ |
548 | extern int _getopt_internal (int argc, char *const *argv, | 552 | extern int _getopt_internal(int argc, char *const *argv, |
549 | const char *shortopts, | 553 | const char *shortopts, |
550 | const struct option *longopts, int *longind, | 554 | const struct option *longopts, |
551 | int long_only); | 555 | int *longind, int long_only); |
552 | #else /* not __STDC__ */ | 556 | #else /* not __STDC__ */ |
553 | extern int getopt (); | 557 | extern int getopt(); |
554 | extern int getopt_long (); | 558 | extern int getopt_long(); |
555 | extern int getopt_long_only (); | 559 | extern int getopt_long_only(); |
556 | 560 | ||
557 | extern int _getopt_internal (); | 561 | extern int _getopt_internal(); |
558 | #endif /* not __STDC__ */ | 562 | #endif /* not __STDC__ */ |
559 | 563 | ||
560 | #ifdef __cplusplus | 564 | #ifdef __cplusplus |
561 | } | 565 | } |
562 | #endif | 566 | #endif |
563 | 567 | #endif /* _GETOPT_H */ | |
564 | #endif /* _GETOPT_H */ | ||
565 | |||
566 | |||
567 | #include <time.h> | 568 | #include <time.h> |
568 | #include <fcntl.h> | 569 | #include <fcntl.h> |
569 | #include <unistd.h> | 570 | #include <unistd.h> |
570 | |||
571 | #include <stdlib.h> | 571 | #include <stdlib.h> |
572 | |||
573 | #if defined(DIRENT) | 572 | #if defined(DIRENT) |
574 | # include <dirent.h> | 573 | # include <dirent.h> |
575 | typedef struct dirent dir_type; | 574 | typedef struct dirent dir_type; |
575 | |||
576 | # define NLENGTH(dirent) ((int)strlen((dirent)->d_name)) | 576 | # define NLENGTH(dirent) ((int)strlen((dirent)->d_name)) |
577 | # define DIR_OPT "DIRENT" | 577 | # define DIR_OPT "DIRENT" |
578 | #else | 578 | #else |
579 | # define NLENGTH(dirent) ((dirent)->d_namlen) | 579 | # define NLENGTH(dirent) ((dirent)->d_namlen) |
580 | # ifdef SYSDIR | 580 | # ifdef SYSDIR |
581 | # include <sys/dir.h> | 581 | # include <sys/dir.h> |
582 | typedef struct direct dir_type; | 582 | typedef struct direct dir_type; |
583 | |||
583 | # define DIR_OPT "SYSDIR" | 584 | # define DIR_OPT "SYSDIR" |
584 | # else | 585 | # else |
585 | # ifdef SYSNDIR | 586 | # ifdef SYSNDIR |
586 | # include <sys/ndir.h> | 587 | # include <sys/ndir.h> |
587 | typedef struct direct dir_type; | 588 | typedef struct direct dir_type; |
589 | |||
588 | # define DIR_OPT "SYSNDIR" | 590 | # define DIR_OPT "SYSNDIR" |
589 | # else | 591 | # else |
590 | # ifdef NDIR | 592 | # ifdef NDIR |
591 | # include <ndir.h> | 593 | # include <ndir.h> |
592 | typedef struct direct dir_type; | 594 | typedef struct direct dir_type; |
595 | |||
593 | # define DIR_OPT "NDIR" | 596 | # define DIR_OPT "NDIR" |
594 | # else | 597 | # else |
595 | # define NO_DIR | 598 | # define NO_DIR |
@@ -598,18 +601,16 @@ extern int _getopt_internal (); | |||
598 | # endif | 601 | # endif |
599 | # endif | 602 | # endif |
600 | #endif | 603 | #endif |
601 | |||
602 | #if !defined(S_ISDIR) && defined(S_IFDIR) | 604 | #if !defined(S_ISDIR) && defined(S_IFDIR) |
603 | # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) | 605 | # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) |
604 | #endif | 606 | #endif |
605 | #if !defined(S_ISREG) && defined(S_IFREG) | 607 | #if !defined(S_ISREG) && defined(S_IFREG) |
606 | # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) | 608 | # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) |
607 | #endif | 609 | #endif |
608 | 610 | typedef RETSIGTYPE(*sig_type) OF((int)); | |
609 | typedef RETSIGTYPE (*sig_type) OF((int)); | ||
610 | 611 | ||
611 | #ifndef O_BINARY | 612 | #ifndef O_BINARY |
612 | # define O_BINARY 0 /* creation mode for open() */ | 613 | # define O_BINARY 0 /* creation mode for open() */ |
613 | #endif | 614 | #endif |
614 | 615 | ||
615 | #ifndef O_CREAT | 616 | #ifndef O_CREAT |
@@ -629,9 +630,9 @@ typedef RETSIGTYPE (*sig_type) OF((int)); | |||
629 | #ifndef S_IWUSR | 630 | #ifndef S_IWUSR |
630 | # define S_IWUSR 0200 | 631 | # define S_IWUSR 0200 |
631 | #endif | 632 | #endif |
632 | #define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */ | 633 | #define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */ |
633 | 634 | ||
634 | #ifndef MAX_PATH_LEN /* max pathname length */ | 635 | #ifndef MAX_PATH_LEN /* max pathname length */ |
635 | # ifdef PATH_MAX | 636 | # ifdef PATH_MAX |
636 | # define MAX_PATH_LEN PATH_MAX | 637 | # define MAX_PATH_LEN PATH_MAX |
637 | # else | 638 | # else |
@@ -644,224 +645,224 @@ typedef RETSIGTYPE (*sig_type) OF((int)); | |||
644 | #endif | 645 | #endif |
645 | 646 | ||
646 | #ifdef NO_OFF_T | 647 | #ifdef NO_OFF_T |
647 | typedef long off_t; | 648 | typedef long off_t; |
648 | off_t lseek OF((int fd, off_t offset, int whence)); | 649 | off_t lseek OF((int fd, off_t offset, int whence)); |
649 | #endif | 650 | #endif |
650 | 651 | ||
651 | 652 | ||
652 | /* global buffers */ | 653 | /* global buffers */ |
653 | 654 | ||
654 | DECLARE(uch, inbuf, INBUFSIZ +INBUF_EXTRA); | 655 | DECLARE(uch, inbuf, INBUFSIZ + INBUF_EXTRA); |
655 | DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA); | 656 | DECLARE(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA); |
656 | DECLARE(ush, d_buf, DIST_BUFSIZE); | 657 | DECLARE(ush, d_buf, DIST_BUFSIZE); |
657 | DECLARE(uch, window, 2L*WSIZE); | 658 | DECLARE(uch, window, 2L * WSIZE); |
658 | #ifndef MAXSEG_64K | 659 | #ifndef MAXSEG_64K |
659 | DECLARE(ush, tab_prefix, 1L<<BITS); | 660 | DECLARE(ush, tab_prefix, 1L << BITS); |
660 | #else | 661 | #else |
661 | DECLARE(ush, tab_prefix0, 1L<<(BITS-1)); | 662 | DECLARE(ush, tab_prefix0, 1L << (BITS - 1)); |
662 | DECLARE(ush, tab_prefix1, 1L<<(BITS-1)); | 663 | DECLARE(ush, tab_prefix1, 1L << (BITS - 1)); |
663 | #endif | 664 | #endif |
664 | 665 | ||
665 | /* local variables */ | 666 | /* local variables */ |
666 | 667 | ||
667 | int test_mode = 0; /* check file integrity option */ | 668 | int test_mode = 0; /* check file integrity option */ |
668 | int foreground; /* set if program run in foreground */ | 669 | int foreground; /* set if program run in foreground */ |
669 | int maxbits = BITS; /* max bits per code for LZW */ | 670 | int maxbits = BITS; /* max bits per code for LZW */ |
670 | int method = DEFLATED;/* compression method */ | 671 | int method = DEFLATED; /* compression method */ |
671 | int exit_code = OK; /* program exit code */ | 672 | int exit_code = OK; /* program exit code */ |
672 | int last_member; /* set for .zip and .Z files */ | 673 | int last_member; /* set for .zip and .Z files */ |
673 | int part_nb; /* number of parts in .gz file */ | 674 | int part_nb; /* number of parts in .gz file */ |
674 | long ifile_size; /* input file size, -1 for devices (debug only) */ | 675 | long ifile_size; /* input file size, -1 for devices (debug only) */ |
675 | 676 | ||
676 | long bytes_in; /* number of input bytes */ | 677 | long bytes_in; /* number of input bytes */ |
677 | long bytes_out; /* number of output bytes */ | 678 | long bytes_out; /* number of output bytes */ |
678 | long total_in = 0; /* input bytes for all files */ | 679 | long total_in = 0; /* input bytes for all files */ |
679 | long total_out = 0; /* output bytes for all files */ | 680 | long total_out = 0; /* output bytes for all files */ |
680 | struct stat istat; /* status for input file */ | 681 | struct stat istat; /* status for input file */ |
681 | int ifd; /* input file descriptor */ | 682 | int ifd; /* input file descriptor */ |
682 | int ofd; /* output file descriptor */ | 683 | int ofd; /* output file descriptor */ |
683 | unsigned insize; /* valid bytes in inbuf */ | 684 | unsigned insize; /* valid bytes in inbuf */ |
684 | unsigned inptr; /* index of next byte to be processed in inbuf */ | 685 | unsigned inptr; /* index of next byte to be processed in inbuf */ |
685 | unsigned outcnt; /* bytes in output buffer */ | 686 | unsigned outcnt; /* bytes in output buffer */ |
686 | 687 | ||
687 | long header_bytes; /* number of bytes in gzip header */ | 688 | long header_bytes; /* number of bytes in gzip header */ |
688 | 689 | ||
689 | /* local functions */ | 690 | /* local functions */ |
690 | 691 | ||
691 | local int get_method OF((int in)); | 692 | local int get_method OF((int in)); |
692 | 693 | ||
693 | #define strequ(s1, s2) (strcmp((s1),(s2)) == 0) | 694 | #define strequ(s1, s2) (strcmp((s1),(s2)) == 0) |
694 | 695 | ||
695 | /* ======================================================================== */ | 696 | /* ======================================================================== */ |
696 | int gunzip_main (int argc, char** argv) | 697 | int gunzip_main(int argc, char **argv) |
697 | { | 698 | { |
698 | int file_count; /* number of files to precess */ | 699 | int file_count; /* number of files to precess */ |
699 | int to_stdout = 0; | 700 | int to_stdout = 0; |
700 | int fromstdin = 0; | 701 | int fromstdin = 0; |
701 | int result; | 702 | int result; |
702 | int inFileNum; | 703 | int inFileNum; |
703 | int outFileNum; | 704 | int outFileNum; |
704 | int delInputFile=0; | 705 | int delInputFile = 0; |
705 | struct stat statBuf; | 706 | struct stat statBuf; |
706 | char* delFileName; | 707 | char *delFileName; |
707 | char ifname[MAX_PATH_LEN + 1]; /* input file name */ | 708 | char ifname[MAX_PATH_LEN + 1]; /* input file name */ |
708 | char ofname[MAX_PATH_LEN + 1]; /* output file name */ | 709 | char ofname[MAX_PATH_LEN + 1]; /* output file name */ |
709 | 710 | ||
710 | if (argc==1) | 711 | if (argc == 1) |
711 | usage(gunzip_usage); | 712 | usage(gunzip_usage); |
712 | 713 | ||
713 | if (strcmp(*argv, "zcat")==0) | 714 | if (strcmp(*argv, "zcat") == 0) |
714 | to_stdout = 1; | ||
715 | |||
716 | /* Parse any options */ | ||
717 | while (--argc > 0 && **(++argv) == '-') { | ||
718 | if (*((*argv)+1) == '\0') { | ||
719 | fromstdin = 1; | ||
720 | to_stdout = 1; | ||
721 | } | ||
722 | while (*(++(*argv))) { | ||
723 | switch (**argv) { | ||
724 | case 'c': | ||
725 | to_stdout = 1; | 715 | to_stdout = 1; |
726 | break; | ||
727 | case 't': | ||
728 | test_mode = 1; | ||
729 | break; | ||
730 | 716 | ||
731 | default: | 717 | /* Parse any options */ |
732 | usage(gunzip_usage); | 718 | while (--argc > 0 && **(++argv) == '-') { |
733 | } | 719 | if (*((*argv) + 1) == '\0') { |
720 | fromstdin = 1; | ||
721 | to_stdout = 1; | ||
722 | } | ||
723 | while (*(++(*argv))) { | ||
724 | switch (**argv) { | ||
725 | case 'c': | ||
726 | to_stdout = 1; | ||
727 | break; | ||
728 | case 't': | ||
729 | test_mode = 1; | ||
730 | break; | ||
731 | |||
732 | default: | ||
733 | usage(gunzip_usage); | ||
734 | } | ||
735 | } | ||
734 | } | 736 | } |
735 | } | ||
736 | 737 | ||
737 | foreground = signal(SIGINT, SIG_IGN) != SIG_IGN; | 738 | foreground = signal(SIGINT, SIG_IGN) != SIG_IGN; |
738 | if (foreground) { | 739 | if (foreground) { |
739 | (void) signal (SIGINT, (sig_type)abort_gzip); | 740 | (void) signal(SIGINT, (sig_type) abort_gzip); |
740 | } | 741 | } |
741 | #ifdef SIGTERM | 742 | #ifdef SIGTERM |
742 | if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { | 743 | if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { |
743 | (void) signal(SIGTERM, (sig_type)abort_gzip); | 744 | (void) signal(SIGTERM, (sig_type) abort_gzip); |
744 | } | 745 | } |
745 | #endif | 746 | #endif |
746 | #ifdef SIGHUP | 747 | #ifdef SIGHUP |
747 | if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { | 748 | if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { |
748 | (void) signal(SIGHUP, (sig_type)abort_gzip); | 749 | (void) signal(SIGHUP, (sig_type) abort_gzip); |
749 | } | 750 | } |
750 | #endif | 751 | #endif |
751 | 752 | ||
752 | file_count = argc - optind; | 753 | file_count = argc - optind; |
753 | 754 | ||
754 | /* Allocate all global buffers (for DYN_ALLOC option) */ | 755 | /* Allocate all global buffers (for DYN_ALLOC option) */ |
755 | ALLOC(uch, inbuf, INBUFSIZ +INBUF_EXTRA); | 756 | ALLOC(uch, inbuf, INBUFSIZ + INBUF_EXTRA); |
756 | ALLOC(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA); | 757 | ALLOC(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA); |
757 | ALLOC(ush, d_buf, DIST_BUFSIZE); | 758 | ALLOC(ush, d_buf, DIST_BUFSIZE); |
758 | ALLOC(uch, window, 2L*WSIZE); | 759 | ALLOC(uch, window, 2L * WSIZE); |
759 | #ifndef MAXSEG_64K | 760 | #ifndef MAXSEG_64K |
760 | ALLOC(ush, tab_prefix, 1L<<BITS); | 761 | ALLOC(ush, tab_prefix, 1L << BITS); |
761 | #else | 762 | #else |
762 | ALLOC(ush, tab_prefix0, 1L<<(BITS-1)); | 763 | ALLOC(ush, tab_prefix0, 1L << (BITS - 1)); |
763 | ALLOC(ush, tab_prefix1, 1L<<(BITS-1)); | 764 | ALLOC(ush, tab_prefix1, 1L << (BITS - 1)); |
764 | #endif | 765 | #endif |
765 | 766 | ||
766 | if (fromstdin==1) { | 767 | if (fromstdin == 1) { |
767 | strcpy(ofname, "stdin"); | 768 | strcpy(ofname, "stdin"); |
768 | |||
769 | inFileNum=fileno(stdin); | ||
770 | ifile_size = -1L; /* convention for unknown size */ | ||
771 | } else { | ||
772 | /* Open up the input file */ | ||
773 | if (*argv=='\0') | ||
774 | usage(gunzip_usage); | ||
775 | if (strlen(*argv) > MAX_PATH_LEN) { | ||
776 | fprintf(stderr, name_too_long, "gunzip"); | ||
777 | do_exit(WARNING); | ||
778 | } | ||
779 | strcpy(ifname, *argv); | ||
780 | 769 | ||
781 | /* Open input fille */ | 770 | inFileNum = fileno(stdin); |
782 | inFileNum=open( ifname, O_RDONLY); | 771 | ifile_size = -1L; /* convention for unknown size */ |
783 | if (inFileNum < 0) { | ||
784 | perror(ifname); | ||
785 | do_exit(WARNING); | ||
786 | } | ||
787 | /* Get the time stamp on the input file. */ | ||
788 | result = stat(ifname, &statBuf); | ||
789 | if (result < 0) { | ||
790 | perror(ifname); | ||
791 | do_exit(WARNING); | ||
792 | } | ||
793 | ifile_size = statBuf.st_size; | ||
794 | } | ||
795 | |||
796 | if (to_stdout==1) { | ||
797 | /* And get to work */ | ||
798 | strcpy(ofname, "stdout"); | ||
799 | outFileNum=fileno(stdout); | ||
800 | |||
801 | clear_bufs(); /* clear input and output buffers */ | ||
802 | part_nb = 0; | ||
803 | |||
804 | /* Actually do the compression/decompression. */ | ||
805 | unzip(inFileNum, outFileNum); | ||
806 | |||
807 | } else if (test_mode) { | ||
808 | /* Actually do the compression/decompression. */ | ||
809 | unzip(inFileNum, 2); | ||
810 | } else { | ||
811 | char* pos; | ||
812 | |||
813 | /* And get to work */ | ||
814 | if (strlen(ifname) > MAX_PATH_LEN - 4) { | ||
815 | fprintf(stderr, name_too_long, "gunzip"); | ||
816 | do_exit(WARNING); | ||
817 | } | ||
818 | strcpy(ofname, ifname); | ||
819 | pos=strstr(ofname, ".gz"); | ||
820 | if (pos != NULL) { | ||
821 | *pos='\0'; | ||
822 | delInputFile=1; | ||
823 | } else { | 772 | } else { |
824 | pos=strstr(ofname, ".tgz"); | 773 | /* Open up the input file */ |
825 | if (pos != NULL) { | 774 | if (*argv == '\0') |
826 | *pos='\0'; | 775 | usage(gunzip_usage); |
827 | strcat( pos, ".tar"); | 776 | if (strlen(*argv) > MAX_PATH_LEN) { |
828 | delInputFile=1; | 777 | fprintf(stderr, name_too_long, "gunzip"); |
829 | } | 778 | do_exit(WARNING); |
779 | } | ||
780 | strcpy(ifname, *argv); | ||
781 | |||
782 | /* Open input fille */ | ||
783 | inFileNum = open(ifname, O_RDONLY); | ||
784 | if (inFileNum < 0) { | ||
785 | perror(ifname); | ||
786 | do_exit(WARNING); | ||
787 | } | ||
788 | /* Get the time stamp on the input file. */ | ||
789 | result = stat(ifname, &statBuf); | ||
790 | if (result < 0) { | ||
791 | perror(ifname); | ||
792 | do_exit(WARNING); | ||
793 | } | ||
794 | ifile_size = statBuf.st_size; | ||
830 | } | 795 | } |
831 | 796 | ||
832 | /* Open output fille */ | 797 | if (to_stdout == 1) { |
798 | /* And get to work */ | ||
799 | strcpy(ofname, "stdout"); | ||
800 | outFileNum = fileno(stdout); | ||
801 | |||
802 | clear_bufs(); /* clear input and output buffers */ | ||
803 | part_nb = 0; | ||
804 | |||
805 | /* Actually do the compression/decompression. */ | ||
806 | unzip(inFileNum, outFileNum); | ||
807 | |||
808 | } else if (test_mode) { | ||
809 | /* Actually do the compression/decompression. */ | ||
810 | unzip(inFileNum, 2); | ||
811 | } else { | ||
812 | char *pos; | ||
813 | |||
814 | /* And get to work */ | ||
815 | if (strlen(ifname) > MAX_PATH_LEN - 4) { | ||
816 | fprintf(stderr, name_too_long, "gunzip"); | ||
817 | do_exit(WARNING); | ||
818 | } | ||
819 | strcpy(ofname, ifname); | ||
820 | pos = strstr(ofname, ".gz"); | ||
821 | if (pos != NULL) { | ||
822 | *pos = '\0'; | ||
823 | delInputFile = 1; | ||
824 | } else { | ||
825 | pos = strstr(ofname, ".tgz"); | ||
826 | if (pos != NULL) { | ||
827 | *pos = '\0'; | ||
828 | strcat(pos, ".tar"); | ||
829 | delInputFile = 1; | ||
830 | } | ||
831 | } | ||
832 | |||
833 | /* Open output fille */ | ||
833 | #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) | 834 | #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) |
834 | outFileNum=open( ofname, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW); | 835 | outFileNum = open(ofname, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW); |
835 | #else | 836 | #else |
836 | outFileNum=open( ofname, O_RDWR|O_CREAT|O_EXCL); | 837 | outFileNum = open(ofname, O_RDWR | O_CREAT | O_EXCL); |
837 | #endif | 838 | #endif |
838 | if (outFileNum < 0) { | 839 | if (outFileNum < 0) { |
839 | perror(ofname); | 840 | perror(ofname); |
840 | do_exit(WARNING); | 841 | do_exit(WARNING); |
841 | } | 842 | } |
842 | /* Set permissions on the file */ | 843 | /* Set permissions on the file */ |
843 | fchmod(outFileNum, statBuf.st_mode); | 844 | fchmod(outFileNum, statBuf.st_mode); |
844 | 845 | ||
845 | clear_bufs(); /* clear input and output buffers */ | 846 | clear_bufs(); /* clear input and output buffers */ |
846 | part_nb = 0; | 847 | part_nb = 0; |
847 | 848 | ||
848 | /* Actually do the compression/decompression. */ | 849 | /* Actually do the compression/decompression. */ |
849 | result=unzip(inFileNum, outFileNum); | 850 | result = unzip(inFileNum, outFileNum); |
850 | 851 | ||
851 | close( outFileNum); | 852 | close(outFileNum); |
852 | close( inFileNum); | 853 | close(inFileNum); |
853 | /* Delete the original file */ | 854 | /* Delete the original file */ |
854 | if (result == OK) | 855 | if (result == OK) |
855 | delFileName=ifname; | 856 | delFileName = ifname; |
856 | else | 857 | else |
857 | delFileName=ofname; | 858 | delFileName = ofname; |
858 | 859 | ||
859 | if (delInputFile == 1 && unlink (delFileName) < 0) { | 860 | if (delInputFile == 1 && unlink(delFileName) < 0) { |
860 | perror (delFileName); | 861 | perror(delFileName); |
861 | exit( FALSE); | 862 | exit(FALSE); |
863 | } | ||
862 | } | 864 | } |
863 | } | 865 | do_exit(exit_code); |
864 | do_exit(exit_code); | ||
865 | } | 866 | } |
866 | 867 | ||
867 | 868 | ||
@@ -877,71 +878,76 @@ int gunzip_main (int argc, char** argv) | |||
877 | * If the member is a zip file, it must be the only one. | 878 | * If the member is a zip file, it must be the only one. |
878 | */ | 879 | */ |
879 | local int get_method(in) | 880 | local int get_method(in) |
880 | int in; /* input file descriptor */ | 881 | int in; /* input file descriptor */ |
881 | { | 882 | { |
882 | uch flags; /* compression flags */ | 883 | uch flags; /* compression flags */ |
883 | char magic[2]; /* magic header */ | 884 | char magic[2]; /* magic header */ |
884 | 885 | ||
885 | magic[0] = (char)get_byte(); | 886 | magic[0] = (char) get_byte(); |
886 | magic[1] = (char)get_byte(); | 887 | magic[1] = (char) get_byte(); |
887 | method = -1; /* unknown yet */ | 888 | method = -1; /* unknown yet */ |
888 | part_nb++; /* number of parts in gzip file */ | 889 | part_nb++; /* number of parts in gzip file */ |
889 | header_bytes = 0; | 890 | header_bytes = 0; |
890 | last_member = RECORD_IO; | 891 | last_member = RECORD_IO; |
891 | /* assume multiple members in gzip file except for record oriented I/O */ | 892 | /* assume multiple members in gzip file except for record oriented I/O */ |
892 | 893 | ||
893 | if (memcmp(magic, GZIP_MAGIC, 2) == 0) { | 894 | if (memcmp(magic, GZIP_MAGIC, 2) == 0) { |
894 | 895 | ||
895 | method = (int)get_byte(); | 896 | method = (int) get_byte(); |
896 | if (method != DEFLATED) { | 897 | if (method != DEFLATED) { |
897 | fprintf(stderr, | 898 | fprintf(stderr, |
898 | "unknown method %d -- get newer version of gzip\n", | 899 | "unknown method %d -- get newer version of gzip\n", |
899 | method); | 900 | method); |
900 | exit_code = ERROR; | 901 | exit_code = ERROR; |
901 | return -1; | 902 | return -1; |
902 | } | 903 | } |
903 | flags = (uch)get_byte(); | 904 | flags = (uch) get_byte(); |
904 | 905 | ||
905 | (ulg)get_byte(); /* Ignore time stamp */ | 906 | (ulg) get_byte(); /* Ignore time stamp */ |
906 | (ulg)get_byte(); | 907 | (ulg) get_byte(); |
907 | (ulg)get_byte(); | 908 | (ulg) get_byte(); |
908 | (ulg)get_byte(); | 909 | (ulg) get_byte(); |
910 | |||
911 | (void) get_byte(); /* Ignore extra flags for the moment */ | ||
912 | (void) get_byte(); /* Ignore OS type for the moment */ | ||
913 | |||
914 | if ((flags & EXTRA_FIELD) != 0) { | ||
915 | unsigned len = (unsigned) get_byte(); | ||
916 | |||
917 | len |= ((unsigned) get_byte()) << 8; | ||
918 | |||
919 | while (len--) | ||
920 | (void) get_byte(); | ||
921 | } | ||
922 | |||
923 | /* Discard original name if any */ | ||
924 | if ((flags & ORIG_NAME) != 0) { | ||
925 | while (get_char() != 0) /* null */ | ||
926 | ; | ||
927 | } | ||
928 | |||
929 | /* Discard file comment if any */ | ||
930 | if ((flags & COMMENT) != 0) { | ||
931 | while (get_char() != 0) /* null */ | ||
932 | ; | ||
933 | } | ||
934 | if (part_nb == 1) { | ||
935 | header_bytes = inptr + 2 * sizeof(long); /* include crc and size */ | ||
936 | } | ||
909 | 937 | ||
910 | (void)get_byte(); /* Ignore extra flags for the moment */ | ||
911 | (void)get_byte(); /* Ignore OS type for the moment */ | ||
912 | |||
913 | if ((flags & EXTRA_FIELD) != 0) { | ||
914 | unsigned len = (unsigned)get_byte(); | ||
915 | len |= ((unsigned)get_byte())<<8; | ||
916 | |||
917 | while (len--) (void)get_byte(); | ||
918 | } | 938 | } |
919 | 939 | ||
920 | /* Discard original name if any */ | 940 | if (method >= 0) |
921 | if ((flags & ORIG_NAME) != 0) { | 941 | return method; |
922 | while (get_char() != 0) /* null */ ; | ||
923 | } | ||
924 | 942 | ||
925 | /* Discard file comment if any */ | ||
926 | if ((flags & COMMENT) != 0) { | ||
927 | while (get_char() != 0) /* null */ ; | ||
928 | } | ||
929 | if (part_nb == 1) { | 943 | if (part_nb == 1) { |
930 | header_bytes = inptr + 2*sizeof(long); /* include crc and size */ | 944 | fprintf(stderr, "\nnot in gzip format\n"); |
945 | exit_code = ERROR; | ||
946 | return -1; | ||
947 | } else { | ||
948 | WARN((stderr, "\ndecompression OK, trailing garbage ignored\n")); | ||
949 | return -2; | ||
931 | } | 950 | } |
932 | |||
933 | } | ||
934 | |||
935 | if (method >= 0) return method; | ||
936 | |||
937 | if (part_nb == 1) { | ||
938 | fprintf(stderr, "\nnot in gzip format\n"); | ||
939 | exit_code = ERROR; | ||
940 | return -1; | ||
941 | } else { | ||
942 | WARN((stderr, "\ndecompression OK, trailing garbage ignored\n")); | ||
943 | return -2; | ||
944 | } | ||
945 | } | 951 | } |
946 | 952 | ||
947 | /* ======================================================================== | 953 | /* ======================================================================== |
@@ -949,8 +955,9 @@ local int get_method(in) | |||
949 | */ | 955 | */ |
950 | RETSIGTYPE abort_gzip() | 956 | RETSIGTYPE abort_gzip() |
951 | { | 957 | { |
952 | do_exit(ERROR); | 958 | do_exit(ERROR); |
953 | } | 959 | } |
960 | |||
954 | /* unzip.c -- decompress files in gzip or pkzip format. | 961 | /* unzip.c -- decompress files in gzip or pkzip format. |
955 | * Copyright (C) 1992-1993 Jean-loup Gailly | 962 | * Copyright (C) 1992-1993 Jean-loup Gailly |
956 | * This is free software; you can redistribute it and/or modify it under the | 963 | * This is free software; you can redistribute it and/or modify it under the |
@@ -973,35 +980,35 @@ RETSIGTYPE abort_gzip() | |||
973 | */ | 980 | */ |
974 | 981 | ||
975 | #ifdef CRYPT | 982 | #ifdef CRYPT |
976 | # undef CRYPT /* dummy version */ | 983 | # undef CRYPT /* dummy version */ |
977 | #endif | 984 | #endif |
978 | 985 | ||
979 | #define RAND_HEAD_LEN 12 /* length of encryption random header */ | 986 | #define RAND_HEAD_LEN 12 /* length of encryption random header */ |
980 | 987 | ||
981 | #define zencode | 988 | #define zencode |
982 | #define zdecode | 989 | #define zdecode |
983 | 990 | ||
984 | /* PKZIP header definitions */ | 991 | /* PKZIP header definitions */ |
985 | #define LOCSIG 0x04034b50L /* four-byte lead-in (lsb first) */ | 992 | #define LOCSIG 0x04034b50L /* four-byte lead-in (lsb first) */ |
986 | #define LOCFLG 6 /* offset of bit flag */ | 993 | #define LOCFLG 6 /* offset of bit flag */ |
987 | #define CRPFLG 1 /* bit for encrypted entry */ | 994 | #define CRPFLG 1 /* bit for encrypted entry */ |
988 | #define EXTFLG 8 /* bit for extended local header */ | 995 | #define EXTFLG 8 /* bit for extended local header */ |
989 | #define LOCHOW 8 /* offset of compression method */ | 996 | #define LOCHOW 8 /* offset of compression method */ |
990 | #define LOCTIM 10 /* file mod time (for decryption) */ | 997 | #define LOCTIM 10 /* file mod time (for decryption) */ |
991 | #define LOCCRC 14 /* offset of crc */ | 998 | #define LOCCRC 14 /* offset of crc */ |
992 | #define LOCSIZ 18 /* offset of compressed size */ | 999 | #define LOCSIZ 18 /* offset of compressed size */ |
993 | #define LOCLEN 22 /* offset of uncompressed length */ | 1000 | #define LOCLEN 22 /* offset of uncompressed length */ |
994 | #define LOCFIL 26 /* offset of file name field length */ | 1001 | #define LOCFIL 26 /* offset of file name field length */ |
995 | #define LOCEXT 28 /* offset of extra field length */ | 1002 | #define LOCEXT 28 /* offset of extra field length */ |
996 | #define LOCHDR 30 /* size of local header, including sig */ | 1003 | #define LOCHDR 30 /* size of local header, including sig */ |
997 | #define EXTHDR 16 /* size of extended local header, inc sig */ | 1004 | #define EXTHDR 16 /* size of extended local header, inc sig */ |
998 | 1005 | ||
999 | 1006 | ||
1000 | /* Globals */ | 1007 | /* Globals */ |
1001 | 1008 | ||
1002 | char *key; /* not used--needed to link crypt.c */ | 1009 | char *key; /* not used--needed to link crypt.c */ |
1003 | int pkzip = 0; /* set for a pkzip file */ | 1010 | int pkzip = 0; /* set for a pkzip file */ |
1004 | int ext_header = 0; /* set if extended local header */ | 1011 | int ext_header = 0; /* set if extended local header */ |
1005 | 1012 | ||
1006 | /* =========================================================================== | 1013 | /* =========================================================================== |
1007 | * Unzip in to out. This routine works on both gzip and pkzip files. | 1014 | * Unzip in to out. This routine works on both gzip and pkzip files. |
@@ -1011,81 +1018,82 @@ int ext_header = 0; /* set if extended local header */ | |||
1011 | * The magic header has already been checked. The output buffer is cleared. | 1018 | * The magic header has already been checked. The output buffer is cleared. |
1012 | */ | 1019 | */ |
1013 | int unzip(in, out) | 1020 | int unzip(in, out) |
1014 | int in, out; /* input and output file descriptors */ | 1021 | int in, out; /* input and output file descriptors */ |
1015 | { | 1022 | { |
1016 | ulg orig_crc = 0; /* original crc */ | 1023 | ulg orig_crc = 0; /* original crc */ |
1017 | ulg orig_len = 0; /* original uncompressed length */ | 1024 | ulg orig_len = 0; /* original uncompressed length */ |
1018 | int n; | 1025 | int n; |
1019 | uch buf[EXTHDR]; /* extended local header */ | 1026 | uch buf[EXTHDR]; /* extended local header */ |
1020 | 1027 | ||
1021 | ifd = in; | 1028 | ifd = in; |
1022 | ofd = out; | 1029 | ofd = out; |
1023 | method = get_method(ifd); | 1030 | method = get_method(ifd); |
1024 | if (method < 0) { | 1031 | if (method < 0) { |
1025 | do_exit(exit_code); /* error message already emitted */ | 1032 | do_exit(exit_code); /* error message already emitted */ |
1026 | } | ||
1027 | |||
1028 | updcrc(NULL, 0); /* initialize crc */ | ||
1029 | |||
1030 | if (pkzip && !ext_header) { /* crc and length at the end otherwise */ | ||
1031 | orig_crc = LG(inbuf + LOCCRC); | ||
1032 | orig_len = LG(inbuf + LOCLEN); | ||
1033 | } | ||
1034 | |||
1035 | /* Decompress */ | ||
1036 | if (method == DEFLATED) { | ||
1037 | |||
1038 | int res = inflate(); | ||
1039 | |||
1040 | if (res == 3) { | ||
1041 | error("out of memory"); | ||
1042 | } else if (res != 0) { | ||
1043 | error("invalid compressed data--format violated"); | ||
1044 | } | 1033 | } |
1045 | 1034 | ||
1046 | } else { | 1035 | updcrc(NULL, 0); /* initialize crc */ |
1047 | error("internal error, invalid method"); | 1036 | |
1048 | } | 1037 | if (pkzip && !ext_header) { /* crc and length at the end otherwise */ |
1049 | 1038 | orig_crc = LG(inbuf + LOCCRC); | |
1050 | /* Get the crc and original length */ | 1039 | orig_len = LG(inbuf + LOCLEN); |
1051 | if (!pkzip) { | ||
1052 | /* crc32 (see algorithm.doc) | ||
1053 | * uncompressed input size modulo 2^32 | ||
1054 | */ | ||
1055 | for (n = 0; n < 8; n++) { | ||
1056 | buf[n] = (uch)get_byte(); /* may cause an error if EOF */ | ||
1057 | } | 1040 | } |
1058 | orig_crc = LG(buf); | 1041 | |
1059 | orig_len = LG(buf+4); | 1042 | /* Decompress */ |
1060 | 1043 | if (method == DEFLATED) { | |
1061 | } else if (ext_header) { /* If extended header, check it */ | 1044 | |
1062 | /* signature - 4bytes: 0x50 0x4b 0x07 0x08 | 1045 | int res = inflate(); |
1063 | * CRC-32 value | 1046 | |
1064 | * compressed size 4-bytes | 1047 | if (res == 3) { |
1065 | * uncompressed size 4-bytes | 1048 | error("out of memory"); |
1066 | */ | 1049 | } else if (res != 0) { |
1067 | for (n = 0; n < EXTHDR; n++) { | 1050 | error("invalid compressed data--format violated"); |
1068 | buf[n] = (uch)get_byte(); /* may cause an error if EOF */ | 1051 | } |
1052 | |||
1053 | } else { | ||
1054 | error("internal error, invalid method"); | ||
1055 | } | ||
1056 | |||
1057 | /* Get the crc and original length */ | ||
1058 | if (!pkzip) { | ||
1059 | /* crc32 (see algorithm.doc) | ||
1060 | * uncompressed input size modulo 2^32 | ||
1061 | */ | ||
1062 | for (n = 0; n < 8; n++) { | ||
1063 | buf[n] = (uch) get_byte(); /* may cause an error if EOF */ | ||
1064 | } | ||
1065 | orig_crc = LG(buf); | ||
1066 | orig_len = LG(buf + 4); | ||
1067 | |||
1068 | } else if (ext_header) { /* If extended header, check it */ | ||
1069 | /* signature - 4bytes: 0x50 0x4b 0x07 0x08 | ||
1070 | * CRC-32 value | ||
1071 | * compressed size 4-bytes | ||
1072 | * uncompressed size 4-bytes | ||
1073 | */ | ||
1074 | for (n = 0; n < EXTHDR; n++) { | ||
1075 | buf[n] = (uch) get_byte(); /* may cause an error if EOF */ | ||
1076 | } | ||
1077 | orig_crc = LG(buf + 4); | ||
1078 | orig_len = LG(buf + 12); | ||
1079 | } | ||
1080 | |||
1081 | /* Validate decompression */ | ||
1082 | if (orig_crc != updcrc(outbuf, 0)) { | ||
1083 | error("invalid compressed data--crc error"); | ||
1069 | } | 1084 | } |
1070 | orig_crc = LG(buf+4); | 1085 | if (orig_len != (ulg) bytes_out) { |
1071 | orig_len = LG(buf+12); | 1086 | error("invalid compressed data--length error"); |
1072 | } | 1087 | } |
1073 | 1088 | ||
1074 | /* Validate decompression */ | 1089 | /* Check if there are more entries in a pkzip file */ |
1075 | if (orig_crc != updcrc(outbuf, 0)) { | 1090 | if (pkzip && inptr + 4 < insize && LG(inbuf + inptr) == LOCSIG) { |
1076 | error("invalid compressed data--crc error"); | 1091 | WARN((stderr, "has more than one entry--rest ignored\n")); |
1077 | } | 1092 | } |
1078 | if (orig_len != (ulg)bytes_out) { | 1093 | ext_header = pkzip = 0; /* for next file */ |
1079 | error("invalid compressed data--length error"); | 1094 | return OK; |
1080 | } | ||
1081 | |||
1082 | /* Check if there are more entries in a pkzip file */ | ||
1083 | if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) { | ||
1084 | WARN((stderr,"has more than one entry--rest ignored\n")); | ||
1085 | } | ||
1086 | ext_header = pkzip = 0; /* for next file */ | ||
1087 | return OK; | ||
1088 | } | 1095 | } |
1096 | |||
1089 | /* util.c -- utility functions for gzip support | 1097 | /* util.c -- utility functions for gzip support |
1090 | * Copyright (C) 1992-1993 Jean-loup Gailly | 1098 | * Copyright (C) 1992-1993 Jean-loup Gailly |
1091 | * This is free software; you can redistribute it and/or modify it under the | 1099 | * This is free software; you can redistribute it and/or modify it under the |
@@ -1106,10 +1114,10 @@ int unzip(in, out) | |||
1106 | #if defined(STDC_HEADERS) || !defined(NO_STDLIB_H) | 1114 | #if defined(STDC_HEADERS) || !defined(NO_STDLIB_H) |
1107 | # include <stdlib.h> | 1115 | # include <stdlib.h> |
1108 | #else | 1116 | #else |
1109 | extern int errno; | 1117 | extern int errno; |
1110 | #endif | 1118 | #endif |
1111 | 1119 | ||
1112 | static const ulg crc_32_tab[]; /* crc table, defined below */ | 1120 | static const ulg crc_32_tab[]; /* crc table, defined below */ |
1113 | 1121 | ||
1114 | /* =========================================================================== | 1122 | /* =========================================================================== |
1115 | * Run a set of bytes through the crc shift register. If s is a NULL | 1123 | * Run a set of bytes through the crc shift register. If s is a NULL |
@@ -1117,23 +1125,24 @@ static const ulg crc_32_tab[]; /* crc table, defined below */ | |||
1117 | * Return the current crc in either case. | 1125 | * Return the current crc in either case. |
1118 | */ | 1126 | */ |
1119 | ulg updcrc(s, n) | 1127 | ulg updcrc(s, n) |
1120 | uch *s; /* pointer to bytes to pump through */ | 1128 | uch *s; /* pointer to bytes to pump through */ |
1121 | unsigned n; /* number of bytes in s[] */ | 1129 | unsigned n; /* number of bytes in s[] */ |
1122 | { | 1130 | { |
1123 | register ulg c; /* temporary variable */ | 1131 | register ulg c; /* temporary variable */ |
1124 | 1132 | ||
1125 | static ulg crc = (ulg)0xffffffffL; /* shift register contents */ | 1133 | static ulg crc = (ulg) 0xffffffffL; /* shift register contents */ |
1126 | 1134 | ||
1127 | if (s == NULL) { | 1135 | if (s == NULL) { |
1128 | c = 0xffffffffL; | 1136 | c = 0xffffffffL; |
1129 | } else { | 1137 | } else { |
1130 | c = crc; | 1138 | c = crc; |
1131 | if (n) do { | 1139 | if (n) |
1132 | c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); | 1140 | do { |
1133 | } while (--n); | 1141 | c = crc_32_tab[((int) c ^ (*s++)) & 0xff] ^ (c >> 8); |
1134 | } | 1142 | } while (--n); |
1135 | crc = c; | 1143 | } |
1136 | return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ | 1144 | crc = c; |
1145 | return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ | ||
1137 | } | 1146 | } |
1138 | 1147 | ||
1139 | /* =========================================================================== | 1148 | /* =========================================================================== |
@@ -1141,35 +1150,37 @@ ulg updcrc(s, n) | |||
1141 | */ | 1150 | */ |
1142 | void clear_bufs() | 1151 | void clear_bufs() |
1143 | { | 1152 | { |
1144 | outcnt = 0; | 1153 | outcnt = 0; |
1145 | insize = inptr = 0; | 1154 | insize = inptr = 0; |
1146 | bytes_in = bytes_out = 0L; | 1155 | bytes_in = bytes_out = 0L; |
1147 | } | 1156 | } |
1148 | 1157 | ||
1149 | /* =========================================================================== | 1158 | /* =========================================================================== |
1150 | * Fill the input buffer. This is called only when the buffer is empty. | 1159 | * Fill the input buffer. This is called only when the buffer is empty. |
1151 | */ | 1160 | */ |
1152 | int fill_inbuf(eof_ok) | 1161 | int fill_inbuf(eof_ok) |
1153 | int eof_ok; /* set if EOF acceptable as a result */ | 1162 | int eof_ok; /* set if EOF acceptable as a result */ |
1154 | { | 1163 | { |
1155 | int len; | 1164 | int len; |
1156 | 1165 | ||
1157 | /* Read as much as possible */ | 1166 | /* Read as much as possible */ |
1158 | insize = 0; | 1167 | insize = 0; |
1159 | errno = 0; | 1168 | errno = 0; |
1160 | do { | 1169 | do { |
1161 | len = read(ifd, (char*)inbuf+insize, INBUFSIZ-insize); | 1170 | len = read(ifd, (char *) inbuf + insize, INBUFSIZ - insize); |
1162 | if (len == 0 || len == EOF) break; | 1171 | if (len == 0 || len == EOF) |
1163 | insize += len; | 1172 | break; |
1164 | } while (insize < INBUFSIZ); | 1173 | insize += len; |
1165 | 1174 | } while (insize < INBUFSIZ); | |
1166 | if (insize == 0) { | 1175 | |
1167 | if (eof_ok) return EOF; | 1176 | if (insize == 0) { |
1168 | read_error(); | 1177 | if (eof_ok) |
1169 | } | 1178 | return EOF; |
1170 | bytes_in += (ulg)insize; | 1179 | read_error(); |
1171 | inptr = 1; | 1180 | } |
1172 | return inbuf[0]; | 1181 | bytes_in += (ulg) insize; |
1182 | inptr = 1; | ||
1183 | return inbuf[0]; | ||
1173 | } | 1184 | } |
1174 | 1185 | ||
1175 | /* =========================================================================== | 1186 | /* =========================================================================== |
@@ -1178,12 +1189,13 @@ int fill_inbuf(eof_ok) | |||
1178 | */ | 1189 | */ |
1179 | void flush_outbuf() | 1190 | void flush_outbuf() |
1180 | { | 1191 | { |
1181 | if (outcnt == 0) return; | 1192 | if (outcnt == 0) |
1193 | return; | ||
1182 | 1194 | ||
1183 | if (!test_mode) | 1195 | if (!test_mode) |
1184 | write_buf(ofd, (char *)outbuf, outcnt); | 1196 | write_buf(ofd, (char *) outbuf, outcnt); |
1185 | bytes_out += (ulg)outcnt; | 1197 | bytes_out += (ulg) outcnt; |
1186 | outcnt = 0; | 1198 | outcnt = 0; |
1187 | } | 1199 | } |
1188 | 1200 | ||
1189 | /* =========================================================================== | 1201 | /* =========================================================================== |
@@ -1192,13 +1204,14 @@ void flush_outbuf() | |||
1192 | */ | 1204 | */ |
1193 | void flush_window() | 1205 | void flush_window() |
1194 | { | 1206 | { |
1195 | if (outcnt == 0) return; | 1207 | if (outcnt == 0) |
1196 | updcrc(window, outcnt); | 1208 | return; |
1197 | 1209 | updcrc(window, outcnt); | |
1198 | if (!test_mode) | 1210 | |
1199 | write_buf(ofd, (char *)window, outcnt); | 1211 | if (!test_mode) |
1200 | bytes_out += (ulg)outcnt; | 1212 | write_buf(ofd, (char *) window, outcnt); |
1201 | outcnt = 0; | 1213 | bytes_out += (ulg) outcnt; |
1214 | outcnt = 0; | ||
1202 | } | 1215 | } |
1203 | 1216 | ||
1204 | /* =========================================================================== | 1217 | /* =========================================================================== |
@@ -1206,19 +1219,19 @@ void flush_window() | |||
1206 | * for error return. | 1219 | * for error return. |
1207 | */ | 1220 | */ |
1208 | void write_buf(fd, buf, cnt) | 1221 | void write_buf(fd, buf, cnt) |
1209 | int fd; | 1222 | int fd; |
1210 | voidp buf; | 1223 | voidp buf; |
1211 | unsigned cnt; | 1224 | unsigned cnt; |
1212 | { | 1225 | { |
1213 | unsigned n; | 1226 | unsigned n; |
1214 | 1227 | ||
1215 | while ((n = write(fd, buf, cnt)) != cnt) { | 1228 | while ((n = write(fd, buf, cnt)) != cnt) { |
1216 | if (n == (unsigned)(-1)) { | 1229 | if (n == (unsigned) (-1)) { |
1217 | write_error(); | 1230 | write_error(); |
1231 | } | ||
1232 | cnt -= n; | ||
1233 | buf = (voidp) ((char *) buf + n); | ||
1218 | } | 1234 | } |
1219 | cnt -= n; | ||
1220 | buf = (voidp)((char*)buf+n); | ||
1221 | } | ||
1222 | } | 1235 | } |
1223 | 1236 | ||
1224 | #if defined(NO_STRING_H) && !defined(STDC_HEADERS) | 1237 | #if defined(NO_STRING_H) && !defined(STDC_HEADERS) |
@@ -1229,7 +1242,7 @@ void write_buf(fd, buf, cnt) | |||
1229 | # define const | 1242 | # define const |
1230 | # endif | 1243 | # endif |
1231 | 1244 | ||
1232 | int strspn OF((const char *s, const char *accept)); | 1245 | int strspn OF((const char *s, const char *accept)); |
1233 | int strcspn OF((const char *s, const char *reject)); | 1246 | int strcspn OF((const char *s, const char *reject)); |
1234 | 1247 | ||
1235 | /* ======================================================================== | 1248 | /* ======================================================================== |
@@ -1237,21 +1250,23 @@ int strcspn OF((const char *s, const char *reject)); | |||
1237 | * of s which contains only characters in accept. | 1250 | * of s which contains only characters in accept. |
1238 | */ | 1251 | */ |
1239 | int strspn(s, accept) | 1252 | int strspn(s, accept) |
1240 | const char *s; | 1253 | const char *s; |
1241 | const char *accept; | 1254 | const char *accept; |
1242 | { | 1255 | { |
1243 | register const char *p; | 1256 | register const char *p; |
1244 | register const char *a; | 1257 | register const char *a; |
1245 | register int count = 0; | 1258 | register int count = 0; |
1246 | 1259 | ||
1247 | for (p = s; *p != '\0'; ++p) { | 1260 | for (p = s; *p != '\0'; ++p) { |
1248 | for (a = accept; *a != '\0'; ++a) { | 1261 | for (a = accept; *a != '\0'; ++a) { |
1249 | if (*p == *a) break; | 1262 | if (*p == *a) |
1263 | break; | ||
1264 | } | ||
1265 | if (*a == '\0') | ||
1266 | return count; | ||
1267 | ++count; | ||
1250 | } | 1268 | } |
1251 | if (*a == '\0') return count; | 1269 | return count; |
1252 | ++count; | ||
1253 | } | ||
1254 | return count; | ||
1255 | } | 1270 | } |
1256 | 1271 | ||
1257 | /* ======================================================================== | 1272 | /* ======================================================================== |
@@ -1259,46 +1274,47 @@ int strspn(s, accept) | |||
1259 | * which contains no characters from reject. | 1274 | * which contains no characters from reject. |
1260 | */ | 1275 | */ |
1261 | int strcspn(s, reject) | 1276 | int strcspn(s, reject) |
1262 | const char *s; | 1277 | const char *s; |
1263 | const char *reject; | 1278 | const char *reject; |
1264 | { | 1279 | { |
1265 | register int count = 0; | 1280 | register int count = 0; |
1266 | 1281 | ||
1267 | while (*s != '\0') { | 1282 | while (*s != '\0') { |
1268 | if (strchr(reject, *s++) != NULL) return count; | 1283 | if (strchr(reject, *s++) != NULL) |
1269 | ++count; | 1284 | return count; |
1270 | } | 1285 | ++count; |
1271 | return count; | 1286 | } |
1287 | return count; | ||
1272 | } | 1288 | } |
1273 | 1289 | ||
1274 | #endif /* NO_STRING_H */ | 1290 | #endif /* NO_STRING_H */ |
1275 | 1291 | ||
1276 | 1292 | ||
1277 | /* ======================================================================== | 1293 | /* ======================================================================== |
1278 | * Error handlers. | 1294 | * Error handlers. |
1279 | */ | 1295 | */ |
1280 | void warn(a, b) | 1296 | void warn(a, b) |
1281 | char *a, *b; /* message strings juxtaposed in output */ | 1297 | char *a, *b; /* message strings juxtaposed in output */ |
1282 | { | 1298 | { |
1283 | WARN((stderr, "warning: %s%s\n", a, b)); | 1299 | WARN((stderr, "warning: %s%s\n", a, b)); |
1284 | } | 1300 | } |
1285 | 1301 | ||
1286 | void read_error() | 1302 | void read_error() |
1287 | { | 1303 | { |
1288 | fprintf(stderr, "\n"); | 1304 | fprintf(stderr, "\n"); |
1289 | if (errno != 0) { | 1305 | if (errno != 0) { |
1290 | perror(""); | 1306 | perror(""); |
1291 | } else { | 1307 | } else { |
1292 | fprintf(stderr, "unexpected end of file\n"); | 1308 | fprintf(stderr, "unexpected end of file\n"); |
1293 | } | 1309 | } |
1294 | abort_gzip(); | 1310 | abort_gzip(); |
1295 | } | 1311 | } |
1296 | 1312 | ||
1297 | void write_error() | 1313 | void write_error() |
1298 | { | 1314 | { |
1299 | fprintf(stderr, "\n"); | 1315 | fprintf(stderr, "\n"); |
1300 | perror(""); | 1316 | perror(""); |
1301 | abort_gzip(); | 1317 | abort_gzip(); |
1302 | } | 1318 | } |
1303 | 1319 | ||
1304 | 1320 | ||
@@ -1306,59 +1322,60 @@ void write_error() | |||
1306 | * Table of CRC-32's of all single-byte values (made by makecrc.c) | 1322 | * Table of CRC-32's of all single-byte values (made by makecrc.c) |
1307 | */ | 1323 | */ |
1308 | static const ulg crc_32_tab[] = { | 1324 | static const ulg crc_32_tab[] = { |
1309 | 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, | 1325 | 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, |
1310 | 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, | 1326 | 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, |
1311 | 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, | 1327 | 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, |
1312 | 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, | 1328 | 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, |
1313 | 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, | 1329 | 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, |
1314 | 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, | 1330 | 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, |
1315 | 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, | 1331 | 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, |
1316 | 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, | 1332 | 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, |
1317 | 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, | 1333 | 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, |
1318 | 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, | 1334 | 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, |
1319 | 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, | 1335 | 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, |
1320 | 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, | 1336 | 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, |
1321 | 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, | 1337 | 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, |
1322 | 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, | 1338 | 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, |
1323 | 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, | 1339 | 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, |
1324 | 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, | 1340 | 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, |
1325 | 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, | 1341 | 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, |
1326 | 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, | 1342 | 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, |
1327 | 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, | 1343 | 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, |
1328 | 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, | 1344 | 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, |
1329 | 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, | 1345 | 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, |
1330 | 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, | 1346 | 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, |
1331 | 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, | 1347 | 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, |
1332 | 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, | 1348 | 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, |
1333 | 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, | 1349 | 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, |
1334 | 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, | 1350 | 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, |
1335 | 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, | 1351 | 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, |
1336 | 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, | 1352 | 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, |
1337 | 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, | 1353 | 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, |
1338 | 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, | 1354 | 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, |
1339 | 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, | 1355 | 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, |
1340 | 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, | 1356 | 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, |
1341 | 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, | 1357 | 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, |
1342 | 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, | 1358 | 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, |
1343 | 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, | 1359 | 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, |
1344 | 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, | 1360 | 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, |
1345 | 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, | 1361 | 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, |
1346 | 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, | 1362 | 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, |
1347 | 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, | 1363 | 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, |
1348 | 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, | 1364 | 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, |
1349 | 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, | 1365 | 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, |
1350 | 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, | 1366 | 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, |
1351 | 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, | 1367 | 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, |
1352 | 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, | 1368 | 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, |
1353 | 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, | 1369 | 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, |
1354 | 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, | 1370 | 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, |
1355 | 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, | 1371 | 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, |
1356 | 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, | 1372 | 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, |
1357 | 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, | 1373 | 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, |
1358 | 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, | 1374 | 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, |
1359 | 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, | 1375 | 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, |
1360 | 0x2d02ef8dL | 1376 | 0x2d02ef8dL |
1361 | }; | 1377 | }; |
1378 | |||
1362 | /* inflate.c -- Not copyrighted 1992 by Mark Adler | 1379 | /* inflate.c -- Not copyrighted 1992 by Mark Adler |
1363 | version c10p1, 10 January 1993 */ | 1380 | version c10p1, 10 January 1993 */ |
1364 | 1381 | ||
@@ -1474,18 +1491,18 @@ static const ulg crc_32_tab[] = { | |||
1474 | an unused code. If a code with e == 99 is looked up, this implies an | 1491 | an unused code. If a code with e == 99 is looked up, this implies an |
1475 | error in the data. */ | 1492 | error in the data. */ |
1476 | struct huft { | 1493 | struct huft { |
1477 | uch e; /* number of extra bits or operation */ | 1494 | uch e; /* number of extra bits or operation */ |
1478 | uch b; /* number of bits in this code or subcode */ | 1495 | uch b; /* number of bits in this code or subcode */ |
1479 | union { | 1496 | union { |
1480 | ush n; /* literal, length base, or distance base */ | 1497 | ush n; /* literal, length base, or distance base */ |
1481 | struct huft *t; /* pointer to next level of table */ | 1498 | struct huft *t; /* pointer to next level of table */ |
1482 | } v; | 1499 | } v; |
1483 | }; | 1500 | }; |
1484 | 1501 | ||
1485 | 1502 | ||
1486 | /* Function prototypes */ | 1503 | /* Function prototypes */ |
1487 | int huft_build OF((unsigned *, unsigned, unsigned, ush *, ush *, | 1504 | int huft_build OF((unsigned *, unsigned, unsigned, ush *, ush *, |
1488 | struct huft **, int *)); | 1505 | struct huft **, int *)); |
1489 | int huft_free OF((struct huft *)); | 1506 | int huft_free OF((struct huft *)); |
1490 | int inflate_codes OF((struct huft *, struct huft *, int, int)); | 1507 | int inflate_codes OF((struct huft *, struct huft *, int, int)); |
1491 | int inflate_stored OF((void)); | 1508 | int inflate_stored OF((void)); |
@@ -1508,23 +1525,29 @@ int inflate OF((void)); | |||
1508 | #define flush_output(w) (wp=(w),flush_window()) | 1525 | #define flush_output(w) (wp=(w),flush_window()) |
1509 | 1526 | ||
1510 | /* Tables for deflate from PKZIP's appnote.txt. */ | 1527 | /* Tables for deflate from PKZIP's appnote.txt. */ |
1511 | static unsigned border[] = { /* Order of the bit length code lengths */ | 1528 | static unsigned border[] = { /* Order of the bit length code lengths */ |
1512 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; | 1529 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 |
1513 | static ush cplens[] = { /* Copy lengths for literal codes 257..285 */ | 1530 | }; |
1514 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, | 1531 | static ush cplens[] = { /* Copy lengths for literal codes 257..285 */ |
1515 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; | 1532 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, |
1516 | /* note: see note #13 above about the 258 in this list. */ | 1533 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 |
1517 | static ush cplext[] = { /* Extra bits for literal codes 257..285 */ | 1534 | }; |
1518 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, | 1535 | |
1519 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ | 1536 | /* note: see note #13 above about the 258 in this list. */ |
1520 | static ush cpdist[] = { /* Copy offsets for distance codes 0..29 */ | 1537 | static ush cplext[] = { /* Extra bits for literal codes 257..285 */ |
1521 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, | 1538 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, |
1522 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, | 1539 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 |
1523 | 8193, 12289, 16385, 24577}; | 1540 | }; /* 99==invalid */ |
1524 | static ush cpdext[] = { /* Extra bits for distance codes */ | 1541 | static ush cpdist[] = { /* Copy offsets for distance codes 0..29 */ |
1525 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, | 1542 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, |
1526 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, | 1543 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, |
1527 | 12, 12, 13, 13}; | 1544 | 8193, 12289, 16385, 24577 |
1545 | }; | ||
1546 | static ush cpdext[] = { /* Extra bits for distance codes */ | ||
1547 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, | ||
1548 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, | ||
1549 | 12, 12, 13, 13 | ||
1550 | }; | ||
1528 | 1551 | ||
1529 | 1552 | ||
1530 | 1553 | ||
@@ -1558,17 +1581,18 @@ static ush cpdext[] = { /* Extra bits for distance codes */ | |||
1558 | the stream. | 1581 | the stream. |
1559 | */ | 1582 | */ |
1560 | 1583 | ||
1561 | ulg bb; /* bit buffer */ | 1584 | ulg bb; /* bit buffer */ |
1562 | unsigned bk; /* bits in bit buffer */ | 1585 | unsigned bk; /* bits in bit buffer */ |
1563 | 1586 | ||
1564 | ush mask_bits[] = { | 1587 | ush mask_bits[] = { |
1565 | 0x0000, | 1588 | 0x0000, |
1566 | 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, | 1589 | 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, |
1567 | 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff | 1590 | 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff |
1568 | }; | 1591 | }; |
1569 | 1592 | ||
1570 | #ifdef CRYPT | 1593 | #ifdef CRYPT |
1571 | uch cc; | 1594 | uch cc; |
1595 | |||
1572 | # define NEXTBYTE() (cc = get_byte(), zdecode(cc), cc) | 1596 | # define NEXTBYTE() (cc = get_byte(), zdecode(cc), cc) |
1573 | #else | 1597 | #else |
1574 | # define NEXTBYTE() (uch)get_byte() | 1598 | # define NEXTBYTE() (uch)get_byte() |
@@ -1610,342 +1634,342 @@ ush mask_bits[] = { | |||
1610 | */ | 1634 | */ |
1611 | 1635 | ||
1612 | 1636 | ||
1613 | int lbits = 9; /* bits in base literal/length lookup table */ | 1637 | int lbits = 9; /* bits in base literal/length lookup table */ |
1614 | int dbits = 6; /* bits in base distance lookup table */ | 1638 | int dbits = 6; /* bits in base distance lookup table */ |
1615 | 1639 | ||
1616 | 1640 | ||
1617 | /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ | 1641 | /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ |
1618 | #define BMAX 16 /* maximum bit length of any code (16 for explode) */ | 1642 | #define BMAX 16 /* maximum bit length of any code (16 for explode) */ |
1619 | #define N_MAX 288 /* maximum number of codes in any set */ | 1643 | #define N_MAX 288 /* maximum number of codes in any set */ |
1620 | 1644 | ||
1621 | 1645 | ||
1622 | unsigned hufts; /* track memory usage */ | 1646 | unsigned hufts; /* track memory usage */ |
1623 | 1647 | ||
1624 | 1648 | ||
1625 | int huft_build(b, n, s, d, e, t, m) | 1649 | int huft_build(b, n, s, d, e, t, m) |
1626 | unsigned *b; /* code lengths in bits (all assumed <= BMAX) */ | 1650 | unsigned *b; /* code lengths in bits (all assumed <= BMAX) */ |
1627 | unsigned n; /* number of codes (assumed <= N_MAX) */ | 1651 | unsigned n; /* number of codes (assumed <= N_MAX) */ |
1628 | unsigned s; /* number of simple-valued codes (0..s-1) */ | 1652 | unsigned s; /* number of simple-valued codes (0..s-1) */ |
1629 | ush *d; /* list of base values for non-simple codes */ | 1653 | ush *d; /* list of base values for non-simple codes */ |
1630 | ush *e; /* list of extra bits for non-simple codes */ | 1654 | ush *e; /* list of extra bits for non-simple codes */ |
1631 | struct huft **t; /* result: starting table */ | 1655 | struct huft **t; /* result: starting table */ |
1632 | int *m; /* maximum lookup bits, returns actual */ | 1656 | int *m; /* maximum lookup bits, returns actual */ |
1657 | |||
1633 | /* Given a list of code lengths and a maximum table size, make a set of | 1658 | /* Given a list of code lengths and a maximum table size, make a set of |
1634 | tables to decode that set of codes. Return zero on success, one if | 1659 | tables to decode that set of codes. Return zero on success, one if |
1635 | the given code set is incomplete (the tables are still built in this | 1660 | the given code set is incomplete (the tables are still built in this |
1636 | case), two if the input is invalid (all zero length codes or an | 1661 | case), two if the input is invalid (all zero length codes or an |
1637 | oversubscribed set of lengths), and three if not enough memory. */ | 1662 | oversubscribed set of lengths), and three if not enough memory. */ |
1638 | { | 1663 | { |
1639 | unsigned a; /* counter for codes of length k */ | 1664 | unsigned a; /* counter for codes of length k */ |
1640 | unsigned c[BMAX+1]; /* bit length count table */ | 1665 | unsigned c[BMAX + 1]; /* bit length count table */ |
1641 | unsigned f; /* i repeats in table every f entries */ | 1666 | unsigned f; /* i repeats in table every f entries */ |
1642 | int g; /* maximum code length */ | 1667 | int g; /* maximum code length */ |
1643 | int h; /* table level */ | 1668 | int h; /* table level */ |
1644 | register unsigned i; /* counter, current code */ | 1669 | register unsigned i; /* counter, current code */ |
1645 | register unsigned j; /* counter */ | 1670 | register unsigned j; /* counter */ |
1646 | register int k; /* number of bits in current code */ | 1671 | register int k; /* number of bits in current code */ |
1647 | int l; /* bits per table (returned in m) */ | 1672 | int l; /* bits per table (returned in m) */ |
1648 | register unsigned *p; /* pointer into c[], b[], or v[] */ | 1673 | register unsigned *p; /* pointer into c[], b[], or v[] */ |
1649 | register struct huft *q; /* points to current table */ | 1674 | register struct huft *q; /* points to current table */ |
1650 | struct huft r; /* table entry for structure assignment */ | 1675 | struct huft r; /* table entry for structure assignment */ |
1651 | struct huft *u[BMAX]; /* table stack */ | 1676 | struct huft *u[BMAX]; /* table stack */ |
1652 | unsigned v[N_MAX]; /* values in order of bit length */ | 1677 | unsigned v[N_MAX]; /* values in order of bit length */ |
1653 | register int w; /* bits before this table == (l * h) */ | 1678 | register int w; /* bits before this table == (l * h) */ |
1654 | unsigned x[BMAX+1]; /* bit offsets, then code stack */ | 1679 | unsigned x[BMAX + 1]; /* bit offsets, then code stack */ |
1655 | unsigned *xp; /* pointer into x */ | 1680 | unsigned *xp; /* pointer into x */ |
1656 | int y; /* number of dummy codes added */ | 1681 | int y; /* number of dummy codes added */ |
1657 | unsigned z; /* number of entries in current table */ | 1682 | unsigned z; /* number of entries in current table */ |
1658 | 1683 | ||
1659 | 1684 | ||
1660 | /* Generate counts for each bit length */ | 1685 | /* Generate counts for each bit length */ |
1661 | memzero(c, sizeof(c)); | 1686 | memzero(c, sizeof(c)); |
1662 | p = b; i = n; | 1687 | p = b; |
1663 | do { | 1688 | i = n; |
1664 | Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), | 1689 | do { |
1665 | n-i, *p)); | 1690 | Tracecv(*p, |
1666 | c[*p]++; /* assume all entries <= BMAX */ | 1691 | (stderr, |
1667 | p++; /* Can't combine with above line (Solaris bug) */ | 1692 | (n - i >= ' ' |
1668 | } while (--i); | 1693 | && n - i <= '~' ? "%c %d\n" : "0x%x %d\n"), n - i, *p)); |
1669 | if (c[0] == n) /* null input--all zero length codes */ | 1694 | c[*p]++; /* assume all entries <= BMAX */ |
1670 | { | 1695 | p++; /* Can't combine with above line (Solaris bug) */ |
1671 | *t = (struct huft *)NULL; | 1696 | } while (--i); |
1672 | *m = 0; | 1697 | if (c[0] == n) { /* null input--all zero length codes */ |
1673 | return 0; | 1698 | *t = (struct huft *) NULL; |
1674 | } | 1699 | *m = 0; |
1675 | 1700 | return 0; | |
1676 | 1701 | } | |
1677 | /* Find minimum and maximum length, bound *m by those */ | 1702 | |
1678 | l = *m; | 1703 | |
1679 | for (j = 1; j <= BMAX; j++) | 1704 | /* Find minimum and maximum length, bound *m by those */ |
1680 | if (c[j]) | 1705 | l = *m; |
1681 | break; | 1706 | for (j = 1; j <= BMAX; j++) |
1682 | k = j; /* minimum code length */ | 1707 | if (c[j]) |
1683 | if ((unsigned)l < j) | 1708 | break; |
1684 | l = j; | 1709 | k = j; /* minimum code length */ |
1685 | for (i = BMAX; i; i--) | 1710 | if ((unsigned) l < j) |
1686 | if (c[i]) | 1711 | l = j; |
1687 | break; | 1712 | for (i = BMAX; i; i--) |
1688 | g = i; /* maximum code length */ | 1713 | if (c[i]) |
1689 | if ((unsigned)l > i) | 1714 | break; |
1690 | l = i; | 1715 | g = i; /* maximum code length */ |
1691 | *m = l; | 1716 | if ((unsigned) l > i) |
1692 | 1717 | l = i; | |
1693 | 1718 | *m = l; | |
1694 | /* Adjust last length count to fill out codes, if needed */ | 1719 | |
1695 | for (y = 1 << j; j < i; j++, y <<= 1) | 1720 | |
1696 | if ((y -= c[j]) < 0) | 1721 | /* Adjust last length count to fill out codes, if needed */ |
1697 | return 2; /* bad input: more codes than bits */ | 1722 | for (y = 1 << j; j < i; j++, y <<= 1) |
1698 | if ((y -= c[i]) < 0) | 1723 | if ((y -= c[j]) < 0) |
1699 | return 2; | 1724 | return 2; /* bad input: more codes than bits */ |
1700 | c[i] += y; | 1725 | if ((y -= c[i]) < 0) |
1701 | 1726 | return 2; | |
1702 | 1727 | c[i] += y; | |
1703 | /* Generate starting offsets into the value table for each length */ | 1728 | |
1704 | x[1] = j = 0; | 1729 | |
1705 | p = c + 1; xp = x + 2; | 1730 | /* Generate starting offsets into the value table for each length */ |
1706 | while (--i) { /* note that i == g from above */ | 1731 | x[1] = j = 0; |
1707 | *xp++ = (j += *p++); | 1732 | p = c + 1; |
1708 | } | 1733 | xp = x + 2; |
1709 | 1734 | while (--i) { /* note that i == g from above */ | |
1710 | 1735 | *xp++ = (j += *p++); | |
1711 | /* Make a table of values in order of bit lengths */ | 1736 | } |
1712 | p = b; i = 0; | 1737 | |
1713 | do { | 1738 | |
1714 | if ((j = *p++) != 0) | 1739 | /* Make a table of values in order of bit lengths */ |
1715 | v[x[j]++] = i; | 1740 | p = b; |
1716 | } while (++i < n); | 1741 | i = 0; |
1717 | 1742 | do { | |
1718 | 1743 | if ((j = *p++) != 0) | |
1719 | /* Generate the Huffman codes and for each, make the table entries */ | 1744 | v[x[j]++] = i; |
1720 | x[0] = i = 0; /* first Huffman code is zero */ | 1745 | } while (++i < n); |
1721 | p = v; /* grab values in bit order */ | 1746 | |
1722 | h = -1; /* no tables yet--level -1 */ | 1747 | |
1723 | w = -l; /* bits decoded == (l * h) */ | 1748 | /* Generate the Huffman codes and for each, make the table entries */ |
1724 | u[0] = (struct huft *)NULL; /* just to keep compilers happy */ | 1749 | x[0] = i = 0; /* first Huffman code is zero */ |
1725 | q = (struct huft *)NULL; /* ditto */ | 1750 | p = v; /* grab values in bit order */ |
1726 | z = 0; /* ditto */ | 1751 | h = -1; /* no tables yet--level -1 */ |
1727 | 1752 | w = -l; /* bits decoded == (l * h) */ | |
1728 | /* go through the bit lengths (k already is bits in shortest code) */ | 1753 | u[0] = (struct huft *) NULL; /* just to keep compilers happy */ |
1729 | for (; k <= g; k++) | 1754 | q = (struct huft *) NULL; /* ditto */ |
1730 | { | 1755 | z = 0; /* ditto */ |
1731 | a = c[k]; | 1756 | |
1732 | while (a--) | 1757 | /* go through the bit lengths (k already is bits in shortest code) */ |
1733 | { | 1758 | for (; k <= g; k++) { |
1734 | /* here i is the Huffman code of length k bits for value *p */ | 1759 | a = c[k]; |
1735 | /* make tables up to required level */ | 1760 | while (a--) { |
1736 | while (k > w + l) | 1761 | /* here i is the Huffman code of length k bits for value *p */ |
1737 | { | 1762 | /* make tables up to required level */ |
1738 | h++; | 1763 | while (k > w + l) { |
1739 | w += l; /* previous table always l bits */ | 1764 | h++; |
1740 | 1765 | w += l; /* previous table always l bits */ | |
1741 | /* compute minimum size table less than or equal to l bits */ | 1766 | |
1742 | z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */ | 1767 | /* compute minimum size table less than or equal to l bits */ |
1743 | if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ | 1768 | z = (z = g - w) > (unsigned) l ? l : z; /* upper limit on table size */ |
1744 | { /* too few codes for k-w bit table */ | 1769 | if ((f = 1 << (j = k - w)) > a + 1) { /* try a k-w bit table *//* too few codes for k-w bit table */ |
1745 | f -= a + 1; /* deduct codes from patterns left */ | 1770 | f -= a + 1; /* deduct codes from patterns left */ |
1746 | xp = c + k; | 1771 | xp = c + k; |
1747 | while (++j < z) /* try smaller tables up to z bits */ | 1772 | while (++j < z) { /* try smaller tables up to z bits */ |
1748 | { | 1773 | if ((f <<= 1) <= *++xp) |
1749 | if ((f <<= 1) <= *++xp) | 1774 | break; /* enough codes to use up j bits */ |
1750 | break; /* enough codes to use up j bits */ | 1775 | f -= *xp; /* else deduct codes from patterns */ |
1751 | f -= *xp; /* else deduct codes from patterns */ | 1776 | } |
1752 | } | 1777 | } |
1753 | } | 1778 | z = 1 << j; /* table entries for j-bit table */ |
1754 | z = 1 << j; /* table entries for j-bit table */ | 1779 | |
1755 | 1780 | /* allocate and link in new table */ | |
1756 | /* allocate and link in new table */ | 1781 | if ( |
1757 | if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) == | 1782 | (q = |
1758 | (struct huft *)NULL) | 1783 | (struct huft *) malloc((z + 1) * |
1759 | { | 1784 | sizeof(struct huft))) == |
1760 | if (h) | 1785 | (struct huft *) NULL) { |
1761 | huft_free(u[0]); | 1786 | if (h) |
1762 | return 3; /* not enough memory */ | 1787 | huft_free(u[0]); |
1763 | } | 1788 | return 3; /* not enough memory */ |
1764 | hufts += z + 1; /* track memory usage */ | 1789 | } |
1765 | *t = q + 1; /* link to list for huft_free() */ | 1790 | hufts += z + 1; /* track memory usage */ |
1766 | *(t = &(q->v.t)) = (struct huft *)NULL; | 1791 | *t = q + 1; /* link to list for huft_free() */ |
1767 | u[h] = ++q; /* table starts after link */ | 1792 | *(t = &(q->v.t)) = (struct huft *) NULL; |
1768 | 1793 | u[h] = ++q; /* table starts after link */ | |
1769 | /* connect to last table, if there is one */ | 1794 | |
1770 | if (h) | 1795 | /* connect to last table, if there is one */ |
1771 | { | 1796 | if (h) { |
1772 | x[h] = i; /* save pattern for backing up */ | 1797 | x[h] = i; /* save pattern for backing up */ |
1773 | r.b = (uch)l; /* bits to dump before this table */ | 1798 | r.b = (uch) l; /* bits to dump before this table */ |
1774 | r.e = (uch)(16 + j); /* bits in this table */ | 1799 | r.e = (uch) (16 + j); /* bits in this table */ |
1775 | r.v.t = q; /* pointer to this table */ | 1800 | r.v.t = q; /* pointer to this table */ |
1776 | j = i >> (w - l); /* (get around Turbo C bug) */ | 1801 | j = i >> (w - l); /* (get around Turbo C bug) */ |
1777 | u[h-1][j] = r; /* connect to last table */ | 1802 | u[h - 1][j] = r; /* connect to last table */ |
1778 | } | 1803 | } |
1779 | } | 1804 | } |
1780 | 1805 | ||
1781 | /* set up table entry in r */ | 1806 | /* set up table entry in r */ |
1782 | r.b = (uch)(k - w); | 1807 | r.b = (uch) (k - w); |
1783 | if (p >= v + n) | 1808 | if (p >= v + n) |
1784 | r.e = 99; /* out of values--invalid code */ | 1809 | r.e = 99; /* out of values--invalid code */ |
1785 | else if (*p < s) | 1810 | else if (*p < s) { |
1786 | { | 1811 | r.e = (uch) (*p < 256 ? 16 : 15); /* 256 is end-of-block code */ |
1787 | r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ | 1812 | r.v.n = (ush) (*p); /* simple code is just the value */ |
1788 | r.v.n = (ush)(*p); /* simple code is just the value */ | 1813 | p++; /* one compiler does not like *p++ */ |
1789 | p++; /* one compiler does not like *p++ */ | 1814 | } else { |
1790 | } | 1815 | r.e = (uch) e[*p - s]; /* non-simple--look up in lists */ |
1791 | else | 1816 | r.v.n = d[*p++ - s]; |
1792 | { | 1817 | } |
1793 | r.e = (uch)e[*p - s]; /* non-simple--look up in lists */ | 1818 | |
1794 | r.v.n = d[*p++ - s]; | 1819 | /* fill code-like entries with r */ |
1795 | } | 1820 | f = 1 << (k - w); |
1796 | 1821 | for (j = i >> w; j < z; j += f) | |
1797 | /* fill code-like entries with r */ | 1822 | q[j] = r; |
1798 | f = 1 << (k - w); | 1823 | |
1799 | for (j = i >> w; j < z; j += f) | 1824 | /* backwards increment the k-bit code i */ |
1800 | q[j] = r; | 1825 | for (j = 1 << (k - 1); i & j; j >>= 1) |
1801 | 1826 | i ^= j; | |
1802 | /* backwards increment the k-bit code i */ | 1827 | i ^= j; |
1803 | for (j = 1 << (k - 1); i & j; j >>= 1) | 1828 | |
1804 | i ^= j; | 1829 | /* backup over finished tables */ |
1805 | i ^= j; | 1830 | while ((i & ((1 << w) - 1)) != x[h]) { |
1806 | 1831 | h--; /* don't need to update q */ | |
1807 | /* backup over finished tables */ | 1832 | w -= l; |
1808 | while ((i & ((1 << w) - 1)) != x[h]) | 1833 | } |
1809 | { | 1834 | } |
1810 | h--; /* don't need to update q */ | 1835 | } |
1811 | w -= l; | 1836 | |
1812 | } | 1837 | |
1813 | } | 1838 | /* Return true (1) if we were given an incomplete table */ |
1814 | } | 1839 | return y != 0 && g != 1; |
1815 | |||
1816 | |||
1817 | /* Return true (1) if we were given an incomplete table */ | ||
1818 | return y != 0 && g != 1; | ||
1819 | } | 1840 | } |
1820 | 1841 | ||
1821 | 1842 | ||
1822 | 1843 | ||
1823 | int huft_free(t) | 1844 | int huft_free(t) |
1824 | struct huft *t; /* table to free */ | 1845 | struct huft *t; /* table to free */ |
1846 | |||
1825 | /* Free the malloc'ed tables built by huft_build(), which makes a linked | 1847 | /* Free the malloc'ed tables built by huft_build(), which makes a linked |
1826 | list of the tables it made, with the links in a dummy first entry of | 1848 | list of the tables it made, with the links in a dummy first entry of |
1827 | each table. */ | 1849 | each table. */ |
1828 | { | 1850 | { |
1829 | register struct huft *p, *q; | 1851 | register struct huft *p, *q; |
1830 | 1852 | ||
1831 | 1853 | ||
1832 | /* Go through linked list, freeing from the malloced (t[-1]) address. */ | 1854 | /* Go through linked list, freeing from the malloced (t[-1]) address. */ |
1833 | p = t; | 1855 | p = t; |
1834 | while (p != (struct huft *)NULL) | 1856 | while (p != (struct huft *) NULL) { |
1835 | { | 1857 | q = (--p)->v.t; |
1836 | q = (--p)->v.t; | 1858 | free((char *) p); |
1837 | free((char*)p); | 1859 | p = q; |
1838 | p = q; | 1860 | } |
1839 | } | 1861 | return 0; |
1840 | return 0; | ||
1841 | } | 1862 | } |
1842 | 1863 | ||
1843 | 1864 | ||
1844 | int inflate_codes(tl, td, bl, bd) | 1865 | int inflate_codes(tl, td, bl, bd) |
1845 | struct huft *tl, *td; /* literal/length and distance decoder tables */ | 1866 | struct huft *tl, *td; /* literal/length and distance decoder tables */ |
1846 | int bl, bd; /* number of bits decoded by tl[] and td[] */ | 1867 | int bl, bd; /* number of bits decoded by tl[] and td[] */ |
1868 | |||
1847 | /* inflate (decompress) the codes in a deflated (compressed) block. | 1869 | /* inflate (decompress) the codes in a deflated (compressed) block. |
1848 | Return an error code or zero if it all goes ok. */ | 1870 | Return an error code or zero if it all goes ok. */ |
1849 | { | 1871 | { |
1850 | register unsigned e; /* table entry flag/number of extra bits */ | 1872 | register unsigned e; /* table entry flag/number of extra bits */ |
1851 | unsigned n, d; /* length and index for copy */ | 1873 | unsigned n, d; /* length and index for copy */ |
1852 | unsigned w; /* current window position */ | 1874 | unsigned w; /* current window position */ |
1853 | struct huft *t; /* pointer to table entry */ | 1875 | struct huft *t; /* pointer to table entry */ |
1854 | unsigned ml, md; /* masks for bl and bd bits */ | 1876 | unsigned ml, md; /* masks for bl and bd bits */ |
1855 | register ulg b; /* bit buffer */ | 1877 | register ulg b; /* bit buffer */ |
1856 | register unsigned k; /* number of bits in bit buffer */ | 1878 | register unsigned k; /* number of bits in bit buffer */ |
1857 | 1879 | ||
1858 | 1880 | ||
1859 | /* make local copies of globals */ | 1881 | /* make local copies of globals */ |
1860 | b = bb; /* initialize bit buffer */ | 1882 | b = bb; /* initialize bit buffer */ |
1861 | k = bk; | 1883 | k = bk; |
1862 | w = wp; /* initialize window position */ | 1884 | w = wp; /* initialize window position */ |
1863 | 1885 | ||
1864 | /* inflate the coded data */ | 1886 | /* inflate the coded data */ |
1865 | ml = mask_bits[bl]; /* precompute masks for speed */ | 1887 | ml = mask_bits[bl]; /* precompute masks for speed */ |
1866 | md = mask_bits[bd]; | 1888 | md = mask_bits[bd]; |
1867 | for (;;) /* do until end of block */ | 1889 | for (;;) { /* do until end of block */ |
1868 | { | 1890 | NEEDBITS((unsigned) bl) |
1869 | NEEDBITS((unsigned)bl) | 1891 | if ((e = (t = tl + ((unsigned) b & ml))->e) > 16) |
1870 | if ((e = (t = tl + ((unsigned)b & ml))->e) > 16) | 1892 | do { |
1871 | do { | 1893 | if (e == 99) |
1872 | if (e == 99) | 1894 | return 1; |
1873 | return 1; | 1895 | DUMPBITS(t->b) |
1874 | DUMPBITS(t->b) | 1896 | e -= 16; |
1875 | e -= 16; | 1897 | NEEDBITS(e) |
1876 | NEEDBITS(e) | 1898 | } while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) |
1877 | } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); | 1899 | > 16); |
1878 | DUMPBITS(t->b) | 1900 | DUMPBITS(t->b) |
1879 | if (e == 16) /* then it's a literal */ | 1901 | if (e == 16) { /* then it's a literal */ |
1880 | { | 1902 | slide[w++] = (uch) t->v.n; |
1881 | slide[w++] = (uch)t->v.n; | 1903 | Tracevv((stderr, "%c", slide[w - 1])); |
1882 | Tracevv((stderr, "%c", slide[w-1])); | 1904 | if (w == WSIZE) { |
1883 | if (w == WSIZE) | 1905 | flush_output(w); |
1884 | { | 1906 | w = 0; |
1885 | flush_output(w); | 1907 | } |
1886 | w = 0; | 1908 | } else { /* it's an EOB or a length */ |
1887 | } | 1909 | |
1888 | } | 1910 | /* exit if end of block */ |
1889 | else /* it's an EOB or a length */ | 1911 | if (e == 15) |
1890 | { | 1912 | break; |
1891 | /* exit if end of block */ | 1913 | |
1892 | if (e == 15) | 1914 | /* get length of block to copy */ |
1893 | break; | 1915 | NEEDBITS(e) |
1894 | 1916 | n = t->v.n + ((unsigned) b & mask_bits[e]); | |
1895 | /* get length of block to copy */ | 1917 | DUMPBITS(e); |
1896 | NEEDBITS(e) | 1918 | |
1897 | n = t->v.n + ((unsigned)b & mask_bits[e]); | 1919 | /* decode distance of block to copy */ |
1898 | DUMPBITS(e); | 1920 | NEEDBITS((unsigned) bd) |
1899 | 1921 | if ((e = (t = td + ((unsigned) b & md))->e) > 16) | |
1900 | /* decode distance of block to copy */ | 1922 | do { |
1901 | NEEDBITS((unsigned)bd) | 1923 | if (e == 99) |
1902 | if ((e = (t = td + ((unsigned)b & md))->e) > 16) | 1924 | return 1; |
1903 | do { | 1925 | DUMPBITS(t->b) |
1904 | if (e == 99) | 1926 | e -= 16; |
1905 | return 1; | 1927 | NEEDBITS(e) |
1906 | DUMPBITS(t->b) | 1928 | } |
1907 | e -= 16; | 1929 | while ( |
1908 | NEEDBITS(e) | 1930 | (e = |
1909 | } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); | 1931 | (t = |
1910 | DUMPBITS(t->b) | 1932 | t->v.t + ((unsigned) b & mask_bits[e]))->e) > |
1911 | NEEDBITS(e) | 1933 | 16); |
1912 | d = w - t->v.n - ((unsigned)b & mask_bits[e]); | 1934 | DUMPBITS(t->b) |
1913 | DUMPBITS(e) | 1935 | NEEDBITS(e) |
1914 | Tracevv((stderr,"\\[%d,%d]", w-d, n)); | 1936 | d = w - t->v.n - ((unsigned) b & mask_bits[e]); |
1915 | 1937 | DUMPBITS(e) | |
1916 | /* do the copy */ | 1938 | Tracevv((stderr, "\\[%d,%d]", w - d, n)); |
1917 | do { | 1939 | |
1918 | n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); | 1940 | /* do the copy */ |
1941 | do { | ||
1942 | n -= (e = | ||
1943 | (e = | ||
1944 | WSIZE - ((d &= WSIZE - 1) > w ? d : w)) > | ||
1945 | n ? n : e); | ||
1919 | #if !defined(NOMEMCPY) && !defined(DEBUG) | 1946 | #if !defined(NOMEMCPY) && !defined(DEBUG) |
1920 | if (w - d >= e) /* (this test assumes unsigned comparison) */ | 1947 | if (w - d >= e) { /* (this test assumes unsigned comparison) */ |
1921 | { | 1948 | memcpy(slide + w, slide + d, e); |
1922 | memcpy(slide + w, slide + d, e); | 1949 | w += e; |
1923 | w += e; | 1950 | d += e; |
1924 | d += e; | 1951 | } else /* do it slow to avoid memcpy() overlap */ |
1925 | } | 1952 | #endif /* !NOMEMCPY */ |
1926 | else /* do it slow to avoid memcpy() overlap */ | 1953 | do { |
1927 | #endif /* !NOMEMCPY */ | 1954 | slide[w++] = slide[d++]; |
1928 | do { | 1955 | Tracevv((stderr, "%c", slide[w - 1])); |
1929 | slide[w++] = slide[d++]; | 1956 | } while (--e); |
1930 | Tracevv((stderr, "%c", slide[w-1])); | 1957 | if (w == WSIZE) { |
1931 | } while (--e); | 1958 | flush_output(w); |
1932 | if (w == WSIZE) | 1959 | w = 0; |
1933 | { | 1960 | } |
1934 | flush_output(w); | 1961 | } while (n); |
1935 | w = 0; | 1962 | } |
1936 | } | 1963 | } |
1937 | } while (n); | 1964 | |
1938 | } | 1965 | |
1939 | } | 1966 | /* restore the globals from the locals */ |
1940 | 1967 | wp = w; /* restore global window pointer */ | |
1941 | 1968 | bb = b; /* restore global bit buffer */ | |
1942 | /* restore the globals from the locals */ | 1969 | bk = k; |
1943 | wp = w; /* restore global window pointer */ | 1970 | |
1944 | bb = b; /* restore global bit buffer */ | 1971 | /* done */ |
1945 | bk = k; | 1972 | return 0; |
1946 | |||
1947 | /* done */ | ||
1948 | return 0; | ||
1949 | } | 1973 | } |
1950 | 1974 | ||
1951 | 1975 | ||
@@ -1953,52 +1977,50 @@ int bl, bd; /* number of bits decoded by tl[] and td[] */ | |||
1953 | int inflate_stored() | 1977 | int inflate_stored() |
1954 | /* "decompress" an inflated type 0 (stored) block. */ | 1978 | /* "decompress" an inflated type 0 (stored) block. */ |
1955 | { | 1979 | { |
1956 | unsigned n; /* number of bytes in block */ | 1980 | unsigned n; /* number of bytes in block */ |
1957 | unsigned w; /* current window position */ | 1981 | unsigned w; /* current window position */ |
1958 | register ulg b; /* bit buffer */ | 1982 | register ulg b; /* bit buffer */ |
1959 | register unsigned k; /* number of bits in bit buffer */ | 1983 | register unsigned k; /* number of bits in bit buffer */ |
1960 | 1984 | ||
1961 | 1985 | ||
1962 | /* make local copies of globals */ | 1986 | /* make local copies of globals */ |
1963 | b = bb; /* initialize bit buffer */ | 1987 | b = bb; /* initialize bit buffer */ |
1964 | k = bk; | 1988 | k = bk; |
1965 | w = wp; /* initialize window position */ | 1989 | w = wp; /* initialize window position */ |
1966 | 1990 | ||
1967 | 1991 | ||
1968 | /* go to byte boundary */ | 1992 | /* go to byte boundary */ |
1969 | n = k & 7; | 1993 | n = k & 7; |
1970 | DUMPBITS(n); | 1994 | DUMPBITS(n); |
1971 | 1995 | ||
1972 | 1996 | ||
1973 | /* get the length and its complement */ | 1997 | /* get the length and its complement */ |
1974 | NEEDBITS(16) | 1998 | NEEDBITS(16) |
1975 | n = ((unsigned)b & 0xffff); | 1999 | n = ((unsigned) b & 0xffff); |
1976 | DUMPBITS(16) | 2000 | DUMPBITS(16) |
1977 | NEEDBITS(16) | 2001 | NEEDBITS(16) |
1978 | if (n != (unsigned)((~b) & 0xffff)) | 2002 | if (n != (unsigned) ((~b) & 0xffff)) |
1979 | return 1; /* error in compressed data */ | 2003 | return 1; /* error in compressed data */ |
1980 | DUMPBITS(16) | 2004 | DUMPBITS(16) |
1981 | 2005 | ||
1982 | 2006 | ||
1983 | /* read and output the compressed data */ | 2007 | /* read and output the compressed data */ |
1984 | while (n--) | 2008 | while (n--) { |
1985 | { | 2009 | NEEDBITS(8) |
1986 | NEEDBITS(8) | 2010 | slide[w++] = (uch) b; |
1987 | slide[w++] = (uch)b; | 2011 | if (w == WSIZE) { |
1988 | if (w == WSIZE) | 2012 | flush_output(w); |
1989 | { | 2013 | w = 0; |
1990 | flush_output(w); | 2014 | } |
1991 | w = 0; | 2015 | DUMPBITS(8) |
1992 | } | 2016 | } |
1993 | DUMPBITS(8) | 2017 | |
1994 | } | 2018 | |
1995 | 2019 | /* restore the globals from the locals */ | |
1996 | 2020 | wp = w; /* restore global window pointer */ | |
1997 | /* restore the globals from the locals */ | 2021 | bb = b; /* restore global bit buffer */ |
1998 | wp = w; /* restore global window pointer */ | 2022 | bk = k; |
1999 | bb = b; /* restore global bit buffer */ | 2023 | return 0; |
2000 | bk = k; | ||
2001 | return 0; | ||
2002 | } | 2024 | } |
2003 | 2025 | ||
2004 | 2026 | ||
@@ -2008,48 +2030,47 @@ int inflate_fixed() | |||
2008 | either replace this with a custom decoder, or at least precompute the | 2030 | either replace this with a custom decoder, or at least precompute the |
2009 | Huffman tables. */ | 2031 | Huffman tables. */ |
2010 | { | 2032 | { |
2011 | int i; /* temporary variable */ | 2033 | int i; /* temporary variable */ |
2012 | struct huft *tl; /* literal/length code table */ | 2034 | struct huft *tl; /* literal/length code table */ |
2013 | struct huft *td; /* distance code table */ | 2035 | struct huft *td; /* distance code table */ |
2014 | int bl; /* lookup bits for tl */ | 2036 | int bl; /* lookup bits for tl */ |
2015 | int bd; /* lookup bits for td */ | 2037 | int bd; /* lookup bits for td */ |
2016 | unsigned l[288]; /* length list for huft_build */ | 2038 | unsigned l[288]; /* length list for huft_build */ |
2017 | 2039 | ||
2018 | 2040 | ||
2019 | /* set up literal table */ | 2041 | /* set up literal table */ |
2020 | for (i = 0; i < 144; i++) | 2042 | for (i = 0; i < 144; i++) |
2021 | l[i] = 8; | 2043 | l[i] = 8; |
2022 | for (; i < 256; i++) | 2044 | for (; i < 256; i++) |
2023 | l[i] = 9; | 2045 | l[i] = 9; |
2024 | for (; i < 280; i++) | 2046 | for (; i < 280; i++) |
2025 | l[i] = 7; | 2047 | l[i] = 7; |
2026 | for (; i < 288; i++) /* make a complete, but wrong code set */ | 2048 | for (; i < 288; i++) /* make a complete, but wrong code set */ |
2027 | l[i] = 8; | 2049 | l[i] = 8; |
2028 | bl = 7; | 2050 | bl = 7; |
2029 | if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) | 2051 | if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) |
2030 | return i; | 2052 | return i; |
2031 | 2053 | ||
2032 | 2054 | ||
2033 | /* set up distance table */ | 2055 | /* set up distance table */ |
2034 | for (i = 0; i < 30; i++) /* make an incomplete code set */ | 2056 | for (i = 0; i < 30; i++) /* make an incomplete code set */ |
2035 | l[i] = 5; | 2057 | l[i] = 5; |
2036 | bd = 5; | 2058 | bd = 5; |
2037 | if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) | 2059 | if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) { |
2038 | { | 2060 | huft_free(tl); |
2039 | huft_free(tl); | 2061 | return i; |
2040 | return i; | 2062 | } |
2041 | } | 2063 | |
2042 | 2064 | ||
2043 | 2065 | /* decompress until an end-of-block code */ | |
2044 | /* decompress until an end-of-block code */ | 2066 | if (inflate_codes(tl, td, bl, bd)) |
2045 | if (inflate_codes(tl, td, bl, bd)) | 2067 | return 1; |
2046 | return 1; | 2068 | |
2047 | 2069 | ||
2048 | 2070 | /* free the decoding tables, return */ | |
2049 | /* free the decoding tables, return */ | 2071 | huft_free(tl); |
2050 | huft_free(tl); | 2072 | huft_free(td); |
2051 | huft_free(td); | 2073 | return 0; |
2052 | return 0; | ||
2053 | } | 2074 | } |
2054 | 2075 | ||
2055 | 2076 | ||
@@ -2057,209 +2078,202 @@ int inflate_fixed() | |||
2057 | int inflate_dynamic() | 2078 | int inflate_dynamic() |
2058 | /* decompress an inflated type 2 (dynamic Huffman codes) block. */ | 2079 | /* decompress an inflated type 2 (dynamic Huffman codes) block. */ |
2059 | { | 2080 | { |
2060 | int i; /* temporary variables */ | 2081 | int i; /* temporary variables */ |
2061 | unsigned j; | 2082 | unsigned j; |
2062 | unsigned l; /* last length */ | 2083 | unsigned l; /* last length */ |
2063 | unsigned m; /* mask for bit lengths table */ | 2084 | unsigned m; /* mask for bit lengths table */ |
2064 | unsigned n; /* number of lengths to get */ | 2085 | unsigned n; /* number of lengths to get */ |
2065 | struct huft *tl; /* literal/length code table */ | 2086 | struct huft *tl; /* literal/length code table */ |
2066 | struct huft *td; /* distance code table */ | 2087 | struct huft *td; /* distance code table */ |
2067 | int bl; /* lookup bits for tl */ | 2088 | int bl; /* lookup bits for tl */ |
2068 | int bd; /* lookup bits for td */ | 2089 | int bd; /* lookup bits for td */ |
2069 | unsigned nb; /* number of bit length codes */ | 2090 | unsigned nb; /* number of bit length codes */ |
2070 | unsigned nl; /* number of literal/length codes */ | 2091 | unsigned nl; /* number of literal/length codes */ |
2071 | unsigned nd; /* number of distance codes */ | 2092 | unsigned nd; /* number of distance codes */ |
2093 | |||
2072 | #ifdef PKZIP_BUG_WORKAROUND | 2094 | #ifdef PKZIP_BUG_WORKAROUND |
2073 | unsigned ll[288+32]; /* literal/length and distance code lengths */ | 2095 | unsigned ll[288 + 32]; /* literal/length and distance code lengths */ |
2074 | #else | 2096 | #else |
2075 | unsigned ll[286+30]; /* literal/length and distance code lengths */ | 2097 | unsigned ll[286 + 30]; /* literal/length and distance code lengths */ |
2076 | #endif | 2098 | #endif |
2077 | register ulg b; /* bit buffer */ | 2099 | register ulg b; /* bit buffer */ |
2078 | register unsigned k; /* number of bits in bit buffer */ | 2100 | register unsigned k; /* number of bits in bit buffer */ |
2079 | 2101 | ||
2080 | 2102 | ||
2081 | /* make local bit buffer */ | 2103 | /* make local bit buffer */ |
2082 | b = bb; | 2104 | b = bb; |
2083 | k = bk; | 2105 | k = bk; |
2084 | 2106 | ||
2085 | 2107 | ||
2086 | /* read in table lengths */ | 2108 | /* read in table lengths */ |
2087 | NEEDBITS(5) | 2109 | NEEDBITS(5) |
2088 | nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */ | 2110 | nl = 257 + ((unsigned) b & 0x1f); /* number of literal/length codes */ |
2089 | DUMPBITS(5) | 2111 | DUMPBITS(5) |
2090 | NEEDBITS(5) | 2112 | NEEDBITS(5) |
2091 | nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */ | 2113 | nd = 1 + ((unsigned) b & 0x1f); /* number of distance codes */ |
2092 | DUMPBITS(5) | 2114 | DUMPBITS(5) |
2093 | NEEDBITS(4) | 2115 | NEEDBITS(4) |
2094 | nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */ | 2116 | nb = 4 + ((unsigned) b & 0xf); /* number of bit length codes */ |
2095 | DUMPBITS(4) | 2117 | DUMPBITS(4) |
2096 | #ifdef PKZIP_BUG_WORKAROUND | 2118 | #ifdef PKZIP_BUG_WORKAROUND |
2097 | if (nl > 288 || nd > 32) | 2119 | if (nl > 288 || nd > 32) |
2098 | #else | 2120 | #else |
2099 | if (nl > 286 || nd > 30) | 2121 | if (nl > 286 || nd > 30) |
2100 | #endif | 2122 | #endif |
2101 | return 1; /* bad lengths */ | 2123 | return 1; /* bad lengths */ |
2102 | 2124 | ||
2103 | 2125 | ||
2104 | /* read in bit-length-code lengths */ | 2126 | /* read in bit-length-code lengths */ |
2105 | for (j = 0; j < nb; j++) | 2127 | for (j = 0; j < nb; j++) { |
2106 | { | 2128 | NEEDBITS(3) |
2107 | NEEDBITS(3) | 2129 | ll[border[j]] = (unsigned) b & 7; |
2108 | ll[border[j]] = (unsigned)b & 7; | 2130 | DUMPBITS(3) |
2109 | DUMPBITS(3) | 2131 | } |
2110 | } | 2132 | for (; j < 19; j++) |
2111 | for (; j < 19; j++) | 2133 | ll[border[j]] = 0; |
2112 | ll[border[j]] = 0; | 2134 | |
2113 | 2135 | ||
2114 | 2136 | /* build decoding table for trees--single level, 7 bit lookup */ | |
2115 | /* build decoding table for trees--single level, 7 bit lookup */ | 2137 | bl = 7; |
2116 | bl = 7; | 2138 | if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) { |
2117 | if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) | 2139 | if (i == 1) |
2118 | { | 2140 | huft_free(tl); |
2119 | if (i == 1) | 2141 | return i; /* incomplete code set */ |
2120 | huft_free(tl); | 2142 | } |
2121 | return i; /* incomplete code set */ | 2143 | |
2122 | } | 2144 | |
2123 | 2145 | /* read in literal and distance code lengths */ | |
2124 | 2146 | n = nl + nd; | |
2125 | /* read in literal and distance code lengths */ | 2147 | m = mask_bits[bl]; |
2126 | n = nl + nd; | 2148 | i = l = 0; |
2127 | m = mask_bits[bl]; | 2149 | while ((unsigned) i < n) { |
2128 | i = l = 0; | 2150 | NEEDBITS((unsigned) bl) |
2129 | while ((unsigned)i < n) | 2151 | j = (td = tl + ((unsigned) b & m))->b; |
2130 | { | 2152 | DUMPBITS(j) |
2131 | NEEDBITS((unsigned)bl) | 2153 | j = td->v.n; |
2132 | j = (td = tl + ((unsigned)b & m))->b; | 2154 | if (j < 16) /* length of code in bits (0..15) */ |
2133 | DUMPBITS(j) | 2155 | ll[i++] = l = j; /* save last length in l */ |
2134 | j = td->v.n; | 2156 | else if (j == 16) { /* repeat last length 3 to 6 times */ |
2135 | if (j < 16) /* length of code in bits (0..15) */ | 2157 | NEEDBITS(2) |
2136 | ll[i++] = l = j; /* save last length in l */ | 2158 | j = 3 + ((unsigned) b & 3); |
2137 | else if (j == 16) /* repeat last length 3 to 6 times */ | 2159 | DUMPBITS(2) |
2138 | { | 2160 | if ((unsigned) i + j > n) |
2139 | NEEDBITS(2) | 2161 | return 1; |
2140 | j = 3 + ((unsigned)b & 3); | 2162 | while (j--) |
2141 | DUMPBITS(2) | 2163 | ll[i++] = l; |
2142 | if ((unsigned)i + j > n) | 2164 | } else if (j == 17) { /* 3 to 10 zero length codes */ |
2143 | return 1; | 2165 | NEEDBITS(3) |
2144 | while (j--) | 2166 | j = 3 + ((unsigned) b & 7); |
2145 | ll[i++] = l; | 2167 | DUMPBITS(3) |
2146 | } | 2168 | if ((unsigned) i + j > n) |
2147 | else if (j == 17) /* 3 to 10 zero length codes */ | 2169 | return 1; |
2148 | { | 2170 | while (j--) |
2149 | NEEDBITS(3) | 2171 | ll[i++] = 0; |
2150 | j = 3 + ((unsigned)b & 7); | 2172 | l = 0; |
2151 | DUMPBITS(3) | 2173 | } else { /* j == 18: 11 to 138 zero length codes */ |
2152 | if ((unsigned)i + j > n) | 2174 | |
2153 | return 1; | 2175 | NEEDBITS(7) |
2154 | while (j--) | 2176 | j = 11 + ((unsigned) b & 0x7f); |
2155 | ll[i++] = 0; | 2177 | DUMPBITS(7) |
2156 | l = 0; | 2178 | if ((unsigned) i + j > n) |
2157 | } | 2179 | return 1; |
2158 | else /* j == 18: 11 to 138 zero length codes */ | 2180 | while (j--) |
2159 | { | 2181 | ll[i++] = 0; |
2160 | NEEDBITS(7) | 2182 | l = 0; |
2161 | j = 11 + ((unsigned)b & 0x7f); | 2183 | } |
2162 | DUMPBITS(7) | 2184 | } |
2163 | if ((unsigned)i + j > n) | 2185 | |
2164 | return 1; | 2186 | |
2165 | while (j--) | 2187 | /* free decoding table for trees */ |
2166 | ll[i++] = 0; | 2188 | huft_free(tl); |
2167 | l = 0; | 2189 | |
2168 | } | 2190 | |
2169 | } | 2191 | /* restore the global bit buffer */ |
2170 | 2192 | bb = b; | |
2171 | 2193 | bk = k; | |
2172 | /* free decoding table for trees */ | 2194 | |
2173 | huft_free(tl); | 2195 | |
2174 | 2196 | /* build the decoding tables for literal/length and distance codes */ | |
2175 | 2197 | bl = lbits; | |
2176 | /* restore the global bit buffer */ | 2198 | if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) { |
2177 | bb = b; | 2199 | if (i == 1) { |
2178 | bk = k; | 2200 | fprintf(stderr, " incomplete literal tree\n"); |
2179 | 2201 | huft_free(tl); | |
2180 | 2202 | } | |
2181 | /* build the decoding tables for literal/length and distance codes */ | 2203 | return i; /* incomplete code set */ |
2182 | bl = lbits; | 2204 | } |
2183 | if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) | 2205 | bd = dbits; |
2184 | { | 2206 | if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) { |
2185 | if (i == 1) { | 2207 | if (i == 1) { |
2186 | fprintf(stderr, " incomplete literal tree\n"); | 2208 | fprintf(stderr, " incomplete distance tree\n"); |
2187 | huft_free(tl); | ||
2188 | } | ||
2189 | return i; /* incomplete code set */ | ||
2190 | } | ||
2191 | bd = dbits; | ||
2192 | if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) | ||
2193 | { | ||
2194 | if (i == 1) { | ||
2195 | fprintf(stderr, " incomplete distance tree\n"); | ||
2196 | #ifdef PKZIP_BUG_WORKAROUND | 2209 | #ifdef PKZIP_BUG_WORKAROUND |
2197 | i = 0; | 2210 | i = 0; |
2198 | } | 2211 | } |
2199 | #else | 2212 | #else |
2200 | huft_free(td); | 2213 | huft_free(td); |
2201 | } | 2214 | } |
2202 | huft_free(tl); | 2215 | huft_free(tl); |
2203 | return i; /* incomplete code set */ | 2216 | return i; /* incomplete code set */ |
2204 | #endif | 2217 | #endif |
2205 | } | 2218 | } |
2206 | 2219 | ||
2207 | 2220 | ||
2208 | /* decompress until an end-of-block code */ | 2221 | /* decompress until an end-of-block code */ |
2209 | if (inflate_codes(tl, td, bl, bd)) | 2222 | if (inflate_codes(tl, td, bl, bd)) |
2210 | return 1; | 2223 | return 1; |
2211 | 2224 | ||
2212 | 2225 | ||
2213 | /* free the decoding tables, return */ | 2226 | /* free the decoding tables, return */ |
2214 | huft_free(tl); | 2227 | huft_free(tl); |
2215 | huft_free(td); | 2228 | huft_free(td); |
2216 | return 0; | 2229 | return 0; |
2217 | } | 2230 | } |
2218 | 2231 | ||
2219 | 2232 | ||
2220 | 2233 | ||
2221 | int inflate_block(e) | 2234 | int inflate_block(e) |
2222 | int *e; /* last block flag */ | 2235 | int *e; /* last block flag */ |
2236 | |||
2223 | /* decompress an inflated block */ | 2237 | /* decompress an inflated block */ |
2224 | { | 2238 | { |
2225 | unsigned t; /* block type */ | 2239 | unsigned t; /* block type */ |
2226 | register ulg b; /* bit buffer */ | 2240 | register ulg b; /* bit buffer */ |
2227 | register unsigned k; /* number of bits in bit buffer */ | 2241 | register unsigned k; /* number of bits in bit buffer */ |
2228 | 2242 | ||
2229 | 2243 | ||
2230 | /* make local bit buffer */ | 2244 | /* make local bit buffer */ |
2231 | b = bb; | 2245 | b = bb; |
2232 | k = bk; | 2246 | k = bk; |
2233 | 2247 | ||
2234 | 2248 | ||
2235 | /* read in last block bit */ | 2249 | /* read in last block bit */ |
2236 | NEEDBITS(1) | 2250 | NEEDBITS(1) |
2237 | *e = (int)b & 1; | 2251 | * e = (int) b & 1; |
2238 | DUMPBITS(1) | 2252 | DUMPBITS(1) |
2239 | 2253 | ||
2240 | 2254 | ||
2241 | /* read in block type */ | 2255 | /* read in block type */ |
2242 | NEEDBITS(2) | 2256 | NEEDBITS(2) |
2243 | t = (unsigned)b & 3; | 2257 | t = (unsigned) b & 3; |
2244 | DUMPBITS(2) | 2258 | DUMPBITS(2) |
2245 | 2259 | ||
2246 | 2260 | ||
2247 | /* restore the global bit buffer */ | 2261 | /* restore the global bit buffer */ |
2248 | bb = b; | 2262 | bb = b; |
2249 | bk = k; | 2263 | bk = k; |
2250 | 2264 | ||
2251 | 2265 | ||
2252 | /* inflate that block type */ | 2266 | /* inflate that block type */ |
2253 | if (t == 2) | 2267 | if (t == 2) |
2254 | return inflate_dynamic(); | 2268 | return inflate_dynamic(); |
2255 | if (t == 0) | 2269 | if (t == 0) |
2256 | return inflate_stored(); | 2270 | return inflate_stored(); |
2257 | if (t == 1) | 2271 | if (t == 1) |
2258 | return inflate_fixed(); | 2272 | return inflate_fixed(); |
2259 | 2273 | ||
2260 | 2274 | ||
2261 | /* bad block type */ | 2275 | /* bad block type */ |
2262 | return 2; | 2276 | return 2; |
2263 | } | 2277 | } |
2264 | 2278 | ||
2265 | 2279 | ||
@@ -2267,42 +2281,42 @@ int *e; /* last block flag */ | |||
2267 | int inflate() | 2281 | int inflate() |
2268 | /* decompress an inflated entry */ | 2282 | /* decompress an inflated entry */ |
2269 | { | 2283 | { |
2270 | int e; /* last block flag */ | 2284 | int e; /* last block flag */ |
2271 | int r; /* result code */ | 2285 | int r; /* result code */ |
2272 | unsigned h; /* maximum struct huft's malloc'ed */ | 2286 | unsigned h; /* maximum struct huft's malloc'ed */ |
2273 | 2287 | ||
2274 | 2288 | ||
2275 | /* initialize window, bit buffer */ | 2289 | /* initialize window, bit buffer */ |
2276 | wp = 0; | 2290 | wp = 0; |
2277 | bk = 0; | 2291 | bk = 0; |
2278 | bb = 0; | 2292 | bb = 0; |
2279 | 2293 | ||
2280 | 2294 | ||
2281 | /* decompress until the last block */ | 2295 | /* decompress until the last block */ |
2282 | h = 0; | 2296 | h = 0; |
2283 | do { | 2297 | do { |
2284 | hufts = 0; | 2298 | hufts = 0; |
2285 | if ((r = inflate_block(&e)) != 0) | 2299 | if ((r = inflate_block(&e)) != 0) |
2286 | return r; | 2300 | return r; |
2287 | if (hufts > h) | 2301 | if (hufts > h) |
2288 | h = hufts; | 2302 | h = hufts; |
2289 | } while (!e); | 2303 | } while (!e); |
2290 | 2304 | ||
2291 | /* Undo too much lookahead. The next read will be byte aligned so we | 2305 | /* Undo too much lookahead. The next read will be byte aligned so we |
2292 | * can discard unused bits in the last meaningful byte. | 2306 | * can discard unused bits in the last meaningful byte. |
2293 | */ | 2307 | */ |
2294 | while (bk >= 8) { | 2308 | while (bk >= 8) { |
2295 | bk -= 8; | 2309 | bk -= 8; |
2296 | inptr--; | 2310 | inptr--; |
2297 | } | 2311 | } |
2298 | 2312 | ||
2299 | /* flush out slide */ | 2313 | /* flush out slide */ |
2300 | flush_output(wp); | 2314 | flush_output(wp); |
2301 | 2315 | ||
2302 | 2316 | ||
2303 | /* return success */ | 2317 | /* return success */ |
2304 | #ifdef DEBUG | 2318 | #ifdef DEBUG |
2305 | fprintf(stderr, "<%u> ", h); | 2319 | fprintf(stderr, "<%u> ", h); |
2306 | #endif /* DEBUG */ | 2320 | #endif /* DEBUG */ |
2307 | return 0; | 2321 | return 0; |
2308 | } | 2322 | } |
diff --git a/archival/gzip.c b/archival/gzip.c index 3438ee42f..f132679f7 100644 --- a/archival/gzip.c +++ b/archival/gzip.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* gzip.c -- this is a stripped down version of gzip I put into busybox, it does | 2 | /* gzip.c -- this is a stripped down version of gzip I put into busybox, it does |
2 | * only standard in to standard out with -9 compression. It also requires the | 3 | * only standard in to standard out with -9 compression. It also requires the |
3 | * zcat module for some important functions. | 4 | * zcat module for some important functions. |
@@ -12,11 +13,12 @@ | |||
12 | //#endif | 13 | //#endif |
13 | 14 | ||
14 | static const char gzip_usage[] = | 15 | static const char gzip_usage[] = |
15 | "gzip [OPTION]... FILE\n\n" | 16 | "gzip [OPTION]... FILE\n\n" |
16 | "Compress FILE with maximum compression.\n" | 17 | "Compress FILE with maximum compression.\n" |
17 | "When FILE is -, reads standard input. Implies -c.\n\n" | 18 | "When FILE is -, reads standard input. Implies -c.\n\n" |
18 | "Options:\n" | 19 | |
19 | "\t-c\tWrite output to standard output instead of FILE.gz\n"; | 20 | "Options:\n" |
21 | "\t-c\tWrite output to standard output instead of FILE.gz\n"; | ||
20 | 22 | ||
21 | 23 | ||
22 | /* gzip.h -- common declarations for all gzip modules | 24 | /* gzip.h -- common declarations for all gzip modules |
@@ -32,9 +34,9 @@ static const char gzip_usage[] = | |||
32 | #endif | 34 | #endif |
33 | 35 | ||
34 | #ifdef __STDC__ | 36 | #ifdef __STDC__ |
35 | typedef void *voidp; | 37 | typedef void *voidp; |
36 | #else | 38 | #else |
37 | typedef char *voidp; | 39 | typedef char *voidp; |
38 | #endif | 40 | #endif |
39 | 41 | ||
40 | /* I don't like nested includes, but the string and io functions are used | 42 | /* I don't like nested includes, but the string and io functions are used |
@@ -49,10 +51,10 @@ static const char gzip_usage[] = | |||
49 | # define memzero(s, n) memset ((voidp)(s), 0, (n)) | 51 | # define memzero(s, n) memset ((voidp)(s), 0, (n)) |
50 | #else | 52 | #else |
51 | # include <strings.h> | 53 | # include <strings.h> |
52 | # define strchr index | 54 | # define strchr index |
53 | # define strrchr rindex | 55 | # define strrchr rindex |
54 | # define memcpy(d, s, n) bcopy((s), (d), (n)) | 56 | # define memcpy(d, s, n) bcopy((s), (d), (n)) |
55 | # define memcmp(s1, s2, n) bcmp((s1), (s2), (n)) | 57 | # define memcmp(s1, s2, n) bcmp((s1), (s2), (n)) |
56 | # define memzero(s, n) bzero((s), (n)) | 58 | # define memzero(s, n) bzero((s), (n)) |
57 | #endif | 59 | #endif |
58 | 60 | ||
@@ -62,9 +64,9 @@ static const char gzip_usage[] = | |||
62 | 64 | ||
63 | #define local static | 65 | #define local static |
64 | 66 | ||
65 | typedef unsigned char uch; | 67 | typedef unsigned char uch; |
66 | typedef unsigned short ush; | 68 | typedef unsigned short ush; |
67 | typedef unsigned long ulg; | 69 | typedef unsigned long ulg; |
68 | 70 | ||
69 | /* Return codes from gzip */ | 71 | /* Return codes from gzip */ |
70 | #define OK 0 | 72 | #define OK 0 |
@@ -79,7 +81,7 @@ typedef unsigned long ulg; | |||
79 | /* methods 4 to 7 reserved */ | 81 | /* methods 4 to 7 reserved */ |
80 | #define DEFLATED 8 | 82 | #define DEFLATED 8 |
81 | #define MAX_METHODS 9 | 83 | #define MAX_METHODS 9 |
82 | extern int method; /* compression method */ | 84 | extern int method; /* compression method */ |
83 | 85 | ||
84 | /* To save memory for 16 bit systems, some arrays are overlaid between | 86 | /* To save memory for 16 bit systems, some arrays are overlaid between |
85 | * the various modules: | 87 | * the various modules: |
@@ -94,27 +96,27 @@ extern int method; /* compression method */ | |||
94 | 96 | ||
95 | #ifndef INBUFSIZ | 97 | #ifndef INBUFSIZ |
96 | # ifdef SMALL_MEM | 98 | # ifdef SMALL_MEM |
97 | # define INBUFSIZ 0x2000 /* input buffer size */ | 99 | # define INBUFSIZ 0x2000 /* input buffer size */ |
98 | # else | 100 | # else |
99 | # define INBUFSIZ 0x8000 /* input buffer size */ | 101 | # define INBUFSIZ 0x8000 /* input buffer size */ |
100 | # endif | 102 | # endif |
101 | #endif | 103 | #endif |
102 | #define INBUF_EXTRA 64 /* required by unlzw() */ | 104 | #define INBUF_EXTRA 64 /* required by unlzw() */ |
103 | 105 | ||
104 | #ifndef OUTBUFSIZ | 106 | #ifndef OUTBUFSIZ |
105 | # ifdef SMALL_MEM | 107 | # ifdef SMALL_MEM |
106 | # define OUTBUFSIZ 8192 /* output buffer size */ | 108 | # define OUTBUFSIZ 8192 /* output buffer size */ |
107 | # else | 109 | # else |
108 | # define OUTBUFSIZ 16384 /* output buffer size */ | 110 | # define OUTBUFSIZ 16384 /* output buffer size */ |
109 | # endif | 111 | # endif |
110 | #endif | 112 | #endif |
111 | #define OUTBUF_EXTRA 2048 /* required by unlzw() */ | 113 | #define OUTBUF_EXTRA 2048 /* required by unlzw() */ |
112 | 114 | ||
113 | #ifndef DIST_BUFSIZE | 115 | #ifndef DIST_BUFSIZE |
114 | # ifdef SMALL_MEM | 116 | # ifdef SMALL_MEM |
115 | # define DIST_BUFSIZE 0x2000 /* buffer for distances, see trees.c */ | 117 | # define DIST_BUFSIZE 0x2000 /* buffer for distances, see trees.c */ |
116 | # else | 118 | # else |
117 | # define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */ | 119 | # define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */ |
118 | # endif | 120 | # endif |
119 | #endif | 121 | #endif |
120 | 122 | ||
@@ -133,60 +135,61 @@ extern int method; /* compression method */ | |||
133 | # define FREE(array) | 135 | # define FREE(array) |
134 | #endif | 136 | #endif |
135 | 137 | ||
136 | EXTERN(uch, inbuf); /* input buffer */ | 138 | EXTERN(uch, inbuf); /* input buffer */ |
137 | EXTERN(uch, outbuf); /* output buffer */ | 139 | EXTERN(uch, outbuf); /* output buffer */ |
138 | EXTERN(ush, d_buf); /* buffer for distances, see trees.c */ | 140 | EXTERN(ush, d_buf); /* buffer for distances, see trees.c */ |
139 | EXTERN(uch, window); /* Sliding window and suffix table (unlzw) */ | 141 | EXTERN(uch, window); /* Sliding window and suffix table (unlzw) */ |
140 | #define tab_suffix window | 142 | #define tab_suffix window |
141 | #ifndef MAXSEG_64K | 143 | #ifndef MAXSEG_64K |
142 | # define tab_prefix prev /* hash link (see deflate.c) */ | 144 | # define tab_prefix prev /* hash link (see deflate.c) */ |
143 | # define head (prev+WSIZE) /* hash head (see deflate.c) */ | 145 | # define head (prev+WSIZE) /* hash head (see deflate.c) */ |
144 | EXTERN(ush, tab_prefix); /* prefix code (see unlzw.c) */ | 146 | EXTERN(ush, tab_prefix); /* prefix code (see unlzw.c) */ |
145 | #else | 147 | #else |
146 | # define tab_prefix0 prev | 148 | # define tab_prefix0 prev |
147 | # define head tab_prefix1 | 149 | # define head tab_prefix1 |
148 | EXTERN(ush, tab_prefix0); /* prefix for even codes */ | 150 | EXTERN(ush, tab_prefix0); /* prefix for even codes */ |
149 | EXTERN(ush, tab_prefix1); /* prefix for odd codes */ | 151 | EXTERN(ush, tab_prefix1); /* prefix for odd codes */ |
150 | #endif | 152 | #endif |
151 | 153 | ||
152 | extern unsigned insize; /* valid bytes in inbuf */ | 154 | extern unsigned insize; /* valid bytes in inbuf */ |
153 | extern unsigned inptr; /* index of next byte to be processed in inbuf */ | 155 | extern unsigned inptr; /* index of next byte to be processed in inbuf */ |
154 | extern unsigned outcnt; /* bytes in output buffer */ | 156 | extern unsigned outcnt; /* bytes in output buffer */ |
155 | 157 | ||
156 | extern long bytes_in; /* number of input bytes */ | 158 | extern long bytes_in; /* number of input bytes */ |
157 | extern long bytes_out; /* number of output bytes */ | 159 | extern long bytes_out; /* number of output bytes */ |
158 | extern long header_bytes;/* number of bytes in gzip header */ | 160 | extern long header_bytes; /* number of bytes in gzip header */ |
159 | 161 | ||
160 | #define isize bytes_in | 162 | #define isize bytes_in |
161 | /* for compatibility with old zip sources (to be cleaned) */ | 163 | /* for compatibility with old zip sources (to be cleaned) */ |
162 | 164 | ||
163 | extern int ifd; /* input file descriptor */ | 165 | extern int ifd; /* input file descriptor */ |
164 | extern int ofd; /* output file descriptor */ | 166 | extern int ofd; /* output file descriptor */ |
165 | extern char ifname[]; /* input file name or "stdin" */ | 167 | extern char ifname[]; /* input file name or "stdin" */ |
166 | extern char ofname[]; /* output file name or "stdout" */ | 168 | extern char ofname[]; /* output file name or "stdout" */ |
167 | extern char *progname; /* program name */ | 169 | extern char *progname; /* program name */ |
170 | |||
171 | extern long time_stamp; /* original time stamp (modification time) */ | ||
172 | extern long ifile_size; /* input file size, -1 for devices (debug only) */ | ||
168 | 173 | ||
169 | extern long time_stamp; /* original time stamp (modification time) */ | 174 | typedef int file_t; /* Do not use stdio */ |
170 | extern long ifile_size; /* input file size, -1 for devices (debug only) */ | ||
171 | 175 | ||
172 | typedef int file_t; /* Do not use stdio */ | 176 | #define NO_FILE (-1) /* in memory compression */ |
173 | #define NO_FILE (-1) /* in memory compression */ | ||
174 | 177 | ||
175 | 178 | ||
176 | #define PACK_MAGIC "\037\036" /* Magic header for packed files */ | 179 | #define PACK_MAGIC "\037\036" /* Magic header for packed files */ |
177 | #define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */ | 180 | #define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */ |
178 | #define OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */ | 181 | #define OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */ |
179 | #define LZH_MAGIC "\037\240" /* Magic header for SCO LZH Compress files*/ | 182 | #define LZH_MAGIC "\037\240" /* Magic header for SCO LZH Compress files */ |
180 | #define PKZIP_MAGIC "\120\113\003\004" /* Magic header for pkzip files */ | 183 | #define PKZIP_MAGIC "\120\113\003\004" /* Magic header for pkzip files */ |
181 | 184 | ||
182 | /* gzip flag byte */ | 185 | /* gzip flag byte */ |
183 | #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ | 186 | #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ |
184 | #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ | 187 | #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ |
185 | #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ | 188 | #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ |
186 | #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ | 189 | #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ |
187 | #define COMMENT 0x10 /* bit 4 set: file comment present */ | 190 | #define COMMENT 0x10 /* bit 4 set: file comment present */ |
188 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ | 191 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ |
189 | #define RESERVED 0xC0 /* bit 6,7: reserved */ | 192 | #define RESERVED 0xC0 /* bit 6,7: reserved */ |
190 | 193 | ||
191 | /* internal file attribute */ | 194 | /* internal file attribute */ |
192 | #define UNKNOWN 0xffff | 195 | #define UNKNOWN 0xffff |
@@ -194,8 +197,8 @@ typedef int file_t; /* Do not use stdio */ | |||
194 | #define ASCII 1 | 197 | #define ASCII 1 |
195 | 198 | ||
196 | #ifndef WSIZE | 199 | #ifndef WSIZE |
197 | # define WSIZE 0x8000 /* window size--must be a power of two, and */ | 200 | # define WSIZE 0x8000 /* window size--must be a power of two, and */ |
198 | #endif /* at least 32K for zip's deflate method */ | 201 | #endif /* at least 32K for zip's deflate method */ |
199 | 202 | ||
200 | #define MIN_MATCH 3 | 203 | #define MIN_MATCH 3 |
201 | #define MAX_MATCH 258 | 204 | #define MAX_MATCH 258 |
@@ -211,12 +214,12 @@ typedef int file_t; /* Do not use stdio */ | |||
211 | * distances are limited to MAX_DIST instead of WSIZE. | 214 | * distances are limited to MAX_DIST instead of WSIZE. |
212 | */ | 215 | */ |
213 | 216 | ||
214 | extern int decrypt; /* flag to turn on decryption */ | 217 | extern int decrypt; /* flag to turn on decryption */ |
215 | extern int exit_code; /* program exit code */ | 218 | extern int exit_code; /* program exit code */ |
216 | extern int verbose; /* be verbose (-v) */ | 219 | extern int verbose; /* be verbose (-v) */ |
217 | extern int quiet; /* be quiet (-q) */ | 220 | extern int quiet; /* be quiet (-q) */ |
218 | extern int test; /* check .z file integrity */ | 221 | extern int test; /* check .z file integrity */ |
219 | extern int save_orig_name; /* set if original name must be saved */ | 222 | extern int save_orig_name; /* set if original name must be saved */ |
220 | 223 | ||
221 | #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(0)) | 224 | #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(0)) |
222 | #define try_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(1)) | 225 | #define try_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(1)) |
@@ -248,10 +251,10 @@ extern int save_orig_name; /* set if original name must be saved */ | |||
248 | put_short(((ulg)(n)) >> 16); \ | 251 | put_short(((ulg)(n)) >> 16); \ |
249 | } | 252 | } |
250 | 253 | ||
251 | #define seekable() 0 /* force sequential output */ | 254 | #define seekable() 0 /* force sequential output */ |
252 | #define translate_eol 0 /* no option -a yet */ | 255 | #define translate_eol 0 /* no option -a yet */ |
253 | 256 | ||
254 | #define tolow(c) (isupper(c) ? (c)-'A'+'a' : (c)) /* force to lower case */ | 257 | #define tolow(c) (isupper(c) ? (c)-'A'+'a' : (c)) /* force to lower case */ |
255 | 258 | ||
256 | /* Macros for getting two-byte and four-byte header values */ | 259 | /* Macros for getting two-byte and four-byte header values */ |
257 | #define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)) | 260 | #define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)) |
@@ -281,57 +284,58 @@ extern int save_orig_name; /* set if original name must be saved */ | |||
281 | 284 | ||
282 | 285 | ||
283 | /* in zip.c: */ | 286 | /* in zip.c: */ |
284 | extern int zip OF((int in, int out)); | 287 | extern int zip OF((int in, int out)); |
285 | extern int file_read OF((char *buf, unsigned size)); | 288 | extern int file_read OF((char *buf, unsigned size)); |
286 | 289 | ||
287 | /* in unzip.c */ | 290 | /* in unzip.c */ |
288 | extern int unzip OF((int in, int out)); | 291 | extern int unzip OF((int in, int out)); |
289 | extern int check_zipfile OF((int in)); | 292 | extern int check_zipfile OF((int in)); |
290 | 293 | ||
291 | /* in unpack.c */ | 294 | /* in unpack.c */ |
292 | extern int unpack OF((int in, int out)); | 295 | extern int unpack OF((int in, int out)); |
293 | 296 | ||
294 | /* in unlzh.c */ | 297 | /* in unlzh.c */ |
295 | extern int unlzh OF((int in, int out)); | 298 | extern int unlzh OF((int in, int out)); |
296 | 299 | ||
297 | /* in gzip.c */ | 300 | /* in gzip.c */ |
298 | RETSIGTYPE abort_gzip OF((void)); | 301 | RETSIGTYPE abort_gzip OF((void)); |
299 | 302 | ||
300 | /* in deflate.c */ | 303 | /* in deflate.c */ |
301 | void lm_init OF((ush *flags)); | 304 | void lm_init OF((ush * flags)); |
302 | ulg deflate OF((void)); | 305 | ulg deflate OF((void)); |
303 | 306 | ||
304 | /* in trees.c */ | 307 | /* in trees.c */ |
305 | void ct_init OF((ush *attr, int *method)); | 308 | void ct_init OF((ush * attr, int *method)); |
306 | int ct_tally OF((int dist, int lc)); | 309 | int ct_tally OF((int dist, int lc)); |
307 | ulg flush_block OF((char *buf, ulg stored_len, int eof)); | 310 | ulg flush_block OF((char *buf, ulg stored_len, int eof)); |
308 | 311 | ||
309 | /* in bits.c */ | 312 | /* in bits.c */ |
310 | void bi_init OF((file_t zipfile)); | 313 | void bi_init OF((file_t zipfile)); |
311 | void send_bits OF((int value, int length)); | 314 | void send_bits OF((int value, int length)); |
312 | unsigned bi_reverse OF((unsigned value, int length)); | 315 | unsigned bi_reverse OF((unsigned value, int length)); |
313 | void bi_windup OF((void)); | 316 | void bi_windup OF((void)); |
314 | void copy_block OF((char *buf, unsigned len, int header)); | 317 | void copy_block OF((char *buf, unsigned len, int header)); |
315 | extern int (*read_buf) OF((char *buf, unsigned size)); | 318 | extern int (*read_buf) OF((char *buf, unsigned size)); |
316 | 319 | ||
317 | /* in util.c: */ | 320 | /* in util.c: */ |
318 | extern int copy OF((int in, int out)); | 321 | extern int copy OF((int in, int out)); |
319 | extern ulg updcrc OF((uch *s, unsigned n)); | 322 | extern ulg updcrc OF((uch * s, unsigned n)); |
320 | extern void clear_bufs OF((void)); | 323 | extern void clear_bufs OF((void)); |
321 | extern int fill_inbuf OF((int eof_ok)); | 324 | extern int fill_inbuf OF((int eof_ok)); |
322 | extern void flush_outbuf OF((void)); | 325 | extern void flush_outbuf OF((void)); |
323 | extern void flush_window OF((void)); | 326 | extern void flush_window OF((void)); |
324 | extern void write_buf OF((int fd, voidp buf, unsigned cnt)); | 327 | extern void write_buf OF((int fd, voidp buf, unsigned cnt)); |
325 | extern char *strlwr OF((char *s)); | 328 | extern char *strlwr OF((char *s)); |
326 | extern char *add_envopt OF((int *argcp, char ***argvp, char *env)); | 329 | extern char *add_envopt OF((int *argcp, char ***argvp, char *env)); |
327 | extern void error OF((char *m)); | 330 | extern void error OF((char *m)); |
328 | extern void warn OF((char *a, char *b)); | 331 | extern void warn OF((char *a, char *b)); |
329 | extern void read_error OF((void)); | 332 | extern void read_error OF((void)); |
330 | extern void write_error OF((void)); | 333 | extern void write_error OF((void)); |
331 | extern void display_ratio OF((long num, long den, FILE *file)); | 334 | extern void display_ratio OF((long num, long den, FILE * file)); |
332 | 335 | ||
333 | /* in inflate.c */ | 336 | /* in inflate.c */ |
334 | extern int inflate OF((void)); | 337 | extern int inflate OF((void)); |
338 | |||
335 | /* lzw.h -- define the lzw functions. | 339 | /* lzw.h -- define the lzw functions. |
336 | * Copyright (C) 1992-1993 Jean-loup Gailly. | 340 | * Copyright (C) 1992-1993 Jean-loup Gailly. |
337 | * This is free software; you can redistribute it and/or modify it under the | 341 | * This is free software; you can redistribute it and/or modify it under the |
@@ -345,9 +349,9 @@ extern int inflate OF((void)); | |||
345 | #ifndef BITS | 349 | #ifndef BITS |
346 | # define BITS 16 | 350 | # define BITS 16 |
347 | #endif | 351 | #endif |
348 | #define INIT_BITS 9 /* Initial number of bits per code */ | 352 | #define INIT_BITS 9 /* Initial number of bits per code */ |
349 | 353 | ||
350 | #define BIT_MASK 0x1f /* Mask for 'number of compression bits' */ | 354 | #define BIT_MASK 0x1f /* Mask for 'number of compression bits' */ |
351 | /* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free. | 355 | /* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free. |
352 | * It's a pity that old uncompress does not check bit 0x20. That makes | 356 | * It's a pity that old uncompress does not check bit 0x20. That makes |
353 | * extension of the format actually undesirable because old compress | 357 | * extension of the format actually undesirable because old compress |
@@ -362,13 +366,13 @@ extern int inflate OF((void)); | |||
362 | * clear the dictionary. | 366 | * clear the dictionary. |
363 | */ | 367 | */ |
364 | 368 | ||
365 | #define LZW_RESERVED 0x60 /* reserved bits */ | 369 | #define LZW_RESERVED 0x60 /* reserved bits */ |
366 | 370 | ||
367 | #define CLEAR 256 /* flush the dictionary */ | 371 | #define CLEAR 256 /* flush the dictionary */ |
368 | #define FIRST (CLEAR+1) /* first free entry */ | 372 | #define FIRST (CLEAR+1) /* first free entry */ |
369 | 373 | ||
370 | extern int maxbits; /* max bits per code for LZW */ | 374 | extern int maxbits; /* max bits per code for LZW */ |
371 | extern int block_mode; /* block compress mode -C compatible with 2.0 */ | 375 | extern int block_mode; /* block compress mode -C compatible with 2.0 */ |
372 | 376 | ||
373 | /* revision.h -- define the version number | 377 | /* revision.h -- define the version number |
374 | * Copyright (C) 1992-1993 Jean-loup Gailly. | 378 | * Copyright (C) 1992-1993 Jean-loup Gailly. |
@@ -404,18 +408,18 @@ extern int block_mode; /* block compress mode -C compatible with 2.0 */ | |||
404 | # define OS2 | 408 | # define OS2 |
405 | #endif | 409 | #endif |
406 | 410 | ||
407 | #if defined(OS2) && defined(MSDOS) /* MS C under OS/2 */ | 411 | #if defined(OS2) && defined(MSDOS) /* MS C under OS/2 */ |
408 | # undef MSDOS | 412 | # undef MSDOS |
409 | #endif | 413 | #endif |
410 | 414 | ||
411 | #ifdef MSDOS | 415 | #ifdef MSDOS |
412 | # ifdef __GNUC__ | 416 | # ifdef __GNUC__ |
413 | /* DJGPP version 1.09+ on MS-DOS. | 417 | /* DJGPP version 1.09+ on MS-DOS. |
414 | * The DJGPP 1.09 stat() function must be upgraded before gzip will | 418 | * The DJGPP 1.09 stat() function must be upgraded before gzip will |
415 | * fully work. | 419 | * fully work. |
416 | * No need for DIRENT, since <unistd.h> defines POSIX_SOURCE which | 420 | * No need for DIRENT, since <unistd.h> defines POSIX_SOURCE which |
417 | * implies DIRENT. | 421 | * implies DIRENT. |
418 | */ | 422 | */ |
419 | # define near | 423 | # define near |
420 | # else | 424 | # else |
421 | # define MAXSEG_64K | 425 | # define MAXSEG_64K |
@@ -426,7 +430,7 @@ extern int block_mode; /* block compress mode -C compatible with 2.0 */ | |||
426 | # else | 430 | # else |
427 | # define NO_UTIME | 431 | # define NO_UTIME |
428 | # endif | 432 | # endif |
429 | # else /* MSC */ | 433 | # else /* MSC */ |
430 | # define HAVE_SYS_UTIME_H | 434 | # define HAVE_SYS_UTIME_H |
431 | # define NO_UTIME_H | 435 | # define NO_UTIME_H |
432 | # endif | 436 | # endif |
@@ -441,7 +445,7 @@ extern int block_mode; /* block compress mode -C compatible with 2.0 */ | |||
441 | # define PROTO | 445 | # define PROTO |
442 | # define STDC_HEADERS | 446 | # define STDC_HEADERS |
443 | # define NO_SIZE_CHECK | 447 | # define NO_SIZE_CHECK |
444 | # define casemap(c) tolow(c) /* Force file names to lower case */ | 448 | # define casemap(c) tolow(c) /* Force file names to lower case */ |
445 | # include <io.h> | 449 | # include <io.h> |
446 | # define OS_CODE 0x00 | 450 | # define OS_CODE 0x00 |
447 | # define SET_BINARY_MODE(fd) setmode(fd, O_BINARY) | 451 | # define SET_BINARY_MODE(fd) setmode(fd, O_BINARY) |
@@ -494,7 +498,7 @@ extern int block_mode; /* block compress mode -C compatible with 2.0 */ | |||
494 | # endif | 498 | # endif |
495 | #endif | 499 | #endif |
496 | 500 | ||
497 | #ifdef WIN32 /* Windows NT */ | 501 | #ifdef WIN32 /* Windows NT */ |
498 | # define HAVE_SYS_UTIME_H | 502 | # define HAVE_SYS_UTIME_H |
499 | # define NO_UTIME_H | 503 | # define NO_UTIME_H |
500 | # define PATH_SEP2 '\\' | 504 | # define PATH_SEP2 '\\' |
@@ -510,7 +514,7 @@ extern int block_mode; /* block compress mode -C compatible with 2.0 */ | |||
510 | # define NO_MULTIPLE_DOTS | 514 | # define NO_MULTIPLE_DOTS |
511 | # define MAX_EXT_CHARS 3 | 515 | # define MAX_EXT_CHARS 3 |
512 | # define Z_SUFFIX "z" | 516 | # define Z_SUFFIX "z" |
513 | # define casemap(c) tolow(c) /* Force file names to lower case */ | 517 | # define casemap(c) tolow(c) /* Force file names to lower case */ |
514 | # endif | 518 | # endif |
515 | # define OS_CODE 0x0b | 519 | # define OS_CODE 0x0b |
516 | #endif | 520 | #endif |
@@ -519,10 +523,10 @@ extern int block_mode; /* block compress mode -C compatible with 2.0 */ | |||
519 | # ifdef __TURBOC__ | 523 | # ifdef __TURBOC__ |
520 | # include <alloc.h> | 524 | # include <alloc.h> |
521 | # define DYN_ALLOC | 525 | # define DYN_ALLOC |
522 | /* Turbo C 2.0 does not accept static allocations of large arrays */ | 526 | /* Turbo C 2.0 does not accept static allocations of large arrays */ |
523 | void * fcalloc (unsigned items, unsigned size); | 527 | void *fcalloc(unsigned items, unsigned size); |
524 | void fcfree (void *ptr); | 528 | void fcfree(void *ptr); |
525 | # else /* MSC */ | 529 | # else /* MSC */ |
526 | # include <malloc.h> | 530 | # include <malloc.h> |
527 | # define fcalloc(nitems,itemsize) halloc((long)(nitems),(itemsize)) | 531 | # define fcalloc(nitems,itemsize) halloc((long)(nitems),(itemsize)) |
528 | # define fcfree(ptr) hfree(ptr) | 532 | # define fcfree(ptr) hfree(ptr) |
@@ -565,17 +569,18 @@ extern int block_mode; /* block compress mode -C compatible with 2.0 */ | |||
565 | # ifdef __GNUC__ | 569 | # ifdef __GNUC__ |
566 | # define DIRENT | 570 | # define DIRENT |
567 | # define HAVE_UNISTD_H | 571 | # define HAVE_UNISTD_H |
568 | # else /* SASC */ | 572 | # else /* SASC */ |
569 | # define NO_STDIN_FSTAT | 573 | # define NO_STDIN_FSTAT |
570 | # define SYSDIR | 574 | # define SYSDIR |
571 | # define NO_SYMLINK | 575 | # define NO_SYMLINK |
572 | # define NO_CHOWN | 576 | # define NO_CHOWN |
573 | # define NO_FCNTL_H | 577 | # define NO_FCNTL_H |
574 | # include <fcntl.h> /* for read() and write() */ | 578 | # include <fcntl.h> /* for read() and write() */ |
575 | # define direct dirent | 579 | # define direct dirent |
576 | extern void _expand_args(int *argc, char ***argv); | 580 | extern void _expand_args(int *argc, char ***argv); |
581 | |||
577 | # define EXPAND(argc,argv) _expand_args(&argc,&argv); | 582 | # define EXPAND(argc,argv) _expand_args(&argc,&argv); |
578 | # undef O_BINARY /* disable useless --ascii option */ | 583 | # undef O_BINARY /* disable useless --ascii option */ |
579 | # endif | 584 | # endif |
580 | #endif | 585 | #endif |
581 | 586 | ||
@@ -595,7 +600,7 @@ extern int block_mode; /* block compress mode -C compatible with 2.0 */ | |||
595 | # define MAX_EXT_CHARS 3 | 600 | # define MAX_EXT_CHARS 3 |
596 | # define Z_SUFFIX "z" | 601 | # define Z_SUFFIX "z" |
597 | # define NO_CHOWN | 602 | # define NO_CHOWN |
598 | # define casemap(c) tolow(c) /* Force file names to lower case */ | 603 | # define casemap(c) tolow(c) /* Force file names to lower case */ |
599 | # define NO_SYMLINK | 604 | # define NO_SYMLINK |
600 | # endif | 605 | # endif |
601 | #endif | 606 | #endif |
@@ -615,28 +620,28 @@ extern int block_mode; /* block compress mode -C compatible with 2.0 */ | |||
615 | # endif | 620 | # endif |
616 | #endif | 621 | #endif |
617 | 622 | ||
618 | #ifdef __50SERIES /* Prime/PRIMOS */ | 623 | #ifdef __50SERIES /* Prime/PRIMOS */ |
619 | # define PATH_SEP '>' | 624 | # define PATH_SEP '>' |
620 | # define STDC_HEADERS | 625 | # define STDC_HEADERS |
621 | # define NO_MEMORY_H | 626 | # define NO_MEMORY_H |
622 | # define NO_UTIME_H | 627 | # define NO_UTIME_H |
623 | # define NO_UTIME | 628 | # define NO_UTIME |
624 | # define NO_CHOWN | 629 | # define NO_CHOWN |
625 | # define NO_STDIN_FSTAT | 630 | # define NO_STDIN_FSTAT |
626 | # define NO_SIZE_CHECK | 631 | # define NO_SIZE_CHECK |
627 | # define NO_SYMLINK | 632 | # define NO_SYMLINK |
628 | # define RECORD_IO 1 | 633 | # define RECORD_IO 1 |
629 | # define casemap(c) tolow(c) /* Force file names to lower case */ | 634 | # define casemap(c) tolow(c) /* Force file names to lower case */ |
630 | # define put_char(c) put_byte((c) & 0x7F) | 635 | # define put_char(c) put_byte((c) & 0x7F) |
631 | # define get_char(c) ascii2pascii(get_byte()) | 636 | # define get_char(c) ascii2pascii(get_byte()) |
632 | # define OS_CODE 0x0F /* temporary, subject to change */ | 637 | # define OS_CODE 0x0F /* temporary, subject to change */ |
633 | # ifdef SIGTERM | 638 | # ifdef SIGTERM |
634 | # undef SIGTERM /* We don't want a signal handler for SIGTERM */ | 639 | # undef SIGTERM /* We don't want a signal handler for SIGTERM */ |
635 | # endif | 640 | # endif |
636 | #endif | 641 | #endif |
637 | 642 | ||
638 | #if defined(pyr) && !defined(NOMEMCPY) /* Pyramid */ | 643 | #if defined(pyr) && !defined(NOMEMCPY) /* Pyramid */ |
639 | # define NOMEMCPY /* problem with overlapping copies */ | 644 | # define NOMEMCPY /* problem with overlapping copies */ |
640 | #endif | 645 | #endif |
641 | 646 | ||
642 | #ifdef TOPS20 | 647 | #ifdef TOPS20 |
@@ -644,14 +649,14 @@ extern int block_mode; /* block compress mode -C compatible with 2.0 */ | |||
644 | #endif | 649 | #endif |
645 | 650 | ||
646 | #ifndef unix | 651 | #ifndef unix |
647 | # define NO_ST_INO /* don't rely on inode numbers */ | 652 | # define NO_ST_INO /* don't rely on inode numbers */ |
648 | #endif | 653 | #endif |
649 | 654 | ||
650 | 655 | ||
651 | /* Common defaults */ | 656 | /* Common defaults */ |
652 | 657 | ||
653 | #ifndef OS_CODE | 658 | #ifndef OS_CODE |
654 | # define OS_CODE 0x03 /* assume Unix */ | 659 | # define OS_CODE 0x03 /* assume Unix */ |
655 | #endif | 660 | #endif |
656 | 661 | ||
657 | #ifndef PATH_SEP | 662 | #ifndef PATH_SEP |
@@ -773,9 +778,10 @@ extern int block_mode; /* block compress mode -C compatible with 2.0 */ | |||
773 | * Local data used by the "bit string" routines. | 778 | * Local data used by the "bit string" routines. |
774 | */ | 779 | */ |
775 | 780 | ||
776 | local file_t zfile; /* output gzip file */ | 781 | local file_t zfile; /* output gzip file */ |
777 | 782 | ||
778 | local unsigned short bi_buf; | 783 | local unsigned short bi_buf; |
784 | |||
779 | /* Output buffer. bits are inserted starting at the bottom (least significant | 785 | /* Output buffer. bits are inserted starting at the bottom (least significant |
780 | * bits). | 786 | * bits). |
781 | */ | 787 | */ |
@@ -786,36 +792,38 @@ local unsigned short bi_buf; | |||
786 | */ | 792 | */ |
787 | 793 | ||
788 | local int bi_valid; | 794 | local int bi_valid; |
795 | |||
789 | /* Number of valid bits in bi_buf. All bits above the last valid bit | 796 | /* Number of valid bits in bi_buf. All bits above the last valid bit |
790 | * are always zero. | 797 | * are always zero. |
791 | */ | 798 | */ |
792 | 799 | ||
793 | int (*read_buf) OF((char *buf, unsigned size)); | 800 | int (*read_buf) OF((char *buf, unsigned size)); |
801 | |||
794 | /* Current input function. Set to mem_read for in-memory compression */ | 802 | /* Current input function. Set to mem_read for in-memory compression */ |
795 | 803 | ||
796 | #ifdef DEBUG | 804 | #ifdef DEBUG |
797 | ulg bits_sent; /* bit length of the compressed data */ | 805 | ulg bits_sent; /* bit length of the compressed data */ |
798 | #endif | 806 | #endif |
799 | 807 | ||
800 | /* =========================================================================== | 808 | /* =========================================================================== |
801 | * Initialize the bit string routines. | 809 | * Initialize the bit string routines. |
802 | */ | 810 | */ |
803 | void bi_init (zipfile) | 811 | void bi_init(zipfile) |
804 | file_t zipfile; /* output zip file, NO_FILE for in-memory compression */ | 812 | file_t zipfile; /* output zip file, NO_FILE for in-memory compression */ |
805 | { | 813 | { |
806 | zfile = zipfile; | 814 | zfile = zipfile; |
807 | bi_buf = 0; | 815 | bi_buf = 0; |
808 | bi_valid = 0; | 816 | bi_valid = 0; |
809 | #ifdef DEBUG | 817 | #ifdef DEBUG |
810 | bits_sent = 0L; | 818 | bits_sent = 0L; |
811 | #endif | 819 | #endif |
812 | 820 | ||
813 | /* Set the defaults for file compression. They are set by memcompress | 821 | /* Set the defaults for file compression. They are set by memcompress |
814 | * for in-memory compression. | 822 | * for in-memory compression. |
815 | */ | 823 | */ |
816 | if (zfile != NO_FILE) { | 824 | if (zfile != NO_FILE) { |
817 | read_buf = file_read; | 825 | read_buf = file_read; |
818 | } | 826 | } |
819 | } | 827 | } |
820 | 828 | ||
821 | /* =========================================================================== | 829 | /* =========================================================================== |
@@ -823,27 +831,27 @@ void bi_init (zipfile) | |||
823 | * IN assertion: length <= 16 and value fits in length bits. | 831 | * IN assertion: length <= 16 and value fits in length bits. |
824 | */ | 832 | */ |
825 | void send_bits(value, length) | 833 | void send_bits(value, length) |
826 | int value; /* value to send */ | 834 | int value; /* value to send */ |
827 | int length; /* number of bits */ | 835 | int length; /* number of bits */ |
828 | { | 836 | { |
829 | #ifdef DEBUG | 837 | #ifdef DEBUG |
830 | Tracev((stderr," l %2d v %4x ", length, value)); | 838 | Tracev((stderr, " l %2d v %4x ", length, value)); |
831 | Assert(length > 0 && length <= 15, "invalid length"); | 839 | Assert(length > 0 && length <= 15, "invalid length"); |
832 | bits_sent += (ulg)length; | 840 | bits_sent += (ulg) length; |
833 | #endif | 841 | #endif |
834 | /* If not enough room in bi_buf, use (valid) bits from bi_buf and | 842 | /* If not enough room in bi_buf, use (valid) bits from bi_buf and |
835 | * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) | 843 | * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) |
836 | * unused bits in value. | 844 | * unused bits in value. |
837 | */ | 845 | */ |
838 | if (bi_valid > (int)Buf_size - length) { | 846 | if (bi_valid > (int) Buf_size - length) { |
839 | bi_buf |= (value << bi_valid); | 847 | bi_buf |= (value << bi_valid); |
840 | put_short(bi_buf); | 848 | put_short(bi_buf); |
841 | bi_buf = (ush)value >> (Buf_size - bi_valid); | 849 | bi_buf = (ush) value >> (Buf_size - bi_valid); |
842 | bi_valid += length - Buf_size; | 850 | bi_valid += length - Buf_size; |
843 | } else { | 851 | } else { |
844 | bi_buf |= value << bi_valid; | 852 | bi_buf |= value << bi_valid; |
845 | bi_valid += length; | 853 | bi_valid += length; |
846 | } | 854 | } |
847 | } | 855 | } |
848 | 856 | ||
849 | /* =========================================================================== | 857 | /* =========================================================================== |
@@ -852,15 +860,16 @@ void send_bits(value, length) | |||
852 | * IN assertion: 1 <= len <= 15 | 860 | * IN assertion: 1 <= len <= 15 |
853 | */ | 861 | */ |
854 | unsigned bi_reverse(code, len) | 862 | unsigned bi_reverse(code, len) |
855 | unsigned code; /* the value to invert */ | 863 | unsigned code; /* the value to invert */ |
856 | int len; /* its bit length */ | 864 | int len; /* its bit length */ |
857 | { | 865 | { |
858 | register unsigned res = 0; | 866 | register unsigned res = 0; |
859 | do { | 867 | |
860 | res |= code & 1; | 868 | do { |
861 | code >>= 1, res <<= 1; | 869 | res |= code & 1; |
862 | } while (--len > 0); | 870 | code >>= 1, res <<= 1; |
863 | return res >> 1; | 871 | } while (--len > 0); |
872 | return res >> 1; | ||
864 | } | 873 | } |
865 | 874 | ||
866 | /* =========================================================================== | 875 | /* =========================================================================== |
@@ -868,15 +877,15 @@ unsigned bi_reverse(code, len) | |||
868 | */ | 877 | */ |
869 | void bi_windup() | 878 | void bi_windup() |
870 | { | 879 | { |
871 | if (bi_valid > 8) { | 880 | if (bi_valid > 8) { |
872 | put_short(bi_buf); | 881 | put_short(bi_buf); |
873 | } else if (bi_valid > 0) { | 882 | } else if (bi_valid > 0) { |
874 | put_byte(bi_buf); | 883 | put_byte(bi_buf); |
875 | } | 884 | } |
876 | bi_buf = 0; | 885 | bi_buf = 0; |
877 | bi_valid = 0; | 886 | bi_valid = 0; |
878 | #ifdef DEBUG | 887 | #ifdef DEBUG |
879 | bits_sent = (bits_sent+7) & ~7; | 888 | bits_sent = (bits_sent + 7) & ~7; |
880 | #endif | 889 | #endif |
881 | } | 890 | } |
882 | 891 | ||
@@ -885,30 +894,33 @@ void bi_windup() | |||
885 | * one's complement if requested. | 894 | * one's complement if requested. |
886 | */ | 895 | */ |
887 | void copy_block(buf, len, header) | 896 | void copy_block(buf, len, header) |
888 | char *buf; /* the input data */ | 897 | char *buf; /* the input data */ |
889 | unsigned len; /* its length */ | 898 | unsigned len; /* its length */ |
890 | int header; /* true if block header must be written */ | 899 | int header; /* true if block header must be written */ |
891 | { | 900 | { |
892 | bi_windup(); /* align on byte boundary */ | 901 | bi_windup(); /* align on byte boundary */ |
893 | 902 | ||
894 | if (header) { | 903 | if (header) { |
895 | put_short((ush)len); | 904 | put_short((ush) len); |
896 | put_short((ush)~len); | 905 | put_short((ush) ~ len); |
897 | #ifdef DEBUG | 906 | #ifdef DEBUG |
898 | bits_sent += 2*16; | 907 | bits_sent += 2 * 16; |
899 | #endif | 908 | #endif |
900 | } | 909 | } |
901 | #ifdef DEBUG | 910 | #ifdef DEBUG |
902 | bits_sent += (ulg)len<<3; | 911 | bits_sent += (ulg) len << 3; |
903 | #endif | 912 | #endif |
904 | while (len--) { | 913 | while (len--) { |
905 | #ifdef CRYPT | 914 | #ifdef CRYPT |
906 | int t; | 915 | int t; |
907 | if (key) zencode(*buf, t); | 916 | |
917 | if (key) | ||
918 | zencode(*buf, t); | ||
908 | #endif | 919 | #endif |
909 | put_byte(*buf++); | 920 | put_byte(*buf++); |
910 | } | 921 | } |
911 | } | 922 | } |
923 | |||
912 | /* deflate.c -- compress data using the deflation algorithm | 924 | /* deflate.c -- compress data using the deflation algorithm |
913 | * Copyright (C) 1992-1993 Jean-loup Gailly | 925 | * Copyright (C) 1992-1993 Jean-loup Gailly |
914 | * This is free software; you can redistribute it and/or modify it under the | 926 | * This is free software; you can redistribute it and/or modify it under the |
@@ -987,7 +999,7 @@ void copy_block(buf, len, header) | |||
987 | */ | 999 | */ |
988 | 1000 | ||
989 | #ifdef SMALL_MEM | 1001 | #ifdef SMALL_MEM |
990 | # define HASH_BITS 13 /* Number of bits used to hash strings */ | 1002 | # define HASH_BITS 13 /* Number of bits used to hash strings */ |
991 | #endif | 1003 | #endif |
992 | #ifdef MEDIUM_MEM | 1004 | #ifdef MEDIUM_MEM |
993 | # define HASH_BITS 14 | 1005 | # define HASH_BITS 14 |
@@ -1001,35 +1013,30 @@ void copy_block(buf, len, header) | |||
1001 | * window with tab_suffix. Check that we can do this: | 1013 | * window with tab_suffix. Check that we can do this: |
1002 | */ | 1014 | */ |
1003 | #if (WSIZE<<1) > (1<<BITS) | 1015 | #if (WSIZE<<1) > (1<<BITS) |
1004 | error: cannot overlay window with tab_suffix and prev with tab_prefix0 | 1016 | error:cannot overlay window with tab_suffix and prev with tab_prefix0 |
1005 | #endif | 1017 | #endif |
1006 | #if HASH_BITS > BITS-1 | 1018 | #if HASH_BITS > BITS-1 |
1007 | error: cannot overlay head with tab_prefix1 | 1019 | error:cannot overlay head with tab_prefix1 |
1008 | #endif | 1020 | #endif |
1009 | |||
1010 | #define HASH_SIZE (unsigned)(1<<HASH_BITS) | 1021 | #define HASH_SIZE (unsigned)(1<<HASH_BITS) |
1011 | #define HASH_MASK (HASH_SIZE-1) | 1022 | #define HASH_MASK (HASH_SIZE-1) |
1012 | #define WMASK (WSIZE-1) | 1023 | #define WMASK (WSIZE-1) |
1013 | /* HASH_SIZE and WSIZE must be powers of two */ | 1024 | /* HASH_SIZE and WSIZE must be powers of two */ |
1014 | |||
1015 | #define NIL 0 | 1025 | #define NIL 0 |
1016 | /* Tail of hash chains */ | 1026 | /* Tail of hash chains */ |
1017 | |||
1018 | #define FAST 4 | 1027 | #define FAST 4 |
1019 | #define SLOW 2 | 1028 | #define SLOW 2 |
1020 | /* speed options for the general purpose bit flag */ | 1029 | /* speed options for the general purpose bit flag */ |
1021 | |||
1022 | #ifndef TOO_FAR | 1030 | #ifndef TOO_FAR |
1023 | # define TOO_FAR 4096 | 1031 | # define TOO_FAR 4096 |
1024 | #endif | 1032 | #endif |
1025 | /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ | 1033 | /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ |
1026 | |||
1027 | /* =========================================================================== | 1034 | /* =========================================================================== |
1028 | * Local data used by the "longest match" routines. | 1035 | * Local data used by the "longest match" routines. |
1029 | */ | 1036 | */ |
1030 | |||
1031 | typedef ush Pos; | 1037 | typedef ush Pos; |
1032 | typedef unsigned IPos; | 1038 | typedef unsigned IPos; |
1039 | |||
1033 | /* A Pos is an index in the character window. We use short instead of int to | 1040 | /* A Pos is an index in the character window. We use short instead of int to |
1034 | * save space in the various tables. IPos is used only for parameter passing. | 1041 | * save space in the various tables. IPos is used only for parameter passing. |
1035 | */ | 1042 | */ |
@@ -1054,17 +1061,19 @@ typedef unsigned IPos; | |||
1054 | /* DECLARE(Pos, head, 1<<HASH_BITS); */ | 1061 | /* DECLARE(Pos, head, 1<<HASH_BITS); */ |
1055 | /* Heads of the hash chains or NIL. */ | 1062 | /* Heads of the hash chains or NIL. */ |
1056 | 1063 | ||
1057 | ulg window_size = (ulg)2*WSIZE; | 1064 | ulg window_size = (ulg) 2 * WSIZE; |
1065 | |||
1058 | /* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the | 1066 | /* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the |
1059 | * input file length plus MIN_LOOKAHEAD. | 1067 | * input file length plus MIN_LOOKAHEAD. |
1060 | */ | 1068 | */ |
1061 | 1069 | ||
1062 | long block_start; | 1070 | long block_start; |
1071 | |||
1063 | /* window position at the beginning of the current output block. Gets | 1072 | /* window position at the beginning of the current output block. Gets |
1064 | * negative when the window is moved backwards. | 1073 | * negative when the window is moved backwards. |
1065 | */ | 1074 | */ |
1066 | 1075 | ||
1067 | local unsigned ins_h; /* hash index of string to be inserted */ | 1076 | local unsigned ins_h; /* hash index of string to be inserted */ |
1068 | 1077 | ||
1069 | #define H_SHIFT ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH) | 1078 | #define H_SHIFT ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH) |
1070 | /* Number of bits by which ins_h and del_h must be shifted at each | 1079 | /* Number of bits by which ins_h and del_h must be shifted at each |
@@ -1074,21 +1083,24 @@ local unsigned ins_h; /* hash index of string to be inserted */ | |||
1074 | */ | 1083 | */ |
1075 | 1084 | ||
1076 | unsigned int near prev_length; | 1085 | unsigned int near prev_length; |
1086 | |||
1077 | /* Length of the best match at previous step. Matches not greater than this | 1087 | /* Length of the best match at previous step. Matches not greater than this |
1078 | * are discarded. This is used in the lazy match evaluation. | 1088 | * are discarded. This is used in the lazy match evaluation. |
1079 | */ | 1089 | */ |
1080 | 1090 | ||
1081 | unsigned near strstart; /* start of string to insert */ | 1091 | unsigned near strstart; /* start of string to insert */ |
1082 | unsigned near match_start; /* start of matching string */ | 1092 | unsigned near match_start; /* start of matching string */ |
1083 | local int eofile; /* flag set at end of input file */ | 1093 | local int eofile; /* flag set at end of input file */ |
1084 | local unsigned lookahead; /* number of valid bytes ahead in window */ | 1094 | local unsigned lookahead; /* number of valid bytes ahead in window */ |
1085 | 1095 | ||
1086 | unsigned near max_chain_length; | 1096 | unsigned near max_chain_length; |
1097 | |||
1087 | /* To speed up deflation, hash chains are never searched beyond this length. | 1098 | /* To speed up deflation, hash chains are never searched beyond this length. |
1088 | * A higher limit improves compression ratio but degrades the speed. | 1099 | * A higher limit improves compression ratio but degrades the speed. |
1089 | */ | 1100 | */ |
1090 | 1101 | ||
1091 | local unsigned int max_lazy_match; | 1102 | local unsigned int max_lazy_match; |
1103 | |||
1092 | /* Attempt to find a better match only when the current match is strictly | 1104 | /* Attempt to find a better match only when the current match is strictly |
1093 | * smaller than this value. This mechanism is used only for compression | 1105 | * smaller than this value. This mechanism is used only for compression |
1094 | * levels >= 4. | 1106 | * levels >= 4. |
@@ -1100,6 +1112,7 @@ local unsigned int max_lazy_match; | |||
1100 | */ | 1112 | */ |
1101 | 1113 | ||
1102 | unsigned near good_match; | 1114 | unsigned near good_match; |
1115 | |||
1103 | /* Use a faster search when the previous match is longer than this */ | 1116 | /* Use a faster search when the previous match is longer than this */ |
1104 | 1117 | ||
1105 | 1118 | ||
@@ -1110,20 +1123,21 @@ unsigned near good_match; | |||
1110 | */ | 1123 | */ |
1111 | 1124 | ||
1112 | typedef struct config { | 1125 | typedef struct config { |
1113 | ush good_length; /* reduce lazy search above this match length */ | 1126 | ush good_length; /* reduce lazy search above this match length */ |
1114 | ush max_lazy; /* do not perform lazy search above this match length */ | 1127 | ush max_lazy; /* do not perform lazy search above this match length */ |
1115 | ush nice_length; /* quit search above this match length */ | 1128 | ush nice_length; /* quit search above this match length */ |
1116 | ush max_chain; | 1129 | ush max_chain; |
1117 | } config; | 1130 | } config; |
1118 | 1131 | ||
1119 | #ifdef FULL_SEARCH | 1132 | #ifdef FULL_SEARCH |
1120 | # define nice_match MAX_MATCH | 1133 | # define nice_match MAX_MATCH |
1121 | #else | 1134 | #else |
1122 | int near nice_match; /* Stop searching when current match exceeds this */ | 1135 | int near nice_match; /* Stop searching when current match exceeds this */ |
1123 | #endif | 1136 | #endif |
1124 | 1137 | ||
1125 | local config configuration_table = | 1138 | local config configuration_table = |
1126 | /* 9 */ {32, 258, 258, 4096}; /* maximum compression */ | 1139 | /* 9 */ { 32, 258, 258, 4096 }; |
1140 | /* maximum compression */ | ||
1127 | 1141 | ||
1128 | /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 | 1142 | /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 |
1129 | * For deflate_fast() (levels <= 3) good is ignored and lazy has a different | 1143 | * For deflate_fast() (levels <= 3) good is ignored and lazy has a different |
@@ -1136,15 +1150,16 @@ local config configuration_table = | |||
1136 | /* =========================================================================== | 1150 | /* =========================================================================== |
1137 | * Prototypes for local functions. | 1151 | * Prototypes for local functions. |
1138 | */ | 1152 | */ |
1139 | local void fill_window OF((void)); | 1153 | local void fill_window OF((void)); |
1154 | |||
1155 | int longest_match OF((IPos cur_match)); | ||
1140 | 1156 | ||
1141 | int longest_match OF((IPos cur_match)); | ||
1142 | #ifdef ASMV | 1157 | #ifdef ASMV |
1143 | void match_init OF((void)); /* asm code initialization */ | 1158 | void match_init OF((void)); /* asm code initialization */ |
1144 | #endif | 1159 | #endif |
1145 | 1160 | ||
1146 | #ifdef DEBUG | 1161 | #ifdef DEBUG |
1147 | local void check_match OF((IPos start, IPos match, int length)); | 1162 | local void check_match OF((IPos start, IPos match, int length)); |
1148 | #endif | 1163 | #endif |
1149 | 1164 | ||
1150 | /* =========================================================================== | 1165 | /* =========================================================================== |
@@ -1171,54 +1186,57 @@ local void check_match OF((IPos start, IPos match, int length)); | |||
1171 | /* =========================================================================== | 1186 | /* =========================================================================== |
1172 | * Initialize the "longest match" routines for a new file | 1187 | * Initialize the "longest match" routines for a new file |
1173 | */ | 1188 | */ |
1174 | void lm_init (flags) | 1189 | void lm_init(flags) |
1175 | ush *flags; /* general purpose bit flag */ | 1190 | ush *flags; /* general purpose bit flag */ |
1176 | { | 1191 | { |
1177 | register unsigned j; | 1192 | register unsigned j; |
1178 | 1193 | ||
1179 | /* Initialize the hash table. */ | 1194 | /* Initialize the hash table. */ |
1180 | #if defined(MAXSEG_64K) && HASH_BITS == 15 | 1195 | #if defined(MAXSEG_64K) && HASH_BITS == 15 |
1181 | for (j = 0; j < HASH_SIZE; j++) head[j] = NIL; | 1196 | for (j = 0; j < HASH_SIZE; j++) |
1197 | head[j] = NIL; | ||
1182 | #else | 1198 | #else |
1183 | memzero((char*)head, HASH_SIZE*sizeof(*head)); | 1199 | memzero((char *) head, HASH_SIZE * sizeof(*head)); |
1184 | #endif | 1200 | #endif |
1185 | /* prev will be initialized on the fly */ | 1201 | /* prev will be initialized on the fly */ |
1186 | 1202 | ||
1187 | /* Set the default configuration parameters: | 1203 | /* Set the default configuration parameters: |
1188 | */ | 1204 | */ |
1189 | max_lazy_match = configuration_table.max_lazy; | 1205 | max_lazy_match = configuration_table.max_lazy; |
1190 | good_match = configuration_table.good_length; | 1206 | good_match = configuration_table.good_length; |
1191 | #ifndef FULL_SEARCH | 1207 | #ifndef FULL_SEARCH |
1192 | nice_match = configuration_table.nice_length; | 1208 | nice_match = configuration_table.nice_length; |
1193 | #endif | 1209 | #endif |
1194 | max_chain_length = configuration_table.max_chain; | 1210 | max_chain_length = configuration_table.max_chain; |
1195 | *flags |= SLOW; | 1211 | *flags |= SLOW; |
1196 | /* ??? reduce max_chain_length for binary files */ | 1212 | /* ??? reduce max_chain_length for binary files */ |
1197 | 1213 | ||
1198 | strstart = 0; | 1214 | strstart = 0; |
1199 | block_start = 0L; | 1215 | block_start = 0L; |
1200 | #ifdef ASMV | 1216 | #ifdef ASMV |
1201 | match_init(); /* initialize the asm code */ | 1217 | match_init(); /* initialize the asm code */ |
1202 | #endif | 1218 | #endif |
1203 | 1219 | ||
1204 | lookahead = read_buf((char*)window, | 1220 | lookahead = read_buf((char *) window, |
1205 | sizeof(int) <= 2 ? (unsigned)WSIZE : 2*WSIZE); | 1221 | sizeof(int) <= 2 ? (unsigned) WSIZE : 2 * WSIZE); |
1206 | 1222 | ||
1207 | if (lookahead == 0 || lookahead == (unsigned)EOF) { | 1223 | if (lookahead == 0 || lookahead == (unsigned) EOF) { |
1208 | eofile = 1, lookahead = 0; | 1224 | eofile = 1, lookahead = 0; |
1209 | return; | 1225 | return; |
1210 | } | 1226 | } |
1211 | eofile = 0; | 1227 | eofile = 0; |
1212 | /* Make sure that we always have enough lookahead. This is important | 1228 | /* Make sure that we always have enough lookahead. This is important |
1213 | * if input comes from a device such as a tty. | 1229 | * if input comes from a device such as a tty. |
1214 | */ | 1230 | */ |
1215 | while (lookahead < MIN_LOOKAHEAD && !eofile) fill_window(); | 1231 | while (lookahead < MIN_LOOKAHEAD && !eofile) |
1216 | 1232 | fill_window(); | |
1217 | ins_h = 0; | 1233 | |
1218 | for (j=0; j<MIN_MATCH-1; j++) UPDATE_HASH(ins_h, window[j]); | 1234 | ins_h = 0; |
1219 | /* If lookahead < MIN_MATCH, ins_h is garbage, but this is | 1235 | for (j = 0; j < MIN_MATCH - 1; j++) |
1220 | * not important since only literal bytes will be emitted. | 1236 | UPDATE_HASH(ins_h, window[j]); |
1221 | */ | 1237 | /* If lookahead < MIN_MATCH, ins_h is garbage, but this is |
1238 | * not important since only literal bytes will be emitted. | ||
1239 | */ | ||
1222 | } | 1240 | } |
1223 | 1241 | ||
1224 | /* =========================================================================== | 1242 | /* =========================================================================== |
@@ -1235,151 +1253,157 @@ void lm_init (flags) | |||
1235 | * if desired. | 1253 | * if desired. |
1236 | */ | 1254 | */ |
1237 | int longest_match(cur_match) | 1255 | int longest_match(cur_match) |
1238 | IPos cur_match; /* current match */ | 1256 | IPos cur_match; /* current match */ |
1239 | { | 1257 | { |
1240 | unsigned chain_length = max_chain_length; /* max hash chain length */ | 1258 | unsigned chain_length = max_chain_length; /* max hash chain length */ |
1241 | register uch *scan = window + strstart; /* current string */ | 1259 | register uch *scan = window + strstart; /* current string */ |
1242 | register uch *match; /* matched string */ | 1260 | register uch *match; /* matched string */ |
1243 | register int len; /* length of current match */ | 1261 | register int len; /* length of current match */ |
1244 | int best_len = prev_length; /* best match length so far */ | 1262 | int best_len = prev_length; /* best match length so far */ |
1245 | IPos limit = strstart > (IPos)MAX_DIST ? strstart - (IPos)MAX_DIST : NIL; | 1263 | IPos limit = |
1246 | /* Stop when cur_match becomes <= limit. To simplify the code, | 1264 | |
1247 | * we prevent matches with the string of window index 0. | 1265 | strstart > (IPos) MAX_DIST ? strstart - (IPos) MAX_DIST : NIL; |
1248 | */ | 1266 | /* Stop when cur_match becomes <= limit. To simplify the code, |
1267 | * we prevent matches with the string of window index 0. | ||
1268 | */ | ||
1249 | 1269 | ||
1250 | /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. | 1270 | /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. |
1251 | * It is easy to get rid of this optimization if necessary. | 1271 | * It is easy to get rid of this optimization if necessary. |
1252 | */ | 1272 | */ |
1253 | #if HASH_BITS < 8 || MAX_MATCH != 258 | 1273 | #if HASH_BITS < 8 || MAX_MATCH != 258 |
1254 | error: Code too clever | 1274 | error:Code too clever |
1255 | #endif | 1275 | #endif |
1256 | |||
1257 | #ifdef UNALIGNED_OK | 1276 | #ifdef UNALIGNED_OK |
1258 | /* Compare two bytes at a time. Note: this is not always beneficial. | 1277 | /* Compare two bytes at a time. Note: this is not always beneficial. |
1259 | * Try with and without -DUNALIGNED_OK to check. | 1278 | * Try with and without -DUNALIGNED_OK to check. |
1260 | */ | 1279 | */ |
1261 | register uch *strend = window + strstart + MAX_MATCH - 1; | 1280 | register uch *strend = window + strstart + MAX_MATCH - 1; |
1262 | register ush scan_start = *(ush*)scan; | 1281 | register ush scan_start = *(ush *) scan; |
1263 | register ush scan_end = *(ush*)(scan+best_len-1); | 1282 | register ush scan_end = *(ush *) (scan + best_len - 1); |
1264 | #else | 1283 | #else |
1265 | register uch *strend = window + strstart + MAX_MATCH; | 1284 | register uch *strend = window + strstart + MAX_MATCH; |
1266 | register uch scan_end1 = scan[best_len-1]; | 1285 | register uch scan_end1 = scan[best_len - 1]; |
1267 | register uch scan_end = scan[best_len]; | 1286 | register uch scan_end = scan[best_len]; |
1268 | #endif | 1287 | #endif |
1269 | 1288 | ||
1270 | /* Do not waste too much time if we already have a good match: */ | 1289 | /* Do not waste too much time if we already have a good match: */ |
1271 | if (prev_length >= good_match) { | 1290 | if (prev_length >= good_match) { |
1272 | chain_length >>= 2; | 1291 | chain_length >>= 2; |
1273 | } | 1292 | } |
1274 | Assert(strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead"); | 1293 | Assert(strstart <= window_size - MIN_LOOKAHEAD, |
1294 | "insufficient lookahead"); | ||
1275 | 1295 | ||
1276 | do { | 1296 | do { |
1277 | Assert(cur_match < strstart, "no future"); | 1297 | Assert(cur_match < strstart, "no future"); |
1278 | match = window + cur_match; | 1298 | match = window + cur_match; |
1279 | 1299 | ||
1280 | /* Skip to next match if the match length cannot increase | 1300 | /* Skip to next match if the match length cannot increase |
1281 | * or if the match length is less than 2: | 1301 | * or if the match length is less than 2: |
1282 | */ | 1302 | */ |
1283 | #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) | 1303 | #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) |
1284 | /* This code assumes sizeof(unsigned short) == 2. Do not use | 1304 | /* This code assumes sizeof(unsigned short) == 2. Do not use |
1285 | * UNALIGNED_OK if your compiler uses a different size. | 1305 | * UNALIGNED_OK if your compiler uses a different size. |
1286 | */ | 1306 | */ |
1287 | if (*(ush*)(match+best_len-1) != scan_end || | 1307 | if (*(ush *) (match + best_len - 1) != scan_end || |
1288 | *(ush*)match != scan_start) continue; | 1308 | *(ush *) match != scan_start) |
1289 | 1309 | continue; | |
1290 | /* It is not necessary to compare scan[2] and match[2] since they are | 1310 | |
1291 | * always equal when the other bytes match, given that the hash keys | 1311 | /* It is not necessary to compare scan[2] and match[2] since they are |
1292 | * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at | 1312 | * always equal when the other bytes match, given that the hash keys |
1293 | * strstart+3, +5, ... up to strstart+257. We check for insufficient | 1313 | * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at |
1294 | * lookahead only every 4th comparison; the 128th check will be made | 1314 | * strstart+3, +5, ... up to strstart+257. We check for insufficient |
1295 | * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is | 1315 | * lookahead only every 4th comparison; the 128th check will be made |
1296 | * necessary to put more guard bytes at the end of the window, or | 1316 | * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is |
1297 | * to check more often for insufficient lookahead. | 1317 | * necessary to put more guard bytes at the end of the window, or |
1298 | */ | 1318 | * to check more often for insufficient lookahead. |
1299 | scan++, match++; | 1319 | */ |
1300 | do { | 1320 | scan++, match++; |
1301 | } while (*(ush*)(scan+=2) == *(ush*)(match+=2) && | 1321 | do { |
1302 | *(ush*)(scan+=2) == *(ush*)(match+=2) && | 1322 | } while (*(ush *) (scan += 2) == *(ush *) (match += 2) && |
1303 | *(ush*)(scan+=2) == *(ush*)(match+=2) && | 1323 | *(ush *) (scan += 2) == *(ush *) (match += 2) && |
1304 | *(ush*)(scan+=2) == *(ush*)(match+=2) && | 1324 | *(ush *) (scan += 2) == *(ush *) (match += 2) && |
1305 | scan < strend); | 1325 | *(ush *) (scan += 2) == *(ush *) (match += 2) && |
1306 | /* The funny "do {}" generates better code on most compilers */ | 1326 | scan < strend); |
1307 | 1327 | /* The funny "do {}" generates better code on most compilers */ | |
1308 | /* Here, scan <= window+strstart+257 */ | 1328 | |
1309 | Assert(scan <= window+(unsigned)(window_size-1), "wild scan"); | 1329 | /* Here, scan <= window+strstart+257 */ |
1310 | if (*scan == *match) scan++; | 1330 | Assert(scan <= window + (unsigned) (window_size - 1), "wild scan"); |
1311 | 1331 | if (*scan == *match) | |
1312 | len = (MAX_MATCH - 1) - (int)(strend-scan); | 1332 | scan++; |
1313 | scan = strend - (MAX_MATCH-1); | 1333 | |
1314 | 1334 | len = (MAX_MATCH - 1) - (int) (strend - scan); | |
1315 | #else /* UNALIGNED_OK */ | 1335 | scan = strend - (MAX_MATCH - 1); |
1316 | 1336 | ||
1317 | if (match[best_len] != scan_end || | 1337 | #else /* UNALIGNED_OK */ |
1318 | match[best_len-1] != scan_end1 || | 1338 | |
1319 | *match != *scan || | 1339 | if (match[best_len] != scan_end || |
1320 | *++match != scan[1]) continue; | 1340 | match[best_len - 1] != scan_end1 || |
1321 | 1341 | *match != *scan || *++match != scan[1]) | |
1322 | /* The check at best_len-1 can be removed because it will be made | 1342 | continue; |
1323 | * again later. (This heuristic is not always a win.) | 1343 | |
1324 | * It is not necessary to compare scan[2] and match[2] since they | 1344 | /* The check at best_len-1 can be removed because it will be made |
1325 | * are always equal when the other bytes match, given that | 1345 | * again later. (This heuristic is not always a win.) |
1326 | * the hash keys are equal and that HASH_BITS >= 8. | 1346 | * It is not necessary to compare scan[2] and match[2] since they |
1327 | */ | 1347 | * are always equal when the other bytes match, given that |
1328 | scan += 2, match++; | 1348 | * the hash keys are equal and that HASH_BITS >= 8. |
1329 | 1349 | */ | |
1330 | /* We check for insufficient lookahead only every 8th comparison; | 1350 | scan += 2, match++; |
1331 | * the 256th check will be made at strstart+258. | 1351 | |
1332 | */ | 1352 | /* We check for insufficient lookahead only every 8th comparison; |
1333 | do { | 1353 | * the 256th check will be made at strstart+258. |
1334 | } while (*++scan == *++match && *++scan == *++match && | 1354 | */ |
1335 | *++scan == *++match && *++scan == *++match && | 1355 | do { |
1336 | *++scan == *++match && *++scan == *++match && | 1356 | } while (*++scan == *++match && *++scan == *++match && |
1337 | *++scan == *++match && *++scan == *++match && | 1357 | *++scan == *++match && *++scan == *++match && |
1338 | scan < strend); | 1358 | *++scan == *++match && *++scan == *++match && |
1339 | 1359 | *++scan == *++match && *++scan == *++match && | |
1340 | len = MAX_MATCH - (int)(strend - scan); | 1360 | scan < strend); |
1341 | scan = strend - MAX_MATCH; | 1361 | |
1342 | 1362 | len = MAX_MATCH - (int) (strend - scan); | |
1343 | #endif /* UNALIGNED_OK */ | 1363 | scan = strend - MAX_MATCH; |
1344 | 1364 | ||
1345 | if (len > best_len) { | 1365 | #endif /* UNALIGNED_OK */ |
1346 | match_start = cur_match; | 1366 | |
1347 | best_len = len; | 1367 | if (len > best_len) { |
1348 | if (len >= nice_match) break; | 1368 | match_start = cur_match; |
1369 | best_len = len; | ||
1370 | if (len >= nice_match) | ||
1371 | break; | ||
1349 | #ifdef UNALIGNED_OK | 1372 | #ifdef UNALIGNED_OK |
1350 | scan_end = *(ush*)(scan+best_len-1); | 1373 | scan_end = *(ush *) (scan + best_len - 1); |
1351 | #else | 1374 | #else |
1352 | scan_end1 = scan[best_len-1]; | 1375 | scan_end1 = scan[best_len - 1]; |
1353 | scan_end = scan[best_len]; | 1376 | scan_end = scan[best_len]; |
1354 | #endif | 1377 | #endif |
1355 | } | 1378 | } |
1356 | } while ((cur_match = prev[cur_match & WMASK]) > limit | 1379 | } while ((cur_match = prev[cur_match & WMASK]) > limit |
1357 | && --chain_length != 0); | 1380 | && --chain_length != 0); |
1358 | 1381 | ||
1359 | return best_len; | 1382 | return best_len; |
1360 | } | 1383 | } |
1361 | #endif /* ASMV */ | 1384 | #endif /* ASMV */ |
1362 | 1385 | ||
1363 | #ifdef DEBUG | 1386 | #ifdef DEBUG |
1364 | /* =========================================================================== | 1387 | /* =========================================================================== |
1365 | * Check that the match at match_start is indeed a match. | 1388 | * Check that the match at match_start is indeed a match. |
1366 | */ | 1389 | */ |
1367 | local void check_match(start, match, length) | 1390 | local void check_match(start, match, length) |
1368 | IPos start, match; | 1391 | IPos start, match; |
1369 | int length; | 1392 | int length; |
1370 | { | 1393 | { |
1371 | /* check that the match is indeed a match */ | 1394 | /* check that the match is indeed a match */ |
1372 | if (memcmp((char*)window + match, | 1395 | if (memcmp((char *) window + match, |
1373 | (char*)window + start, length) != EQUAL) { | 1396 | (char *) window + start, length) != EQUAL) { |
1374 | fprintf(stderr, | 1397 | fprintf(stderr, |
1375 | " start %d, match %d, length %d\n", | 1398 | " start %d, match %d, length %d\n", start, match, length); |
1376 | start, match, length); | 1399 | error("invalid match"); |
1377 | error("invalid match"); | 1400 | } |
1378 | } | 1401 | if (verbose > 1) { |
1379 | if (verbose > 1) { | 1402 | fprintf(stderr, "\\[%d,%d]", start - match, length); |
1380 | fprintf(stderr,"\\[%d,%d]", start-match, length); | 1403 | do { |
1381 | do { putc(window[start++], stderr); } while (--length != 0); | 1404 | putc(window[start++], stderr); |
1382 | } | 1405 | } while (--length != 0); |
1406 | } | ||
1383 | } | 1407 | } |
1384 | #else | 1408 | #else |
1385 | # define check_match(start, match, length) | 1409 | # define check_match(start, match, length) |
@@ -1395,52 +1419,54 @@ local void check_match(start, match, length) | |||
1395 | */ | 1419 | */ |
1396 | local void fill_window() | 1420 | local void fill_window() |
1397 | { | 1421 | { |
1398 | register unsigned n, m; | 1422 | register unsigned n, m; |
1399 | unsigned more = (unsigned)(window_size - (ulg)lookahead - (ulg)strstart); | 1423 | unsigned more = |
1400 | /* Amount of free space at the end of the window. */ | 1424 | |
1401 | 1425 | (unsigned) (window_size - (ulg) lookahead - (ulg) strstart); | |
1402 | /* If the window is almost full and there is insufficient lookahead, | 1426 | /* Amount of free space at the end of the window. */ |
1403 | * move the upper half to the lower one to make room in the upper half. | 1427 | |
1404 | */ | 1428 | /* If the window is almost full and there is insufficient lookahead, |
1405 | if (more == (unsigned)EOF) { | 1429 | * move the upper half to the lower one to make room in the upper half. |
1406 | /* Very unlikely, but possible on 16 bit machine if strstart == 0 | 1430 | */ |
1407 | * and lookahead == 1 (input done one byte at time) | 1431 | if (more == (unsigned) EOF) { |
1408 | */ | 1432 | /* Very unlikely, but possible on 16 bit machine if strstart == 0 |
1409 | more--; | 1433 | * and lookahead == 1 (input done one byte at time) |
1410 | } else if (strstart >= WSIZE+MAX_DIST) { | 1434 | */ |
1411 | /* By the IN assertion, the window is not empty so we can't confuse | 1435 | more--; |
1412 | * more == 0 with more == 64K on a 16 bit machine. | 1436 | } else if (strstart >= WSIZE + MAX_DIST) { |
1413 | */ | 1437 | /* By the IN assertion, the window is not empty so we can't confuse |
1414 | Assert(window_size == (ulg)2*WSIZE, "no sliding with BIG_MEM"); | 1438 | * more == 0 with more == 64K on a 16 bit machine. |
1415 | 1439 | */ | |
1416 | memcpy((char*)window, (char*)window+WSIZE, (unsigned)WSIZE); | 1440 | Assert(window_size == (ulg) 2 * WSIZE, "no sliding with BIG_MEM"); |
1417 | match_start -= WSIZE; | 1441 | |
1418 | strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */ | 1442 | memcpy((char *) window, (char *) window + WSIZE, (unsigned) WSIZE); |
1419 | 1443 | match_start -= WSIZE; | |
1420 | block_start -= (long) WSIZE; | 1444 | strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */ |
1421 | 1445 | ||
1422 | for (n = 0; n < HASH_SIZE; n++) { | 1446 | block_start -= (long) WSIZE; |
1423 | m = head[n]; | 1447 | |
1424 | head[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); | 1448 | for (n = 0; n < HASH_SIZE; n++) { |
1425 | } | 1449 | m = head[n]; |
1426 | for (n = 0; n < WSIZE; n++) { | 1450 | head[n] = (Pos) (m >= WSIZE ? m - WSIZE : NIL); |
1427 | m = prev[n]; | 1451 | } |
1428 | prev[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); | 1452 | for (n = 0; n < WSIZE; n++) { |
1429 | /* If n is not on any hash chain, prev[n] is garbage but | 1453 | m = prev[n]; |
1430 | * its value will never be used. | 1454 | prev[n] = (Pos) (m >= WSIZE ? m - WSIZE : NIL); |
1431 | */ | 1455 | /* If n is not on any hash chain, prev[n] is garbage but |
1432 | } | 1456 | * its value will never be used. |
1433 | more += WSIZE; | 1457 | */ |
1434 | } | 1458 | } |
1435 | /* At this point, more >= 2 */ | 1459 | more += WSIZE; |
1436 | if (!eofile) { | 1460 | } |
1437 | n = read_buf((char*)window+strstart+lookahead, more); | 1461 | /* At this point, more >= 2 */ |
1438 | if (n == 0 || n == (unsigned)EOF) { | 1462 | if (!eofile) { |
1439 | eofile = 1; | 1463 | n = read_buf((char *) window + strstart + lookahead, more); |
1440 | } else { | 1464 | if (n == 0 || n == (unsigned) EOF) { |
1441 | lookahead += n; | 1465 | eofile = 1; |
1442 | } | 1466 | } else { |
1443 | } | 1467 | lookahead += n; |
1468 | } | ||
1469 | } | ||
1444 | } | 1470 | } |
1445 | 1471 | ||
1446 | /* =========================================================================== | 1472 | /* =========================================================================== |
@@ -1458,105 +1484,114 @@ local void fill_window() | |||
1458 | */ | 1484 | */ |
1459 | ulg deflate() | 1485 | ulg deflate() |
1460 | { | 1486 | { |
1461 | IPos hash_head; /* head of hash chain */ | 1487 | IPos hash_head; /* head of hash chain */ |
1462 | IPos prev_match; /* previous match */ | 1488 | IPos prev_match; /* previous match */ |
1463 | int flush; /* set if current block must be flushed */ | 1489 | int flush; /* set if current block must be flushed */ |
1464 | int match_available = 0; /* set if previous match exists */ | 1490 | int match_available = 0; /* set if previous match exists */ |
1465 | register unsigned match_length = MIN_MATCH-1; /* length of best match */ | 1491 | register unsigned match_length = MIN_MATCH - 1; /* length of best match */ |
1492 | |||
1466 | #ifdef DEBUG | 1493 | #ifdef DEBUG |
1467 | extern long isize; /* byte length of input file, for debug only */ | 1494 | extern long isize; /* byte length of input file, for debug only */ |
1468 | #endif | 1495 | #endif |
1469 | 1496 | ||
1470 | /* Process the input block. */ | 1497 | /* Process the input block. */ |
1471 | while (lookahead != 0) { | 1498 | while (lookahead != 0) { |
1472 | /* Insert the string window[strstart .. strstart+2] in the | 1499 | /* Insert the string window[strstart .. strstart+2] in the |
1473 | * dictionary, and set hash_head to the head of the hash chain: | 1500 | * dictionary, and set hash_head to the head of the hash chain: |
1474 | */ | 1501 | */ |
1475 | INSERT_STRING(strstart, hash_head); | 1502 | INSERT_STRING(strstart, hash_head); |
1476 | 1503 | ||
1477 | /* Find the longest match, discarding those <= prev_length. | 1504 | /* Find the longest match, discarding those <= prev_length. |
1478 | */ | 1505 | */ |
1479 | prev_length = match_length, prev_match = match_start; | 1506 | prev_length = match_length, prev_match = match_start; |
1480 | match_length = MIN_MATCH-1; | 1507 | match_length = MIN_MATCH - 1; |
1481 | 1508 | ||
1482 | if (hash_head != NIL && prev_length < max_lazy_match && | 1509 | if (hash_head != NIL && prev_length < max_lazy_match && |
1483 | strstart - hash_head <= MAX_DIST) { | 1510 | strstart - hash_head <= MAX_DIST) { |
1484 | /* To simplify the code, we prevent matches with the string | 1511 | /* To simplify the code, we prevent matches with the string |
1485 | * of window index 0 (in particular we have to avoid a match | 1512 | * of window index 0 (in particular we have to avoid a match |
1486 | * of the string with itself at the start of the input file). | 1513 | * of the string with itself at the start of the input file). |
1487 | */ | 1514 | */ |
1488 | match_length = longest_match (hash_head); | 1515 | match_length = longest_match(hash_head); |
1489 | /* longest_match() sets match_start */ | 1516 | /* longest_match() sets match_start */ |
1490 | if (match_length > lookahead) match_length = lookahead; | 1517 | if (match_length > lookahead) |
1491 | 1518 | match_length = lookahead; | |
1492 | /* Ignore a length 3 match if it is too distant: */ | 1519 | |
1493 | if (match_length == MIN_MATCH && strstart-match_start > TOO_FAR){ | 1520 | /* Ignore a length 3 match if it is too distant: */ |
1494 | /* If prev_match is also MIN_MATCH, match_start is garbage | 1521 | if (match_length == MIN_MATCH |
1495 | * but we will ignore the current match anyway. | 1522 | && strstart - match_start > TOO_FAR) { |
1496 | */ | 1523 | /* If prev_match is also MIN_MATCH, match_start is garbage |
1497 | match_length--; | 1524 | * but we will ignore the current match anyway. |
1498 | } | 1525 | */ |
1499 | } | 1526 | match_length--; |
1500 | /* If there was a match at the previous step and the current | 1527 | } |
1501 | * match is not better, output the previous match: | 1528 | } |
1502 | */ | 1529 | /* If there was a match at the previous step and the current |
1503 | if (prev_length >= MIN_MATCH && match_length <= prev_length) { | 1530 | * match is not better, output the previous match: |
1504 | 1531 | */ | |
1505 | check_match(strstart-1, prev_match, prev_length); | 1532 | if (prev_length >= MIN_MATCH && match_length <= prev_length) { |
1506 | 1533 | ||
1507 | flush = ct_tally(strstart-1-prev_match, prev_length - MIN_MATCH); | 1534 | check_match(strstart - 1, prev_match, prev_length); |
1508 | 1535 | ||
1509 | /* Insert in hash table all strings up to the end of the match. | 1536 | flush = |
1510 | * strstart-1 and strstart are already inserted. | 1537 | ct_tally(strstart - 1 - prev_match, |
1511 | */ | 1538 | prev_length - MIN_MATCH); |
1512 | lookahead -= prev_length-1; | 1539 | |
1513 | prev_length -= 2; | 1540 | /* Insert in hash table all strings up to the end of the match. |
1514 | do { | 1541 | * strstart-1 and strstart are already inserted. |
1515 | strstart++; | 1542 | */ |
1516 | INSERT_STRING(strstart, hash_head); | 1543 | lookahead -= prev_length - 1; |
1517 | /* strstart never exceeds WSIZE-MAX_MATCH, so there are | 1544 | prev_length -= 2; |
1518 | * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH | 1545 | do { |
1519 | * these bytes are garbage, but it does not matter since the | 1546 | strstart++; |
1520 | * next lookahead bytes will always be emitted as literals. | 1547 | INSERT_STRING(strstart, hash_head); |
1521 | */ | 1548 | /* strstart never exceeds WSIZE-MAX_MATCH, so there are |
1522 | } while (--prev_length != 0); | 1549 | * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH |
1523 | match_available = 0; | 1550 | * these bytes are garbage, but it does not matter since the |
1524 | match_length = MIN_MATCH-1; | 1551 | * next lookahead bytes will always be emitted as literals. |
1525 | strstart++; | 1552 | */ |
1526 | if (flush) FLUSH_BLOCK(0), block_start = strstart; | 1553 | } while (--prev_length != 0); |
1527 | 1554 | match_available = 0; | |
1528 | } else if (match_available) { | 1555 | match_length = MIN_MATCH - 1; |
1529 | /* If there was no match at the previous position, output a | 1556 | strstart++; |
1530 | * single literal. If there was a match but the current match | 1557 | if (flush) |
1531 | * is longer, truncate the previous match to a single literal. | 1558 | FLUSH_BLOCK(0), block_start = strstart; |
1532 | */ | 1559 | |
1533 | Tracevv((stderr,"%c",window[strstart-1])); | 1560 | } else if (match_available) { |
1534 | if (ct_tally (0, window[strstart-1])) { | 1561 | /* If there was no match at the previous position, output a |
1535 | FLUSH_BLOCK(0), block_start = strstart; | 1562 | * single literal. If there was a match but the current match |
1536 | } | 1563 | * is longer, truncate the previous match to a single literal. |
1537 | strstart++; | 1564 | */ |
1538 | lookahead--; | 1565 | Tracevv((stderr, "%c", window[strstart - 1])); |
1539 | } else { | 1566 | if (ct_tally(0, window[strstart - 1])) { |
1540 | /* There is no previous match to compare with, wait for | 1567 | FLUSH_BLOCK(0), block_start = strstart; |
1541 | * the next step to decide. | 1568 | } |
1542 | */ | 1569 | strstart++; |
1543 | match_available = 1; | 1570 | lookahead--; |
1544 | strstart++; | 1571 | } else { |
1545 | lookahead--; | 1572 | /* There is no previous match to compare with, wait for |
1546 | } | 1573 | * the next step to decide. |
1547 | Assert (strstart <= isize && lookahead <= isize, "a bit too far"); | 1574 | */ |
1548 | 1575 | match_available = 1; | |
1549 | /* Make sure that we always have enough lookahead, except | 1576 | strstart++; |
1550 | * at the end of the input file. We need MAX_MATCH bytes | 1577 | lookahead--; |
1551 | * for the next match, plus MIN_MATCH bytes to insert the | 1578 | } |
1552 | * string following the next match. | 1579 | Assert(strstart <= isize && lookahead <= isize, "a bit too far"); |
1553 | */ | 1580 | |
1554 | while (lookahead < MIN_LOOKAHEAD && !eofile) fill_window(); | 1581 | /* Make sure that we always have enough lookahead, except |
1555 | } | 1582 | * at the end of the input file. We need MAX_MATCH bytes |
1556 | if (match_available) ct_tally (0, window[strstart-1]); | 1583 | * for the next match, plus MIN_MATCH bytes to insert the |
1557 | 1584 | * string following the next match. | |
1558 | return FLUSH_BLOCK(1); /* eof */ | 1585 | */ |
1586 | while (lookahead < MIN_LOOKAHEAD && !eofile) | ||
1587 | fill_window(); | ||
1588 | } | ||
1589 | if (match_available) | ||
1590 | ct_tally(0, window[strstart - 1]); | ||
1591 | |||
1592 | return FLUSH_BLOCK(1); /* eof */ | ||
1559 | } | 1593 | } |
1594 | |||
1560 | /* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface | 1595 | /* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface |
1561 | * Copyright (C) 1992-1993 Jean-loup Gailly | 1596 | * Copyright (C) 1992-1993 Jean-loup Gailly |
1562 | * The unzip code was written and put in the public domain by Mark Adler. | 1597 | * The unzip code was written and put in the public domain by Mark Adler. |
@@ -1611,29 +1646,33 @@ ulg deflate() | |||
1611 | #if defined(STDC_HEADERS) || !defined(NO_STDLIB_H) | 1646 | #if defined(STDC_HEADERS) || !defined(NO_STDLIB_H) |
1612 | # include <stdlib.h> | 1647 | # include <stdlib.h> |
1613 | #else | 1648 | #else |
1614 | extern int errno; | 1649 | extern int errno; |
1615 | #endif | 1650 | #endif |
1616 | 1651 | ||
1617 | #if defined(DIRENT) | 1652 | #if defined(DIRENT) |
1618 | # include <dirent.h> | 1653 | # include <dirent.h> |
1619 | typedef struct dirent dir_type; | 1654 | typedef struct dirent dir_type; |
1655 | |||
1620 | # define NLENGTH(dirent) ((int)strlen((dirent)->d_name)) | 1656 | # define NLENGTH(dirent) ((int)strlen((dirent)->d_name)) |
1621 | # define DIR_OPT "DIRENT" | 1657 | # define DIR_OPT "DIRENT" |
1622 | #else | 1658 | #else |
1623 | # define NLENGTH(dirent) ((dirent)->d_namlen) | 1659 | # define NLENGTH(dirent) ((dirent)->d_namlen) |
1624 | # ifdef SYSDIR | 1660 | # ifdef SYSDIR |
1625 | # include <sys/dir.h> | 1661 | # include <sys/dir.h> |
1626 | typedef struct direct dir_type; | 1662 | typedef struct direct dir_type; |
1663 | |||
1627 | # define DIR_OPT "SYSDIR" | 1664 | # define DIR_OPT "SYSDIR" |
1628 | # else | 1665 | # else |
1629 | # ifdef SYSNDIR | 1666 | # ifdef SYSNDIR |
1630 | # include <sys/ndir.h> | 1667 | # include <sys/ndir.h> |
1631 | typedef struct direct dir_type; | 1668 | typedef struct direct dir_type; |
1669 | |||
1632 | # define DIR_OPT "SYSNDIR" | 1670 | # define DIR_OPT "SYSNDIR" |
1633 | # else | 1671 | # else |
1634 | # ifdef NDIR | 1672 | # ifdef NDIR |
1635 | # include <ndir.h> | 1673 | # include <ndir.h> |
1636 | typedef struct direct dir_type; | 1674 | typedef struct direct dir_type; |
1675 | |||
1637 | # define DIR_OPT "NDIR" | 1676 | # define DIR_OPT "NDIR" |
1638 | # else | 1677 | # else |
1639 | # define NO_DIR | 1678 | # define NO_DIR |
@@ -1652,10 +1691,11 @@ ulg deflate() | |||
1652 | # include <sys/utime.h> | 1691 | # include <sys/utime.h> |
1653 | # define TIME_OPT "SYS_UTIME" | 1692 | # define TIME_OPT "SYS_UTIME" |
1654 | # else | 1693 | # else |
1655 | struct utimbuf { | 1694 | struct utimbuf { |
1656 | time_t actime; | 1695 | time_t actime; |
1657 | time_t modtime; | 1696 | time_t modtime; |
1658 | }; | 1697 | }; |
1698 | |||
1659 | # define TIME_OPT "" | 1699 | # define TIME_OPT "" |
1660 | # endif | 1700 | # endif |
1661 | # endif | 1701 | # endif |
@@ -1670,10 +1710,10 @@ ulg deflate() | |||
1670 | # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) | 1710 | # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) |
1671 | #endif | 1711 | #endif |
1672 | 1712 | ||
1673 | typedef RETSIGTYPE (*sig_type) OF((int)); | 1713 | typedef RETSIGTYPE(*sig_type) OF((int)); |
1674 | 1714 | ||
1675 | #ifndef O_BINARY | 1715 | #ifndef O_BINARY |
1676 | # define O_BINARY 0 /* creation mode for open() */ | 1716 | # define O_BINARY 0 /* creation mode for open() */ |
1677 | #endif | 1717 | #endif |
1678 | 1718 | ||
1679 | #ifndef O_CREAT | 1719 | #ifndef O_CREAT |
@@ -1693,10 +1733,10 @@ typedef RETSIGTYPE (*sig_type) OF((int)); | |||
1693 | #ifndef S_IWUSR | 1733 | #ifndef S_IWUSR |
1694 | # define S_IWUSR 0200 | 1734 | # define S_IWUSR 0200 |
1695 | #endif | 1735 | #endif |
1696 | #define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */ | 1736 | #define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */ |
1697 | 1737 | ||
1698 | #ifndef MAX_PATH_LEN | 1738 | #ifndef MAX_PATH_LEN |
1699 | # define MAX_PATH_LEN 1024 /* max pathname length */ | 1739 | # define MAX_PATH_LEN 1024 /* max pathname length */ |
1700 | #endif | 1740 | #endif |
1701 | 1741 | ||
1702 | #ifndef SEEK_END | 1742 | #ifndef SEEK_END |
@@ -1704,8 +1744,8 @@ typedef RETSIGTYPE (*sig_type) OF((int)); | |||
1704 | #endif | 1744 | #endif |
1705 | 1745 | ||
1706 | #ifdef NO_OFF_T | 1746 | #ifdef NO_OFF_T |
1707 | typedef long off_t; | 1747 | typedef long off_t; |
1708 | off_t lseek OF((int fd, off_t offset, int whence)); | 1748 | off_t lseek OF((int fd, off_t offset, int whence)); |
1709 | #endif | 1749 | #endif |
1710 | 1750 | ||
1711 | /* Separator for file name parts (see shorten_name()) */ | 1751 | /* Separator for file name parts (see shorten_name()) */ |
@@ -1717,48 +1757,48 @@ typedef RETSIGTYPE (*sig_type) OF((int)); | |||
1717 | 1757 | ||
1718 | /* global buffers */ | 1758 | /* global buffers */ |
1719 | 1759 | ||
1720 | DECLARE(uch, inbuf, INBUFSIZ +INBUF_EXTRA); | 1760 | DECLARE(uch, inbuf, INBUFSIZ + INBUF_EXTRA); |
1721 | DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA); | 1761 | DECLARE(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA); |
1722 | DECLARE(ush, d_buf, DIST_BUFSIZE); | 1762 | DECLARE(ush, d_buf, DIST_BUFSIZE); |
1723 | DECLARE(uch, window, 2L*WSIZE); | 1763 | DECLARE(uch, window, 2L * WSIZE); |
1724 | #ifndef MAXSEG_64K | 1764 | #ifndef MAXSEG_64K |
1725 | DECLARE(ush, tab_prefix, 1L<<BITS); | 1765 | DECLARE(ush, tab_prefix, 1L << BITS); |
1726 | #else | 1766 | #else |
1727 | DECLARE(ush, tab_prefix0, 1L<<(BITS-1)); | 1767 | DECLARE(ush, tab_prefix0, 1L << (BITS - 1)); |
1728 | DECLARE(ush, tab_prefix1, 1L<<(BITS-1)); | 1768 | DECLARE(ush, tab_prefix1, 1L << (BITS - 1)); |
1729 | #endif | 1769 | #endif |
1730 | 1770 | ||
1731 | /* local variables */ | 1771 | /* local variables */ |
1732 | 1772 | ||
1733 | int ascii = 0; /* convert end-of-lines to local OS conventions */ | 1773 | int ascii = 0; /* convert end-of-lines to local OS conventions */ |
1734 | int decompress = 0; /* decompress (-d) */ | 1774 | int decompress = 0; /* decompress (-d) */ |
1735 | int no_name = -1; /* don't save or restore the original file name */ | 1775 | int no_name = -1; /* don't save or restore the original file name */ |
1736 | int no_time = -1; /* don't save or restore the original file time */ | 1776 | int no_time = -1; /* don't save or restore the original file time */ |
1737 | int foreground; /* set if program run in foreground */ | 1777 | int foreground; /* set if program run in foreground */ |
1738 | char *progname; /* program name */ | 1778 | char *progname; /* program name */ |
1739 | static int method = DEFLATED;/* compression method */ | 1779 | static int method = DEFLATED; /* compression method */ |
1740 | static int exit_code = OK; /* program exit code */ | 1780 | static int exit_code = OK; /* program exit code */ |
1741 | int save_orig_name; /* set if original name must be saved */ | 1781 | int save_orig_name; /* set if original name must be saved */ |
1742 | int last_member; /* set for .zip and .Z files */ | 1782 | int last_member; /* set for .zip and .Z files */ |
1743 | int part_nb; /* number of parts in .gz file */ | 1783 | int part_nb; /* number of parts in .gz file */ |
1744 | long time_stamp; /* original time stamp (modification time) */ | 1784 | long time_stamp; /* original time stamp (modification time) */ |
1745 | long ifile_size; /* input file size, -1 for devices (debug only) */ | 1785 | long ifile_size; /* input file size, -1 for devices (debug only) */ |
1746 | char *env; /* contents of GZIP env variable */ | 1786 | char *env; /* contents of GZIP env variable */ |
1747 | char **args = NULL; /* argv pointer if GZIP env variable defined */ | 1787 | char **args = NULL; /* argv pointer if GZIP env variable defined */ |
1748 | char z_suffix[MAX_SUFFIX+1]; /* default suffix (can be set with --suffix) */ | 1788 | char z_suffix[MAX_SUFFIX + 1]; /* default suffix (can be set with --suffix) */ |
1749 | int z_len; /* strlen(z_suffix) */ | 1789 | int z_len; /* strlen(z_suffix) */ |
1750 | 1790 | ||
1751 | long bytes_in; /* number of input bytes */ | 1791 | long bytes_in; /* number of input bytes */ |
1752 | long bytes_out; /* number of output bytes */ | 1792 | long bytes_out; /* number of output bytes */ |
1753 | char ifname[MAX_PATH_LEN]; /* input file name */ | 1793 | char ifname[MAX_PATH_LEN]; /* input file name */ |
1754 | char ofname[MAX_PATH_LEN]; /* output file name */ | 1794 | char ofname[MAX_PATH_LEN]; /* output file name */ |
1755 | int remove_ofname = 0; /* remove output file on error */ | 1795 | int remove_ofname = 0; /* remove output file on error */ |
1756 | struct stat istat; /* status for input file */ | 1796 | struct stat istat; /* status for input file */ |
1757 | int ifd; /* input file descriptor */ | 1797 | int ifd; /* input file descriptor */ |
1758 | int ofd; /* output file descriptor */ | 1798 | int ofd; /* output file descriptor */ |
1759 | unsigned insize; /* valid bytes in inbuf */ | 1799 | unsigned insize; /* valid bytes in inbuf */ |
1760 | unsigned inptr; /* index of next byte to be processed in inbuf */ | 1800 | unsigned inptr; /* index of next byte to be processed in inbuf */ |
1761 | unsigned outcnt; /* bytes in output buffer */ | 1801 | unsigned outcnt; /* bytes in output buffer */ |
1762 | 1802 | ||
1763 | /* local functions */ | 1803 | /* local functions */ |
1764 | 1804 | ||
@@ -1768,148 +1808,148 @@ unsigned outcnt; /* bytes in output buffer */ | |||
1768 | // int main (argc, argv) | 1808 | // int main (argc, argv) |
1769 | // int argc; | 1809 | // int argc; |
1770 | // char **argv; | 1810 | // char **argv; |
1771 | int gzip_main(int argc, char ** argv) | 1811 | int gzip_main(int argc, char **argv) |
1772 | { | 1812 | { |
1773 | int result; | 1813 | int result; |
1774 | int inFileNum; | 1814 | int inFileNum; |
1775 | int outFileNum; | 1815 | int outFileNum; |
1776 | struct stat statBuf; | 1816 | struct stat statBuf; |
1777 | char* delFileName; | 1817 | char *delFileName; |
1778 | int tostdout = 0; | 1818 | int tostdout = 0; |
1779 | int fromstdin = 0; | 1819 | int fromstdin = 0; |
1780 | 1820 | ||
1781 | if (argc==1) | 1821 | if (argc == 1) |
1782 | usage(gzip_usage); | ||
1783 | |||
1784 | /* Parse any options */ | ||
1785 | while (--argc > 0 && **(++argv) == '-') { | ||
1786 | if (*((*argv)+1) == '\0') { | ||
1787 | fromstdin = 1; | ||
1788 | tostdout = 1; | ||
1789 | } | ||
1790 | while (*(++(*argv))) { | ||
1791 | switch (**argv) { | ||
1792 | case 'c': | ||
1793 | tostdout = 1; | ||
1794 | break; | ||
1795 | default: | ||
1796 | usage(gzip_usage); | 1822 | usage(gzip_usage); |
1797 | } | 1823 | |
1824 | /* Parse any options */ | ||
1825 | while (--argc > 0 && **(++argv) == '-') { | ||
1826 | if (*((*argv) + 1) == '\0') { | ||
1827 | fromstdin = 1; | ||
1828 | tostdout = 1; | ||
1829 | } | ||
1830 | while (*(++(*argv))) { | ||
1831 | switch (**argv) { | ||
1832 | case 'c': | ||
1833 | tostdout = 1; | ||
1834 | break; | ||
1835 | default: | ||
1836 | usage(gzip_usage); | ||
1837 | } | ||
1838 | } | ||
1798 | } | 1839 | } |
1799 | } | ||
1800 | 1840 | ||
1801 | foreground = signal(SIGINT, SIG_IGN) != SIG_IGN; | 1841 | foreground = signal(SIGINT, SIG_IGN) != SIG_IGN; |
1802 | if (foreground) { | 1842 | if (foreground) { |
1803 | (void) signal (SIGINT, (sig_type)abort_gzip); | 1843 | (void) signal(SIGINT, (sig_type) abort_gzip); |
1804 | } | 1844 | } |
1805 | #ifdef SIGTERM | 1845 | #ifdef SIGTERM |
1806 | if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { | 1846 | if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { |
1807 | (void) signal(SIGTERM, (sig_type)abort_gzip); | 1847 | (void) signal(SIGTERM, (sig_type) abort_gzip); |
1808 | } | 1848 | } |
1809 | #endif | 1849 | #endif |
1810 | #ifdef SIGHUP | 1850 | #ifdef SIGHUP |
1811 | if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { | 1851 | if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { |
1812 | (void) signal(SIGHUP, (sig_type)abort_gzip); | 1852 | (void) signal(SIGHUP, (sig_type) abort_gzip); |
1813 | } | 1853 | } |
1814 | #endif | 1854 | #endif |
1815 | 1855 | ||
1816 | strncpy(z_suffix, Z_SUFFIX, sizeof(z_suffix)-1); | 1856 | strncpy(z_suffix, Z_SUFFIX, sizeof(z_suffix) - 1); |
1817 | z_len = strlen(z_suffix); | 1857 | z_len = strlen(z_suffix); |
1818 | 1858 | ||
1819 | /* Allocate all global buffers (for DYN_ALLOC option) */ | 1859 | /* Allocate all global buffers (for DYN_ALLOC option) */ |
1820 | ALLOC(uch, inbuf, INBUFSIZ +INBUF_EXTRA); | 1860 | ALLOC(uch, inbuf, INBUFSIZ + INBUF_EXTRA); |
1821 | ALLOC(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA); | 1861 | ALLOC(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA); |
1822 | ALLOC(ush, d_buf, DIST_BUFSIZE); | 1862 | ALLOC(ush, d_buf, DIST_BUFSIZE); |
1823 | ALLOC(uch, window, 2L*WSIZE); | 1863 | ALLOC(uch, window, 2L * WSIZE); |
1824 | #ifndef MAXSEG_64K | 1864 | #ifndef MAXSEG_64K |
1825 | ALLOC(ush, tab_prefix, 1L<<BITS); | 1865 | ALLOC(ush, tab_prefix, 1L << BITS); |
1826 | #else | 1866 | #else |
1827 | ALLOC(ush, tab_prefix0, 1L<<(BITS-1)); | 1867 | ALLOC(ush, tab_prefix0, 1L << (BITS - 1)); |
1828 | ALLOC(ush, tab_prefix1, 1L<<(BITS-1)); | 1868 | ALLOC(ush, tab_prefix1, 1L << (BITS - 1)); |
1829 | #endif | 1869 | #endif |
1830 | 1870 | ||
1831 | if (fromstdin==1) { | 1871 | if (fromstdin == 1) { |
1832 | strcpy(ofname, "stdin"); | 1872 | strcpy(ofname, "stdin"); |
1833 | 1873 | ||
1834 | inFileNum=fileno(stdin); | 1874 | inFileNum = fileno(stdin); |
1835 | time_stamp = 0; /* time unknown by default */ | 1875 | time_stamp = 0; /* time unknown by default */ |
1836 | ifile_size = -1L; /* convention for unknown size */ | 1876 | ifile_size = -1L; /* convention for unknown size */ |
1837 | } else { | 1877 | } else { |
1838 | /* Open up the input file */ | 1878 | /* Open up the input file */ |
1839 | if (*argv=='\0') | 1879 | if (*argv == '\0') |
1840 | usage(gzip_usage); | 1880 | usage(gzip_usage); |
1841 | strncpy(ifname, *argv, MAX_PATH_LEN); | 1881 | strncpy(ifname, *argv, MAX_PATH_LEN); |
1842 | 1882 | ||
1843 | /* Open input fille */ | 1883 | /* Open input fille */ |
1844 | inFileNum=open( ifname, O_RDONLY); | 1884 | inFileNum = open(ifname, O_RDONLY); |
1845 | if (inFileNum < 0) { | 1885 | if (inFileNum < 0) { |
1846 | perror(ifname); | 1886 | perror(ifname); |
1847 | do_exit(WARNING); | 1887 | do_exit(WARNING); |
1848 | } | 1888 | } |
1849 | /* Get the time stamp on the input file. */ | 1889 | /* Get the time stamp on the input file. */ |
1850 | result = stat(ifname, &statBuf); | 1890 | result = stat(ifname, &statBuf); |
1851 | if (result < 0) { | 1891 | if (result < 0) { |
1852 | perror(ifname); | 1892 | perror(ifname); |
1853 | do_exit(WARNING); | 1893 | do_exit(WARNING); |
1894 | } | ||
1895 | time_stamp = statBuf.st_ctime; | ||
1896 | ifile_size = statBuf.st_size; | ||
1854 | } | 1897 | } |
1855 | time_stamp = statBuf.st_ctime; | ||
1856 | ifile_size = statBuf.st_size; | ||
1857 | } | ||
1858 | 1898 | ||
1859 | 1899 | ||
1860 | if (tostdout==1) { | 1900 | if (tostdout == 1) { |
1861 | /* And get to work */ | 1901 | /* And get to work */ |
1862 | strcpy(ofname, "stdout"); | 1902 | strcpy(ofname, "stdout"); |
1863 | outFileNum=fileno(stdout); | 1903 | outFileNum = fileno(stdout); |
1864 | SET_BINARY_MODE(fileno(stdout)); | 1904 | SET_BINARY_MODE(fileno(stdout)); |
1865 | 1905 | ||
1866 | clear_bufs(); /* clear input and output buffers */ | 1906 | clear_bufs(); /* clear input and output buffers */ |
1867 | part_nb = 0; | 1907 | part_nb = 0; |
1868 | 1908 | ||
1869 | /* Actually do the compression/decompression. */ | 1909 | /* Actually do the compression/decompression. */ |
1870 | zip(inFileNum, outFileNum); | 1910 | zip(inFileNum, outFileNum); |
1871 | 1911 | ||
1872 | } else { | 1912 | } else { |
1873 | 1913 | ||
1874 | /* And get to work */ | 1914 | /* And get to work */ |
1875 | strncpy(ofname, ifname, MAX_PATH_LEN-4); | 1915 | strncpy(ofname, ifname, MAX_PATH_LEN - 4); |
1876 | strcat(ofname, ".gz"); | 1916 | strcat(ofname, ".gz"); |
1877 | 1917 | ||
1878 | 1918 | ||
1879 | /* Open output fille */ | 1919 | /* Open output fille */ |
1880 | #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) | 1920 | #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) |
1881 | outFileNum=open( ofname, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW); | 1921 | outFileNum = open(ofname, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW); |
1882 | #else | 1922 | #else |
1883 | outFileNum=open( ofname, O_RDWR|O_CREAT|O_EXCL); | 1923 | outFileNum = open(ofname, O_RDWR | O_CREAT | O_EXCL); |
1884 | #endif | 1924 | #endif |
1885 | if (outFileNum < 0) { | 1925 | if (outFileNum < 0) { |
1886 | perror(ofname); | 1926 | perror(ofname); |
1887 | do_exit(WARNING); | 1927 | do_exit(WARNING); |
1888 | } | 1928 | } |
1889 | SET_BINARY_MODE(outFileNum); | 1929 | SET_BINARY_MODE(outFileNum); |
1890 | /* Set permissions on the file */ | 1930 | /* Set permissions on the file */ |
1891 | fchmod(outFileNum, statBuf.st_mode); | 1931 | fchmod(outFileNum, statBuf.st_mode); |
1892 | 1932 | ||
1893 | clear_bufs(); /* clear input and output buffers */ | 1933 | clear_bufs(); /* clear input and output buffers */ |
1894 | part_nb = 0; | 1934 | part_nb = 0; |
1895 | 1935 | ||
1896 | /* Actually do the compression/decompression. */ | 1936 | /* Actually do the compression/decompression. */ |
1897 | result=zip(inFileNum, outFileNum); | 1937 | result = zip(inFileNum, outFileNum); |
1898 | close( outFileNum); | 1938 | close(outFileNum); |
1899 | close( inFileNum); | 1939 | close(inFileNum); |
1900 | /* Delete the original file */ | 1940 | /* Delete the original file */ |
1901 | if (result == OK) | 1941 | if (result == OK) |
1902 | delFileName=ifname; | 1942 | delFileName = ifname; |
1903 | else | 1943 | else |
1904 | delFileName=ofname; | 1944 | delFileName = ofname; |
1905 | 1945 | ||
1906 | if (unlink (delFileName) < 0) { | 1946 | if (unlink(delFileName) < 0) { |
1907 | perror (delFileName); | 1947 | perror(delFileName); |
1908 | exit( FALSE); | 1948 | exit(FALSE); |
1949 | } | ||
1909 | } | 1950 | } |
1910 | } | ||
1911 | 1951 | ||
1912 | do_exit(exit_code); | 1952 | do_exit(exit_code); |
1913 | } | 1953 | } |
1914 | 1954 | ||
1915 | /* trees.c -- output deflated data using Huffman coding | 1955 | /* trees.c -- output deflated data using Huffman coding |
@@ -1998,14 +2038,16 @@ int gzip_main(int argc, char ** argv) | |||
1998 | /* number of codes used to transfer the bit lengths */ | 2038 | /* number of codes used to transfer the bit lengths */ |
1999 | 2039 | ||
2000 | 2040 | ||
2001 | local int near extra_lbits[LENGTH_CODES] /* extra bits for each length code */ | 2041 | local int near extra_lbits[LENGTH_CODES] /* extra bits for each length code */ |
2002 | = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; | 2042 | = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, |
2043 | 4, 4, 5, 5, 5, 5, 0 }; | ||
2003 | 2044 | ||
2004 | local int near extra_dbits[D_CODES] /* extra bits for each distance code */ | 2045 | local int near extra_dbits[D_CODES] /* extra bits for each distance code */ |
2005 | = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; | 2046 | = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, |
2047 | 10, 10, 11, 11, 12, 12, 13, 13 }; | ||
2006 | 2048 | ||
2007 | local int near extra_blbits[BL_CODES]/* extra bits for each bit length code */ | 2049 | local int near extra_blbits[BL_CODES] /* extra bits for each bit length code */ |
2008 | = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; | 2050 | = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 }; |
2009 | 2051 | ||
2010 | #define STORED_BLOCK 0 | 2052 | #define STORED_BLOCK 0 |
2011 | #define STATIC_TREES 1 | 2053 | #define STATIC_TREES 1 |
@@ -2047,32 +2089,24 @@ local int near extra_blbits[BL_CODES]/* extra bits for each bit length code */ | |||
2047 | * if we rely on DIST_BUFSIZE == LIT_BUFSIZE. | 2089 | * if we rely on DIST_BUFSIZE == LIT_BUFSIZE. |
2048 | */ | 2090 | */ |
2049 | #if LIT_BUFSIZE > INBUFSIZ | 2091 | #if LIT_BUFSIZE > INBUFSIZ |
2050 | error cannot overlay l_buf and inbuf | 2092 | error cannot overlay l_buf and inbuf |
2051 | #endif | 2093 | #endif |
2052 | |||
2053 | #define REP_3_6 16 | 2094 | #define REP_3_6 16 |
2054 | /* repeat previous bit length 3-6 times (2 bits of repeat count) */ | 2095 | /* repeat previous bit length 3-6 times (2 bits of repeat count) */ |
2055 | |||
2056 | #define REPZ_3_10 17 | 2096 | #define REPZ_3_10 17 |
2057 | /* repeat a zero length 3-10 times (3 bits of repeat count) */ | 2097 | /* repeat a zero length 3-10 times (3 bits of repeat count) */ |
2058 | |||
2059 | #define REPZ_11_138 18 | 2098 | #define REPZ_11_138 18 |
2060 | /* repeat a zero length 11-138 times (7 bits of repeat count) */ | 2099 | /* repeat a zero length 11-138 times (7 bits of repeat count) *//* =========================================================================== |
2061 | |||
2062 | /* =========================================================================== | ||
2063 | * Local data | 2100 | * Local data |
2064 | */ | 2101 | *//* Data structure describing a single value and its code string. */ typedef struct ct_data { |
2065 | 2102 | union { | |
2066 | /* Data structure describing a single value and its code string. */ | 2103 | ush freq; /* frequency count */ |
2067 | typedef struct ct_data { | 2104 | ush code; /* bit string */ |
2068 | union { | 2105 | } fc; |
2069 | ush freq; /* frequency count */ | 2106 | union { |
2070 | ush code; /* bit string */ | 2107 | ush dad; /* father node in Huffman tree */ |
2071 | } fc; | 2108 | ush len; /* length of bit string */ |
2072 | union { | 2109 | } dl; |
2073 | ush dad; /* father node in Huffman tree */ | ||
2074 | ush len; /* length of bit string */ | ||
2075 | } dl; | ||
2076 | } ct_data; | 2110 | } ct_data; |
2077 | 2111 | ||
2078 | #define Freq fc.freq | 2112 | #define Freq fc.freq |
@@ -2083,10 +2117,11 @@ typedef struct ct_data { | |||
2083 | #define HEAP_SIZE (2*L_CODES+1) | 2117 | #define HEAP_SIZE (2*L_CODES+1) |
2084 | /* maximum heap size */ | 2118 | /* maximum heap size */ |
2085 | 2119 | ||
2086 | local ct_data near dyn_ltree[HEAP_SIZE]; /* literal and length tree */ | 2120 | local ct_data near dyn_ltree[HEAP_SIZE]; /* literal and length tree */ |
2087 | local ct_data near dyn_dtree[2*D_CODES+1]; /* distance tree */ | 2121 | local ct_data near dyn_dtree[2 * D_CODES + 1]; /* distance tree */ |
2122 | |||
2123 | local ct_data near static_ltree[L_CODES + 2]; | ||
2088 | 2124 | ||
2089 | local ct_data near static_ltree[L_CODES+2]; | ||
2090 | /* The static literal tree. Since the bit lengths are imposed, there is no | 2125 | /* The static literal tree. Since the bit lengths are imposed, there is no |
2091 | * need for the L_CODES extra codes used during heap construction. However | 2126 | * need for the L_CODES extra codes used during heap construction. However |
2092 | * The codes 286 and 287 are needed to build a canonical tree (see ct_init | 2127 | * The codes 286 and 287 are needed to build a canonical tree (see ct_init |
@@ -2094,65 +2129,77 @@ local ct_data near static_ltree[L_CODES+2]; | |||
2094 | */ | 2129 | */ |
2095 | 2130 | ||
2096 | local ct_data near static_dtree[D_CODES]; | 2131 | local ct_data near static_dtree[D_CODES]; |
2132 | |||
2097 | /* The static distance tree. (Actually a trivial tree since all codes use | 2133 | /* The static distance tree. (Actually a trivial tree since all codes use |
2098 | * 5 bits.) | 2134 | * 5 bits.) |
2099 | */ | 2135 | */ |
2100 | 2136 | ||
2101 | local ct_data near bl_tree[2*BL_CODES+1]; | 2137 | local ct_data near bl_tree[2 * BL_CODES + 1]; |
2138 | |||
2102 | /* Huffman tree for the bit lengths */ | 2139 | /* Huffman tree for the bit lengths */ |
2103 | 2140 | ||
2104 | typedef struct tree_desc { | 2141 | typedef struct tree_desc { |
2105 | ct_data near *dyn_tree; /* the dynamic tree */ | 2142 | ct_data near *dyn_tree; /* the dynamic tree */ |
2106 | ct_data near *static_tree; /* corresponding static tree or NULL */ | 2143 | ct_data near *static_tree; /* corresponding static tree or NULL */ |
2107 | int near *extra_bits; /* extra bits for each code or NULL */ | 2144 | int near *extra_bits; /* extra bits for each code or NULL */ |
2108 | int extra_base; /* base index for extra_bits */ | 2145 | int extra_base; /* base index for extra_bits */ |
2109 | int elems; /* max number of elements in the tree */ | 2146 | int elems; /* max number of elements in the tree */ |
2110 | int max_length; /* max bit length for the codes */ | 2147 | int max_length; /* max bit length for the codes */ |
2111 | int max_code; /* largest code with non zero frequency */ | 2148 | int max_code; /* largest code with non zero frequency */ |
2112 | } tree_desc; | 2149 | } tree_desc; |
2113 | 2150 | ||
2114 | local tree_desc near l_desc = | 2151 | local tree_desc near l_desc = |
2115 | {dyn_ltree, static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS, 0}; | 2152 | { dyn_ltree, static_ltree, extra_lbits, LITERALS + 1, L_CODES, |
2153 | MAX_BITS, 0 }; | ||
2116 | 2154 | ||
2117 | local tree_desc near d_desc = | 2155 | local tree_desc near d_desc = |
2118 | {dyn_dtree, static_dtree, extra_dbits, 0, D_CODES, MAX_BITS, 0}; | 2156 | { dyn_dtree, static_dtree, extra_dbits, 0, D_CODES, MAX_BITS, 0 }; |
2119 | 2157 | ||
2120 | local tree_desc near bl_desc = | 2158 | local tree_desc near bl_desc = |
2121 | {bl_tree, (ct_data near *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS, 0}; | 2159 | { bl_tree, (ct_data near *) 0, extra_blbits, 0, BL_CODES, MAX_BL_BITS, |
2160 | 0 }; | ||
2122 | 2161 | ||
2123 | 2162 | ||
2124 | local ush near bl_count[MAX_BITS+1]; | 2163 | local ush near bl_count[MAX_BITS + 1]; |
2164 | |||
2125 | /* number of codes at each bit length for an optimal tree */ | 2165 | /* number of codes at each bit length for an optimal tree */ |
2126 | 2166 | ||
2127 | local uch near bl_order[BL_CODES] | 2167 | local uch near bl_order[BL_CODES] |
2128 | = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; | 2168 | = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; |
2169 | |||
2129 | /* The lengths of the bit length codes are sent in order of decreasing | 2170 | /* The lengths of the bit length codes are sent in order of decreasing |
2130 | * probability, to avoid transmitting the lengths for unused bit length codes. | 2171 | * probability, to avoid transmitting the lengths for unused bit length codes. |
2131 | */ | 2172 | */ |
2132 | 2173 | ||
2133 | local int near heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ | 2174 | local int near heap[2 * L_CODES + 1]; /* heap used to build the Huffman trees */ |
2134 | local int heap_len; /* number of elements in the heap */ | 2175 | local int heap_len; /* number of elements in the heap */ |
2135 | local int heap_max; /* element of largest frequency */ | 2176 | local int heap_max; /* element of largest frequency */ |
2177 | |||
2136 | /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. | 2178 | /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. |
2137 | * The same heap array is used to build all trees. | 2179 | * The same heap array is used to build all trees. |
2138 | */ | 2180 | */ |
2139 | 2181 | ||
2140 | local uch near depth[2*L_CODES+1]; | 2182 | local uch near depth[2 * L_CODES + 1]; |
2183 | |||
2141 | /* Depth of each subtree used as tie breaker for trees of equal frequency */ | 2184 | /* Depth of each subtree used as tie breaker for trees of equal frequency */ |
2142 | 2185 | ||
2143 | local uch length_code[MAX_MATCH-MIN_MATCH+1]; | 2186 | local uch length_code[MAX_MATCH - MIN_MATCH + 1]; |
2187 | |||
2144 | /* length code for each normalized match length (0 == MIN_MATCH) */ | 2188 | /* length code for each normalized match length (0 == MIN_MATCH) */ |
2145 | 2189 | ||
2146 | local uch dist_code[512]; | 2190 | local uch dist_code[512]; |
2191 | |||
2147 | /* distance codes. The first 256 values correspond to the distances | 2192 | /* distance codes. The first 256 values correspond to the distances |
2148 | * 3 .. 258, the last 256 values correspond to the top 8 bits of | 2193 | * 3 .. 258, the last 256 values correspond to the top 8 bits of |
2149 | * the 15 bit distances. | 2194 | * the 15 bit distances. |
2150 | */ | 2195 | */ |
2151 | 2196 | ||
2152 | local int near base_length[LENGTH_CODES]; | 2197 | local int near base_length[LENGTH_CODES]; |
2198 | |||
2153 | /* First normalized length for each code (0 = MIN_MATCH) */ | 2199 | /* First normalized length for each code (0 = MIN_MATCH) */ |
2154 | 2200 | ||
2155 | local int near base_dist[D_CODES]; | 2201 | local int near base_dist[D_CODES]; |
2202 | |||
2156 | /* First normalized distance for each code (0 = distance of 1) */ | 2203 | /* First normalized distance for each code (0 = distance of 1) */ |
2157 | 2204 | ||
2158 | #define l_buf inbuf | 2205 | #define l_buf inbuf |
@@ -2160,62 +2207,65 @@ local int near base_dist[D_CODES]; | |||
2160 | 2207 | ||
2161 | /* DECLARE(ush, d_buf, DIST_BUFSIZE); buffer for distances */ | 2208 | /* DECLARE(ush, d_buf, DIST_BUFSIZE); buffer for distances */ |
2162 | 2209 | ||
2163 | local uch near flag_buf[(LIT_BUFSIZE/8)]; | 2210 | local uch near flag_buf[(LIT_BUFSIZE / 8)]; |
2211 | |||
2164 | /* flag_buf is a bit array distinguishing literals from lengths in | 2212 | /* flag_buf is a bit array distinguishing literals from lengths in |
2165 | * l_buf, thus indicating the presence or absence of a distance. | 2213 | * l_buf, thus indicating the presence or absence of a distance. |
2166 | */ | 2214 | */ |
2167 | 2215 | ||
2168 | local unsigned last_lit; /* running index in l_buf */ | 2216 | local unsigned last_lit; /* running index in l_buf */ |
2169 | local unsigned last_dist; /* running index in d_buf */ | 2217 | local unsigned last_dist; /* running index in d_buf */ |
2170 | local unsigned last_flags; /* running index in flag_buf */ | 2218 | local unsigned last_flags; /* running index in flag_buf */ |
2171 | local uch flags; /* current flags not yet saved in flag_buf */ | 2219 | local uch flags; /* current flags not yet saved in flag_buf */ |
2172 | local uch flag_bit; /* current bit used in flags */ | 2220 | local uch flag_bit; /* current bit used in flags */ |
2221 | |||
2173 | /* bits are filled in flags starting at bit 0 (least significant). | 2222 | /* bits are filled in flags starting at bit 0 (least significant). |
2174 | * Note: these flags are overkill in the current code since we don't | 2223 | * Note: these flags are overkill in the current code since we don't |
2175 | * take advantage of DIST_BUFSIZE == LIT_BUFSIZE. | 2224 | * take advantage of DIST_BUFSIZE == LIT_BUFSIZE. |
2176 | */ | 2225 | */ |
2177 | 2226 | ||
2178 | local ulg opt_len; /* bit length of current block with optimal trees */ | 2227 | local ulg opt_len; /* bit length of current block with optimal trees */ |
2179 | local ulg static_len; /* bit length of current block with static trees */ | 2228 | local ulg static_len; /* bit length of current block with static trees */ |
2229 | |||
2230 | local ulg compressed_len; /* total bit length of compressed file */ | ||
2180 | 2231 | ||
2181 | local ulg compressed_len; /* total bit length of compressed file */ | 2232 | local ulg input_len; /* total byte length of input file */ |
2182 | 2233 | ||
2183 | local ulg input_len; /* total byte length of input file */ | ||
2184 | /* input_len is for debugging only since we can get it by other means. */ | 2234 | /* input_len is for debugging only since we can get it by other means. */ |
2185 | 2235 | ||
2186 | ush *file_type; /* pointer to UNKNOWN, BINARY or ASCII */ | 2236 | ush *file_type; /* pointer to UNKNOWN, BINARY or ASCII */ |
2187 | int *file_method; /* pointer to DEFLATE or STORE */ | 2237 | int *file_method; /* pointer to DEFLATE or STORE */ |
2188 | 2238 | ||
2189 | #ifdef DEBUG | 2239 | #ifdef DEBUG |
2190 | extern ulg bits_sent; /* bit length of the compressed data */ | 2240 | extern ulg bits_sent; /* bit length of the compressed data */ |
2191 | extern long isize; /* byte length of input file */ | 2241 | extern long isize; /* byte length of input file */ |
2192 | #endif | 2242 | #endif |
2193 | 2243 | ||
2194 | extern long block_start; /* window offset of current block */ | 2244 | extern long block_start; /* window offset of current block */ |
2195 | extern unsigned near strstart; /* window offset of current string */ | 2245 | extern unsigned near strstart; /* window offset of current string */ |
2196 | 2246 | ||
2197 | /* =========================================================================== | 2247 | /* =========================================================================== |
2198 | * Local (static) routines in this file. | 2248 | * Local (static) routines in this file. |
2199 | */ | 2249 | */ |
2200 | 2250 | ||
2201 | local void init_block OF((void)); | 2251 | local void init_block OF((void)); |
2202 | local void pqdownheap OF((ct_data near *tree, int k)); | 2252 | local void pqdownheap OF((ct_data near * tree, int k)); |
2203 | local void gen_bitlen OF((tree_desc near *desc)); | 2253 | local void gen_bitlen OF((tree_desc near * desc)); |
2204 | local void gen_codes OF((ct_data near *tree, int max_code)); | 2254 | local void gen_codes OF((ct_data near * tree, int max_code)); |
2205 | local void build_tree OF((tree_desc near *desc)); | 2255 | local void build_tree OF((tree_desc near * desc)); |
2206 | local void scan_tree OF((ct_data near *tree, int max_code)); | 2256 | local void scan_tree OF((ct_data near * tree, int max_code)); |
2207 | local void send_tree OF((ct_data near *tree, int max_code)); | 2257 | local void send_tree OF((ct_data near * tree, int max_code)); |
2208 | local int build_bl_tree OF((void)); | 2258 | local int build_bl_tree OF((void)); |
2209 | local void send_all_trees OF((int lcodes, int dcodes, int blcodes)); | 2259 | local void send_all_trees OF((int lcodes, int dcodes, int blcodes)); |
2210 | local void compress_block OF((ct_data near *ltree, ct_data near *dtree)); | 2260 | local void compress_block OF((ct_data near * ltree, ct_data near * dtree)); |
2211 | local void set_file_type OF((void)); | 2261 | local void set_file_type OF((void)); |
2212 | 2262 | ||
2213 | 2263 | ||
2214 | #ifndef DEBUG | 2264 | #ifndef DEBUG |
2215 | # define send_code(c, tree) send_bits(tree[c].Code, tree[c].Len) | 2265 | # define send_code(c, tree) send_bits(tree[c].Code, tree[c].Len) |
2216 | /* Send a code of the given tree. c and tree must not have side effects */ | 2266 | /* Send a code of the given tree. c and tree must not have side effects */ |
2217 | 2267 | ||
2218 | #else /* DEBUG */ | 2268 | #else /* DEBUG */ |
2219 | # define send_code(c, tree) \ | 2269 | # define send_code(c, tree) \ |
2220 | { if (verbose>1) fprintf(stderr,"\ncd %3d ",(c)); \ | 2270 | { if (verbose>1) fprintf(stderr,"\ncd %3d ",(c)); \ |
2221 | send_bits(tree[c].Code, tree[c].Len); } | 2271 | send_bits(tree[c].Code, tree[c].Len); } |
@@ -2237,75 +2287,81 @@ local void set_file_type OF((void)); | |||
2237 | * (DEFLATE/STORE). | 2287 | * (DEFLATE/STORE). |
2238 | */ | 2288 | */ |
2239 | void ct_init(attr, methodp) | 2289 | void ct_init(attr, methodp) |
2240 | ush *attr; /* pointer to internal file attribute */ | 2290 | ush *attr; /* pointer to internal file attribute */ |
2241 | int *methodp; /* pointer to compression method */ | 2291 | int *methodp; /* pointer to compression method */ |
2242 | { | 2292 | { |
2243 | int n; /* iterates over tree elements */ | 2293 | int n; /* iterates over tree elements */ |
2244 | int bits; /* bit counter */ | 2294 | int bits; /* bit counter */ |
2245 | int length; /* length value */ | 2295 | int length; /* length value */ |
2246 | int code; /* code value */ | 2296 | int code; /* code value */ |
2247 | int dist; /* distance index */ | 2297 | int dist; /* distance index */ |
2248 | 2298 | ||
2249 | file_type = attr; | 2299 | file_type = attr; |
2250 | file_method = methodp; | 2300 | file_method = methodp; |
2251 | compressed_len = input_len = 0L; | 2301 | compressed_len = input_len = 0L; |
2252 | 2302 | ||
2253 | if (static_dtree[0].Len != 0) return; /* ct_init already called */ | 2303 | if (static_dtree[0].Len != 0) |
2254 | 2304 | return; /* ct_init already called */ | |
2255 | /* Initialize the mapping length (0..255) -> length code (0..28) */ | 2305 | |
2256 | length = 0; | 2306 | /* Initialize the mapping length (0..255) -> length code (0..28) */ |
2257 | for (code = 0; code < LENGTH_CODES-1; code++) { | 2307 | length = 0; |
2258 | base_length[code] = length; | 2308 | for (code = 0; code < LENGTH_CODES - 1; code++) { |
2259 | for (n = 0; n < (1<<extra_lbits[code]); n++) { | 2309 | base_length[code] = length; |
2260 | length_code[length++] = (uch)code; | 2310 | for (n = 0; n < (1 << extra_lbits[code]); n++) { |
2261 | } | 2311 | length_code[length++] = (uch) code; |
2262 | } | 2312 | } |
2263 | Assert (length == 256, "ct_init: length != 256"); | 2313 | } |
2264 | /* Note that the length 255 (match length 258) can be represented | 2314 | Assert(length == 256, "ct_init: length != 256"); |
2265 | * in two different ways: code 284 + 5 bits or code 285, so we | 2315 | /* Note that the length 255 (match length 258) can be represented |
2266 | * overwrite length_code[255] to use the best encoding: | 2316 | * in two different ways: code 284 + 5 bits or code 285, so we |
2267 | */ | 2317 | * overwrite length_code[255] to use the best encoding: |
2268 | length_code[length-1] = (uch)code; | 2318 | */ |
2269 | 2319 | length_code[length - 1] = (uch) code; | |
2270 | /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ | 2320 | |
2271 | dist = 0; | 2321 | /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ |
2272 | for (code = 0 ; code < 16; code++) { | 2322 | dist = 0; |
2273 | base_dist[code] = dist; | 2323 | for (code = 0; code < 16; code++) { |
2274 | for (n = 0; n < (1<<extra_dbits[code]); n++) { | 2324 | base_dist[code] = dist; |
2275 | dist_code[dist++] = (uch)code; | 2325 | for (n = 0; n < (1 << extra_dbits[code]); n++) { |
2276 | } | 2326 | dist_code[dist++] = (uch) code; |
2277 | } | 2327 | } |
2278 | Assert (dist == 256, "ct_init: dist != 256"); | 2328 | } |
2279 | dist >>= 7; /* from now on, all distances are divided by 128 */ | 2329 | Assert(dist == 256, "ct_init: dist != 256"); |
2280 | for ( ; code < D_CODES; code++) { | 2330 | dist >>= 7; /* from now on, all distances are divided by 128 */ |
2281 | base_dist[code] = dist << 7; | 2331 | for (; code < D_CODES; code++) { |
2282 | for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { | 2332 | base_dist[code] = dist << 7; |
2283 | dist_code[256 + dist++] = (uch)code; | 2333 | for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { |
2284 | } | 2334 | dist_code[256 + dist++] = (uch) code; |
2285 | } | 2335 | } |
2286 | Assert (dist == 256, "ct_init: 256+dist != 512"); | 2336 | } |
2287 | 2337 | Assert(dist == 256, "ct_init: 256+dist != 512"); | |
2288 | /* Construct the codes of the static literal tree */ | 2338 | |
2289 | for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; | 2339 | /* Construct the codes of the static literal tree */ |
2290 | n = 0; | 2340 | for (bits = 0; bits <= MAX_BITS; bits++) |
2291 | while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; | 2341 | bl_count[bits] = 0; |
2292 | while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; | 2342 | n = 0; |
2293 | while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; | 2343 | while (n <= 143) |
2294 | while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; | 2344 | static_ltree[n++].Len = 8, bl_count[8]++; |
2295 | /* Codes 286 and 287 do not exist, but we must include them in the | 2345 | while (n <= 255) |
2296 | * tree construction to get a canonical Huffman tree (longest code | 2346 | static_ltree[n++].Len = 9, bl_count[9]++; |
2297 | * all ones) | 2347 | while (n <= 279) |
2298 | */ | 2348 | static_ltree[n++].Len = 7, bl_count[7]++; |
2299 | gen_codes((ct_data near *)static_ltree, L_CODES+1); | 2349 | while (n <= 287) |
2300 | 2350 | static_ltree[n++].Len = 8, bl_count[8]++; | |
2301 | /* The static distance tree is trivial: */ | 2351 | /* Codes 286 and 287 do not exist, but we must include them in the |
2302 | for (n = 0; n < D_CODES; n++) { | 2352 | * tree construction to get a canonical Huffman tree (longest code |
2303 | static_dtree[n].Len = 5; | 2353 | * all ones) |
2304 | static_dtree[n].Code = bi_reverse(n, 5); | 2354 | */ |
2305 | } | 2355 | gen_codes((ct_data near *) static_ltree, L_CODES + 1); |
2306 | 2356 | ||
2307 | /* Initialize the first block of the first file: */ | 2357 | /* The static distance tree is trivial: */ |
2308 | init_block(); | 2358 | for (n = 0; n < D_CODES; n++) { |
2359 | static_dtree[n].Len = 5; | ||
2360 | static_dtree[n].Code = bi_reverse(n, 5); | ||
2361 | } | ||
2362 | |||
2363 | /* Initialize the first block of the first file: */ | ||
2364 | init_block(); | ||
2309 | } | 2365 | } |
2310 | 2366 | ||
2311 | /* =========================================================================== | 2367 | /* =========================================================================== |
@@ -2313,17 +2369,21 @@ void ct_init(attr, methodp) | |||
2313 | */ | 2369 | */ |
2314 | local void init_block() | 2370 | local void init_block() |
2315 | { | 2371 | { |
2316 | int n; /* iterates over tree elements */ | 2372 | int n; /* iterates over tree elements */ |
2317 | 2373 | ||
2318 | /* Initialize the trees. */ | 2374 | /* Initialize the trees. */ |
2319 | for (n = 0; n < L_CODES; n++) dyn_ltree[n].Freq = 0; | 2375 | for (n = 0; n < L_CODES; n++) |
2320 | for (n = 0; n < D_CODES; n++) dyn_dtree[n].Freq = 0; | 2376 | dyn_ltree[n].Freq = 0; |
2321 | for (n = 0; n < BL_CODES; n++) bl_tree[n].Freq = 0; | 2377 | for (n = 0; n < D_CODES; n++) |
2322 | 2378 | dyn_dtree[n].Freq = 0; | |
2323 | dyn_ltree[END_BLOCK].Freq = 1; | 2379 | for (n = 0; n < BL_CODES; n++) |
2324 | opt_len = static_len = 0L; | 2380 | bl_tree[n].Freq = 0; |
2325 | last_lit = last_dist = last_flags = 0; | 2381 | |
2326 | flags = 0; flag_bit = 1; | 2382 | dyn_ltree[END_BLOCK].Freq = 1; |
2383 | opt_len = static_len = 0L; | ||
2384 | last_lit = last_dist = last_flags = 0; | ||
2385 | flags = 0; | ||
2386 | flag_bit = 1; | ||
2327 | } | 2387 | } |
2328 | 2388 | ||
2329 | #define SMALLEST 1 | 2389 | #define SMALLEST 1 |
@@ -2356,25 +2416,29 @@ local void init_block() | |||
2356 | * two sons). | 2416 | * two sons). |
2357 | */ | 2417 | */ |
2358 | local void pqdownheap(tree, k) | 2418 | local void pqdownheap(tree, k) |
2359 | ct_data near *tree; /* the tree to restore */ | 2419 | ct_data near *tree; /* the tree to restore */ |
2360 | int k; /* node to move down */ | 2420 | int k; /* node to move down */ |
2361 | { | 2421 | { |
2362 | int v = heap[k]; | 2422 | int v = heap[k]; |
2363 | int j = k << 1; /* left son of k */ | 2423 | int j = k << 1; /* left son of k */ |
2364 | while (j <= heap_len) { | 2424 | |
2365 | /* Set j to the smallest of the two sons: */ | 2425 | while (j <= heap_len) { |
2366 | if (j < heap_len && smaller(tree, heap[j+1], heap[j])) j++; | 2426 | /* Set j to the smallest of the two sons: */ |
2367 | 2427 | if (j < heap_len && smaller(tree, heap[j + 1], heap[j])) | |
2368 | /* Exit if v is smaller than both sons */ | 2428 | j++; |
2369 | if (smaller(tree, v, heap[j])) break; | 2429 | |
2370 | 2430 | /* Exit if v is smaller than both sons */ | |
2371 | /* Exchange v with the smallest son */ | 2431 | if (smaller(tree, v, heap[j])) |
2372 | heap[k] = heap[j]; k = j; | 2432 | break; |
2373 | 2433 | ||
2374 | /* And continue down the tree, setting j to the left son of k */ | 2434 | /* Exchange v with the smallest son */ |
2375 | j <<= 1; | 2435 | heap[k] = heap[j]; |
2376 | } | 2436 | k = j; |
2377 | heap[k] = v; | 2437 | |
2438 | /* And continue down the tree, setting j to the left son of k */ | ||
2439 | j <<= 1; | ||
2440 | } | ||
2441 | heap[k] = v; | ||
2378 | } | 2442 | } |
2379 | 2443 | ||
2380 | /* =========================================================================== | 2444 | /* =========================================================================== |
@@ -2388,80 +2452,93 @@ local void pqdownheap(tree, k) | |||
2388 | * not null. | 2452 | * not null. |
2389 | */ | 2453 | */ |
2390 | local void gen_bitlen(desc) | 2454 | local void gen_bitlen(desc) |
2391 | tree_desc near *desc; /* the tree descriptor */ | 2455 | tree_desc near *desc; /* the tree descriptor */ |
2392 | { | 2456 | { |
2393 | ct_data near *tree = desc->dyn_tree; | 2457 | ct_data near *tree = desc->dyn_tree; |
2394 | int near *extra = desc->extra_bits; | 2458 | int near *extra = desc->extra_bits; |
2395 | int base = desc->extra_base; | 2459 | int base = desc->extra_base; |
2396 | int max_code = desc->max_code; | 2460 | int max_code = desc->max_code; |
2397 | int max_length = desc->max_length; | 2461 | int max_length = desc->max_length; |
2398 | ct_data near *stree = desc->static_tree; | 2462 | ct_data near *stree = desc->static_tree; |
2399 | int h; /* heap index */ | 2463 | int h; /* heap index */ |
2400 | int n, m; /* iterate over the tree elements */ | 2464 | int n, m; /* iterate over the tree elements */ |
2401 | int bits; /* bit length */ | 2465 | int bits; /* bit length */ |
2402 | int xbits; /* extra bits */ | 2466 | int xbits; /* extra bits */ |
2403 | ush f; /* frequency */ | 2467 | ush f; /* frequency */ |
2404 | int overflow = 0; /* number of elements with bit length too large */ | 2468 | int overflow = 0; /* number of elements with bit length too large */ |
2405 | 2469 | ||
2406 | for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; | 2470 | for (bits = 0; bits <= MAX_BITS; bits++) |
2407 | 2471 | bl_count[bits] = 0; | |
2408 | /* In a first pass, compute the optimal bit lengths (which may | 2472 | |
2409 | * overflow in the case of the bit length tree). | 2473 | /* In a first pass, compute the optimal bit lengths (which may |
2410 | */ | 2474 | * overflow in the case of the bit length tree). |
2411 | tree[heap[heap_max]].Len = 0; /* root of the heap */ | 2475 | */ |
2412 | 2476 | tree[heap[heap_max]].Len = 0; /* root of the heap */ | |
2413 | for (h = heap_max+1; h < HEAP_SIZE; h++) { | 2477 | |
2414 | n = heap[h]; | 2478 | for (h = heap_max + 1; h < HEAP_SIZE; h++) { |
2415 | bits = tree[tree[n].Dad].Len + 1; | 2479 | n = heap[h]; |
2416 | if (bits > max_length) bits = max_length, overflow++; | 2480 | bits = tree[tree[n].Dad].Len + 1; |
2417 | tree[n].Len = (ush)bits; | 2481 | if (bits > max_length) |
2418 | /* We overwrite tree[n].Dad which is no longer needed */ | 2482 | bits = max_length, overflow++; |
2419 | 2483 | tree[n].Len = (ush) bits; | |
2420 | if (n > max_code) continue; /* not a leaf node */ | 2484 | /* We overwrite tree[n].Dad which is no longer needed */ |
2421 | 2485 | ||
2422 | bl_count[bits]++; | 2486 | if (n > max_code) |
2423 | xbits = 0; | 2487 | continue; /* not a leaf node */ |
2424 | if (n >= base) xbits = extra[n-base]; | 2488 | |
2425 | f = tree[n].Freq; | 2489 | bl_count[bits]++; |
2426 | opt_len += (ulg)f * (bits + xbits); | 2490 | xbits = 0; |
2427 | if (stree) static_len += (ulg)f * (stree[n].Len + xbits); | 2491 | if (n >= base) |
2428 | } | 2492 | xbits = extra[n - base]; |
2429 | if (overflow == 0) return; | 2493 | f = tree[n].Freq; |
2430 | 2494 | opt_len += (ulg) f *(bits + xbits); | |
2431 | Trace((stderr,"\nbit length overflow\n")); | 2495 | |
2432 | /* This happens for example on obj2 and pic of the Calgary corpus */ | 2496 | if (stree) |
2433 | 2497 | static_len += (ulg) f *(stree[n].Len + xbits); | |
2434 | /* Find the first bit length which could increase: */ | 2498 | } |
2435 | do { | 2499 | if (overflow == 0) |
2436 | bits = max_length-1; | 2500 | return; |
2437 | while (bl_count[bits] == 0) bits--; | 2501 | |
2438 | bl_count[bits]--; /* move one leaf down the tree */ | 2502 | Trace((stderr, "\nbit length overflow\n")); |
2439 | bl_count[bits+1] += 2; /* move one overflow item as its brother */ | 2503 | /* This happens for example on obj2 and pic of the Calgary corpus */ |
2440 | bl_count[max_length]--; | 2504 | |
2441 | /* The brother of the overflow item also moves one step up, | 2505 | /* Find the first bit length which could increase: */ |
2442 | * but this does not affect bl_count[max_length] | 2506 | do { |
2443 | */ | 2507 | bits = max_length - 1; |
2444 | overflow -= 2; | 2508 | while (bl_count[bits] == 0) |
2445 | } while (overflow > 0); | 2509 | bits--; |
2446 | 2510 | bl_count[bits]--; /* move one leaf down the tree */ | |
2447 | /* Now recompute all bit lengths, scanning in increasing frequency. | 2511 | bl_count[bits + 1] += 2; /* move one overflow item as its brother */ |
2448 | * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all | 2512 | bl_count[max_length]--; |
2449 | * lengths instead of fixing only the wrong ones. This idea is taken | 2513 | /* The brother of the overflow item also moves one step up, |
2450 | * from 'ar' written by Haruhiko Okumura.) | 2514 | * but this does not affect bl_count[max_length] |
2451 | */ | 2515 | */ |
2452 | for (bits = max_length; bits != 0; bits--) { | 2516 | overflow -= 2; |
2453 | n = bl_count[bits]; | 2517 | } while (overflow > 0); |
2454 | while (n != 0) { | 2518 | |
2455 | m = heap[--h]; | 2519 | /* Now recompute all bit lengths, scanning in increasing frequency. |
2456 | if (m > max_code) continue; | 2520 | * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all |
2457 | if (tree[m].Len != (unsigned) bits) { | 2521 | * lengths instead of fixing only the wrong ones. This idea is taken |
2458 | Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); | 2522 | * from 'ar' written by Haruhiko Okumura.) |
2459 | opt_len += ((long)bits-(long)tree[m].Len)*(long)tree[m].Freq; | 2523 | */ |
2460 | tree[m].Len = (ush)bits; | 2524 | for (bits = max_length; bits != 0; bits--) { |
2461 | } | 2525 | n = bl_count[bits]; |
2462 | n--; | 2526 | while (n != 0) { |
2463 | } | 2527 | m = heap[--h]; |
2464 | } | 2528 | if (m > max_code) |
2529 | continue; | ||
2530 | if (tree[m].Len != (unsigned) bits) { | ||
2531 | Trace( | ||
2532 | (stderr, "code %d bits %d->%d\n", m, tree[m].Len, | ||
2533 | bits)); | ||
2534 | opt_len += | ||
2535 | ((long) bits - | ||
2536 | (long) tree[m].Len) * (long) tree[m].Freq; | ||
2537 | tree[m].Len = (ush) bits; | ||
2538 | } | ||
2539 | n--; | ||
2540 | } | ||
2541 | } | ||
2465 | } | 2542 | } |
2466 | 2543 | ||
2467 | /* =========================================================================== | 2544 | /* =========================================================================== |
@@ -2472,37 +2549,41 @@ local void gen_bitlen(desc) | |||
2472 | * OUT assertion: the field code is set for all tree elements of non | 2549 | * OUT assertion: the field code is set for all tree elements of non |
2473 | * zero code length. | 2550 | * zero code length. |
2474 | */ | 2551 | */ |
2475 | local void gen_codes (tree, max_code) | 2552 | local void gen_codes(tree, max_code) |
2476 | ct_data near *tree; /* the tree to decorate */ | 2553 | ct_data near *tree; /* the tree to decorate */ |
2477 | int max_code; /* largest code with non zero frequency */ | 2554 | int max_code; /* largest code with non zero frequency */ |
2478 | { | 2555 | { |
2479 | ush next_code[MAX_BITS+1]; /* next code value for each bit length */ | 2556 | ush next_code[MAX_BITS + 1]; /* next code value for each bit length */ |
2480 | ush code = 0; /* running code value */ | 2557 | ush code = 0; /* running code value */ |
2481 | int bits; /* bit index */ | 2558 | int bits; /* bit index */ |
2482 | int n; /* code index */ | 2559 | int n; /* code index */ |
2483 | 2560 | ||
2484 | /* The distribution counts are first used to generate the code values | 2561 | /* The distribution counts are first used to generate the code values |
2485 | * without bit reversal. | 2562 | * without bit reversal. |
2486 | */ | 2563 | */ |
2487 | for (bits = 1; bits <= MAX_BITS; bits++) { | 2564 | for (bits = 1; bits <= MAX_BITS; bits++) { |
2488 | next_code[bits] = code = (code + bl_count[bits-1]) << 1; | 2565 | next_code[bits] = code = (code + bl_count[bits - 1]) << 1; |
2489 | } | 2566 | } |
2490 | /* Check that the bit counts in bl_count are consistent. The last code | 2567 | /* Check that the bit counts in bl_count are consistent. The last code |
2491 | * must be all ones. | 2568 | * must be all ones. |
2492 | */ | 2569 | */ |
2493 | Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, | 2570 | Assert(code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, |
2494 | "inconsistent bit counts"); | 2571 | "inconsistent bit counts"); |
2495 | Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); | 2572 | Tracev((stderr, "\ngen_codes: max_code %d ", max_code)); |
2496 | 2573 | ||
2497 | for (n = 0; n <= max_code; n++) { | 2574 | for (n = 0; n <= max_code; n++) { |
2498 | int len = tree[n].Len; | 2575 | int len = tree[n].Len; |
2499 | if (len == 0) continue; | 2576 | |
2500 | /* Now reverse the bits */ | 2577 | if (len == 0) |
2501 | tree[n].Code = bi_reverse(next_code[len]++, len); | 2578 | continue; |
2502 | 2579 | /* Now reverse the bits */ | |
2503 | Tracec(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", | 2580 | tree[n].Code = bi_reverse(next_code[len]++, len); |
2504 | n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); | 2581 | |
2505 | } | 2582 | Tracec(tree != static_ltree, |
2583 | (stderr, "\nn %3d %c l %2d c %4x (%x) ", n, | ||
2584 | (isgraph(n) ? n : ' '), len, tree[n].Code, | ||
2585 | next_code[len] - 1)); | ||
2586 | } | ||
2506 | } | 2587 | } |
2507 | 2588 | ||
2508 | /* =========================================================================== | 2589 | /* =========================================================================== |
@@ -2514,84 +2595,89 @@ local void gen_codes (tree, max_code) | |||
2514 | * also updated if stree is not null. The field max_code is set. | 2595 | * also updated if stree is not null. The field max_code is set. |
2515 | */ | 2596 | */ |
2516 | local void build_tree(desc) | 2597 | local void build_tree(desc) |
2517 | tree_desc near *desc; /* the tree descriptor */ | 2598 | tree_desc near *desc; /* the tree descriptor */ |
2518 | { | 2599 | { |
2519 | ct_data near *tree = desc->dyn_tree; | 2600 | ct_data near *tree = desc->dyn_tree; |
2520 | ct_data near *stree = desc->static_tree; | 2601 | ct_data near *stree = desc->static_tree; |
2521 | int elems = desc->elems; | 2602 | int elems = desc->elems; |
2522 | int n, m; /* iterate over heap elements */ | 2603 | int n, m; /* iterate over heap elements */ |
2523 | int max_code = -1; /* largest code with non zero frequency */ | 2604 | int max_code = -1; /* largest code with non zero frequency */ |
2524 | int node = elems; /* next internal node of the tree */ | 2605 | int node = elems; /* next internal node of the tree */ |
2525 | 2606 | ||
2526 | /* Construct the initial heap, with least frequent element in | 2607 | /* Construct the initial heap, with least frequent element in |
2527 | * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. | 2608 | * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. |
2528 | * heap[0] is not used. | 2609 | * heap[0] is not used. |
2529 | */ | 2610 | */ |
2530 | heap_len = 0, heap_max = HEAP_SIZE; | 2611 | heap_len = 0, heap_max = HEAP_SIZE; |
2531 | 2612 | ||
2532 | for (n = 0; n < elems; n++) { | 2613 | for (n = 0; n < elems; n++) { |
2533 | if (tree[n].Freq != 0) { | 2614 | if (tree[n].Freq != 0) { |
2534 | heap[++heap_len] = max_code = n; | 2615 | heap[++heap_len] = max_code = n; |
2535 | depth[n] = 0; | 2616 | depth[n] = 0; |
2536 | } else { | 2617 | } else { |
2537 | tree[n].Len = 0; | 2618 | tree[n].Len = 0; |
2538 | } | 2619 | } |
2539 | } | 2620 | } |
2540 | 2621 | ||
2541 | /* The pkzip format requires that at least one distance code exists, | 2622 | /* The pkzip format requires that at least one distance code exists, |
2542 | * and that at least one bit should be sent even if there is only one | 2623 | * and that at least one bit should be sent even if there is only one |
2543 | * possible code. So to avoid special checks later on we force at least | 2624 | * possible code. So to avoid special checks later on we force at least |
2544 | * two codes of non zero frequency. | 2625 | * two codes of non zero frequency. |
2545 | */ | 2626 | */ |
2546 | while (heap_len < 2) { | 2627 | while (heap_len < 2) { |
2547 | int new = heap[++heap_len] = (max_code < 2 ? ++max_code : 0); | 2628 | int new = heap[++heap_len] = (max_code < 2 ? ++max_code : 0); |
2548 | tree[new].Freq = 1; | 2629 | |
2549 | depth[new] = 0; | 2630 | tree[new].Freq = 1; |
2550 | opt_len--; if (stree) static_len -= stree[new].Len; | 2631 | depth[new] = 0; |
2551 | /* new is 0 or 1 so it does not have extra bits */ | 2632 | opt_len--; |
2552 | } | 2633 | if (stree) |
2553 | desc->max_code = max_code; | 2634 | static_len -= stree[new].Len; |
2554 | 2635 | /* new is 0 or 1 so it does not have extra bits */ | |
2555 | /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, | 2636 | } |
2556 | * establish sub-heaps of increasing lengths: | 2637 | desc->max_code = max_code; |
2557 | */ | 2638 | |
2558 | for (n = heap_len/2; n >= 1; n--) pqdownheap(tree, n); | 2639 | /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, |
2559 | 2640 | * establish sub-heaps of increasing lengths: | |
2560 | /* Construct the Huffman tree by repeatedly combining the least two | 2641 | */ |
2561 | * frequent nodes. | 2642 | for (n = heap_len / 2; n >= 1; n--) |
2562 | */ | 2643 | pqdownheap(tree, n); |
2563 | do { | 2644 | |
2564 | pqremove(tree, n); /* n = node of least frequency */ | 2645 | /* Construct the Huffman tree by repeatedly combining the least two |
2565 | m = heap[SMALLEST]; /* m = node of next least frequency */ | 2646 | * frequent nodes. |
2566 | 2647 | */ | |
2567 | heap[--heap_max] = n; /* keep the nodes sorted by frequency */ | 2648 | do { |
2568 | heap[--heap_max] = m; | 2649 | pqremove(tree, n); /* n = node of least frequency */ |
2569 | 2650 | m = heap[SMALLEST]; /* m = node of next least frequency */ | |
2570 | /* Create a new node father of n and m */ | 2651 | |
2571 | tree[node].Freq = tree[n].Freq + tree[m].Freq; | 2652 | heap[--heap_max] = n; /* keep the nodes sorted by frequency */ |
2572 | depth[node] = (uch) (MAX(depth[n], depth[m]) + 1); | 2653 | heap[--heap_max] = m; |
2573 | tree[n].Dad = tree[m].Dad = (ush)node; | 2654 | |
2655 | /* Create a new node father of n and m */ | ||
2656 | tree[node].Freq = tree[n].Freq + tree[m].Freq; | ||
2657 | depth[node] = (uch) (MAX(depth[n], depth[m]) + 1); | ||
2658 | tree[n].Dad = tree[m].Dad = (ush) node; | ||
2574 | #ifdef DUMP_BL_TREE | 2659 | #ifdef DUMP_BL_TREE |
2575 | if (tree == bl_tree) { | 2660 | if (tree == bl_tree) { |
2576 | fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", | 2661 | fprintf(stderr, "\nnode %d(%d), sons %d(%d) %d(%d)", |
2577 | node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); | 2662 | node, tree[node].Freq, n, tree[n].Freq, m, |
2578 | } | 2663 | tree[m].Freq); |
2664 | } | ||
2579 | #endif | 2665 | #endif |
2580 | /* and insert the new node in the heap */ | 2666 | /* and insert the new node in the heap */ |
2581 | heap[SMALLEST] = node++; | 2667 | heap[SMALLEST] = node++; |
2582 | pqdownheap(tree, SMALLEST); | 2668 | pqdownheap(tree, SMALLEST); |
2583 | 2669 | ||
2584 | } while (heap_len >= 2); | 2670 | } while (heap_len >= 2); |
2585 | 2671 | ||
2586 | heap[--heap_max] = heap[SMALLEST]; | 2672 | heap[--heap_max] = heap[SMALLEST]; |
2587 | 2673 | ||
2588 | /* At this point, the fields freq and dad are set. We can now | 2674 | /* At this point, the fields freq and dad are set. We can now |
2589 | * generate the bit lengths. | 2675 | * generate the bit lengths. |
2590 | */ | 2676 | */ |
2591 | gen_bitlen((tree_desc near *)desc); | 2677 | gen_bitlen((tree_desc near *) desc); |
2592 | 2678 | ||
2593 | /* The field len is now set, we can generate the bit codes */ | 2679 | /* The field len is now set, we can generate the bit codes */ |
2594 | gen_codes ((ct_data near *)tree, max_code); | 2680 | gen_codes((ct_data near *) tree, max_code); |
2595 | } | 2681 | } |
2596 | 2682 | ||
2597 | /* =========================================================================== | 2683 | /* =========================================================================== |
@@ -2600,94 +2686,107 @@ local void build_tree(desc) | |||
2600 | * counts. (The contribution of the bit length codes will be added later | 2686 | * counts. (The contribution of the bit length codes will be added later |
2601 | * during the construction of bl_tree.) | 2687 | * during the construction of bl_tree.) |
2602 | */ | 2688 | */ |
2603 | local void scan_tree (tree, max_code) | 2689 | local void scan_tree(tree, max_code) |
2604 | ct_data near *tree; /* the tree to be scanned */ | 2690 | ct_data near *tree; /* the tree to be scanned */ |
2605 | int max_code; /* and its largest code of non zero frequency */ | 2691 | int max_code; /* and its largest code of non zero frequency */ |
2606 | { | 2692 | { |
2607 | int n; /* iterates over all tree elements */ | 2693 | int n; /* iterates over all tree elements */ |
2608 | int prevlen = -1; /* last emitted length */ | 2694 | int prevlen = -1; /* last emitted length */ |
2609 | int curlen; /* length of current code */ | 2695 | int curlen; /* length of current code */ |
2610 | int nextlen = tree[0].Len; /* length of next code */ | 2696 | int nextlen = tree[0].Len; /* length of next code */ |
2611 | int count = 0; /* repeat count of the current code */ | 2697 | int count = 0; /* repeat count of the current code */ |
2612 | int max_count = 7; /* max repeat count */ | 2698 | int max_count = 7; /* max repeat count */ |
2613 | int min_count = 4; /* min repeat count */ | 2699 | int min_count = 4; /* min repeat count */ |
2614 | 2700 | ||
2615 | if (nextlen == 0) max_count = 138, min_count = 3; | 2701 | if (nextlen == 0) |
2616 | tree[max_code+1].Len = (ush)0xffff; /* guard */ | 2702 | max_count = 138, min_count = 3; |
2617 | 2703 | tree[max_code + 1].Len = (ush) 0xffff; /* guard */ | |
2618 | for (n = 0; n <= max_code; n++) { | 2704 | |
2619 | curlen = nextlen; nextlen = tree[n+1].Len; | 2705 | for (n = 0; n <= max_code; n++) { |
2620 | if (++count < max_count && curlen == nextlen) { | 2706 | curlen = nextlen; |
2621 | continue; | 2707 | nextlen = tree[n + 1].Len; |
2622 | } else if (count < min_count) { | 2708 | if (++count < max_count && curlen == nextlen) { |
2623 | bl_tree[curlen].Freq += count; | 2709 | continue; |
2624 | } else if (curlen != 0) { | 2710 | } else if (count < min_count) { |
2625 | if (curlen != prevlen) bl_tree[curlen].Freq++; | 2711 | bl_tree[curlen].Freq += count; |
2626 | bl_tree[REP_3_6].Freq++; | 2712 | } else if (curlen != 0) { |
2627 | } else if (count <= 10) { | 2713 | if (curlen != prevlen) |
2628 | bl_tree[REPZ_3_10].Freq++; | 2714 | bl_tree[curlen].Freq++; |
2629 | } else { | 2715 | bl_tree[REP_3_6].Freq++; |
2630 | bl_tree[REPZ_11_138].Freq++; | 2716 | } else if (count <= 10) { |
2631 | } | 2717 | bl_tree[REPZ_3_10].Freq++; |
2632 | count = 0; prevlen = curlen; | 2718 | } else { |
2633 | if (nextlen == 0) { | 2719 | bl_tree[REPZ_11_138].Freq++; |
2634 | max_count = 138, min_count = 3; | 2720 | } |
2635 | } else if (curlen == nextlen) { | 2721 | count = 0; |
2636 | max_count = 6, min_count = 3; | 2722 | prevlen = curlen; |
2637 | } else { | 2723 | if (nextlen == 0) { |
2638 | max_count = 7, min_count = 4; | 2724 | max_count = 138, min_count = 3; |
2639 | } | 2725 | } else if (curlen == nextlen) { |
2640 | } | 2726 | max_count = 6, min_count = 3; |
2727 | } else { | ||
2728 | max_count = 7, min_count = 4; | ||
2729 | } | ||
2730 | } | ||
2641 | } | 2731 | } |
2642 | 2732 | ||
2643 | /* =========================================================================== | 2733 | /* =========================================================================== |
2644 | * Send a literal or distance tree in compressed form, using the codes in | 2734 | * Send a literal or distance tree in compressed form, using the codes in |
2645 | * bl_tree. | 2735 | * bl_tree. |
2646 | */ | 2736 | */ |
2647 | local void send_tree (tree, max_code) | 2737 | local void send_tree(tree, max_code) |
2648 | ct_data near *tree; /* the tree to be scanned */ | 2738 | ct_data near *tree; /* the tree to be scanned */ |
2649 | int max_code; /* and its largest code of non zero frequency */ | 2739 | int max_code; /* and its largest code of non zero frequency */ |
2650 | { | 2740 | { |
2651 | int n; /* iterates over all tree elements */ | 2741 | int n; /* iterates over all tree elements */ |
2652 | int prevlen = -1; /* last emitted length */ | 2742 | int prevlen = -1; /* last emitted length */ |
2653 | int curlen; /* length of current code */ | 2743 | int curlen; /* length of current code */ |
2654 | int nextlen = tree[0].Len; /* length of next code */ | 2744 | int nextlen = tree[0].Len; /* length of next code */ |
2655 | int count = 0; /* repeat count of the current code */ | 2745 | int count = 0; /* repeat count of the current code */ |
2656 | int max_count = 7; /* max repeat count */ | 2746 | int max_count = 7; /* max repeat count */ |
2657 | int min_count = 4; /* min repeat count */ | 2747 | int min_count = 4; /* min repeat count */ |
2658 | 2748 | ||
2659 | /* tree[max_code+1].Len = -1; */ /* guard already set */ | 2749 | /* tree[max_code+1].Len = -1; *//* guard already set */ |
2660 | if (nextlen == 0) max_count = 138, min_count = 3; | 2750 | if (nextlen == 0) |
2661 | 2751 | max_count = 138, min_count = 3; | |
2662 | for (n = 0; n <= max_code; n++) { | 2752 | |
2663 | curlen = nextlen; nextlen = tree[n+1].Len; | 2753 | for (n = 0; n <= max_code; n++) { |
2664 | if (++count < max_count && curlen == nextlen) { | 2754 | curlen = nextlen; |
2665 | continue; | 2755 | nextlen = tree[n + 1].Len; |
2666 | } else if (count < min_count) { | 2756 | if (++count < max_count && curlen == nextlen) { |
2667 | do { send_code(curlen, bl_tree); } while (--count != 0); | 2757 | continue; |
2668 | 2758 | } else if (count < min_count) { | |
2669 | } else if (curlen != 0) { | 2759 | do { |
2670 | if (curlen != prevlen) { | 2760 | send_code(curlen, bl_tree); |
2671 | send_code(curlen, bl_tree); count--; | 2761 | } while (--count != 0); |
2672 | } | 2762 | |
2673 | Assert(count >= 3 && count <= 6, " 3_6?"); | 2763 | } else if (curlen != 0) { |
2674 | send_code(REP_3_6, bl_tree); send_bits(count-3, 2); | 2764 | if (curlen != prevlen) { |
2675 | 2765 | send_code(curlen, bl_tree); | |
2676 | } else if (count <= 10) { | 2766 | count--; |
2677 | send_code(REPZ_3_10, bl_tree); send_bits(count-3, 3); | 2767 | } |
2678 | 2768 | Assert(count >= 3 && count <= 6, " 3_6?"); | |
2679 | } else { | 2769 | send_code(REP_3_6, bl_tree); |
2680 | send_code(REPZ_11_138, bl_tree); send_bits(count-11, 7); | 2770 | send_bits(count - 3, 2); |
2681 | } | 2771 | |
2682 | count = 0; prevlen = curlen; | 2772 | } else if (count <= 10) { |
2683 | if (nextlen == 0) { | 2773 | send_code(REPZ_3_10, bl_tree); |
2684 | max_count = 138, min_count = 3; | 2774 | send_bits(count - 3, 3); |
2685 | } else if (curlen == nextlen) { | 2775 | |
2686 | max_count = 6, min_count = 3; | 2776 | } else { |
2687 | } else { | 2777 | send_code(REPZ_11_138, bl_tree); |
2688 | max_count = 7, min_count = 4; | 2778 | send_bits(count - 11, 7); |
2689 | } | 2779 | } |
2690 | } | 2780 | count = 0; |
2781 | prevlen = curlen; | ||
2782 | if (nextlen == 0) { | ||
2783 | max_count = 138, min_count = 3; | ||
2784 | } else if (curlen == nextlen) { | ||
2785 | max_count = 6, min_count = 3; | ||
2786 | } else { | ||
2787 | max_count = 7, min_count = 4; | ||
2788 | } | ||
2789 | } | ||
2691 | } | 2790 | } |
2692 | 2791 | ||
2693 | /* =========================================================================== | 2792 | /* =========================================================================== |
@@ -2696,30 +2795,33 @@ local void send_tree (tree, max_code) | |||
2696 | */ | 2795 | */ |
2697 | local int build_bl_tree() | 2796 | local int build_bl_tree() |
2698 | { | 2797 | { |
2699 | int max_blindex; /* index of last bit length code of non zero freq */ | 2798 | int max_blindex; /* index of last bit length code of non zero freq */ |
2700 | 2799 | ||
2701 | /* Determine the bit length frequencies for literal and distance trees */ | 2800 | /* Determine the bit length frequencies for literal and distance trees */ |
2702 | scan_tree((ct_data near *)dyn_ltree, l_desc.max_code); | 2801 | scan_tree((ct_data near *) dyn_ltree, l_desc.max_code); |
2703 | scan_tree((ct_data near *)dyn_dtree, d_desc.max_code); | 2802 | scan_tree((ct_data near *) dyn_dtree, d_desc.max_code); |
2704 | 2803 | ||
2705 | /* Build the bit length tree: */ | 2804 | /* Build the bit length tree: */ |
2706 | build_tree((tree_desc near *)(&bl_desc)); | 2805 | build_tree((tree_desc near *) (&bl_desc)); |
2707 | /* opt_len now includes the length of the tree representations, except | 2806 | /* opt_len now includes the length of the tree representations, except |
2708 | * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. | 2807 | * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. |
2709 | */ | 2808 | */ |
2710 | 2809 | ||
2711 | /* Determine the number of bit length codes to send. The pkzip format | 2810 | /* Determine the number of bit length codes to send. The pkzip format |
2712 | * requires that at least 4 bit length codes be sent. (appnote.txt says | 2811 | * requires that at least 4 bit length codes be sent. (appnote.txt says |
2713 | * 3 but the actual value used is 4.) | 2812 | * 3 but the actual value used is 4.) |
2714 | */ | 2813 | */ |
2715 | for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { | 2814 | for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) { |
2716 | if (bl_tree[bl_order[max_blindex]].Len != 0) break; | 2815 | if (bl_tree[bl_order[max_blindex]].Len != 0) |
2717 | } | 2816 | break; |
2718 | /* Update opt_len to include the bit length tree and counts */ | 2817 | } |
2719 | opt_len += 3*(max_blindex+1) + 5+5+4; | 2818 | /* Update opt_len to include the bit length tree and counts */ |
2720 | Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", opt_len, static_len)); | 2819 | opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; |
2721 | 2820 | Tracev( | |
2722 | return max_blindex; | 2821 | (stderr, "\ndyn trees: dyn %ld, stat %ld", opt_len, |
2822 | static_len)); | ||
2823 | |||
2824 | return max_blindex; | ||
2723 | } | 2825 | } |
2724 | 2826 | ||
2725 | /* =========================================================================== | 2827 | /* =========================================================================== |
@@ -2728,28 +2830,29 @@ local int build_bl_tree() | |||
2728 | * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. | 2830 | * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. |
2729 | */ | 2831 | */ |
2730 | local void send_all_trees(lcodes, dcodes, blcodes) | 2832 | local void send_all_trees(lcodes, dcodes, blcodes) |
2731 | int lcodes, dcodes, blcodes; /* number of codes for each tree */ | 2833 | int lcodes, dcodes, blcodes; /* number of codes for each tree */ |
2732 | { | 2834 | { |
2733 | int rank; /* index in bl_order */ | 2835 | int rank; /* index in bl_order */ |
2734 | 2836 | ||
2735 | Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); | 2837 | Assert(lcodes >= 257 && dcodes >= 1 |
2736 | Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, | 2838 | && blcodes >= 4, "not enough codes"); |
2737 | "too many codes"); | 2839 | Assert(lcodes <= L_CODES && dcodes <= D_CODES |
2738 | Tracev((stderr, "\nbl counts: ")); | 2840 | && blcodes <= BL_CODES, "too many codes"); |
2739 | send_bits(lcodes-257, 5); /* not +255 as stated in appnote.txt */ | 2841 | Tracev((stderr, "\nbl counts: ")); |
2740 | send_bits(dcodes-1, 5); | 2842 | send_bits(lcodes - 257, 5); /* not +255 as stated in appnote.txt */ |
2741 | send_bits(blcodes-4, 4); /* not -3 as stated in appnote.txt */ | 2843 | send_bits(dcodes - 1, 5); |
2742 | for (rank = 0; rank < blcodes; rank++) { | 2844 | send_bits(blcodes - 4, 4); /* not -3 as stated in appnote.txt */ |
2743 | Tracev((stderr, "\nbl code %2d ", bl_order[rank])); | 2845 | for (rank = 0; rank < blcodes; rank++) { |
2744 | send_bits(bl_tree[bl_order[rank]].Len, 3); | 2846 | Tracev((stderr, "\nbl code %2d ", bl_order[rank])); |
2745 | } | 2847 | send_bits(bl_tree[bl_order[rank]].Len, 3); |
2746 | Tracev((stderr, "\nbl tree: sent %ld", bits_sent)); | 2848 | } |
2747 | 2849 | Tracev((stderr, "\nbl tree: sent %ld", bits_sent)); | |
2748 | send_tree((ct_data near *)dyn_ltree, lcodes-1); /* send the literal tree */ | 2850 | |
2749 | Tracev((stderr, "\nlit tree: sent %ld", bits_sent)); | 2851 | send_tree((ct_data near *) dyn_ltree, lcodes - 1); /* send the literal tree */ |
2750 | 2852 | Tracev((stderr, "\nlit tree: sent %ld", bits_sent)); | |
2751 | send_tree((ct_data near *)dyn_dtree, dcodes-1); /* send the distance tree */ | 2853 | |
2752 | Tracev((stderr, "\ndist tree: sent %ld", bits_sent)); | 2854 | send_tree((ct_data near *) dyn_dtree, dcodes - 1); /* send the distance tree */ |
2855 | Tracev((stderr, "\ndist tree: sent %ld", bits_sent)); | ||
2753 | } | 2856 | } |
2754 | 2857 | ||
2755 | /* =========================================================================== | 2858 | /* =========================================================================== |
@@ -2758,204 +2861,222 @@ local void send_all_trees(lcodes, dcodes, blcodes) | |||
2758 | * returns the total compressed length for the file so far. | 2861 | * returns the total compressed length for the file so far. |
2759 | */ | 2862 | */ |
2760 | ulg flush_block(buf, stored_len, eof) | 2863 | ulg flush_block(buf, stored_len, eof) |
2761 | char *buf; /* input block, or NULL if too old */ | 2864 | char *buf; /* input block, or NULL if too old */ |
2762 | ulg stored_len; /* length of input block */ | 2865 | ulg stored_len; /* length of input block */ |
2763 | int eof; /* true if this is the last block for a file */ | 2866 | int eof; /* true if this is the last block for a file */ |
2764 | { | 2867 | { |
2765 | ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ | 2868 | ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ |
2766 | int max_blindex; /* index of last bit length code of non zero freq */ | 2869 | int max_blindex; /* index of last bit length code of non zero freq */ |
2767 | 2870 | ||
2768 | flag_buf[last_flags] = flags; /* Save the flags for the last 8 items */ | 2871 | flag_buf[last_flags] = flags; /* Save the flags for the last 8 items */ |
2769 | 2872 | ||
2770 | /* Check if the file is ascii or binary */ | 2873 | /* Check if the file is ascii or binary */ |
2771 | if (*file_type == (ush)UNKNOWN) set_file_type(); | 2874 | if (*file_type == (ush) UNKNOWN) |
2772 | 2875 | set_file_type(); | |
2773 | /* Construct the literal and distance trees */ | 2876 | |
2774 | build_tree((tree_desc near *)(&l_desc)); | 2877 | /* Construct the literal and distance trees */ |
2775 | Tracev((stderr, "\nlit data: dyn %ld, stat %ld", opt_len, static_len)); | 2878 | build_tree((tree_desc near *) (&l_desc)); |
2776 | 2879 | Tracev((stderr, "\nlit data: dyn %ld, stat %ld", opt_len, static_len)); | |
2777 | build_tree((tree_desc near *)(&d_desc)); | 2880 | |
2778 | Tracev((stderr, "\ndist data: dyn %ld, stat %ld", opt_len, static_len)); | 2881 | build_tree((tree_desc near *) (&d_desc)); |
2779 | /* At this point, opt_len and static_len are the total bit lengths of | 2882 | Tracev( |
2780 | * the compressed block data, excluding the tree representations. | 2883 | (stderr, "\ndist data: dyn %ld, stat %ld", opt_len, |
2781 | */ | 2884 | static_len)); |
2782 | 2885 | /* At this point, opt_len and static_len are the total bit lengths of | |
2783 | /* Build the bit length tree for the above two trees, and get the index | 2886 | * the compressed block data, excluding the tree representations. |
2784 | * in bl_order of the last bit length code to send. | 2887 | */ |
2785 | */ | 2888 | |
2786 | max_blindex = build_bl_tree(); | 2889 | /* Build the bit length tree for the above two trees, and get the index |
2787 | 2890 | * in bl_order of the last bit length code to send. | |
2788 | /* Determine the best encoding. Compute first the block length in bytes */ | 2891 | */ |
2789 | opt_lenb = (opt_len+3+7)>>3; | 2892 | max_blindex = build_bl_tree(); |
2790 | static_lenb = (static_len+3+7)>>3; | 2893 | |
2791 | input_len += stored_len; /* for debugging only */ | 2894 | /* Determine the best encoding. Compute first the block length in bytes */ |
2792 | 2895 | opt_lenb = (opt_len + 3 + 7) >> 3; | |
2793 | Trace((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", | 2896 | static_lenb = (static_len + 3 + 7) >> 3; |
2794 | opt_lenb, opt_len, static_lenb, static_len, stored_len, | 2897 | input_len += stored_len; /* for debugging only */ |
2795 | last_lit, last_dist)); | 2898 | |
2796 | 2899 | Trace( | |
2797 | if (static_lenb <= opt_lenb) opt_lenb = static_lenb; | 2900 | (stderr, |
2798 | 2901 | "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", | |
2799 | /* If compression failed and this is the first and last block, | 2902 | opt_lenb, opt_len, static_lenb, static_len, stored_len, |
2800 | * and if the zip file can be seeked (to rewrite the local header), | 2903 | last_lit, last_dist)); |
2801 | * the whole file is transformed into a stored file: | 2904 | |
2802 | */ | 2905 | if (static_lenb <= opt_lenb) |
2906 | opt_lenb = static_lenb; | ||
2907 | |||
2908 | /* If compression failed and this is the first and last block, | ||
2909 | * and if the zip file can be seeked (to rewrite the local header), | ||
2910 | * the whole file is transformed into a stored file: | ||
2911 | */ | ||
2803 | #ifdef FORCE_METHOD | 2912 | #ifdef FORCE_METHOD |
2804 | #else | 2913 | #else |
2805 | if (stored_len <= opt_lenb && eof && compressed_len == 0L && seekable()) { | 2914 | if (stored_len <= opt_lenb && eof && compressed_len == 0L |
2915 | && seekable()) { | ||
2806 | #endif | 2916 | #endif |
2807 | /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ | 2917 | /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ |
2808 | if (buf == (char*)0) error ("block vanished"); | 2918 | if (buf == (char *) 0) |
2919 | error("block vanished"); | ||
2809 | 2920 | ||
2810 | copy_block(buf, (unsigned)stored_len, 0); /* without header */ | 2921 | copy_block(buf, (unsigned) stored_len, 0); /* without header */ |
2811 | compressed_len = stored_len << 3; | 2922 | compressed_len = stored_len << 3; |
2812 | *file_method = STORED; | 2923 | *file_method = STORED; |
2813 | 2924 | ||
2814 | #ifdef FORCE_METHOD | 2925 | #ifdef FORCE_METHOD |
2815 | #else | 2926 | #else |
2816 | } else if (stored_len+4 <= opt_lenb && buf != (char*)0) { | 2927 | } else if (stored_len + 4 <= opt_lenb && buf != (char *) 0) { |
2817 | /* 4: two words for the lengths */ | 2928 | /* 4: two words for the lengths */ |
2818 | #endif | 2929 | #endif |
2819 | /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. | 2930 | /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. |
2820 | * Otherwise we can't have processed more than WSIZE input bytes since | 2931 | * Otherwise we can't have processed more than WSIZE input bytes since |
2821 | * the last block flush, because compression would have been | 2932 | * the last block flush, because compression would have been |
2822 | * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to | 2933 | * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to |
2823 | * transform a block into a stored block. | 2934 | * transform a block into a stored block. |
2824 | */ | 2935 | */ |
2825 | send_bits((STORED_BLOCK<<1)+eof, 3); /* send block type */ | 2936 | send_bits((STORED_BLOCK << 1) + eof, 3); /* send block type */ |
2826 | compressed_len = (compressed_len + 3 + 7) & ~7L; | 2937 | compressed_len = (compressed_len + 3 + 7) & ~7L; |
2827 | compressed_len += (stored_len + 4) << 3; | 2938 | compressed_len += (stored_len + 4) << 3; |
2828 | 2939 | ||
2829 | copy_block(buf, (unsigned)stored_len, 1); /* with header */ | 2940 | copy_block(buf, (unsigned) stored_len, 1); /* with header */ |
2830 | 2941 | ||
2831 | #ifdef FORCE_METHOD | 2942 | #ifdef FORCE_METHOD |
2832 | #else | 2943 | #else |
2833 | } else if (static_lenb == opt_lenb) { | 2944 | } else if (static_lenb == opt_lenb) { |
2834 | #endif | 2945 | #endif |
2835 | send_bits((STATIC_TREES<<1)+eof, 3); | 2946 | send_bits((STATIC_TREES << 1) + eof, 3); |
2836 | compress_block((ct_data near *)static_ltree, (ct_data near *)static_dtree); | 2947 | compress_block((ct_data near *) static_ltree, |
2837 | compressed_len += 3 + static_len; | 2948 | (ct_data near *) static_dtree); |
2838 | } else { | 2949 | compressed_len += 3 + static_len; |
2839 | send_bits((DYN_TREES<<1)+eof, 3); | 2950 | } else { |
2840 | send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1); | 2951 | send_bits((DYN_TREES << 1) + eof, 3); |
2841 | compress_block((ct_data near *)dyn_ltree, (ct_data near *)dyn_dtree); | 2952 | send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, |
2842 | compressed_len += 3 + opt_len; | 2953 | max_blindex + 1); |
2843 | } | 2954 | compress_block((ct_data near *) dyn_ltree, |
2844 | Assert (compressed_len == bits_sent, "bad compressed size"); | 2955 | (ct_data near *) dyn_dtree); |
2845 | init_block(); | 2956 | compressed_len += 3 + opt_len; |
2846 | 2957 | } | |
2847 | if (eof) { | 2958 | Assert(compressed_len == bits_sent, "bad compressed size"); |
2848 | Assert (input_len == isize, "bad input size"); | 2959 | init_block(); |
2849 | bi_windup(); | 2960 | |
2850 | compressed_len += 7; /* align on byte boundary */ | 2961 | if (eof) { |
2851 | } | 2962 | Assert(input_len == isize, "bad input size"); |
2852 | Tracev((stderr,"\ncomprlen %lu(%lu) ", compressed_len>>3, | 2963 | bi_windup(); |
2853 | compressed_len-7*eof)); | 2964 | compressed_len += 7; /* align on byte boundary */ |
2854 | 2965 | } | |
2855 | return compressed_len >> 3; | 2966 | Tracev((stderr, "\ncomprlen %lu(%lu) ", compressed_len >> 3, |
2967 | compressed_len - 7 * eof)); | ||
2968 | |||
2969 | return compressed_len >> 3; | ||
2856 | } | 2970 | } |
2857 | 2971 | ||
2858 | /* =========================================================================== | 2972 | /* =========================================================================== |
2859 | * Save the match info and tally the frequency counts. Return true if | 2973 | * Save the match info and tally the frequency counts. Return true if |
2860 | * the current block must be flushed. | 2974 | * the current block must be flushed. |
2861 | */ | 2975 | */ |
2862 | int ct_tally (dist, lc) | 2976 | int ct_tally(dist, lc) |
2863 | int dist; /* distance of matched string */ | 2977 | int dist; /* distance of matched string */ |
2864 | int lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ | 2978 | int lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ |
2865 | { | 2979 | { |
2866 | l_buf[last_lit++] = (uch)lc; | 2980 | l_buf[last_lit++] = (uch) lc; |
2867 | if (dist == 0) { | 2981 | if (dist == 0) { |
2868 | /* lc is the unmatched char */ | 2982 | /* lc is the unmatched char */ |
2869 | dyn_ltree[lc].Freq++; | 2983 | dyn_ltree[lc].Freq++; |
2870 | } else { | 2984 | } else { |
2871 | /* Here, lc is the match length - MIN_MATCH */ | 2985 | /* Here, lc is the match length - MIN_MATCH */ |
2872 | dist--; /* dist = match distance - 1 */ | 2986 | dist--; /* dist = match distance - 1 */ |
2873 | Assert((ush)dist < (ush)MAX_DIST && | 2987 | Assert((ush) dist < (ush) MAX_DIST && |
2874 | (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && | 2988 | (ush) lc <= (ush) (MAX_MATCH - MIN_MATCH) && |
2875 | (ush)d_code(dist) < (ush)D_CODES, "ct_tally: bad match"); | 2989 | (ush) d_code(dist) < (ush) D_CODES, "ct_tally: bad match"); |
2876 | 2990 | ||
2877 | dyn_ltree[length_code[lc]+LITERALS+1].Freq++; | 2991 | dyn_ltree[length_code[lc] + LITERALS + 1].Freq++; |
2878 | dyn_dtree[d_code(dist)].Freq++; | 2992 | dyn_dtree[d_code(dist)].Freq++; |
2879 | 2993 | ||
2880 | d_buf[last_dist++] = (ush)dist; | 2994 | d_buf[last_dist++] = (ush) dist; |
2881 | flags |= flag_bit; | 2995 | flags |= flag_bit; |
2882 | } | 2996 | } |
2883 | flag_bit <<= 1; | 2997 | flag_bit <<= 1; |
2884 | 2998 | ||
2885 | /* Output the flags if they fill a byte: */ | 2999 | /* Output the flags if they fill a byte: */ |
2886 | if ((last_lit & 7) == 0) { | 3000 | if ((last_lit & 7) == 0) { |
2887 | flag_buf[last_flags++] = flags; | 3001 | flag_buf[last_flags++] = flags; |
2888 | flags = 0, flag_bit = 1; | 3002 | flags = 0, flag_bit = 1; |
2889 | } | 3003 | } |
2890 | /* Try to guess if it is profitable to stop the current block here */ | 3004 | /* Try to guess if it is profitable to stop the current block here */ |
2891 | if ((last_lit & 0xfff) == 0) { | 3005 | if ((last_lit & 0xfff) == 0) { |
2892 | /* Compute an upper bound for the compressed length */ | 3006 | /* Compute an upper bound for the compressed length */ |
2893 | ulg out_length = (ulg)last_lit*8L; | 3007 | ulg out_length = (ulg) last_lit * 8L; |
2894 | ulg in_length = (ulg)strstart-block_start; | 3008 | ulg in_length = (ulg) strstart - block_start; |
2895 | int dcode; | 3009 | int dcode; |
2896 | for (dcode = 0; dcode < D_CODES; dcode++) { | 3010 | |
2897 | out_length += (ulg)dyn_dtree[dcode].Freq*(5L+extra_dbits[dcode]); | 3011 | for (dcode = 0; dcode < D_CODES; dcode++) { |
2898 | } | 3012 | out_length += |
2899 | out_length >>= 3; | 3013 | (ulg) dyn_dtree[dcode].Freq * (5L + extra_dbits[dcode]); |
2900 | Trace((stderr,"\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", | 3014 | } |
2901 | last_lit, last_dist, in_length, out_length, | 3015 | out_length >>= 3; |
2902 | 100L - out_length*100L/in_length)); | 3016 | Trace( |
2903 | if (last_dist < last_lit/2 && out_length < in_length/2) return 1; | 3017 | (stderr, |
2904 | } | 3018 | "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", |
2905 | return (last_lit == LIT_BUFSIZE-1 || last_dist == DIST_BUFSIZE); | 3019 | last_lit, last_dist, in_length, out_length, |
2906 | /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K | 3020 | 100L - out_length * 100L / in_length)); |
2907 | * on 16 bit machines and because stored blocks are restricted to | 3021 | if (last_dist < last_lit / 2 && out_length < in_length / 2) |
2908 | * 64K-1 bytes. | 3022 | return 1; |
2909 | */ | 3023 | } |
3024 | return (last_lit == LIT_BUFSIZE - 1 || last_dist == DIST_BUFSIZE); | ||
3025 | /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K | ||
3026 | * on 16 bit machines and because stored blocks are restricted to | ||
3027 | * 64K-1 bytes. | ||
3028 | */ | ||
2910 | } | 3029 | } |
2911 | 3030 | ||
2912 | /* =========================================================================== | 3031 | /* =========================================================================== |
2913 | * Send the block data compressed using the given Huffman trees | 3032 | * Send the block data compressed using the given Huffman trees |
2914 | */ | 3033 | */ |
2915 | local void compress_block(ltree, dtree) | 3034 | local void compress_block(ltree, dtree) |
2916 | ct_data near *ltree; /* literal tree */ | 3035 | ct_data near *ltree; /* literal tree */ |
2917 | ct_data near *dtree; /* distance tree */ | 3036 | ct_data near *dtree; /* distance tree */ |
2918 | { | 3037 | { |
2919 | unsigned dist; /* distance of matched string */ | 3038 | unsigned dist; /* distance of matched string */ |
2920 | int lc; /* match length or unmatched char (if dist == 0) */ | 3039 | int lc; /* match length or unmatched char (if dist == 0) */ |
2921 | unsigned lx = 0; /* running index in l_buf */ | 3040 | unsigned lx = 0; /* running index in l_buf */ |
2922 | unsigned dx = 0; /* running index in d_buf */ | 3041 | unsigned dx = 0; /* running index in d_buf */ |
2923 | unsigned fx = 0; /* running index in flag_buf */ | 3042 | unsigned fx = 0; /* running index in flag_buf */ |
2924 | uch flag = 0; /* current flags */ | 3043 | uch flag = 0; /* current flags */ |
2925 | unsigned code; /* the code to send */ | 3044 | unsigned code; /* the code to send */ |
2926 | int extra; /* number of extra bits to send */ | 3045 | int extra; /* number of extra bits to send */ |
2927 | 3046 | ||
2928 | if (last_lit != 0) do { | 3047 | if (last_lit != 0) |
2929 | if ((lx & 7) == 0) flag = flag_buf[fx++]; | 3048 | do { |
2930 | lc = l_buf[lx++]; | 3049 | if ((lx & 7) == 0) |
2931 | if ((flag & 1) == 0) { | 3050 | flag = flag_buf[fx++]; |
2932 | send_code(lc, ltree); /* send a literal byte */ | 3051 | lc = l_buf[lx++]; |
2933 | Tracecv(isgraph(lc), (stderr," '%c' ", lc)); | 3052 | if ((flag & 1) == 0) { |
2934 | } else { | 3053 | send_code(lc, ltree); /* send a literal byte */ |
2935 | /* Here, lc is the match length - MIN_MATCH */ | 3054 | Tracecv(isgraph(lc), (stderr, " '%c' ", lc)); |
2936 | code = length_code[lc]; | 3055 | } else { |
2937 | send_code(code+LITERALS+1, ltree); /* send the length code */ | 3056 | /* Here, lc is the match length - MIN_MATCH */ |
2938 | extra = extra_lbits[code]; | 3057 | code = length_code[lc]; |
2939 | if (extra != 0) { | 3058 | send_code(code + LITERALS + 1, ltree); /* send the length code */ |
2940 | lc -= base_length[code]; | 3059 | extra = extra_lbits[code]; |
2941 | send_bits(lc, extra); /* send the extra length bits */ | 3060 | if (extra != 0) { |
2942 | } | 3061 | lc -= base_length[code]; |
2943 | dist = d_buf[dx++]; | 3062 | send_bits(lc, extra); /* send the extra length bits */ |
2944 | /* Here, dist is the match distance - 1 */ | 3063 | } |
2945 | code = d_code(dist); | 3064 | dist = d_buf[dx++]; |
2946 | Assert (code < D_CODES, "bad d_code"); | 3065 | /* Here, dist is the match distance - 1 */ |
2947 | 3066 | code = d_code(dist); | |
2948 | send_code(code, dtree); /* send the distance code */ | 3067 | Assert(code < D_CODES, "bad d_code"); |
2949 | extra = extra_dbits[code]; | 3068 | |
2950 | if (extra != 0) { | 3069 | send_code(code, dtree); /* send the distance code */ |
2951 | dist -= base_dist[code]; | 3070 | extra = extra_dbits[code]; |
2952 | send_bits(dist, extra); /* send the extra distance bits */ | 3071 | if (extra != 0) { |
2953 | } | 3072 | dist -= base_dist[code]; |
2954 | } /* literal or match pair ? */ | 3073 | send_bits(dist, extra); /* send the extra distance bits */ |
2955 | flag >>= 1; | 3074 | } |
2956 | } while (lx < last_lit); | 3075 | } /* literal or match pair ? */ |
2957 | 3076 | flag >>= 1; | |
2958 | send_code(END_BLOCK, ltree); | 3077 | } while (lx < last_lit); |
3078 | |||
3079 | send_code(END_BLOCK, ltree); | ||
2959 | } | 3080 | } |
2960 | 3081 | ||
2961 | /* =========================================================================== | 3082 | /* =========================================================================== |
@@ -2966,17 +3087,22 @@ local void compress_block(ltree, dtree) | |||
2966 | */ | 3087 | */ |
2967 | local void set_file_type() | 3088 | local void set_file_type() |
2968 | { | 3089 | { |
2969 | int n = 0; | 3090 | int n = 0; |
2970 | unsigned ascii_freq = 0; | 3091 | unsigned ascii_freq = 0; |
2971 | unsigned bin_freq = 0; | 3092 | unsigned bin_freq = 0; |
2972 | while (n < 7) bin_freq += dyn_ltree[n++].Freq; | 3093 | |
2973 | while (n < 128) ascii_freq += dyn_ltree[n++].Freq; | 3094 | while (n < 7) |
2974 | while (n < LITERALS) bin_freq += dyn_ltree[n++].Freq; | 3095 | bin_freq += dyn_ltree[n++].Freq; |
2975 | *file_type = bin_freq > (ascii_freq >> 2) ? BINARY : ASCII; | 3096 | while (n < 128) |
2976 | if (*file_type == BINARY && translate_eol) { | 3097 | ascii_freq += dyn_ltree[n++].Freq; |
2977 | warn("-l used on binary file", ""); | 3098 | while (n < LITERALS) |
2978 | } | 3099 | bin_freq += dyn_ltree[n++].Freq; |
3100 | *file_type = bin_freq > (ascii_freq >> 2) ? BINARY : ASCII; | ||
3101 | if (*file_type == BINARY && translate_eol) { | ||
3102 | warn("-l used on binary file", ""); | ||
3103 | } | ||
2979 | } | 3104 | } |
3105 | |||
2980 | /* util.c -- utility functions for gzip support | 3106 | /* util.c -- utility functions for gzip support |
2981 | * Copyright (C) 1992-1993 Jean-loup Gailly | 3107 | * Copyright (C) 1992-1993 Jean-loup Gailly |
2982 | * This is free software; you can redistribute it and/or modify it under the | 3108 | * This is free software; you can redistribute it and/or modify it under the |
@@ -2997,7 +3123,7 @@ local void set_file_type() | |||
2997 | #if defined(STDC_HEADERS) || !defined(NO_STDLIB_H) | 3123 | #if defined(STDC_HEADERS) || !defined(NO_STDLIB_H) |
2998 | # include <stdlib.h> | 3124 | # include <stdlib.h> |
2999 | #else | 3125 | #else |
3000 | extern int errno; | 3126 | extern int errno; |
3001 | #endif | 3127 | #endif |
3002 | 3128 | ||
3003 | /* =========================================================================== | 3129 | /* =========================================================================== |
@@ -3005,30 +3131,32 @@ local void set_file_type() | |||
3005 | * IN assertion: insize bytes have already been read in inbuf. | 3131 | * IN assertion: insize bytes have already been read in inbuf. |
3006 | */ | 3132 | */ |
3007 | int copy(in, out) | 3133 | int copy(in, out) |
3008 | int in, out; /* input and output file descriptors */ | 3134 | int in, out; /* input and output file descriptors */ |
3009 | { | 3135 | { |
3010 | errno = 0; | 3136 | errno = 0; |
3011 | while (insize != 0 && (int)insize != EOF) { | 3137 | while (insize != 0 && (int) insize != EOF) { |
3012 | write_buf(out, (char*)inbuf, insize); | 3138 | write_buf(out, (char *) inbuf, insize); |
3013 | bytes_out += insize; | 3139 | bytes_out += insize; |
3014 | insize = read(in, (char*)inbuf, INBUFSIZ); | 3140 | insize = read(in, (char *) inbuf, INBUFSIZ); |
3015 | } | 3141 | } |
3016 | if ((int)insize == EOF && errno != 0) { | 3142 | if ((int) insize == EOF && errno != 0) { |
3017 | read_error(); | 3143 | read_error(); |
3018 | } | 3144 | } |
3019 | bytes_in = bytes_out; | 3145 | bytes_in = bytes_out; |
3020 | return OK; | 3146 | return OK; |
3021 | } | 3147 | } |
3022 | 3148 | ||
3023 | /* ======================================================================== | 3149 | /* ======================================================================== |
3024 | * Put string s in lower case, return s. | 3150 | * Put string s in lower case, return s. |
3025 | */ | 3151 | */ |
3026 | char *strlwr(s) | 3152 | char *strlwr(s) |
3027 | char *s; | 3153 | char *s; |
3028 | { | 3154 | { |
3029 | char *t; | 3155 | char *t; |
3030 | for (t = s; *t; t++) *t = tolow(*t); | 3156 | |
3031 | return s; | 3157 | for (t = s; *t; t++) |
3158 | *t = tolow(*t); | ||
3159 | return s; | ||
3032 | } | 3160 | } |
3033 | 3161 | ||
3034 | #if defined(NO_STRING_H) && !defined(STDC_HEADERS) | 3162 | #if defined(NO_STRING_H) && !defined(STDC_HEADERS) |
@@ -3039,7 +3167,7 @@ char *strlwr(s) | |||
3039 | # define const | 3167 | # define const |
3040 | # endif | 3168 | # endif |
3041 | 3169 | ||
3042 | int strspn OF((const char *s, const char *accept)); | 3170 | int strspn OF((const char *s, const char *accept)); |
3043 | int strcspn OF((const char *s, const char *reject)); | 3171 | int strcspn OF((const char *s, const char *reject)); |
3044 | 3172 | ||
3045 | /* ======================================================================== | 3173 | /* ======================================================================== |
@@ -3047,21 +3175,23 @@ int strcspn OF((const char *s, const char *reject)); | |||
3047 | * of s which contains only characters in accept. | 3175 | * of s which contains only characters in accept. |
3048 | */ | 3176 | */ |
3049 | int strspn(s, accept) | 3177 | int strspn(s, accept) |
3050 | const char *s; | 3178 | const char *s; |
3051 | const char *accept; | 3179 | const char *accept; |
3052 | { | 3180 | { |
3053 | register const char *p; | 3181 | register const char *p; |
3054 | register const char *a; | 3182 | register const char *a; |
3055 | register int count = 0; | 3183 | register int count = 0; |
3056 | 3184 | ||
3057 | for (p = s; *p != '\0'; ++p) { | 3185 | for (p = s; *p != '\0'; ++p) { |
3058 | for (a = accept; *a != '\0'; ++a) { | 3186 | for (a = accept; *a != '\0'; ++a) { |
3059 | if (*p == *a) break; | 3187 | if (*p == *a) |
3188 | break; | ||
3189 | } | ||
3190 | if (*a == '\0') | ||
3191 | return count; | ||
3192 | ++count; | ||
3060 | } | 3193 | } |
3061 | if (*a == '\0') return count; | 3194 | return count; |
3062 | ++count; | ||
3063 | } | ||
3064 | return count; | ||
3065 | } | 3195 | } |
3066 | 3196 | ||
3067 | /* ======================================================================== | 3197 | /* ======================================================================== |
@@ -3069,104 +3199,113 @@ int strspn(s, accept) | |||
3069 | * which contains no characters from reject. | 3199 | * which contains no characters from reject. |
3070 | */ | 3200 | */ |
3071 | int strcspn(s, reject) | 3201 | int strcspn(s, reject) |
3072 | const char *s; | 3202 | const char *s; |
3073 | const char *reject; | 3203 | const char *reject; |
3074 | { | 3204 | { |
3075 | register int count = 0; | 3205 | register int count = 0; |
3076 | 3206 | ||
3077 | while (*s != '\0') { | 3207 | while (*s != '\0') { |
3078 | if (strchr(reject, *s++) != NULL) return count; | 3208 | if (strchr(reject, *s++) != NULL) |
3079 | ++count; | 3209 | return count; |
3080 | } | 3210 | ++count; |
3081 | return count; | 3211 | } |
3212 | return count; | ||
3082 | } | 3213 | } |
3083 | 3214 | ||
3084 | #endif /* NO_STRING_H */ | 3215 | #endif /* NO_STRING_H */ |
3085 | 3216 | ||
3086 | /* ======================================================================== | 3217 | /* ======================================================================== |
3087 | * Add an environment variable (if any) before argv, and update argc. | 3218 | * Add an environment variable (if any) before argv, and update argc. |
3088 | * Return the expanded environment variable to be freed later, or NULL | 3219 | * Return the expanded environment variable to be freed later, or NULL |
3089 | * if no options were added to argv. | 3220 | * if no options were added to argv. |
3090 | */ | 3221 | */ |
3091 | #define SEPARATOR " \t" /* separators in env variable */ | 3222 | #define SEPARATOR " \t" /* separators in env variable */ |
3092 | 3223 | ||
3093 | char *add_envopt(argcp, argvp, env) | 3224 | char *add_envopt(argcp, argvp, env) |
3094 | int *argcp; /* pointer to argc */ | 3225 | int *argcp; /* pointer to argc */ |
3095 | char ***argvp; /* pointer to argv */ | 3226 | char ***argvp; /* pointer to argv */ |
3096 | char *env; /* name of environment variable */ | 3227 | char *env; /* name of environment variable */ |
3097 | { | 3228 | { |
3098 | char *p; /* running pointer through env variable */ | 3229 | char *p; /* running pointer through env variable */ |
3099 | char **oargv; /* runs through old argv array */ | 3230 | char **oargv; /* runs through old argv array */ |
3100 | char **nargv; /* runs through new argv array */ | 3231 | char **nargv; /* runs through new argv array */ |
3101 | int oargc = *argcp; /* old argc */ | 3232 | int oargc = *argcp; /* old argc */ |
3102 | int nargc = 0; /* number of arguments in env variable */ | 3233 | int nargc = 0; /* number of arguments in env variable */ |
3103 | 3234 | ||
3104 | env = (char*)getenv(env); | 3235 | env = (char *) getenv(env); |
3105 | if (env == NULL) return NULL; | 3236 | if (env == NULL) |
3106 | 3237 | return NULL; | |
3107 | p = (char*)xmalloc(strlen(env)+1); | 3238 | |
3108 | env = strcpy(p, env); /* keep env variable intact */ | 3239 | p = (char *) xmalloc(strlen(env) + 1); |
3109 | 3240 | env = strcpy(p, env); /* keep env variable intact */ | |
3110 | for (p = env; *p; nargc++ ) { /* move through env */ | 3241 | |
3111 | p += strspn(p, SEPARATOR); /* skip leading separators */ | 3242 | for (p = env; *p; nargc++) { /* move through env */ |
3112 | if (*p == '\0') break; | 3243 | p += strspn(p, SEPARATOR); /* skip leading separators */ |
3113 | 3244 | if (*p == '\0') | |
3114 | p += strcspn(p, SEPARATOR); /* find end of word */ | 3245 | break; |
3115 | if (*p) *p++ = '\0'; /* mark it */ | 3246 | |
3116 | } | 3247 | p += strcspn(p, SEPARATOR); /* find end of word */ |
3117 | if (nargc == 0) { | 3248 | if (*p) |
3118 | free(env); | 3249 | *p++ = '\0'; /* mark it */ |
3119 | return NULL; | 3250 | } |
3120 | } | 3251 | if (nargc == 0) { |
3121 | *argcp += nargc; | 3252 | free(env); |
3122 | /* Allocate the new argv array, with an extra element just in case | 3253 | return NULL; |
3123 | * the original arg list did not end with a NULL. | 3254 | } |
3124 | */ | 3255 | *argcp += nargc; |
3125 | nargv = (char**)calloc(*argcp+1, sizeof(char *)); | 3256 | /* Allocate the new argv array, with an extra element just in case |
3126 | if (nargv == NULL) error("out of memory"); | 3257 | * the original arg list did not end with a NULL. |
3127 | oargv = *argvp; | 3258 | */ |
3128 | *argvp = nargv; | 3259 | nargv = (char **) calloc(*argcp + 1, sizeof(char *)); |
3129 | 3260 | ||
3130 | /* Copy the program name first */ | 3261 | if (nargv == NULL) |
3131 | if (oargc-- < 0) error("argc<=0"); | 3262 | error("out of memory"); |
3132 | *(nargv++) = *(oargv++); | 3263 | oargv = *argvp; |
3133 | 3264 | *argvp = nargv; | |
3134 | /* Then copy the environment args */ | 3265 | |
3135 | for (p = env; nargc > 0; nargc--) { | 3266 | /* Copy the program name first */ |
3136 | p += strspn(p, SEPARATOR); /* skip separators */ | 3267 | if (oargc-- < 0) |
3137 | *(nargv++) = p; /* store start */ | 3268 | error("argc<=0"); |
3138 | while (*p++) ; /* skip over word */ | 3269 | *(nargv++) = *(oargv++); |
3139 | } | 3270 | |
3140 | 3271 | /* Then copy the environment args */ | |
3141 | /* Finally copy the old args and add a NULL (usual convention) */ | 3272 | for (p = env; nargc > 0; nargc--) { |
3142 | while (oargc--) *(nargv++) = *(oargv++); | 3273 | p += strspn(p, SEPARATOR); /* skip separators */ |
3143 | *nargv = NULL; | 3274 | *(nargv++) = p; /* store start */ |
3144 | return env; | 3275 | while (*p++); /* skip over word */ |
3276 | } | ||
3277 | |||
3278 | /* Finally copy the old args and add a NULL (usual convention) */ | ||
3279 | while (oargc--) | ||
3280 | *(nargv++) = *(oargv++); | ||
3281 | *nargv = NULL; | ||
3282 | return env; | ||
3145 | } | 3283 | } |
3284 | |||
3146 | /* ======================================================================== | 3285 | /* ======================================================================== |
3147 | * Display compression ratio on the given stream on 6 characters. | 3286 | * Display compression ratio on the given stream on 6 characters. |
3148 | */ | 3287 | */ |
3149 | void display_ratio(num, den, file) | 3288 | void display_ratio(num, den, file) |
3150 | long num; | 3289 | long num; |
3151 | long den; | 3290 | long den; |
3152 | FILE *file; | 3291 | FILE *file; |
3153 | { | 3292 | { |
3154 | long ratio; /* 1000 times the compression ratio */ | 3293 | long ratio; /* 1000 times the compression ratio */ |
3155 | 3294 | ||
3156 | if (den == 0) { | 3295 | if (den == 0) { |
3157 | ratio = 0; /* no compression */ | 3296 | ratio = 0; /* no compression */ |
3158 | } else if (den < 2147483L) { /* (2**31 -1)/1000 */ | 3297 | } else if (den < 2147483L) { /* (2**31 -1)/1000 */ |
3159 | ratio = 1000L*num/den; | 3298 | ratio = 1000L * num / den; |
3160 | } else { | 3299 | } else { |
3161 | ratio = num/(den/1000L); | 3300 | ratio = num / (den / 1000L); |
3162 | } | 3301 | } |
3163 | if (ratio < 0) { | 3302 | if (ratio < 0) { |
3164 | putc('-', file); | 3303 | putc('-', file); |
3165 | ratio = -ratio; | 3304 | ratio = -ratio; |
3166 | } else { | 3305 | } else { |
3167 | putc(' ', file); | 3306 | putc(' ', file); |
3168 | } | 3307 | } |
3169 | fprintf(file, "%2ld.%1ld%%", ratio / 10L, ratio % 10L); | 3308 | fprintf(file, "%2ld.%1ld%%", ratio / 10L, ratio % 10L); |
3170 | } | 3309 | } |
3171 | 3310 | ||
3172 | 3311 | ||
@@ -3186,8 +3325,8 @@ void display_ratio(num, den, file) | |||
3186 | # include <fcntl.h> | 3325 | # include <fcntl.h> |
3187 | #endif | 3326 | #endif |
3188 | 3327 | ||
3189 | local ulg crc; /* crc on uncompressed file data */ | 3328 | local ulg crc; /* crc on uncompressed file data */ |
3190 | long header_bytes; /* number of bytes in gzip header */ | 3329 | long header_bytes; /* number of bytes in gzip header */ |
3191 | 3330 | ||
3192 | /* =========================================================================== | 3331 | /* =========================================================================== |
3193 | * Deflate in to out. | 3332 | * Deflate in to out. |
@@ -3195,48 +3334,48 @@ long header_bytes; /* number of bytes in gzip header */ | |||
3195 | * The variables time_stamp and save_orig_name are initialized. | 3334 | * The variables time_stamp and save_orig_name are initialized. |
3196 | */ | 3335 | */ |
3197 | int zip(in, out) | 3336 | int zip(in, out) |
3198 | int in, out; /* input and output file descriptors */ | 3337 | int in, out; /* input and output file descriptors */ |
3199 | { | 3338 | { |
3200 | uch flags = 0; /* general purpose bit flags */ | 3339 | uch flags = 0; /* general purpose bit flags */ |
3201 | ush attr = 0; /* ascii/binary flag */ | 3340 | ush attr = 0; /* ascii/binary flag */ |
3202 | ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ | 3341 | ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ |
3203 | 3342 | ||
3204 | ifd = in; | 3343 | ifd = in; |
3205 | ofd = out; | 3344 | ofd = out; |
3206 | outcnt = 0; | 3345 | outcnt = 0; |
3207 | 3346 | ||
3208 | /* Write the header to the gzip file. See algorithm.doc for the format */ | 3347 | /* Write the header to the gzip file. See algorithm.doc for the format */ |
3209 | 3348 | ||
3210 | 3349 | ||
3211 | method = DEFLATED; | 3350 | method = DEFLATED; |
3212 | put_byte(GZIP_MAGIC[0]); /* magic header */ | 3351 | put_byte(GZIP_MAGIC[0]); /* magic header */ |
3213 | put_byte(GZIP_MAGIC[1]); | 3352 | put_byte(GZIP_MAGIC[1]); |
3214 | put_byte(DEFLATED); /* compression method */ | 3353 | put_byte(DEFLATED); /* compression method */ |
3215 | 3354 | ||
3216 | put_byte(flags); /* general flags */ | 3355 | put_byte(flags); /* general flags */ |
3217 | put_long(time_stamp); | 3356 | put_long(time_stamp); |
3218 | 3357 | ||
3219 | /* Write deflated file to zip file */ | 3358 | /* Write deflated file to zip file */ |
3220 | crc = updcrc(0, 0); | 3359 | crc = updcrc(0, 0); |
3221 | 3360 | ||
3222 | bi_init(out); | 3361 | bi_init(out); |
3223 | ct_init(&attr, &method); | 3362 | ct_init(&attr, &method); |
3224 | lm_init(&deflate_flags); | 3363 | lm_init(&deflate_flags); |
3225 | 3364 | ||
3226 | put_byte((uch)deflate_flags); /* extra flags */ | 3365 | put_byte((uch) deflate_flags); /* extra flags */ |
3227 | put_byte(OS_CODE); /* OS identifier */ | 3366 | put_byte(OS_CODE); /* OS identifier */ |
3228 | 3367 | ||
3229 | header_bytes = (long)outcnt; | 3368 | header_bytes = (long) outcnt; |
3230 | 3369 | ||
3231 | (void)deflate(); | 3370 | (void) deflate(); |
3232 | 3371 | ||
3233 | /* Write the crc and uncompressed size */ | 3372 | /* Write the crc and uncompressed size */ |
3234 | put_long(crc); | 3373 | put_long(crc); |
3235 | put_long(isize); | 3374 | put_long(isize); |
3236 | header_bytes += 2*sizeof(long); | 3375 | header_bytes += 2 * sizeof(long); |
3237 | 3376 | ||
3238 | flush_outbuf(); | 3377 | flush_outbuf(); |
3239 | return OK; | 3378 | return OK; |
3240 | } | 3379 | } |
3241 | 3380 | ||
3242 | 3381 | ||
@@ -3246,18 +3385,19 @@ int zip(in, out) | |||
3246 | * IN assertion: size >= 2 (for end-of-line translation) | 3385 | * IN assertion: size >= 2 (for end-of-line translation) |
3247 | */ | 3386 | */ |
3248 | int file_read(buf, size) | 3387 | int file_read(buf, size) |
3249 | char *buf; | 3388 | char *buf; |
3250 | unsigned size; | 3389 | unsigned size; |
3251 | { | 3390 | { |
3252 | unsigned len; | 3391 | unsigned len; |
3253 | 3392 | ||
3254 | Assert(insize == 0, "inbuf not empty"); | 3393 | Assert(insize == 0, "inbuf not empty"); |
3255 | 3394 | ||
3256 | len = read(ifd, buf, size); | 3395 | len = read(ifd, buf, size); |
3257 | if (len == (unsigned)(-1) || len == 0) return (int)len; | 3396 | if (len == (unsigned) (-1) || len == 0) |
3397 | return (int) len; | ||
3258 | 3398 | ||
3259 | crc = updcrc((uch*)buf, len); | 3399 | crc = updcrc((uch *) buf, len); |
3260 | isize += (ulg)len; | 3400 | isize += (ulg) len; |
3261 | return (int)len; | 3401 | return (int) len; |
3262 | } | 3402 | } |
3263 | #endif | 3403 | #endif |
diff --git a/archival/tar.c b/archival/tar.c index 6496231ae..87b5d2176 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini tar implementation for busybox based on code taken from sash. | 3 | * Mini tar implementation for busybox based on code taken from sash. |
3 | * | 4 | * |
@@ -40,27 +41,29 @@ | |||
40 | #include <utime.h> | 41 | #include <utime.h> |
41 | #include <sys/types.h> | 42 | #include <sys/types.h> |
42 | #include <sys/sysmacros.h> | 43 | #include <sys/sysmacros.h> |
43 | #include <sys/param.h> /* for PATH_MAX */ | 44 | #include <sys/param.h> /* for PATH_MAX */ |
44 | 45 | ||
45 | 46 | ||
46 | #ifdef BB_FEATURE_TAR_CREATE | 47 | #ifdef BB_FEATURE_TAR_CREATE |
47 | 48 | ||
48 | static const char tar_usage[] = | 49 | static const char tar_usage[] = |
49 | "tar -[cxtvOf] [tarFileName] [FILE] ...\n\n" | 50 | "tar -[cxtvOf] [tarFileName] [FILE] ...\n\n" |
50 | "Create, extract, or list files from a tar file.\n\n" | 51 | "Create, extract, or list files from a tar file.\n\n" |
51 | "Options:\n" | 52 | "Options:\n" |
52 | "\tc=create, x=extract, t=list contents, v=verbose,\n" | 53 | |
53 | "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; | 54 | "\tc=create, x=extract, t=list contents, v=verbose,\n" |
55 | "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; | ||
54 | 56 | ||
55 | #else | 57 | #else |
56 | 58 | ||
57 | static const char tar_usage[] = | 59 | static const char tar_usage[] = |
58 | "tar -[xtvOf] [tarFileName] [FILE] ...\n\n" | 60 | "tar -[xtvOf] [tarFileName] [FILE] ...\n\n" |
59 | "Extract, or list files stored in a tar file. This\n" | 61 | "Extract, or list files stored in a tar file. This\n" |
60 | "version of tar does not support creation of tar files.\n\n" | 62 | "version of tar does not support creation of tar files.\n\n" |
61 | "Options:\n" | 63 | "Options:\n" |
62 | "\tx=extract, t=list contents, v=verbose,\n" | 64 | |
63 | "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; | 65 | "\tx=extract, t=list contents, v=verbose,\n" |
66 | "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; | ||
64 | 67 | ||
65 | #endif | 68 | #endif |
66 | 69 | ||
@@ -78,22 +81,22 @@ static const char tar_usage[] = | |||
78 | * with zero padding. We only process this information minimally. | 81 | * with zero padding. We only process this information minimally. |
79 | */ | 82 | */ |
80 | typedef struct { | 83 | typedef struct { |
81 | char name[TAR_NAME_SIZE]; | 84 | char name[TAR_NAME_SIZE]; |
82 | char mode[8]; | 85 | char mode[8]; |
83 | char uid[8]; | 86 | char uid[8]; |
84 | char gid[8]; | 87 | char gid[8]; |
85 | char size[12]; | 88 | char size[12]; |
86 | char mtime[12]; | 89 | char mtime[12]; |
87 | char checkSum[8]; | 90 | char checkSum[8]; |
88 | char typeFlag; | 91 | char typeFlag; |
89 | char linkName[TAR_NAME_SIZE]; | 92 | char linkName[TAR_NAME_SIZE]; |
90 | char magic[6]; | 93 | char magic[6]; |
91 | char version[2]; | 94 | char version[2]; |
92 | char uname[32]; | 95 | char uname[32]; |
93 | char gname[32]; | 96 | char gname[32]; |
94 | char devMajor[8]; | 97 | char devMajor[8]; |
95 | char devMinor[8]; | 98 | char devMinor[8]; |
96 | char prefix[155]; | 99 | char prefix[155]; |
97 | } TarHeader; | 100 | } TarHeader; |
98 | 101 | ||
99 | #define TAR_MAGIC "ustar" | 102 | #define TAR_MAGIC "ustar" |
@@ -113,7 +116,7 @@ static int createFlag; | |||
113 | static int verboseFlag; | 116 | static int verboseFlag; |
114 | static int tostdoutFlag; | 117 | static int tostdoutFlag; |
115 | 118 | ||
116 | static int inHeader; // <- check me | 119 | static int inHeader; // <- check me |
117 | static int badHeader; | 120 | static int badHeader; |
118 | static int errorFlag; | 121 | static int errorFlag; |
119 | static int skipFileFlag; | 122 | static int skipFileFlag; |
@@ -140,141 +143,145 @@ static ino_t tarInode; | |||
140 | /* | 143 | /* |
141 | * Local procedures to restore files from a tar file. | 144 | * Local procedures to restore files from a tar file. |
142 | */ | 145 | */ |
143 | static void readTarFile (int fileCount, char **fileTable); | 146 | static void readTarFile(int fileCount, char **fileTable); |
144 | static void readData (const char *cp, int count); | 147 | static void readData(const char *cp, int count); |
145 | static long getOctal (const char *cp, int len); | 148 | static long getOctal(const char *cp, int len); |
149 | |||
150 | static void readHeader(const TarHeader * hp, | ||
146 | 151 | ||
147 | static void readHeader (const TarHeader * hp, | 152 | int fileCount, char **fileTable); |
148 | int fileCount, char **fileTable); | ||
149 | 153 | ||
150 | static int wantFileName (const char *fileName, | 154 | static int wantFileName(const char *fileName, |
151 | int fileCount, char **fileTable); | 155 | |
156 | int fileCount, char **fileTable); | ||
152 | 157 | ||
153 | #ifdef BB_FEATURE_TAR_CREATE | 158 | #ifdef BB_FEATURE_TAR_CREATE |
154 | /* | 159 | /* |
155 | * Local procedures to save files into a tar file. | 160 | * Local procedures to save files into a tar file. |
156 | */ | 161 | */ |
157 | static void saveFile (const char *fileName, int seeLinks); | 162 | static void saveFile(const char *fileName, int seeLinks); |
163 | |||
164 | static void saveRegularFile(const char *fileName, | ||
158 | 165 | ||
159 | static void saveRegularFile (const char *fileName, | 166 | const struct stat *statbuf); |
160 | const struct stat *statbuf); | ||
161 | 167 | ||
162 | static void saveDirectory (const char *fileName, | 168 | static void saveDirectory(const char *fileName, |
163 | const struct stat *statbuf); | ||
164 | 169 | ||
165 | static void writeHeader (const char *fileName, const struct stat *statbuf); | 170 | const struct stat *statbuf); |
166 | 171 | ||
167 | static void writeTarFile (int fileCount, char **fileTable); | 172 | static void writeHeader(const char *fileName, const struct stat *statbuf); |
168 | static void writeTarBlock (const char *buf, int len); | 173 | |
169 | static int putOctal (char *cp, int len, long value); | 174 | static void writeTarFile(int fileCount, char **fileTable); |
175 | static void writeTarBlock(const char *buf, int len); | ||
176 | static int putOctal(char *cp, int len, long value); | ||
170 | 177 | ||
171 | #endif | 178 | #endif |
172 | 179 | ||
173 | 180 | ||
174 | extern int tar_main (int argc, char **argv) | 181 | extern int tar_main(int argc, char **argv) |
175 | { | 182 | { |
176 | const char *options; | 183 | const char *options; |
177 | 184 | ||
178 | argc--; | 185 | argc--; |
179 | argv++; | 186 | argv++; |
180 | 187 | ||
181 | if (argc < 1) | 188 | if (argc < 1) |
182 | usage( tar_usage); | 189 | usage(tar_usage); |
183 | 190 | ||
184 | 191 | ||
185 | errorFlag = FALSE; | 192 | errorFlag = FALSE; |
186 | extractFlag = FALSE; | 193 | extractFlag = FALSE; |
187 | createFlag = FALSE; | 194 | createFlag = FALSE; |
188 | listFlag = FALSE; | 195 | listFlag = FALSE; |
189 | verboseFlag = FALSE; | 196 | verboseFlag = FALSE; |
190 | tostdoutFlag = FALSE; | 197 | tostdoutFlag = FALSE; |
191 | tarName = NULL; | 198 | tarName = NULL; |
192 | tarDev = 0; | 199 | tarDev = 0; |
193 | tarInode = 0; | 200 | tarInode = 0; |
194 | tarFd = -1; | 201 | tarFd = -1; |
195 | 202 | ||
196 | /* | 203 | /* |
197 | * Parse the options. | 204 | * Parse the options. |
198 | */ | 205 | */ |
199 | if (**argv == '-') | 206 | if (**argv == '-') |
200 | options = (*argv++) + 1; | 207 | options = (*argv++) + 1; |
201 | else | 208 | else |
202 | options = (*argv++); | 209 | options = (*argv++); |
203 | argc--; | 210 | argc--; |
204 | 211 | ||
205 | for (; *options; options++) { | 212 | for (; *options; options++) { |
206 | switch (*options) { | 213 | switch (*options) { |
207 | case 'f': | 214 | case 'f': |
208 | if (tarName != NULL) { | 215 | if (tarName != NULL) { |
209 | fprintf (stderr, "Only one 'f' option allowed\n"); | 216 | fprintf(stderr, "Only one 'f' option allowed\n"); |
210 | 217 | ||
211 | exit (FALSE); | 218 | exit(FALSE); |
212 | } | 219 | } |
213 | 220 | ||
214 | tarName = *argv++; | 221 | tarName = *argv++; |
215 | argc--; | 222 | argc--; |
216 | 223 | ||
217 | break; | 224 | break; |
218 | 225 | ||
219 | case 't': | 226 | case 't': |
220 | if (extractFlag == TRUE || createFlag == TRUE ) | 227 | if (extractFlag == TRUE || createFlag == TRUE) |
221 | goto flagError; | 228 | goto flagError; |
222 | listFlag = TRUE; | 229 | listFlag = TRUE; |
223 | break; | 230 | break; |
224 | 231 | ||
225 | case 'x': | 232 | case 'x': |
226 | if (listFlag == TRUE || createFlag == TRUE ) | 233 | if (listFlag == TRUE || createFlag == TRUE) |
227 | goto flagError; | 234 | goto flagError; |
228 | extractFlag = TRUE; | 235 | extractFlag = TRUE; |
229 | break; | 236 | break; |
230 | case 'c': | 237 | case 'c': |
231 | if (extractFlag == TRUE || listFlag == TRUE) | 238 | if (extractFlag == TRUE || listFlag == TRUE) |
232 | goto flagError; | 239 | goto flagError; |
233 | createFlag = TRUE; | 240 | createFlag = TRUE; |
234 | break; | 241 | break; |
235 | 242 | ||
236 | case 'v': | 243 | case 'v': |
237 | verboseFlag = TRUE; | 244 | verboseFlag = TRUE; |
238 | break; | 245 | break; |
239 | 246 | ||
240 | case 'O': | 247 | case 'O': |
241 | tostdoutFlag = TRUE; | 248 | tostdoutFlag = TRUE; |
242 | break; | 249 | break; |
243 | 250 | ||
244 | case '-': | 251 | case '-': |
245 | usage( tar_usage); | 252 | usage(tar_usage); |
246 | break; | 253 | break; |
247 | 254 | ||
248 | default: | 255 | default: |
249 | fprintf (stderr, "Unknown tar flag '%c'\n" | 256 | fprintf(stderr, "Unknown tar flag '%c'\n" |
250 | "Try `tar --help' for more information\n", | 257 | "Try `tar --help' for more information\n", *options); |
251 | *options); | 258 | exit(FALSE); |
252 | exit (FALSE); | 259 | } |
253 | } | 260 | } |
254 | } | ||
255 | 261 | ||
256 | /* | 262 | /* |
257 | * Do the correct type of action supplying the rest of the | 263 | * Do the correct type of action supplying the rest of the |
258 | * command line arguments as the list of files to process. | 264 | * command line arguments as the list of files to process. |
259 | */ | 265 | */ |
260 | if (createFlag==TRUE) { | 266 | if (createFlag == TRUE) { |
261 | #ifndef BB_FEATURE_TAR_CREATE | 267 | #ifndef BB_FEATURE_TAR_CREATE |
262 | fprintf (stderr, "This version of tar was not compiled with tar creation support.\n" ); | 268 | fprintf(stderr, |
263 | exit (FALSE); | 269 | "This version of tar was not compiled with tar creation support.\n"); |
270 | exit(FALSE); | ||
264 | #else | 271 | #else |
265 | writeTarFile (argc, argv); | 272 | writeTarFile(argc, argv); |
266 | #endif | 273 | #endif |
267 | } else { | 274 | } else { |
268 | readTarFile (argc, argv); | 275 | readTarFile(argc, argv); |
269 | } | 276 | } |
270 | if (errorFlag==TRUE) { | 277 | if (errorFlag == TRUE) { |
271 | fprintf (stderr, "\n"); | 278 | fprintf(stderr, "\n"); |
272 | } | 279 | } |
273 | exit (!errorFlag); | 280 | exit(!errorFlag); |
274 | 281 | ||
275 | flagError: | 282 | flagError: |
276 | fprintf (stderr, "Exactly one of 'c', 'x' or 't' must be specified\n"); | 283 | fprintf(stderr, "Exactly one of 'c', 'x' or 't' must be specified\n"); |
277 | exit (FALSE); | 284 | exit(FALSE); |
278 | } | 285 | } |
279 | 286 | ||
280 | 287 | ||
@@ -282,120 +289,120 @@ flagError: | |||
282 | * Read a tar file and extract or list the specified files within it. | 289 | * Read a tar file and extract or list the specified files within it. |
283 | * If the list is empty than all files are extracted or listed. | 290 | * If the list is empty than all files are extracted or listed. |
284 | */ | 291 | */ |
285 | static void readTarFile (int fileCount, char **fileTable) | 292 | static void readTarFile(int fileCount, char **fileTable) |
286 | { | 293 | { |
287 | const char *cp; | 294 | const char *cp; |
288 | int cc; | 295 | int cc; |
289 | int inCc; | 296 | int inCc; |
290 | int blockSize; | 297 | int blockSize; |
291 | char buf[BUF_SIZE]; | 298 | char buf[BUF_SIZE]; |
292 | 299 | ||
293 | skipFileFlag = FALSE; | 300 | skipFileFlag = FALSE; |
294 | badHeader = FALSE; | 301 | badHeader = FALSE; |
295 | warnedRoot = FALSE; | 302 | warnedRoot = FALSE; |
296 | eofFlag = FALSE; | 303 | eofFlag = FALSE; |
297 | inHeader = TRUE; | 304 | inHeader = TRUE; |
298 | inCc = 0; | 305 | inCc = 0; |
299 | dataCc = 0; | 306 | dataCc = 0; |
300 | outFd = -1; | 307 | outFd = -1; |
301 | blockSize = sizeof (buf); | 308 | blockSize = sizeof(buf); |
302 | cp = buf; | 309 | cp = buf; |
303 | 310 | ||
304 | /* | ||
305 | * Open the tar file for reading. | ||
306 | */ | ||
307 | if ((tarName == NULL) || !strcmp (tarName, "-")) { | ||
308 | tarFd = fileno(stdin); | ||
309 | } else | ||
310 | tarFd = open (tarName, O_RDONLY); | ||
311 | |||
312 | if (tarFd < 0) { | ||
313 | perror (tarName); | ||
314 | errorFlag = TRUE; | ||
315 | return; | ||
316 | } | ||
317 | |||
318 | /* | ||
319 | * Read blocks from the file until an end of file header block | ||
320 | * has been seen. (A real end of file from a read is an error.) | ||
321 | */ | ||
322 | while (eofFlag==FALSE) { | ||
323 | /* | 311 | /* |
324 | * Read the next block of data if necessary. | 312 | * Open the tar file for reading. |
325 | * This will be a large block if possible, which we will | ||
326 | * then process in the small tar blocks. | ||
327 | */ | 313 | */ |
328 | if (inCc <= 0) { | 314 | if ((tarName == NULL) || !strcmp(tarName, "-")) { |
329 | cp = buf; | 315 | tarFd = fileno(stdin); |
330 | inCc = fullRead (tarFd, buf, blockSize); | 316 | } else |
331 | 317 | tarFd = open(tarName, O_RDONLY); | |
332 | if (inCc < 0) { | ||
333 | perror (tarName); | ||
334 | errorFlag = TRUE; | ||
335 | goto done; | ||
336 | } | ||
337 | 318 | ||
338 | if (inCc == 0) { | 319 | if (tarFd < 0) { |
339 | fprintf (stderr, | 320 | perror(tarName); |
340 | "Unexpected end of file from \"%s\"", tarName); | ||
341 | errorFlag = TRUE; | 321 | errorFlag = TRUE; |
342 | goto done; | 322 | return; |
343 | } | ||
344 | } | 323 | } |
345 | 324 | ||
346 | /* | 325 | /* |
347 | * If we are expecting a header block then examine it. | 326 | * Read blocks from the file until an end of file header block |
327 | * has been seen. (A real end of file from a read is an error.) | ||
348 | */ | 328 | */ |
349 | if (inHeader==TRUE) { | 329 | while (eofFlag == FALSE) { |
350 | readHeader ((const TarHeader *) cp, fileCount, fileTable); | 330 | /* |
351 | 331 | * Read the next block of data if necessary. | |
352 | cp += TAR_BLOCK_SIZE; | 332 | * This will be a large block if possible, which we will |
353 | inCc -= TAR_BLOCK_SIZE; | 333 | * then process in the small tar blocks. |
354 | 334 | */ | |
355 | continue; | 335 | if (inCc <= 0) { |
336 | cp = buf; | ||
337 | inCc = fullRead(tarFd, buf, blockSize); | ||
338 | |||
339 | if (inCc < 0) { | ||
340 | perror(tarName); | ||
341 | errorFlag = TRUE; | ||
342 | goto done; | ||
343 | } | ||
344 | |||
345 | if (inCc == 0) { | ||
346 | fprintf(stderr, | ||
347 | "Unexpected end of file from \"%s\"", tarName); | ||
348 | errorFlag = TRUE; | ||
349 | goto done; | ||
350 | } | ||
351 | } | ||
352 | |||
353 | /* | ||
354 | * If we are expecting a header block then examine it. | ||
355 | */ | ||
356 | if (inHeader == TRUE) { | ||
357 | readHeader((const TarHeader *) cp, fileCount, fileTable); | ||
358 | |||
359 | cp += TAR_BLOCK_SIZE; | ||
360 | inCc -= TAR_BLOCK_SIZE; | ||
361 | |||
362 | continue; | ||
363 | } | ||
364 | |||
365 | /* | ||
366 | * We are currently handling the data for a file. | ||
367 | * Process the minimum of the amount of data we have available | ||
368 | * and the amount left to be processed for the file. | ||
369 | */ | ||
370 | cc = inCc; | ||
371 | |||
372 | if (cc > dataCc) | ||
373 | cc = dataCc; | ||
374 | |||
375 | readData(cp, cc); | ||
376 | |||
377 | /* | ||
378 | * If the amount left isn't an exact multiple of the tar block | ||
379 | * size then round it up to the next block boundary since there | ||
380 | * is padding at the end of the file. | ||
381 | */ | ||
382 | if (cc % TAR_BLOCK_SIZE) | ||
383 | cc += TAR_BLOCK_SIZE - (cc % TAR_BLOCK_SIZE); | ||
384 | |||
385 | cp += cc; | ||
386 | inCc -= cc; | ||
356 | } | 387 | } |
357 | 388 | ||
389 | done: | ||
358 | /* | 390 | /* |
359 | * We are currently handling the data for a file. | 391 | * Close the tar file if needed. |
360 | * Process the minimum of the amount of data we have available | ||
361 | * and the amount left to be processed for the file. | ||
362 | */ | 392 | */ |
363 | cc = inCc; | 393 | if ((tarFd >= 0) && (close(tarFd) < 0)) |
364 | 394 | perror(tarName); | |
365 | if (cc > dataCc) | ||
366 | cc = dataCc; | ||
367 | |||
368 | readData (cp, cc); | ||
369 | 395 | ||
370 | /* | 396 | /* |
371 | * If the amount left isn't an exact multiple of the tar block | 397 | * Close the output file if needed. |
372 | * size then round it up to the next block boundary since there | 398 | * This is only done here on a previous error and so no |
373 | * is padding at the end of the file. | 399 | * message is required on errors. |
374 | */ | 400 | */ |
375 | if (cc % TAR_BLOCK_SIZE) | 401 | if (tostdoutFlag == FALSE) { |
376 | cc += TAR_BLOCK_SIZE - (cc % TAR_BLOCK_SIZE); | 402 | if (outFd >= 0) { |
377 | 403 | close(outFd); | |
378 | cp += cc; | 404 | } |
379 | inCc -= cc; | ||
380 | } | ||
381 | |||
382 | done: | ||
383 | /* | ||
384 | * Close the tar file if needed. | ||
385 | */ | ||
386 | if ((tarFd >= 0) && (close (tarFd) < 0)) | ||
387 | perror (tarName); | ||
388 | |||
389 | /* | ||
390 | * Close the output file if needed. | ||
391 | * This is only done here on a previous error and so no | ||
392 | * message is required on errors. | ||
393 | */ | ||
394 | if (tostdoutFlag == FALSE) { | ||
395 | if (outFd >= 0) { | ||
396 | close (outFd); | ||
397 | } | 405 | } |
398 | } | ||
399 | } | 406 | } |
400 | 407 | ||
401 | 408 | ||
@@ -405,304 +412,305 @@ static void readTarFile (int fileCount, char **fileTable) | |||
405 | * the end of the tar file. | 412 | * the end of the tar file. |
406 | */ | 413 | */ |
407 | static void | 414 | static void |
408 | readHeader (const TarHeader * hp, int fileCount, char **fileTable) | 415 | readHeader(const TarHeader * hp, int fileCount, char **fileTable) |
409 | { | 416 | { |
410 | int checkSum; | 417 | int checkSum; |
411 | int cc; | 418 | int cc; |
412 | int hardLink; | 419 | int hardLink; |
413 | int softLink; | 420 | int softLink; |
414 | int devFileFlag; | 421 | int devFileFlag; |
415 | unsigned int major; | 422 | unsigned int major; |
416 | unsigned int minor; | 423 | unsigned int minor; |
417 | long size; | 424 | long size; |
418 | struct utimbuf utb; | 425 | struct utimbuf utb; |
419 | 426 | ||
420 | /* | 427 | /* |
421 | * If the block is completely empty, then this is the end of the | 428 | * If the block is completely empty, then this is the end of the |
422 | * archive file. If the name is null, then just skip this header. | 429 | * archive file. If the name is null, then just skip this header. |
423 | */ | 430 | */ |
424 | outName = hp->name; | 431 | outName = hp->name; |
425 | 432 | ||
426 | if (*outName == '\0') { | 433 | if (*outName == '\0') { |
427 | for (cc = TAR_BLOCK_SIZE; cc > 0; cc--) { | 434 | for (cc = TAR_BLOCK_SIZE; cc > 0; cc--) { |
428 | if (*outName++) | 435 | if (*outName++) |
436 | return; | ||
437 | } | ||
438 | |||
439 | eofFlag = TRUE; | ||
440 | |||
429 | return; | 441 | return; |
430 | } | 442 | } |
431 | 443 | ||
432 | eofFlag = TRUE; | 444 | /* |
433 | 445 | * There is another file in the archive to examine. | |
434 | return; | 446 | * Extract the encoded information and check it. |
435 | } | 447 | */ |
436 | 448 | mode = getOctal(hp->mode, sizeof(hp->mode)); | |
437 | /* | 449 | uid = getOctal(hp->uid, sizeof(hp->uid)); |
438 | * There is another file in the archive to examine. | 450 | gid = getOctal(hp->gid, sizeof(hp->gid)); |
439 | * Extract the encoded information and check it. | 451 | size = getOctal(hp->size, sizeof(hp->size)); |
440 | */ | 452 | mtime = getOctal(hp->mtime, sizeof(hp->mtime)); |
441 | mode = getOctal (hp->mode, sizeof (hp->mode)); | 453 | checkSum = getOctal(hp->checkSum, sizeof(hp->checkSum)); |
442 | uid = getOctal (hp->uid, sizeof (hp->uid)); | 454 | major = getOctal(hp->devMajor, sizeof(hp->devMajor)); |
443 | gid = getOctal (hp->gid, sizeof (hp->gid)); | 455 | minor = getOctal(hp->devMinor, sizeof(hp->devMinor)); |
444 | size = getOctal (hp->size, sizeof (hp->size)); | ||
445 | mtime = getOctal (hp->mtime, sizeof (hp->mtime)); | ||
446 | checkSum = getOctal (hp->checkSum, sizeof (hp->checkSum)); | ||
447 | major = getOctal (hp->devMajor, sizeof (hp->devMajor)); | ||
448 | minor = getOctal (hp->devMinor, sizeof (hp->devMinor)); | ||
449 | |||
450 | if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0)) { | ||
451 | if (badHeader==FALSE) | ||
452 | fprintf (stderr, "Bad tar header, skipping\n"); | ||
453 | |||
454 | badHeader = TRUE; | ||
455 | |||
456 | return; | ||
457 | } | ||
458 | |||
459 | badHeader = FALSE; | ||
460 | skipFileFlag = FALSE; | ||
461 | devFileFlag = FALSE; | ||
462 | |||
463 | /* | ||
464 | * Check for the file modes. | ||
465 | */ | ||
466 | hardLink = ((hp->typeFlag == TAR_TYPE_HARD_LINK) || | ||
467 | (hp->typeFlag == TAR_TYPE_HARD_LINK - '0')); | ||
468 | |||
469 | softLink = ((hp->typeFlag == TAR_TYPE_SOFT_LINK) || | ||
470 | (hp->typeFlag == TAR_TYPE_SOFT_LINK - '0')); | ||
471 | |||
472 | /* | ||
473 | * Check for a directory. | ||
474 | */ | ||
475 | if (outName[strlen (outName) - 1] == '/') | ||
476 | mode |= S_IFDIR; | ||
477 | |||
478 | /* | ||
479 | * Check for absolute paths in the file. | ||
480 | * If we find any, then warn the user and make them relative. | ||
481 | */ | ||
482 | if (*outName == '/') { | ||
483 | while (*outName == '/') | ||
484 | outName++; | ||
485 | |||
486 | if (warnedRoot==FALSE) { | ||
487 | fprintf (stderr, | ||
488 | "Absolute path detected, removing leading slashes\n"); | ||
489 | } | ||
490 | 456 | ||
491 | warnedRoot = TRUE; | 457 | if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0)) { |
492 | } | 458 | if (badHeader == FALSE) |
493 | 459 | fprintf(stderr, "Bad tar header, skipping\n"); | |
494 | /* | ||
495 | * See if we want this file to be restored. | ||
496 | * If not, then set up to skip it. | ||
497 | */ | ||
498 | if (wantFileName (outName, fileCount, fileTable) == FALSE) { | ||
499 | if ( !hardLink && !softLink && (S_ISREG (mode) || S_ISCHR (mode) | ||
500 | || S_ISBLK (mode) || S_ISSOCK(mode) || S_ISFIFO(mode) ) ) { | ||
501 | inHeader = (size == 0)? TRUE : FALSE; | ||
502 | dataCc = size; | ||
503 | } | ||
504 | 460 | ||
505 | skipFileFlag = TRUE; | 461 | badHeader = TRUE; |
506 | 462 | ||
507 | return; | 463 | return; |
508 | } | ||
509 | |||
510 | /* | ||
511 | * This file is to be handled. | ||
512 | * If we aren't extracting then just list information about the file. | ||
513 | */ | ||
514 | if (extractFlag==FALSE) { | ||
515 | if (verboseFlag==TRUE) { | ||
516 | printf ("%s %3d/%-d ", modeString (mode), uid, gid); | ||
517 | if( S_ISCHR (mode) || S_ISBLK (mode) ) | ||
518 | printf ("%4d,%4d %s ", major,minor, timeString (mtime)); | ||
519 | else | ||
520 | printf ("%9ld %s ", size, timeString (mtime)); | ||
521 | } | ||
522 | printf ("%s", outName); | ||
523 | |||
524 | if (hardLink) | ||
525 | printf (" (link to \"%s\")", hp->linkName); | ||
526 | else if (softLink) | ||
527 | printf (" (symlink to \"%s\")", hp->linkName); | ||
528 | else if (S_ISREG (mode) || S_ISCHR (mode) || S_ISBLK (mode) || | ||
529 | S_ISSOCK(mode) || S_ISFIFO(mode) ) { | ||
530 | inHeader = (size == 0)? TRUE : FALSE; | ||
531 | dataCc = size; | ||
532 | } | 464 | } |
533 | 465 | ||
534 | printf ("\n"); | 466 | badHeader = FALSE; |
467 | skipFileFlag = FALSE; | ||
468 | devFileFlag = FALSE; | ||
535 | 469 | ||
536 | return; | 470 | /* |
537 | } | 471 | * Check for the file modes. |
472 | */ | ||
473 | hardLink = ((hp->typeFlag == TAR_TYPE_HARD_LINK) || | ||
474 | (hp->typeFlag == TAR_TYPE_HARD_LINK - '0')); | ||
475 | |||
476 | softLink = ((hp->typeFlag == TAR_TYPE_SOFT_LINK) || | ||
477 | (hp->typeFlag == TAR_TYPE_SOFT_LINK - '0')); | ||
478 | |||
479 | /* | ||
480 | * Check for a directory. | ||
481 | */ | ||
482 | if (outName[strlen(outName) - 1] == '/') | ||
483 | mode |= S_IFDIR; | ||
484 | |||
485 | /* | ||
486 | * Check for absolute paths in the file. | ||
487 | * If we find any, then warn the user and make them relative. | ||
488 | */ | ||
489 | if (*outName == '/') { | ||
490 | while (*outName == '/') | ||
491 | outName++; | ||
538 | 492 | ||
539 | /* | 493 | if (warnedRoot == FALSE) { |
540 | * We really want to extract the file. | 494 | fprintf(stderr, |
541 | */ | 495 | "Absolute path detected, removing leading slashes\n"); |
542 | if (verboseFlag==TRUE) | 496 | } |
543 | printf ("x %s\n", outName); | ||
544 | 497 | ||
545 | if (hardLink) { | 498 | warnedRoot = TRUE; |
546 | if (link (hp->linkName, outName) < 0) { | ||
547 | perror (outName); | ||
548 | return; | ||
549 | } | 499 | } |
550 | /* Set the file time */ | 500 | |
551 | utb.actime = mtime; | 501 | /* |
552 | utb.modtime = mtime; | 502 | * See if we want this file to be restored. |
553 | utime (outName, &utb); | 503 | * If not, then set up to skip it. |
554 | /* Set the file permissions */ | 504 | */ |
555 | chown(outName, uid, gid); | 505 | if (wantFileName(outName, fileCount, fileTable) == FALSE) { |
556 | chmod(outName, mode); | 506 | if (!hardLink && !softLink && (S_ISREG(mode) || S_ISCHR(mode) |
557 | return; | 507 | || S_ISBLK(mode) || S_ISSOCK(mode) |
558 | } | 508 | || S_ISFIFO(mode))) { |
559 | 509 | inHeader = (size == 0) ? TRUE : FALSE; | |
560 | if (softLink) { | 510 | dataCc = size; |
561 | #ifdef S_ISLNK | 511 | } |
562 | if (symlink (hp->linkName, outName) < 0) { | 512 | |
563 | perror (outName); | 513 | skipFileFlag = TRUE; |
564 | return; | 514 | |
515 | return; | ||
565 | } | 516 | } |
566 | /* Try to change ownership of the symlink. | 517 | |
567 | * If libs doesn't support that, don't bother. | 518 | /* |
568 | * Changing the pointed-to file is the Wrong Thing(tm). | 519 | * This file is to be handled. |
520 | * If we aren't extracting then just list information about the file. | ||
569 | */ | 521 | */ |
522 | if (extractFlag == FALSE) { | ||
523 | if (verboseFlag == TRUE) { | ||
524 | printf("%s %3d/%-d ", modeString(mode), uid, gid); | ||
525 | if (S_ISCHR(mode) || S_ISBLK(mode)) | ||
526 | printf("%4d,%4d %s ", major, minor, timeString(mtime)); | ||
527 | else | ||
528 | printf("%9ld %s ", size, timeString(mtime)); | ||
529 | } | ||
530 | printf("%s", outName); | ||
531 | |||
532 | if (hardLink) | ||
533 | printf(" (link to \"%s\")", hp->linkName); | ||
534 | else if (softLink) | ||
535 | printf(" (symlink to \"%s\")", hp->linkName); | ||
536 | else if (S_ISREG(mode) || S_ISCHR(mode) || S_ISBLK(mode) || | ||
537 | S_ISSOCK(mode) || S_ISFIFO(mode)) { | ||
538 | inHeader = (size == 0) ? TRUE : FALSE; | ||
539 | dataCc = size; | ||
540 | } | ||
541 | |||
542 | printf("\n"); | ||
543 | |||
544 | return; | ||
545 | } | ||
546 | |||
547 | /* | ||
548 | * We really want to extract the file. | ||
549 | */ | ||
550 | if (verboseFlag == TRUE) | ||
551 | printf("x %s\n", outName); | ||
552 | |||
553 | if (hardLink) { | ||
554 | if (link(hp->linkName, outName) < 0) { | ||
555 | perror(outName); | ||
556 | return; | ||
557 | } | ||
558 | /* Set the file time */ | ||
559 | utb.actime = mtime; | ||
560 | utb.modtime = mtime; | ||
561 | utime(outName, &utb); | ||
562 | /* Set the file permissions */ | ||
563 | chown(outName, uid, gid); | ||
564 | chmod(outName, mode); | ||
565 | return; | ||
566 | } | ||
567 | |||
568 | if (softLink) { | ||
569 | #ifdef S_ISLNK | ||
570 | if (symlink(hp->linkName, outName) < 0) { | ||
571 | perror(outName); | ||
572 | return; | ||
573 | } | ||
574 | /* Try to change ownership of the symlink. | ||
575 | * If libs doesn't support that, don't bother. | ||
576 | * Changing the pointed-to file is the Wrong Thing(tm). | ||
577 | */ | ||
570 | #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) | 578 | #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) |
571 | lchown(outName, uid, gid); | 579 | lchown(outName, uid, gid); |
572 | #endif | 580 | #endif |
573 | 581 | ||
574 | /* Do not change permissions or date on symlink, | 582 | /* Do not change permissions or date on symlink, |
575 | * since it changes the pointed to file instead. duh. */ | 583 | * since it changes the pointed to file instead. duh. */ |
576 | #else | 584 | #else |
577 | fprintf (stderr, "Cannot create symbolic links\n"); | 585 | fprintf(stderr, "Cannot create symbolic links\n"); |
578 | #endif | 586 | #endif |
579 | return; | 587 | return; |
580 | } | ||
581 | |||
582 | /* Set the umask for this process so it doesn't | ||
583 | * screw things up. */ | ||
584 | umask(0); | ||
585 | |||
586 | /* | ||
587 | * If the file is a directory, then just create the path. | ||
588 | */ | ||
589 | if (S_ISDIR (mode)) { | ||
590 | if (createPath (outName, mode)==TRUE) { | ||
591 | /* Set the file time */ | ||
592 | utb.actime = mtime; | ||
593 | utb.modtime = mtime; | ||
594 | utime (outName, &utb); | ||
595 | /* Set the file permissions */ | ||
596 | chown(outName, uid, gid); | ||
597 | chmod(outName, mode); | ||
598 | return; | ||
599 | } | 588 | } |
600 | return; | 589 | |
601 | } | 590 | /* Set the umask for this process so it doesn't |
602 | 591 | * screw things up. */ | |
603 | /* | 592 | umask(0); |
604 | * There is a file to write. | 593 | |
605 | * First create the path to it if necessary with default permissions. | 594 | /* |
606 | */ | 595 | * If the file is a directory, then just create the path. |
607 | createPath (outName, 0777); | 596 | */ |
608 | 597 | if (S_ISDIR(mode)) { | |
609 | inHeader = (size == 0)? TRUE : FALSE; | 598 | if (createPath(outName, mode) == TRUE) { |
610 | dataCc = size; | 599 | /* Set the file time */ |
611 | 600 | utb.actime = mtime; | |
612 | /* | 601 | utb.modtime = mtime; |
613 | * Start the output file. | 602 | utime(outName, &utb); |
614 | */ | 603 | /* Set the file permissions */ |
615 | if (tostdoutFlag == TRUE) | 604 | chown(outName, uid, gid); |
616 | outFd = fileno(stdout); | 605 | chmod(outName, mode); |
617 | else { | 606 | return; |
618 | if ( S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) ) { | 607 | } |
619 | devFileFlag = TRUE; | 608 | return; |
620 | outFd = mknod (outName, mode, makedev(major, minor) ); | ||
621 | } | 609 | } |
622 | else if (S_ISFIFO(mode) ) { | 610 | |
623 | devFileFlag = TRUE; | 611 | /* |
624 | outFd = mkfifo(outName, mode); | 612 | * There is a file to write. |
625 | } else { | 613 | * First create the path to it if necessary with default permissions. |
626 | outFd = open (outName, O_WRONLY | O_CREAT | O_TRUNC, mode); | 614 | */ |
615 | createPath(outName, 0777); | ||
616 | |||
617 | inHeader = (size == 0) ? TRUE : FALSE; | ||
618 | dataCc = size; | ||
619 | |||
620 | /* | ||
621 | * Start the output file. | ||
622 | */ | ||
623 | if (tostdoutFlag == TRUE) | ||
624 | outFd = fileno(stdout); | ||
625 | else { | ||
626 | if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode)) { | ||
627 | devFileFlag = TRUE; | ||
628 | outFd = mknod(outName, mode, makedev(major, minor)); | ||
629 | } else if (S_ISFIFO(mode)) { | ||
630 | devFileFlag = TRUE; | ||
631 | outFd = mkfifo(outName, mode); | ||
632 | } else { | ||
633 | outFd = open(outName, O_WRONLY | O_CREAT | O_TRUNC, mode); | ||
634 | } | ||
635 | if (outFd < 0) { | ||
636 | perror(outName); | ||
637 | skipFileFlag = TRUE; | ||
638 | return; | ||
639 | } | ||
640 | /* Set the file time */ | ||
641 | utb.actime = mtime; | ||
642 | utb.modtime = mtime; | ||
643 | utime(outName, &utb); | ||
644 | /* Set the file permissions */ | ||
645 | chown(outName, uid, gid); | ||
646 | chmod(outName, mode); | ||
627 | } | 647 | } |
628 | if (outFd < 0) { | 648 | |
629 | perror (outName); | 649 | |
630 | skipFileFlag = TRUE; | 650 | /* |
631 | return; | 651 | * If the file is empty, then that's all we need to do. |
652 | */ | ||
653 | if (size == 0 && (tostdoutFlag == FALSE) && (devFileFlag == FALSE)) { | ||
654 | close(outFd); | ||
655 | outFd = -1; | ||
632 | } | 656 | } |
633 | /* Set the file time */ | ||
634 | utb.actime = mtime; | ||
635 | utb.modtime = mtime; | ||
636 | utime (outName, &utb); | ||
637 | /* Set the file permissions */ | ||
638 | chown(outName, uid, gid); | ||
639 | chmod(outName, mode); | ||
640 | } | ||
641 | |||
642 | |||
643 | /* | ||
644 | * If the file is empty, then that's all we need to do. | ||
645 | */ | ||
646 | if (size == 0 && (tostdoutFlag == FALSE) && (devFileFlag == FALSE)) { | ||
647 | close (outFd); | ||
648 | outFd = -1; | ||
649 | } | ||
650 | } | 657 | } |
651 | 658 | ||
652 | 659 | ||
653 | /* | 660 | /* |
654 | * Handle a data block of some specified size that was read. | 661 | * Handle a data block of some specified size that was read. |
655 | */ | 662 | */ |
656 | static void readData (const char *cp, int count) | 663 | static void readData(const char *cp, int count) |
657 | { | 664 | { |
658 | /* | 665 | /* |
659 | * Reduce the amount of data left in this file. | 666 | * Reduce the amount of data left in this file. |
660 | * If there is no more data left, then we need to read | 667 | * If there is no more data left, then we need to read |
661 | * the header again. | 668 | * the header again. |
662 | */ | 669 | */ |
663 | dataCc -= count; | 670 | dataCc -= count; |
664 | |||
665 | if (dataCc <= 0) | ||
666 | inHeader = TRUE; | ||
667 | 671 | ||
668 | /* | 672 | if (dataCc <= 0) |
669 | * If we aren't extracting files or this file is being | 673 | inHeader = TRUE; |
670 | * skipped then do nothing more. | 674 | |
671 | */ | 675 | /* |
672 | if (extractFlag==FALSE || skipFileFlag==TRUE) | 676 | * If we aren't extracting files or this file is being |
673 | return; | 677 | * skipped then do nothing more. |
674 | 678 | */ | |
675 | /* | 679 | if (extractFlag == FALSE || skipFileFlag == TRUE) |
676 | * Write the data to the output file. | 680 | return; |
677 | */ | 681 | |
678 | if (fullWrite (outFd, cp, count) < 0) { | 682 | /* |
679 | perror (outName); | 683 | * Write the data to the output file. |
680 | if (tostdoutFlag == FALSE) { | 684 | */ |
681 | close (outFd); | 685 | if (fullWrite(outFd, cp, count) < 0) { |
682 | outFd = -1; | 686 | perror(outName); |
687 | if (tostdoutFlag == FALSE) { | ||
688 | close(outFd); | ||
689 | outFd = -1; | ||
690 | } | ||
691 | skipFileFlag = TRUE; | ||
692 | return; | ||
683 | } | 693 | } |
684 | skipFileFlag = TRUE; | ||
685 | return; | ||
686 | } | ||
687 | |||
688 | /* | ||
689 | * Check if we are done writing to the file now. | ||
690 | */ | ||
691 | if (dataCc <= 0 && tostdoutFlag == FALSE) { | ||
692 | struct utimbuf utb; | ||
693 | if (close (outFd)) | ||
694 | perror (outName); | ||
695 | 694 | ||
696 | /* Set the file time */ | 695 | /* |
697 | utb.actime = mtime; | 696 | * Check if we are done writing to the file now. |
698 | utb.modtime = mtime; | 697 | */ |
699 | utime (outName, &utb); | 698 | if (dataCc <= 0 && tostdoutFlag == FALSE) { |
700 | /* Set the file permissions */ | 699 | struct utimbuf utb; |
701 | chown(outName, uid, gid); | 700 | |
702 | chmod(outName, mode); | 701 | if (close(outFd)) |
702 | perror(outName); | ||
703 | 703 | ||
704 | outFd = -1; | 704 | /* Set the file time */ |
705 | } | 705 | utb.actime = mtime; |
706 | utb.modtime = mtime; | ||
707 | utime(outName, &utb); | ||
708 | /* Set the file permissions */ | ||
709 | chown(outName, uid, gid); | ||
710 | chmod(outName, mode); | ||
711 | |||
712 | outFd = -1; | ||
713 | } | ||
706 | } | 714 | } |
707 | 715 | ||
708 | 716 | ||
@@ -712,40 +720,40 @@ static void readData (const char *cp, int count) | |||
712 | * Returns TRUE if the file is selected. | 720 | * Returns TRUE if the file is selected. |
713 | */ | 721 | */ |
714 | static int | 722 | static int |
715 | wantFileName (const char *fileName, int fileCount, char **fileTable) | 723 | wantFileName(const char *fileName, int fileCount, char **fileTable) |
716 | { | 724 | { |
717 | const char *pathName; | 725 | const char *pathName; |
718 | int fileLength; | 726 | int fileLength; |
719 | int pathLength; | 727 | int pathLength; |
720 | 728 | ||
721 | /* | 729 | /* |
722 | * If there are no files in the list, then the file is wanted. | 730 | * If there are no files in the list, then the file is wanted. |
723 | */ | 731 | */ |
724 | if (fileCount == 0) | 732 | if (fileCount == 0) |
725 | return TRUE; | 733 | return TRUE; |
726 | 734 | ||
727 | fileLength = strlen (fileName); | 735 | fileLength = strlen(fileName); |
728 | 736 | ||
729 | /* | 737 | /* |
730 | * Check each of the test paths. | 738 | * Check each of the test paths. |
731 | */ | 739 | */ |
732 | while (fileCount-- > 0) { | 740 | while (fileCount-- > 0) { |
733 | pathName = *fileTable++; | 741 | pathName = *fileTable++; |
734 | 742 | ||
735 | pathLength = strlen (pathName); | 743 | pathLength = strlen(pathName); |
736 | 744 | ||
737 | if (fileLength < pathLength) | 745 | if (fileLength < pathLength) |
738 | continue; | 746 | continue; |
739 | 747 | ||
740 | if (memcmp (fileName, pathName, pathLength) != 0) | 748 | if (memcmp(fileName, pathName, pathLength) != 0) |
741 | continue; | 749 | continue; |
742 | 750 | ||
743 | if ((fileLength == pathLength) || (fileName[pathLength] == '/')) { | 751 | if ((fileLength == pathLength) || (fileName[pathLength] == '/')) { |
744 | return TRUE; | 752 | return TRUE; |
753 | } | ||
745 | } | 754 | } |
746 | } | ||
747 | 755 | ||
748 | return FALSE; | 756 | return FALSE; |
749 | } | 757 | } |
750 | 758 | ||
751 | /* | 759 | /* |
@@ -753,34 +761,34 @@ wantFileName (const char *fileName, int fileCount, char **fileTable) | |||
753 | * spaces on both sides of the number and with an optional null character | 761 | * spaces on both sides of the number and with an optional null character |
754 | * at the end. Returns -1 on an illegal format. | 762 | * at the end. Returns -1 on an illegal format. |
755 | */ | 763 | */ |
756 | static long getOctal (const char *cp, int len) | 764 | static long getOctal(const char *cp, int len) |
757 | { | 765 | { |
758 | long val; | 766 | long val; |
759 | 767 | ||
760 | while ((len > 0) && (*cp == ' ')) { | 768 | while ((len > 0) && (*cp == ' ')) { |
761 | cp++; | 769 | cp++; |
762 | len--; | 770 | len--; |
763 | } | 771 | } |
764 | 772 | ||
765 | if ((len == 0) || !isOctal (*cp)) | 773 | if ((len == 0) || !isOctal(*cp)) |
766 | return -1; | 774 | return -1; |
767 | 775 | ||
768 | val = 0; | 776 | val = 0; |
769 | 777 | ||
770 | while ((len > 0) && isOctal (*cp)) { | 778 | while ((len > 0) && isOctal(*cp)) { |
771 | val = val * 8 + *cp++ - '0'; | 779 | val = val * 8 + *cp++ - '0'; |
772 | len--; | 780 | len--; |
773 | } | 781 | } |
774 | 782 | ||
775 | while ((len > 0) && (*cp == ' ')) { | 783 | while ((len > 0) && (*cp == ' ')) { |
776 | cp++; | 784 | cp++; |
777 | len--; | 785 | len--; |
778 | } | 786 | } |
779 | 787 | ||
780 | if ((len > 0) && *cp) | 788 | if ((len > 0) && *cp) |
781 | return -1; | 789 | return -1; |
782 | 790 | ||
783 | return val; | 791 | return val; |
784 | } | 792 | } |
785 | 793 | ||
786 | 794 | ||
@@ -795,65 +803,65 @@ static long getOctal (const char *cp, int len) | |||
795 | /* | 803 | /* |
796 | * Write a tar file containing the specified files. | 804 | * Write a tar file containing the specified files. |
797 | */ | 805 | */ |
798 | static void writeTarFile (int fileCount, char **fileTable) | 806 | static void writeTarFile(int fileCount, char **fileTable) |
799 | { | 807 | { |
800 | struct stat statbuf; | 808 | struct stat statbuf; |
801 | 809 | ||
802 | /* | 810 | /* |
803 | * Make sure there is at least one file specified. | 811 | * Make sure there is at least one file specified. |
804 | */ | 812 | */ |
805 | if (fileCount <= 0) { | 813 | if (fileCount <= 0) { |
806 | fprintf (stderr, "No files specified to be saved\n"); | 814 | fprintf(stderr, "No files specified to be saved\n"); |
807 | errorFlag = TRUE; | 815 | errorFlag = TRUE; |
808 | } | 816 | } |
809 | 817 | ||
810 | /* | 818 | /* |
811 | * Create the tar file for writing. | 819 | * Create the tar file for writing. |
812 | */ | 820 | */ |
813 | if ((tarName == NULL) || !strcmp (tarName, "-")) { | 821 | if ((tarName == NULL) || !strcmp(tarName, "-")) { |
814 | tostdoutFlag = TRUE; | 822 | tostdoutFlag = TRUE; |
815 | tarFd = fileno(stdout); | 823 | tarFd = fileno(stdout); |
816 | } else | 824 | } else |
817 | tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0666); | 825 | tarFd = open(tarName, O_WRONLY | O_CREAT | O_TRUNC, 0666); |
818 | 826 | ||
819 | if (tarFd < 0) { | 827 | if (tarFd < 0) { |
820 | perror (tarName); | 828 | perror(tarName); |
821 | errorFlag = TRUE; | 829 | errorFlag = TRUE; |
822 | return; | 830 | return; |
823 | } | 831 | } |
824 | 832 | ||
825 | /* | 833 | /* |
826 | * Get the device and inode of the tar file for checking later. | 834 | * Get the device and inode of the tar file for checking later. |
827 | */ | 835 | */ |
828 | if (fstat (tarFd, &statbuf) < 0) { | 836 | if (fstat(tarFd, &statbuf) < 0) { |
829 | perror (tarName); | 837 | perror(tarName); |
830 | errorFlag = TRUE; | 838 | errorFlag = TRUE; |
831 | goto done; | 839 | goto done; |
832 | } | 840 | } |
833 | 841 | ||
834 | tarDev = statbuf.st_dev; | 842 | tarDev = statbuf.st_dev; |
835 | tarInode = statbuf.st_ino; | 843 | tarInode = statbuf.st_ino; |
836 | 844 | ||
837 | /* | 845 | /* |
838 | * Append each file name into the archive file. | 846 | * Append each file name into the archive file. |
839 | * Follow symbolic links for these top level file names. | 847 | * Follow symbolic links for these top level file names. |
840 | */ | 848 | */ |
841 | while (errorFlag==FALSE && (fileCount-- > 0)) { | 849 | while (errorFlag == FALSE && (fileCount-- > 0)) { |
842 | saveFile (*fileTable++, FALSE); | 850 | saveFile(*fileTable++, FALSE); |
843 | } | 851 | } |
844 | 852 | ||
845 | /* | 853 | /* |
846 | * Now write an empty block of zeroes to end the archive. | 854 | * Now write an empty block of zeroes to end the archive. |
847 | */ | 855 | */ |
848 | writeTarBlock ("", 1); | 856 | writeTarBlock("", 1); |
849 | 857 | ||
850 | 858 | ||
851 | done: | 859 | done: |
852 | /* | 860 | /* |
853 | * Close the tar file and check for errors if it was opened. | 861 | * Close the tar file and check for errors if it was opened. |
854 | */ | 862 | */ |
855 | if ((tostdoutFlag == FALSE) && (tarFd >= 0) && (close (tarFd) < 0)) | 863 | if ((tostdoutFlag == FALSE) && (tarFd >= 0) && (close(tarFd) < 0)) |
856 | perror (tarName); | 864 | perror(tarName); |
857 | } | 865 | } |
858 | 866 | ||
859 | /* | 867 | /* |
@@ -863,73 +871,73 @@ static void writeTarFile (int fileCount, char **fileTable) | |||
863 | * flag indicates whether or not we want to see symbolic links as | 871 | * flag indicates whether or not we want to see symbolic links as |
864 | * they really are, instead of blindly following them. | 872 | * they really are, instead of blindly following them. |
865 | */ | 873 | */ |
866 | static void saveFile (const char *fileName, int seeLinks) | 874 | static void saveFile(const char *fileName, int seeLinks) |
867 | { | 875 | { |
868 | int status; | 876 | int status; |
869 | struct stat statbuf; | 877 | struct stat statbuf; |
870 | 878 | ||
871 | if (verboseFlag==TRUE) | 879 | if (verboseFlag == TRUE) |
872 | printf ("a %s\n", fileName); | 880 | printf("a %s\n", fileName); |
873 | 881 | ||
874 | /* | 882 | /* |
875 | * Check that the file name will fit in the header. | 883 | * Check that the file name will fit in the header. |
876 | */ | 884 | */ |
877 | if (strlen (fileName) >= TAR_NAME_SIZE) { | 885 | if (strlen(fileName) >= TAR_NAME_SIZE) { |
878 | fprintf (stderr, "%s: File name is too long\n", fileName); | 886 | fprintf(stderr, "%s: File name is too long\n", fileName); |
879 | 887 | ||
880 | return; | 888 | return; |
881 | } | 889 | } |
882 | 890 | ||
883 | /* | 891 | /* |
884 | * Find out about the file. | 892 | * Find out about the file. |
885 | */ | 893 | */ |
886 | #ifdef S_ISLNK | 894 | #ifdef S_ISLNK |
887 | if (seeLinks==TRUE) | 895 | if (seeLinks == TRUE) |
888 | status = lstat (fileName, &statbuf); | 896 | status = lstat(fileName, &statbuf); |
889 | else | 897 | else |
890 | #endif | 898 | #endif |
891 | status = stat (fileName, &statbuf); | 899 | status = stat(fileName, &statbuf); |
892 | 900 | ||
893 | if (status < 0) { | 901 | if (status < 0) { |
894 | perror (fileName); | 902 | perror(fileName); |
903 | |||
904 | return; | ||
905 | } | ||
895 | 906 | ||
896 | return; | 907 | /* |
897 | } | 908 | * Make sure we aren't trying to save our file into itself. |
909 | */ | ||
910 | if ((statbuf.st_dev == tarDev) && (statbuf.st_ino == tarInode)) { | ||
911 | fprintf(stderr, "Skipping saving of archive file itself\n"); | ||
898 | 912 | ||
899 | /* | 913 | return; |
900 | * Make sure we aren't trying to save our file into itself. | 914 | } |
901 | */ | ||
902 | if ((statbuf.st_dev == tarDev) && (statbuf.st_ino == tarInode)) { | ||
903 | fprintf (stderr, "Skipping saving of archive file itself\n"); | ||
904 | 915 | ||
905 | return; | 916 | /* |
906 | } | 917 | * Check the type of file. |
918 | */ | ||
919 | mode = statbuf.st_mode; | ||
907 | 920 | ||
908 | /* | 921 | if (S_ISDIR(mode)) { |
909 | * Check the type of file. | 922 | saveDirectory(fileName, &statbuf); |
910 | */ | ||
911 | mode = statbuf.st_mode; | ||
912 | 923 | ||
913 | if (S_ISDIR (mode)) { | 924 | return; |
914 | saveDirectory (fileName, &statbuf); | 925 | } |
926 | if (S_ISREG(mode)) { | ||
927 | saveRegularFile(fileName, &statbuf); | ||
915 | 928 | ||
916 | return; | 929 | return; |
917 | } | 930 | } |
918 | if (S_ISREG (mode)) { | ||
919 | saveRegularFile (fileName, &statbuf); | ||
920 | 931 | ||
921 | return; | 932 | /* Some day add support for tarring these up... but not today. :) */ |
922 | } | ||
923 | |||
924 | /* Some day add support for tarring these up... but not today. :) */ | ||
925 | // if (S_ISLNK(mode) || S_ISFIFO(mode) || S_ISBLK(mode) || S_ISCHR (mode) ) { | 933 | // if (S_ISLNK(mode) || S_ISFIFO(mode) || S_ISBLK(mode) || S_ISCHR (mode) ) { |
926 | // fprintf (stderr, "%s: This version of tar can't store this type of file\n", fileName); | 934 | // fprintf (stderr, "%s: This version of tar can't store this type of file\n", fileName); |
927 | // } | 935 | // } |
928 | 936 | ||
929 | /* | 937 | /* |
930 | * The file is a strange type of file, ignore it. | 938 | * The file is a strange type of file, ignore it. |
931 | */ | 939 | */ |
932 | fprintf (stderr, "%s: not a directory or regular file\n", fileName); | 940 | fprintf(stderr, "%s: not a directory or regular file\n", fileName); |
933 | } | 941 | } |
934 | 942 | ||
935 | 943 | ||
@@ -937,173 +945,172 @@ static void saveFile (const char *fileName, int seeLinks) | |||
937 | * Save a regular file to the tar file. | 945 | * Save a regular file to the tar file. |
938 | */ | 946 | */ |
939 | static void | 947 | static void |
940 | saveRegularFile (const char *fileName, const struct stat *statbuf) | 948 | saveRegularFile(const char *fileName, const struct stat *statbuf) |
941 | { | 949 | { |
942 | int sawEof; | 950 | int sawEof; |
943 | int fileFd; | 951 | int fileFd; |
944 | int cc; | 952 | int cc; |
945 | int dataCount; | 953 | int dataCount; |
946 | long fullDataCount; | 954 | long fullDataCount; |
947 | char data[TAR_BLOCK_SIZE * 16]; | 955 | char data[TAR_BLOCK_SIZE * 16]; |
948 | |||
949 | /* | ||
950 | * Open the file for reading. | ||
951 | */ | ||
952 | fileFd = open (fileName, O_RDONLY); | ||
953 | |||
954 | if (fileFd < 0) { | ||
955 | perror (fileName); | ||
956 | |||
957 | return; | ||
958 | } | ||
959 | |||
960 | /* | ||
961 | * Write out the header for the file. | ||
962 | */ | ||
963 | writeHeader (fileName, statbuf); | ||
964 | |||
965 | /* | ||
966 | * Write the data blocks of the file. | ||
967 | * We must be careful to write the amount of data that the stat | ||
968 | * buffer indicated, even if the file has changed size. Otherwise | ||
969 | * the tar file will be incorrect. | ||
970 | */ | ||
971 | fullDataCount = statbuf->st_size; | ||
972 | sawEof = FALSE; | ||
973 | |||
974 | while (fullDataCount > 0) { | ||
975 | /* | ||
976 | * Get the amount to write this iteration which is | ||
977 | * the minumum of the amount left to write and the | ||
978 | * buffer size. | ||
979 | */ | ||
980 | dataCount = sizeof (data); | ||
981 | |||
982 | if (dataCount > fullDataCount) | ||
983 | dataCount = (int) fullDataCount; | ||
984 | 956 | ||
985 | /* | 957 | /* |
986 | * Read the data from the file if we haven't seen the | 958 | * Open the file for reading. |
987 | * end of file yet. | ||
988 | */ | 959 | */ |
989 | cc = 0; | 960 | fileFd = open(fileName, O_RDONLY); |
990 | |||
991 | if (sawEof==FALSE) { | ||
992 | cc = fullRead (fileFd, data, dataCount); | ||
993 | 961 | ||
994 | if (cc < 0) { | 962 | if (fileFd < 0) { |
995 | perror (fileName); | 963 | perror(fileName); |
996 | |||
997 | (void) close (fileFd); | ||
998 | errorFlag = TRUE; | ||
999 | 964 | ||
1000 | return; | 965 | return; |
1001 | } | ||
1002 | |||
1003 | /* | ||
1004 | * If the file ended too soon, complain and set | ||
1005 | * a flag so we will zero fill the rest of it. | ||
1006 | */ | ||
1007 | if (cc < dataCount) { | ||
1008 | fprintf (stderr, | ||
1009 | "%s: Short read - zero filling", fileName); | ||
1010 | |||
1011 | sawEof = TRUE; | ||
1012 | } | ||
1013 | } | 966 | } |
1014 | 967 | ||
1015 | /* | 968 | /* |
1016 | * Zero fill the rest of the data if necessary. | 969 | * Write out the header for the file. |
1017 | */ | 970 | */ |
1018 | if (cc < dataCount) | 971 | writeHeader(fileName, statbuf); |
1019 | memset (data + cc, 0, dataCount - cc); | ||
1020 | 972 | ||
1021 | /* | 973 | /* |
1022 | * Write the buffer to the TAR file. | 974 | * Write the data blocks of the file. |
975 | * We must be careful to write the amount of data that the stat | ||
976 | * buffer indicated, even if the file has changed size. Otherwise | ||
977 | * the tar file will be incorrect. | ||
1023 | */ | 978 | */ |
1024 | writeTarBlock (data, dataCount); | 979 | fullDataCount = statbuf->st_size; |
1025 | 980 | sawEof = FALSE; | |
1026 | fullDataCount -= dataCount; | 981 | |
1027 | } | 982 | while (fullDataCount > 0) { |
983 | /* | ||
984 | * Get the amount to write this iteration which is | ||
985 | * the minumum of the amount left to write and the | ||
986 | * buffer size. | ||
987 | */ | ||
988 | dataCount = sizeof(data); | ||
989 | |||
990 | if (dataCount > fullDataCount) | ||
991 | dataCount = (int) fullDataCount; | ||
992 | |||
993 | /* | ||
994 | * Read the data from the file if we haven't seen the | ||
995 | * end of file yet. | ||
996 | */ | ||
997 | cc = 0; | ||
998 | |||
999 | if (sawEof == FALSE) { | ||
1000 | cc = fullRead(fileFd, data, dataCount); | ||
1001 | |||
1002 | if (cc < 0) { | ||
1003 | perror(fileName); | ||
1004 | |||
1005 | (void) close(fileFd); | ||
1006 | errorFlag = TRUE; | ||
1007 | |||
1008 | return; | ||
1009 | } | ||
1010 | |||
1011 | /* | ||
1012 | * If the file ended too soon, complain and set | ||
1013 | * a flag so we will zero fill the rest of it. | ||
1014 | */ | ||
1015 | if (cc < dataCount) { | ||
1016 | fprintf(stderr, "%s: Short read - zero filling", fileName); | ||
1017 | |||
1018 | sawEof = TRUE; | ||
1019 | } | ||
1020 | } | ||
1021 | |||
1022 | /* | ||
1023 | * Zero fill the rest of the data if necessary. | ||
1024 | */ | ||
1025 | if (cc < dataCount) | ||
1026 | memset(data + cc, 0, dataCount - cc); | ||
1027 | |||
1028 | /* | ||
1029 | * Write the buffer to the TAR file. | ||
1030 | */ | ||
1031 | writeTarBlock(data, dataCount); | ||
1032 | |||
1033 | fullDataCount -= dataCount; | ||
1034 | } | ||
1028 | 1035 | ||
1029 | /* | 1036 | /* |
1030 | * Close the file. | 1037 | * Close the file. |
1031 | */ | 1038 | */ |
1032 | if ((tostdoutFlag == FALSE) && close (fileFd) < 0) | 1039 | if ((tostdoutFlag == FALSE) && close(fileFd) < 0) |
1033 | fprintf (stderr, "%s: close: %s\n", fileName, strerror (errno)); | 1040 | fprintf(stderr, "%s: close: %s\n", fileName, strerror(errno)); |
1034 | } | 1041 | } |
1035 | 1042 | ||
1036 | 1043 | ||
1037 | /* | 1044 | /* |
1038 | * Save a directory and all of its files to the tar file. | 1045 | * Save a directory and all of its files to the tar file. |
1039 | */ | 1046 | */ |
1040 | static void saveDirectory (const char *dirName, const struct stat *statbuf) | 1047 | static void saveDirectory(const char *dirName, const struct stat *statbuf) |
1041 | { | 1048 | { |
1042 | DIR *dir; | 1049 | DIR *dir; |
1043 | struct dirent *entry; | 1050 | struct dirent *entry; |
1044 | int needSlash; | 1051 | int needSlash; |
1045 | char fullName[PATH_MAX + 1]; | 1052 | char fullName[PATH_MAX + 1]; |
1046 | 1053 | ||
1047 | /* | 1054 | /* |
1048 | * Construct the directory name as used in the tar file by appending | 1055 | * Construct the directory name as used in the tar file by appending |
1049 | * a slash character to it. | 1056 | * a slash character to it. |
1050 | */ | 1057 | */ |
1051 | strcpy (fullName, dirName); | 1058 | strcpy(fullName, dirName); |
1052 | strcat (fullName, "/"); | 1059 | strcat(fullName, "/"); |
1053 | 1060 | ||
1054 | /* | 1061 | /* |
1055 | * Write out the header for the directory entry. | 1062 | * Write out the header for the directory entry. |
1056 | */ | 1063 | */ |
1057 | writeHeader (fullName, statbuf); | 1064 | writeHeader(fullName, statbuf); |
1058 | |||
1059 | /* | ||
1060 | * Open the directory. | ||
1061 | */ | ||
1062 | dir = opendir (dirName); | ||
1063 | |||
1064 | if (dir == NULL) { | ||
1065 | fprintf (stderr, "Cannot read directory \"%s\": %s\n", | ||
1066 | dirName, strerror (errno)); | ||
1067 | |||
1068 | return; | ||
1069 | } | ||
1070 | |||
1071 | /* | ||
1072 | * See if a slash is needed. | ||
1073 | */ | ||
1074 | needSlash = (*dirName && (dirName[strlen (dirName) - 1] != '/')); | ||
1075 | |||
1076 | /* | ||
1077 | * Read all of the directory entries and check them, | ||
1078 | * except for the current and parent directory entries. | ||
1079 | */ | ||
1080 | while (errorFlag==FALSE && ((entry = readdir (dir)) != NULL)) { | ||
1081 | if ((strcmp (entry->d_name, ".") == 0) || | ||
1082 | (strcmp (entry->d_name, "..") == 0)) { | ||
1083 | continue; | ||
1084 | } | ||
1085 | 1065 | ||
1086 | /* | 1066 | /* |
1087 | * Build the full path name to the file. | 1067 | * Open the directory. |
1088 | */ | 1068 | */ |
1089 | strcpy (fullName, dirName); | 1069 | dir = opendir(dirName); |
1070 | |||
1071 | if (dir == NULL) { | ||
1072 | fprintf(stderr, "Cannot read directory \"%s\": %s\n", | ||
1073 | dirName, strerror(errno)); | ||
1090 | 1074 | ||
1091 | if (needSlash) | 1075 | return; |
1092 | strcat (fullName, "/"); | 1076 | } |
1093 | 1077 | ||
1094 | strcat (fullName, entry->d_name); | 1078 | /* |
1079 | * See if a slash is needed. | ||
1080 | */ | ||
1081 | needSlash = (*dirName && (dirName[strlen(dirName) - 1] != '/')); | ||
1095 | 1082 | ||
1096 | /* | 1083 | /* |
1097 | * Write this file to the tar file, noticing whether or not | 1084 | * Read all of the directory entries and check them, |
1098 | * the file is a symbolic link. | 1085 | * except for the current and parent directory entries. |
1099 | */ | 1086 | */ |
1100 | saveFile (fullName, TRUE); | 1087 | while (errorFlag == FALSE && ((entry = readdir(dir)) != NULL)) { |
1101 | } | 1088 | if ((strcmp(entry->d_name, ".") == 0) || |
1089 | (strcmp(entry->d_name, "..") == 0)) { | ||
1090 | continue; | ||
1091 | } | ||
1092 | |||
1093 | /* | ||
1094 | * Build the full path name to the file. | ||
1095 | */ | ||
1096 | strcpy(fullName, dirName); | ||
1097 | |||
1098 | if (needSlash) | ||
1099 | strcat(fullName, "/"); | ||
1100 | |||
1101 | strcat(fullName, entry->d_name); | ||
1102 | |||
1103 | /* | ||
1104 | * Write this file to the tar file, noticing whether or not | ||
1105 | * the file is a symbolic link. | ||
1106 | */ | ||
1107 | saveFile(fullName, TRUE); | ||
1108 | } | ||
1102 | 1109 | ||
1103 | /* | 1110 | /* |
1104 | * All done, close the directory. | 1111 | * All done, close the directory. |
1105 | */ | 1112 | */ |
1106 | closedir (dir); | 1113 | closedir(dir); |
1107 | } | 1114 | } |
1108 | 1115 | ||
1109 | 1116 | ||
@@ -1111,54 +1118,54 @@ static void saveDirectory (const char *dirName, const struct stat *statbuf) | |||
1111 | * Write a tar header for the specified file name and status. | 1118 | * Write a tar header for the specified file name and status. |
1112 | * It is assumed that the file name fits. | 1119 | * It is assumed that the file name fits. |
1113 | */ | 1120 | */ |
1114 | static void writeHeader (const char *fileName, const struct stat *statbuf) | 1121 | static void writeHeader(const char *fileName, const struct stat *statbuf) |
1115 | { | 1122 | { |
1116 | long checkSum; | 1123 | long checkSum; |
1117 | const unsigned char *cp; | 1124 | const unsigned char *cp; |
1118 | int len; | 1125 | int len; |
1119 | TarHeader header; | 1126 | TarHeader header; |
1120 | 1127 | ||
1121 | /* | 1128 | /* |
1122 | * Zero the header block in preparation for filling it in. | 1129 | * Zero the header block in preparation for filling it in. |
1123 | */ | 1130 | */ |
1124 | memset ((char *) &header, 0, sizeof (header)); | 1131 | memset((char *) &header, 0, sizeof(header)); |
1125 | 1132 | ||
1126 | /* | 1133 | /* |
1127 | * Fill in the header. | 1134 | * Fill in the header. |
1128 | */ | 1135 | */ |
1129 | strcpy (header.name, fileName); | 1136 | strcpy(header.name, fileName); |
1130 | 1137 | ||
1131 | strncpy (header.magic, TAR_MAGIC, sizeof (header.magic)); | 1138 | strncpy(header.magic, TAR_MAGIC, sizeof(header.magic)); |
1132 | strncpy (header.version, TAR_VERSION, sizeof (header.version)); | 1139 | strncpy(header.version, TAR_VERSION, sizeof(header.version)); |
1133 | 1140 | ||
1134 | putOctal (header.mode, sizeof (header.mode), statbuf->st_mode & 0777); | 1141 | putOctal(header.mode, sizeof(header.mode), statbuf->st_mode & 0777); |
1135 | putOctal (header.uid, sizeof (header.uid), statbuf->st_uid); | 1142 | putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); |
1136 | putOctal (header.gid, sizeof (header.gid), statbuf->st_gid); | 1143 | putOctal(header.gid, sizeof(header.gid), statbuf->st_gid); |
1137 | putOctal (header.size, sizeof (header.size), statbuf->st_size); | 1144 | putOctal(header.size, sizeof(header.size), statbuf->st_size); |
1138 | putOctal (header.mtime, sizeof (header.mtime), statbuf->st_mtime); | 1145 | putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime); |
1139 | 1146 | ||
1140 | header.typeFlag = TAR_TYPE_REGULAR; | 1147 | header.typeFlag = TAR_TYPE_REGULAR; |
1141 | 1148 | ||
1142 | /* | 1149 | /* |
1143 | * Calculate and store the checksum. | 1150 | * Calculate and store the checksum. |
1144 | * This is the sum of all of the bytes of the header, | 1151 | * This is the sum of all of the bytes of the header, |
1145 | * with the checksum field itself treated as blanks. | 1152 | * with the checksum field itself treated as blanks. |
1146 | */ | 1153 | */ |
1147 | memset (header.checkSum, ' ', sizeof (header.checkSum)); | 1154 | memset(header.checkSum, ' ', sizeof(header.checkSum)); |
1148 | 1155 | ||
1149 | cp = (const unsigned char *) &header; | 1156 | cp = (const unsigned char *) &header; |
1150 | len = sizeof (header); | 1157 | len = sizeof(header); |
1151 | checkSum = 0; | 1158 | checkSum = 0; |
1152 | 1159 | ||
1153 | while (len-- > 0) | 1160 | while (len-- > 0) |
1154 | checkSum += *cp++; | 1161 | checkSum += *cp++; |
1155 | 1162 | ||
1156 | putOctal (header.checkSum, sizeof (header.checkSum), checkSum); | 1163 | putOctal(header.checkSum, sizeof(header.checkSum), checkSum); |
1157 | 1164 | ||
1158 | /* | 1165 | /* |
1159 | * Write the tar header. | 1166 | * Write the tar header. |
1160 | */ | 1167 | */ |
1161 | writeTarBlock ((const char *) &header, sizeof (header)); | 1168 | writeTarBlock((const char *) &header, sizeof(header)); |
1162 | } | 1169 | } |
1163 | 1170 | ||
1164 | 1171 | ||
@@ -1167,56 +1174,56 @@ static void writeHeader (const char *fileName, const struct stat *statbuf) | |||
1167 | * The data is always padded out to a multiple of TAR_BLOCK_SIZE. | 1174 | * The data is always padded out to a multiple of TAR_BLOCK_SIZE. |
1168 | * The errorFlag static variable is set on an error. | 1175 | * The errorFlag static variable is set on an error. |
1169 | */ | 1176 | */ |
1170 | static void writeTarBlock (const char *buf, int len) | 1177 | static void writeTarBlock(const char *buf, int len) |
1171 | { | 1178 | { |
1172 | int partialLength; | 1179 | int partialLength; |
1173 | int completeLength; | 1180 | int completeLength; |
1174 | char fullBlock[TAR_BLOCK_SIZE]; | 1181 | char fullBlock[TAR_BLOCK_SIZE]; |
1175 | 1182 | ||
1176 | /* | 1183 | /* |
1177 | * If we had a write error before, then do nothing more. | 1184 | * If we had a write error before, then do nothing more. |
1178 | */ | 1185 | */ |
1179 | if (errorFlag==TRUE) | 1186 | if (errorFlag == TRUE) |
1180 | return; | 1187 | return; |
1181 | 1188 | ||
1182 | /* | 1189 | /* |
1183 | * Get the amount of complete and partial blocks. | 1190 | * Get the amount of complete and partial blocks. |
1184 | */ | 1191 | */ |
1185 | partialLength = len % TAR_BLOCK_SIZE; | 1192 | partialLength = len % TAR_BLOCK_SIZE; |
1186 | completeLength = len - partialLength; | 1193 | completeLength = len - partialLength; |
1187 | 1194 | ||
1188 | /* | 1195 | /* |
1189 | * Write all of the complete blocks. | 1196 | * Write all of the complete blocks. |
1190 | */ | 1197 | */ |
1191 | if ((completeLength > 0) && !fullWrite (tarFd, buf, completeLength)) { | 1198 | if ((completeLength > 0) && !fullWrite(tarFd, buf, completeLength)) { |
1192 | perror (tarName); | 1199 | perror(tarName); |
1193 | 1200 | ||
1194 | errorFlag = TRUE; | 1201 | errorFlag = TRUE; |
1195 | 1202 | ||
1196 | return; | 1203 | return; |
1197 | } | 1204 | } |
1198 | 1205 | ||
1199 | /* | 1206 | /* |
1200 | * If there are no partial blocks left, we are done. | 1207 | * If there are no partial blocks left, we are done. |
1201 | */ | 1208 | */ |
1202 | if (partialLength == 0) | 1209 | if (partialLength == 0) |
1203 | return; | 1210 | return; |
1204 | 1211 | ||
1205 | /* | 1212 | /* |
1206 | * Copy the partial data into a complete block, and pad the rest | 1213 | * Copy the partial data into a complete block, and pad the rest |
1207 | * of it with zeroes. | 1214 | * of it with zeroes. |
1208 | */ | 1215 | */ |
1209 | memcpy (fullBlock, buf + completeLength, partialLength); | 1216 | memcpy(fullBlock, buf + completeLength, partialLength); |
1210 | memset (fullBlock + partialLength, 0, TAR_BLOCK_SIZE - partialLength); | 1217 | memset(fullBlock + partialLength, 0, TAR_BLOCK_SIZE - partialLength); |
1211 | 1218 | ||
1212 | /* | 1219 | /* |
1213 | * Write the last complete block. | 1220 | * Write the last complete block. |
1214 | */ | 1221 | */ |
1215 | if (!fullWrite (tarFd, fullBlock, TAR_BLOCK_SIZE)) { | 1222 | if (!fullWrite(tarFd, fullBlock, TAR_BLOCK_SIZE)) { |
1216 | perror (tarName); | 1223 | perror(tarName); |
1217 | 1224 | ||
1218 | errorFlag = TRUE; | 1225 | errorFlag = TRUE; |
1219 | } | 1226 | } |
1220 | } | 1227 | } |
1221 | 1228 | ||
1222 | 1229 | ||
@@ -1225,48 +1232,48 @@ static void writeTarBlock (const char *buf, int len) | |||
1225 | * The number is zero and space padded and possibly null padded. | 1232 | * The number is zero and space padded and possibly null padded. |
1226 | * Returns TRUE if successful. | 1233 | * Returns TRUE if successful. |
1227 | */ | 1234 | */ |
1228 | static int putOctal (char *cp, int len, long value) | 1235 | static int putOctal(char *cp, int len, long value) |
1229 | { | 1236 | { |
1230 | int tempLength; | 1237 | int tempLength; |
1231 | char *tempString; | 1238 | char *tempString; |
1232 | char tempBuffer[32]; | 1239 | char tempBuffer[32]; |
1233 | |||
1234 | /* | ||
1235 | * Create a string of the specified length with an initial space, | ||
1236 | * leading zeroes and the octal number, and a trailing null. | ||
1237 | */ | ||
1238 | tempString = tempBuffer; | ||
1239 | |||
1240 | sprintf (tempString, " %0*lo", len - 2, value); | ||
1241 | |||
1242 | tempLength = strlen (tempString) + 1; | ||
1243 | |||
1244 | /* | ||
1245 | * If the string is too large, suppress the leading space. | ||
1246 | */ | ||
1247 | if (tempLength > len) { | ||
1248 | tempLength--; | ||
1249 | tempString++; | ||
1250 | } | ||
1251 | |||
1252 | /* | ||
1253 | * If the string is still too large, suppress the trailing null. | ||
1254 | */ | ||
1255 | if (tempLength > len) | ||
1256 | tempLength--; | ||
1257 | |||
1258 | /* | ||
1259 | * If the string is still too large, fail. | ||
1260 | */ | ||
1261 | if (tempLength > len) | ||
1262 | return FALSE; | ||
1263 | 1240 | ||
1264 | /* | 1241 | /* |
1265 | * Copy the string to the field. | 1242 | * Create a string of the specified length with an initial space, |
1266 | */ | 1243 | * leading zeroes and the octal number, and a trailing null. |
1267 | memcpy (cp, tempString, len); | 1244 | */ |
1245 | tempString = tempBuffer; | ||
1268 | 1246 | ||
1269 | return TRUE; | 1247 | sprintf(tempString, " %0*lo", len - 2, value); |
1248 | |||
1249 | tempLength = strlen(tempString) + 1; | ||
1250 | |||
1251 | /* | ||
1252 | * If the string is too large, suppress the leading space. | ||
1253 | */ | ||
1254 | if (tempLength > len) { | ||
1255 | tempLength--; | ||
1256 | tempString++; | ||
1257 | } | ||
1258 | |||
1259 | /* | ||
1260 | * If the string is still too large, suppress the trailing null. | ||
1261 | */ | ||
1262 | if (tempLength > len) | ||
1263 | tempLength--; | ||
1264 | |||
1265 | /* | ||
1266 | * If the string is still too large, fail. | ||
1267 | */ | ||
1268 | if (tempLength > len) | ||
1269 | return FALSE; | ||
1270 | |||
1271 | /* | ||
1272 | * Copy the string to the field. | ||
1273 | */ | ||
1274 | memcpy(cp, tempString, len); | ||
1275 | |||
1276 | return TRUE; | ||
1270 | } | 1277 | } |
1271 | #endif | 1278 | #endif |
1272 | 1279 | ||