"Fossies" - the Fresh Open Source Software Archive 
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1
2 /* ====================================================================
3 *
4 * MOD_GZIP.C - Version 1.3.26.1a
5 *
6 * This program was developed by
7 *
8 * Remote Communications, Inc.
9 * Home page: http://www.RemoteCommunications.com
10 *
11 * and is currently maintained by
12 *
13 * Christian Kruse, <ckruse@wwwtech.de> and Michael Schroepl,
14 * <michael@schroepl.net>
15 * Home page: http://sourceforge.net/projects/mod-gzip/
16 *
17 * Original author: Kevin Kiley, CTO, Remote Communications, Inc.
18 * Email: Kiley@RemoteCommunications.com
19 *
20 * As of this writing there is an online support forum which
21 * anyone may join by following the instructions found at...
22 * http://lists.over.net/mailman/listinfo/mod_gzip
23 *
24 * ====================================================================
25 */
26
27 /* APACHE LICENSE: START
28 *
29 * Portions of this software are covered under the following license
30 * which, as it states, must remain included in this source code
31 * module and may not be altered in any way.
32 */
33
34 /* ====================================================================
35 * The Apache Software License, Version 1.1
36 *
37 * Copyright (c) 2000 The Apache Software Foundation. All rights
38 * reserved.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 *
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 *
47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in
49 * the documentation and/or other materials provided with the
50 * distribution.
51 *
52 * 3. The end-user documentation included with the redistribution,
53 * if any, must include the following acknowledgment:
54 * "This product includes software developed by the
55 * Apache Software Foundation (http://www.apache.org/)."
56 * Alternately, this acknowledgment may appear in the software itself,
57 * if and wherever such third-party acknowledgments normally appear.
58 *
59 * 4. The names "Apache" and "Apache Software Foundation" must
60 * not be used to endorse or promote products derived from this
61 * software without prior written permission. For written
62 * permission, please contact apache@apache.org.
63 *
64 * 5. Products derived from this software may not be called "Apache",
65 * nor may "Apache" appear in their name, without prior written
66 * permission of the Apache Software Foundation.
67 *
68 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
69 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
70 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
71 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
72 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
73 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
74 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
75 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
77 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
78 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
79 * SUCH DAMAGE.
80 * ====================================================================
81 *
82 * This software consists of voluntary contributions made by many
83 * individuals on behalf of the Apache Software Foundation. For more
84 * information on the Apache Software Foundation, please see
85 * <http://www.apache.org/>.
86 *
87 * Portions of this software are based upon public domain software
88 * originally written at the National Center for Supercomputing Applications,
89 * University of Illinois, Urbana-Champaign.
90 */
91
92 #include "httpd.h"
93 #include "http_config.h"
94 #include "http_log.h"
95
96 #include "mod_gzip.h"
97
98 /*--------------------------------------------------------------------------*/
99 /* COMPRESSION_SUPPORT: START */
100 /*--------------------------------------------------------------------------*/
101
102
103 #define BIG_MEM
104
105 typedef unsigned uns;
106 typedef unsigned int uni;
107 typedef unsigned char uch;
108 typedef unsigned short ush;
109 typedef unsigned long ulg;
110 typedef int gz1_file_t;
111
112 #ifdef __STDC__
113 typedef void *voidp;
114 #else
115 typedef char *voidp;
116 #endif
117
118 #if defined(__MSDOS__) && !defined(MSDOS)
119 # define MSDOS
120 #endif
121
122 #if defined(__OS2__) && !defined(OS2)
123 # define OS2
124 #endif
125
126 #if defined(OS2) && defined(MSDOS)
127 # undef MSDOS
128 #endif
129
130 #ifdef MSDOS
131 # ifdef __GNUC__
132 # define near
133 # else
134 # define MAXSEG_64K
135 # ifdef __TURBOC__
136 # define NO_OFF_T
137 # ifdef __BORLANDC__
138 # define DIRENT
139 # else
140 # define NO_UTIME
141 # endif
142 # else
143 # define HAVE_SYS_UTIME_H
144 # define NO_UTIME_H
145 # endif
146 # endif
147 # define PATH_SEP2 '\\'
148 # define PATH_SEP3 ':'
149 # define MAX_PATH_LEN 128
150 # define NO_MULTIPLE_DOTS
151 # define MAX_EXT_CHARS 3
152 # define Z_SUFFIX "z"
153 # define NO_CHOWN
154 # define PROTO
155 # define STDC_HEADERS
156 # define NO_SIZE_CHECK
157 # define casemap(c) tolow(c)
158 # include <io.h>
159 # undef OS_CODE
160 # define OS_CODE 0x00
161 # define SET_BINARY_MODE(fd) setmode(fd, O_BINARY)
162 # if !defined(NO_ASM) && !defined(ASMV)
163 # define ASMV
164 # endif
165 #else
166 # define near
167 #endif
168
169 #ifdef OS2
170 # define PATH_SEP2 '\\'
171 # define PATH_SEP3 ':'
172 # define MAX_PATH_LEN 260
173 # ifdef OS2FAT
174 # define NO_MULTIPLE_DOTS
175 # define MAX_EXT_CHARS 3
176 # define Z_SUFFIX "z"
177 # define casemap(c) tolow(c)
178 # endif
179 # define NO_CHOWN
180 # define PROTO
181 # define STDC_HEADERS
182 # include <io.h>
183 # undef OS_CODE
184 # define OS_CODE 0x06
185 # define SET_BINARY_MODE(fd) setmode(fd, O_BINARY)
186 # ifdef _MSC_VER
187 # define HAVE_SYS_UTIME_H
188 # define NO_UTIME_H
189 # define MAXSEG_64K
190 # undef near
191 # define near _near
192 # endif
193 # ifdef __EMX__
194 # define HAVE_SYS_UTIME_H
195 # define NO_UTIME_H
196 # define DIRENT
197 # define EXPAND(argc,argv) \
198 {_response(&argc, &argv); _wildcard(&argc, &argv);}
199 # endif
200 # ifdef __BORLANDC__
201 # define DIRENT
202 # endif
203 # ifdef __ZTC__
204 # define NO_DIR
205 # define NO_UTIME_H
206 # include <dos.h>
207 # define EXPAND(argc,argv) \
208 {response_expand(&argc, &argv);}
209 # endif
210 #endif
211
212 #ifdef WIN32
213 # define HAVE_SYS_UTIME_H
214 # define NO_UTIME_H
215 # define PATH_SEP2 '\\'
216 # define PATH_SEP3 ':'
217 # undef MAX_PATH_LEN
218 # define MAX_PATH_LEN 260
219 # define NO_CHOWN
220 # define PROTO
221 # define STDC_HEADERS
222 # define SET_BINARY_MODE(fd) setmode(fd, O_BINARY)
223 # include <io.h>
224 # include <malloc.h>
225 # ifdef NTFAT
226 # define NO_MULTIPLE_DOTS
227 # define MAX_EXT_CHARS 3
228 # define Z_SUFFIX "z"
229 # define casemap(c) tolow(c)
230 # endif
231 # undef OS_CODE
232
233 # define OS_CODE 0x00
234
235 #endif
236
237 #ifdef MSDOS
238 # ifdef __TURBOC__
239 # include <alloc.h>
240 # define DYN_ALLOC
241 void * fcalloc (unsigned items, unsigned size);
242 void fcfree (void *ptr);
243 # else
244 # include <malloc.h>
245 # define fcalloc(nitems,itemsize) halloc((long)(nitems),(itemsize))
246 # define fcfree(ptr) hfree(ptr)
247 # endif
248 #else
249 # ifdef MAXSEG_64K
250 # define fcalloc(items,size) calloc((items),(size))
251 # else
252 # define fcalloc(items,size) malloc((size_t)(items)*(size_t)(size))
253 # endif
254 # define fcfree(ptr) free(ptr)
255 #endif
256
257 #if defined(VAXC) || defined(VMS)
258 # define PATH_SEP ']'
259 # define PATH_SEP2 ':'
260 # define SUFFIX_SEP ';'
261 # define NO_MULTIPLE_DOTS
262 # define Z_SUFFIX "-gz"
263 # define RECORD_IO 1
264 # define casemap(c) tolow(c)
265 # undef OS_CODE
266 # define OS_CODE 0x02
267 # define OPTIONS_VAR "GZIP_OPT"
268 # define STDC_HEADERS
269 # define NO_UTIME
270 # define EXPAND(argc,argv) vms_expand_args(&argc,&argv);
271 # include <file.h>
272 # define unlink delete
273 # ifdef VAXC
274 # define NO_FCNTL_H
275 # include <unixio.h>
276 # endif
277 #endif
278
279 #ifdef AMIGA
280 # define PATH_SEP2 ':'
281 # define STDC_HEADERS
282 # undef OS_CODE
283 # define OS_CODE 0x01
284 # define ASMV
285 # ifdef __GNUC__
286 # define DIRENT
287 # define HAVE_UNISTD_H
288 # else
289 # define NO_STDIN_FSTAT
290 # define SYSDIR
291 # define NO_SYMLINK
292 # define NO_CHOWN
293 # define NO_FCNTL_H
294 # include <fcntl.h>
295 # define direct dirent
296 extern void _expand_args(int *argc, char ***argv);
297 # define EXPAND(argc,argv) _expand_args(&argc,&argv);
298 # undef O_BINARY
299 # endif
300 #endif
301
302 #if defined(ATARI) || defined(atarist)
303 # ifndef STDC_HEADERS
304 # define STDC_HEADERS
305 # define HAVE_UNISTD_H
306 # define DIRENT
307 # endif
308 # define ASMV
309 # undef OS_CODE
310 # define OS_CODE 0x05
311 # ifdef TOSFS
312 # define PATH_SEP2 '\\'
313 # define PATH_SEP3 ':'
314 # define MAX_PATH_LEN 128
315 # define NO_MULTIPLE_DOTS
316 # define MAX_EXT_CHARS 3
317 # define Z_SUFFIX "z"
318 # define NO_CHOWN
319 # define casemap(c) tolow(c)
320 # define NO_SYMLINK
321 # endif
322 #endif
323
324 #ifdef MACOS
325 # define PATH_SEP ':'
326 # define DYN_ALLOC
327 # define PROTO
328 # define NO_STDIN_FSTAT
329 # define NO_CHOWN
330 # define NO_UTIME
331 # define chmod(file, mode) (0)
332 # define OPEN(name, flags, mode) open(name, flags)
333 # define SEEKFORWARD(handle, offset) lseek( handle, offset, 1 )
334 # undef OS_CODE
335 # define OS_CODE 0x07
336 # ifdef MPW
337 # define isatty(fd) ((fd) <= 2)
338 # endif
339 #endif
340
341 #ifdef __50SERIES
342 # define PATH_SEP '>'
343 # define STDC_HEADERS
344 # define NO_MEMORY_H
345 # define NO_UTIME_H
346 # define NO_UTIME
347 # define NO_CHOWN
348 # define NO_STDIN_FSTAT
349 # define NO_SIZE_CHECK
350 # define NO_SYMLINK
351 # define RECORD_IO 1
352 # define casemap(c) tolow(c)
353 # define put_char(c) put_byte((c) & 0x7F)
354 # define get_char(c) ascii2pascii(get_byte())
355 # undef OS_CODE
356 # define OS_CODE 0x0F
357 # ifdef SIGTERM
358 # undef SIGTERM
359 # endif
360 #endif
361
362 #if defined(pyr) && !defined(NOMEMCPY)
363 # define NOMEMCPY
364 #endif
365
366 #ifdef TOPS20
367 # undef OS_CODE
368 # define OS_CODE 0x0a
369 #endif
370
371 #ifndef unix
372 # define NO_ST_INO
373 #endif
374
375 #ifndef OS_CODE
376 # undef OS_CODE
377 # define OS_CODE 0x03
378 #endif
379
380 #ifndef PATH_SEP
381 # define PATH_SEP '/'
382 #endif
383
384 #ifndef casemap
385 # define casemap(c) (c)
386 #endif
387
388 #ifndef OPTIONS_VAR
389 # define OPTIONS_VAR "GZIP"
390 #endif
391
392 #ifndef Z_SUFFIX
393 # define Z_SUFFIX ".gz"
394 #endif
395
396 #ifdef MAX_EXT_CHARS
397 # define MAX_SUFFIX MAX_EXT_CHARS
398 #else
399 # define MAX_SUFFIX 30
400 #endif
401
402 #ifndef MIN_PART
403 # define MIN_PART 3
404 #endif
405
406 #ifndef EXPAND
407 # define EXPAND(argc,argv)
408 #endif
409
410 #ifndef RECORD_IO
411 # define RECORD_IO 0
412 #endif
413
414 #ifndef SET_BINARY_MODE
415 # define SET_BINARY_MODE(fd)
416 #endif
417
418 #ifndef OPEN
419 # define OPEN(name, flags, mode) open(name, flags, mode)
420 #endif
421
422 #ifndef SEEKFORWARD
423 # define SEEKFORWARD(handle, offset) lseek( handle, offset, 1 )
424 #endif
425
426 #ifndef get_char
427 # define get_char() get_byte()
428 #endif
429
430 #ifndef put_char
431 # define put_char(c) put_byte(c)
432 #endif
433
434 #ifndef O_BINARY
435 #define O_BINARY 0
436 #endif
437
438 #define OK 0
439 #define LZ1_ERROR 1
440 #define WARNING 2
441 #define STORED 0
442 #define COMPRESSED 1
443 #define PACKED 2
444 #define LZHED 3
445 #define DEFLATED 8
446 #define MAX_METHODS 9
447
448 #ifndef O_CREAT
449 #include <sys/file.h>
450 #ifndef O_CREAT
451 #define O_CREAT FCREAT
452 #endif
453 #ifndef O_EXCL
454 #define O_EXCL FEXCL
455 #endif
456 #endif
457
458 #ifndef S_IRUSR
459 #define S_IRUSR 0400
460 #endif
461 #ifndef S_IWUSR
462 #define S_IWUSR 0200
463 #endif
464 #define RW_USER (S_IRUSR | S_IWUSR)
465
466 #ifndef MAX_PATH_LEN
467 #define MAX_PATH_LEN 256
468 #endif
469
470 #ifndef SEEK_END
471 #define SEEK_END 2
472 #endif
473
474 #define PACK_MAGIC "\037\036"
475 #define GZIP_MAGIC "\037\213"
476 #define OLD_GZIP_MAGIC "\037\236"
477 #define LZH_MAGIC "\037\240"
478 #define PKZIP_MAGIC "\120\113\003\004"
479 #define ASCII_FLAG 0x01
480 #define CONTINUATION 0x02
481 #define EXTRA_FIELD 0x04
482 #define ORIG_NAME 0x08
483 #define COMMENT 0x10
484 #define ENCRYPTED 0x20
485 #define RESERVED 0xC0
486 #define UNKNOWN 0xffff
487 #define BINARY 0
488 #define ASCII 1
489
490 #ifndef WSIZE
491 #define WSIZE 0x8000
492 #endif
493
494 #ifndef INBUFSIZ
495 #ifdef SMALL_MEM
496 #define INBUFSIZ 0x2000
497 #else
498 #define INBUFSIZ 0x8000
499 #endif
500 #endif
501 #define INBUF_EXTRA 64
502
503 #ifndef OUTBUFSIZ
504 #ifdef SMALL_MEM
505 #define OUTBUFSIZ 8192
506 #else
507 #define OUTBUFSIZ 0x4000
508 #endif
509 #endif
510 #define OUTBUF_EXTRA 2048
511
512 #ifndef DIST_BUFSIZE
513 #ifdef SMALL_MEM
514 #define DIST_BUFSIZE 0x2000
515 #else
516 #define DIST_BUFSIZE 0x8000
517 #endif
518 #endif
519
520 #ifndef BITS
521 #define BITS 16
522 #endif
523
524 #define LZW_MAGIC "\037\235"
525
526 #define MIN_MATCH 3
527 #define MAX_MATCH 258
528
529 #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
530 #define MAX_DIST (WSIZE-MIN_LOOKAHEAD)
531
532 #ifdef SMALL_MEM
533 #define HASH_BITS 13
534 #endif
535 #ifdef MEDIUM_MEM
536 #define HASH_BITS 14
537 #endif
538 #ifndef HASH_BITS
539 #define HASH_BITS 15
540 #endif
541
542 #define HASH_SIZE (unsigned)(1<<HASH_BITS)
543 #define HASH_MASK (HASH_SIZE-1)
544 #define WMASK (WSIZE-1)
545 #define H_SHIFT ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH)
546
547 #ifndef TOO_FAR
548 #define TOO_FAR 4096
549 #endif
550
551 #define NIL 0
552 #define FAST 4
553 #define SLOW 2
554 #define REP_3_6 16
555 #define REPZ_3_10 17
556 #define REPZ_11_138 18
557 #define MAX_BITS 15
558 #define MAX_BL_BITS 7
559 #define D_CODES 30
560 #define BL_CODES 19
561 #define SMALLEST 1
562 #define LENGTH_CODES 29
563 #define LITERALS 256
564 #define END_BLOCK 256
565 #define L_CODES (LITERALS+1+LENGTH_CODES)
566
567 #ifndef LIT_BUFSIZE
568 #ifdef SMALL_MEM
569 #define LIT_BUFSIZE 0x2000
570 #else
571 #ifdef MEDIUM_MEM
572 #define LIT_BUFSIZE 0x4000
573 #else
574 #define LIT_BUFSIZE 0x8000
575 #endif
576 #endif
577 #endif
578
579 #define HEAP_SIZE (2*L_CODES+1)
580 #define STORED_BLOCK 0
581 #define STATIC_TREES 1
582 #define DYN_TREES 2
583 #define NO_FILE (-1)
584
585 #define BMAX 16
586 #define N_MAX 288
587
588 #define LOCSIG 0x04034b50L
589 #define LOCFLG 6
590 #define CRPFLG 1
591 #define EXTFLG 8
592 #define LOCHOW 8
593 #define LOCTIM 10
594 #define LOCCRC 14
595 #define LOCSIZ 18
596 #define LOCLEN 22
597 #define LOCFIL 26
598 #define LOCEXT 28
599 #define LOCHDR 30
600 #define EXTHDR 16
601 #define RAND_HEAD_LEN 12
602 #define BUFSIZE (8 * 2*sizeof(char))
603
604 #define translate_eol 0
605
606 #define FLUSH_BLOCK(eof) \
607 flush_block(gz1,gz1->block_start >= 0L ? (char*)&gz1->window[(unsigned)gz1->block_start] : \
608 (char*)NULL, (long)gz1->strstart - gz1->block_start, (eof))
609
610 #ifdef DYN_ALLOC
611 # define ALLOC(type, array, size) { \
612 array = (type*)fcalloc((size_t)(((size)+1L)/2), 2*sizeof(type)); \
613 if (array == NULL) error("insufficient memory"); \
614 }
615 # define FREE(array) {if (array != NULL) fcfree(array), array=NULL;}
616 #else
617 # define ALLOC(type, array, size)
618 # define FREE(array)
619 #endif
620
621 #define GZ1_MAX(a,b) (a >= b ? a : b)
622
623 #define tolow(c) (isupper(c) ? (c)-'A'+'a' : (c))
624
625 #define smaller(tree, n, m) \
626 (tree[n].fc.freq < tree[m].fc.freq || \
627 (tree[n].fc.freq == tree[m].fc.freq && gz1->depth[n] <= gz1->depth[m]))
628
629 #define send_code(c, tree) send_bits(gz1,tree[c].fc.code, tree[c].dl.len)
630
631 #define put_byte(c) {gz1->outbuf[gz1->outcnt++]=(uch)(c); if (gz1->outcnt==OUTBUFSIZ)\
632 flush_outbuf(gz1);}
633
634 #define put_short(w) \
635 { if (gz1->outcnt < OUTBUFSIZ-2) { \
636 gz1->outbuf[gz1->outcnt++] = (uch) ((w) & 0xff); \
637 gz1->outbuf[gz1->outcnt++] = (uch) ((ush)(w) >> 8); \
638 } else { \
639 put_byte((uch)((w) & 0xff)); \
640 put_byte((uch)((ush)(w) >> 8)); \
641 } \
642 }
643
644 #define put_long(n) { \
645 put_short((n) & 0xffff); \
646 put_short(((ulg)(n)) >> 16); \
647 }
648
649 #ifdef CRYPT
650
651 # define NEXTBYTE() \
652 (decrypt ? (cc = get_byte(), zdecode(cc), cc) : get_byte())
653 #else
654 # define NEXTBYTE() (uch)get_byte()
655 #endif
656
657 #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}}
658 #define DUMPBITS(n) {b>>=(n);k-=(n);}
659
660 #define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8))
661 #define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16))
662
663 #define put_ubyte(c) {gz1->window[gz1->outcnt++]=(uch)(c); if (gz1->outcnt==WSIZE)\
664 flush_window(gz1);}
665
666 #define WARN(msg) { if (gz1->exit_code == OK) gz1->exit_code = WARNING; }
667
668 #define get_byte() (gz1->inptr < gz1->insize ? gz1->inbuf[gz1->inptr++] : fill_inbuf(gz1,0))
669 #define try_byte() (gz1->inptr < gz1->insize ? gz1->inbuf[gz1->inptr++] : fill_inbuf(gz1,1))
670
671 #define d_code(dist) \
672 ((dist) < 256 ? gz1->dist_code[dist] : gz1->dist_code[256+((dist)>>7)])
673
674 typedef struct config {
675 ush good_length;
676 ush max_lazy;
677 ush nice_length;
678 ush max_chain;
679 } config;
680
681 config configuration_table[10] = {
682
683 {0, 0, 0, 0},
684 {4, 4, 8, 4},
685 {4, 5, 16, 8},
686 {4, 6, 32, 32},
687 {4, 4, 16, 16},
688 {8, 16, 32, 32},
689 {8, 16, 128, 128},
690 {8, 32, 128, 256},
691 {32, 128, 258, 1024},
692 {32, 258, 258, 4096}};
693
694 typedef struct ct_data {
695
696 union {
697 ush freq;
698 ush code;
699 } fc;
700 union {
701 ush dad;
702 ush len;
703 } dl;
704
705 } ct_data;
706
707 typedef struct tree_desc {
708 ct_data *dyn_tree;
709 ct_data *static_tree;
710 int *extra_bits;
711 int extra_base;
712 int elems;
713 int max_length;
714 int max_code;
715 } tree_desc;
716
717 struct huft {
718 uch e;
719 uch b;
720 union {
721 ush n;
722 struct huft *t;
723 } v;
724 };
725
726 uch bl_order[BL_CODES]
727 = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
728
729 int extra_lbits[LENGTH_CODES]
730 = {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};
731
732 int extra_dbits[D_CODES]
733 = {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};
734
735 int extra_blbits[BL_CODES]
736 = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
737
738 ulg crc_32_tab[] = {
739 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
740 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
741 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
742 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
743 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
744 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
745 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
746 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
747 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
748 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
749 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
750 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
751 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
752 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
753 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
754 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
755 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
756 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
757 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
758 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
759 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
760 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
761 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
762 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
763 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
764 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
765 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
766 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
767 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
768 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
769 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
770 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
771 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
772 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
773 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
774 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
775 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
776 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
777 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
778 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
779 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
780 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
781 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
782 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
783 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
784 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
785 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
786 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
787 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
788 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
789 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
790 0x2d02ef8dL
791 };
792
793 typedef struct _GZ1 {
794 long versionid1;
795 int state;
796 int done;
797 int deflate1_initialized;
798 unsigned deflate1_hash_head;
799 unsigned deflate1_prev_match;
800 int deflate1_flush;
801 int deflate1_match_available;
802 unsigned deflate1_match_length;
803
804 char ifname[MAX_PATH_LEN];
805 char ofname[MAX_PATH_LEN];
806
807 struct stat istat;
808 gz1_file_t zfile;
809
810 int input_ismem;
811 char *input_ptr;
812 long input_bytesleft;
813
814 int output_ismem;
815 char *output_ptr;
816 uns output_maxlen;
817
818 int compr_level;
819 long time_stamp;
820 long ifile_size;
821 int ifd;
822 int ofd;
823 int part_nb;
824 int last_member;
825 int save_orig_name;
826 long header_bytes;
827 long bytes_in;
828 long bytes_out;
829 uns insize;
830 uns inptr;
831 uns outcnt;
832 uns ins_h;
833 long block_start;
834 uns good_match;
835 uni max_lazy_match;
836 uni prev_length;
837 uns max_chain_length;
838 uns strstart;
839 uns match_start;
840 int eofile;
841 uns lookahead;
842 ush *file_type;
843 int *file_method;
844 ulg opt_len;
845 ulg static_len;
846 ulg compressed_len;
847 ulg input_len;
848 uns last_flags;
849 uch flags;
850 uns last_lit;
851 uns last_dist;
852 uch flag_bit;
853 int heap_len;
854 int heap_max;
855 ulg bb;
856 uns bk;
857 ush bi_buf;
858 int bi_valid;
859 uns hufts;
860 int decrypt;
861 int ascii;
862 int msg_done;
863 int abortflag;
864 int decompress;
865 int do_lzw;
866 int to_stdout;
867 int force;
868 int verbose;
869 int quiet;
870 int list;
871 int test;
872 int ext_header;
873 int pkzip;
874 int method;
875 int level;
876 int no_time;
877 int no_name;
878 int exit_code;
879 int lbits;
880 int dbits;
881 ulg window_size;
882 ulg crc;
883
884 uch dist_code[512];
885 uch length_code[MAX_MATCH-MIN_MATCH+1];
886 int heap[2*L_CODES+1];
887 uch depth[2*L_CODES+1];
888 int base_length[LENGTH_CODES];
889 int base_dist[D_CODES];
890 ush bl_count[MAX_BITS+1];
891 uch flag_buf[(LIT_BUFSIZE/8)];
892
893 #ifdef DYN_ALLOC
894 uch *inbuf;
895 uch *outbuf;
896 ush *d_buf;
897 uch *window;
898 #else
899 uch inbuf [INBUFSIZ +INBUF_EXTRA];
900 uch outbuf[OUTBUFSIZ+OUTBUF_EXTRA];
901 ush d_buf [DIST_BUFSIZE];
902 uch window[2L*WSIZE];
903 #endif
904
905 #ifdef FULL_SEARCH
906 #define nice_match MAX_MATCH
907 #else
908 int nice_match;
909 #endif
910
911 #ifdef CRYPT
912 uch cc;
913 #endif
914
915 ct_data static_ltree[L_CODES+2];
916 ct_data static_dtree[D_CODES];
917 ct_data dyn_dtree[(2*D_CODES+1)];
918 ct_data dyn_ltree[HEAP_SIZE];
919 ct_data bl_tree[2*BL_CODES+1];
920
921 tree_desc l_desc;
922 tree_desc d_desc;
923 tree_desc bl_desc;
924
925 #ifndef MAXSEG_64K
926
927 ush prev2[1L<<BITS];
928
929 #define prev gz1->prev2
930 #define head (gz1->prev2+WSIZE)
931
932 #else
933
934 ush * prev2;
935 ush * tab_prefix1;
936
937 #define prev gz1->prev2
938 #define head gz1->tab_prefix1
939
940 #endif
941
942 } GZ1;
943 typedef GZ1 *PGZ1;
944 int gz1_size = sizeof( GZ1 );
945
946 /* Declare some local function protypes... */
947
948 /* Any routine name that can/might conflict with */
949 /* other modules or object code should simply have */
950 /* the standard prefix 'gz1_' added to the front. */
951 /* This will only usually be any kind of problem at all */
952 /* if the code is being compiled directly into the parent */
953 /* instead of being built as a standalone DLL or DSO library. */
954
955 PGZ1 gz1_init ( void );
956 int gz1_cleanup ( PGZ1 gz1 );
957 ulg gz1_deflate ( PGZ1 gz1 );
958 ulg gz1_deflate_fast( PGZ1 gz1 );
959
960 /* The rest of the routines should not need the 'gz1_' prefix. */
961 /* No conflicts reported at this time. */
962
963 int inflate ( PGZ1 gz1 );
964 int inflate_dynamic( PGZ1 gz1 );
965 int inflate_stored ( PGZ1 gz1 );
966 int inflate_fixed ( PGZ1 gz1 );
967 void fill_window ( PGZ1 gz1 );
968 void flush_outbuf ( PGZ1 gz1 );
969 void flush_window ( PGZ1 gz1 );
970 void bi_windup ( PGZ1 gz1 );
971 void set_file_type ( PGZ1 gz1 );
972 void init_block ( PGZ1 gz1 );
973 int build_bl_tree ( PGZ1 gz1 );
974 void read_error ( PGZ1 gz1 );
975 void write_error ( PGZ1 gz1 );
976 int get_header ( PGZ1 gz1, int in );
977 int inflate_block ( PGZ1 gz1, int *e );
978 int fill_inbuf ( PGZ1 gz1, int eof_ok );
979 char *gz1_basename ( PGZ1 gz1, char *fname );
980 int longest_match ( PGZ1 gz1, unsigned cur_match );
981 void bi_init ( PGZ1 gz1, gz1_file_t zipfile );
982 int file_read ( PGZ1 gz1, char *buf, unsigned size );
983 void write_buf ( PGZ1 gz1, int fd, voidp buf, unsigned cnt );
984
985 void error( char *msg );
986
987 int zip(
988 PGZ1 gz1,
989 int in,
990 int out
991 );
992
993 ulg flush_block(
994 PGZ1 gz1,
995 char *buf,
996 ulg stored_len,
997 int eof
998 );
999
1000 void copy_block(
1001 PGZ1 gz1,
1002 char *buf,
1003 unsigned len,
1004 int header
1005 );
1006
1007 int ct_tally(
1008 PGZ1 gz1,
1009 int dist,
1010 int lc
1011 );
1012
1013 void send_bits(
1014 PGZ1 gz1,
1015 int value,
1016 int length
1017 );
1018
1019 void send_tree(
1020 PGZ1 gz1,
1021 ct_data *tree,
1022 int max_code
1023 );
1024
1025 void send_all_trees(
1026 PGZ1 gz1,
1027 int lcodes,
1028 int dcodes,
1029 int blcodes
1030 );
1031
1032 void mod_gzip_ct_init(
1033 PGZ1 gz1,
1034 ush *attr,
1035 int *methodp
1036 );
1037
1038 void lm_init(
1039 PGZ1 gz1,
1040 int pack_level,
1041 ush *flags
1042 );
1043
1044 void build_tree(
1045 PGZ1 gz1,
1046 tree_desc *desc
1047 );
1048
1049 void compress_block(
1050 PGZ1 gz1,
1051 ct_data *ltree,
1052 ct_data *dtree
1053 );
1054
1055 void gen_bitlen(
1056 PGZ1 gz1,
1057 tree_desc *desc
1058 );
1059
1060 void pqdownheap(
1061 PGZ1 gz1,
1062 ct_data *tree,
1063 int k
1064 );
1065
1066 int huft_build(
1067 PGZ1 gz1,
1068 unsigned *b,
1069 unsigned n,
1070 unsigned s,
1071 ush *d,
1072 ush *e,
1073 struct huft **t,
1074 int *m
1075 );
1076
1077 ulg updcrc(
1078 PGZ1 gz1,
1079 uch *s,
1080 unsigned n
1081 );
1082
1083 int inflate_codes(
1084 PGZ1 gz1,
1085 struct huft *tl,
1086 struct huft *td,
1087 int bl,
1088 int bd
1089 );
1090
1091 void gen_codes(
1092 PGZ1 gz1,
1093 ct_data *tree,
1094 int max_code
1095 );
1096
1097 void scan_tree(
1098 PGZ1 gz1,
1099 ct_data *tree,
1100 int max_code
1101 );
1102
1103 unsigned bi_reverse(
1104 PGZ1 gz1,
1105 unsigned code,
1106 int len
1107 );
1108
1109 int huft_free(
1110 PGZ1 gz1,
1111 struct huft *t
1112 );
1113
1114 PGZ1 gz1_init()
1115 {
1116 PGZ1 gz1=0;
1117
1118 gz1 = (PGZ1) malloc( gz1_size );
1119
1120 if ( !gz1 )
1121 {
1122 return 0;
1123 }
1124
1125 memset( gz1, 0, gz1_size );
1126
1127 ALLOC(uch, gz1->inbuf, INBUFSIZ +INBUF_EXTRA);
1128
1129 if ( !gz1->inbuf )
1130 {
1131 free( gz1 );
1132 return 0;
1133 }
1134
1135 ALLOC(uch, gz1->outbuf, OUTBUFSIZ+OUTBUF_EXTRA);
1136
1137 if ( !gz1->outbuf )
1138 {
1139 FREE( gz1->inbuf );
1140 free( gz1 );
1141 return 0;
1142 }
1143
1144 ALLOC(ush, gz1->d_buf, DIST_BUFSIZE);
1145
1146 if ( !gz1->d_buf )
1147 {
1148 FREE( gz1->outbuf );
1149 FREE( gz1->inbuf );
1150 free( gz1 );
1151 return 0;
1152 }
1153
1154 ALLOC(uch, gz1->window, 2L*WSIZE);
1155
1156 if ( !gz1->window )
1157 {
1158 FREE( gz1->d_buf );
1159 FREE( gz1->outbuf );
1160 FREE( gz1->inbuf );
1161 free( gz1 );
1162 return 0;
1163 }
1164
1165 #ifndef MAXSEG_64K
1166
1167 #else
1168
1169 ALLOC(ush, gz1->prev2, 1L<<(BITS-1) );
1170
1171 if ( !gz1->prev2 )
1172 {
1173 FREE( gz1->window );
1174 FREE( gz1->d_buf );
1175 FREE( gz1->outbuf );
1176 FREE( gz1->inbuf );
1177 free( gz1 );
1178 return 0;
1179 }
1180
1181 ALLOC(ush, gz1->tab_prefix1, 1L<<(BITS-1) );
1182
1183 if ( !gz1->tab_prefix1 )
1184 {
1185 FREE( gz1->prev2 );
1186 FREE( gz1->window );
1187 FREE( gz1->d_buf );
1188 FREE( gz1->outbuf );
1189 FREE( gz1->inbuf );
1190 free( gz1 );
1191 return 0;
1192 }
1193
1194 #endif
1195
1196 gz1->method = DEFLATED;
1197 gz1->level = 6;
1198 gz1->no_time = -1;
1199 gz1->no_name = -1;
1200 gz1->exit_code = OK;
1201 gz1->lbits = 9;
1202 gz1->dbits = 6;
1203
1204 gz1->window_size = (ulg)2*WSIZE;
1205 gz1->crc = (ulg)0xffffffffL;
1206
1207 gz1->d_desc.dyn_tree = (ct_data *) gz1->dyn_dtree;
1208 gz1->d_desc.static_tree = (ct_data *) gz1->static_dtree;
1209 gz1->d_desc.extra_bits = (int *) extra_dbits;
1210 gz1->d_desc.extra_base = (int ) 0;
1211 gz1->d_desc.elems = (int ) D_CODES;
1212 gz1->d_desc.max_length = (int ) MAX_BITS;
1213 gz1->d_desc.max_code = (int ) 0;
1214
1215 gz1->l_desc.dyn_tree = (ct_data *) gz1->dyn_ltree;
1216 gz1->l_desc.static_tree = (ct_data *) gz1->static_ltree;
1217 gz1->l_desc.extra_bits = (int *) extra_lbits;
1218 gz1->l_desc.extra_base = (int ) LITERALS+1;
1219 gz1->l_desc.elems = (int ) L_CODES;
1220 gz1->l_desc.max_length = (int ) MAX_BITS;
1221 gz1->l_desc.max_code = (int ) 0;
1222
1223 gz1->bl_desc.dyn_tree = (ct_data *) gz1->bl_tree;
1224 gz1->bl_desc.static_tree = (ct_data *) 0;
1225 gz1->bl_desc.extra_bits = (int *) extra_blbits;
1226 gz1->bl_desc.extra_base = (int ) 0;
1227 gz1->bl_desc.elems = (int ) BL_CODES;
1228 gz1->bl_desc.max_length = (int ) MAX_BL_BITS;
1229 gz1->bl_desc.max_code = (int ) 0;
1230
1231 return (PGZ1) gz1;
1232
1233 }
1234
1235 int gz1_cleanup( PGZ1 gz1 )
1236 {
1237
1238 #ifndef MAXSEG_64K
1239
1240 #else
1241
1242 FREE( gz1->tab_prefix1 );
1243 FREE( gz1->prev2 );
1244 #endif
1245
1246 FREE( gz1->window );
1247 FREE( gz1->d_buf );
1248 FREE( gz1->outbuf );
1249 FREE( gz1->inbuf );
1250
1251 free( gz1 );
1252 gz1 = 0;
1253
1254 return 0;
1255 }
1256
1257 int (*read_buf)(PGZ1 gz1, char *buf, unsigned size);
1258
1259 void error( char *msg )
1260 {
1261 msg = msg;
1262 }
1263
1264 int (*work)( PGZ1 gz1, int infile, int outfile ) = 0;
1265
1266 #ifdef __BORLANDC__
1267 #pragma argsused
1268 #endif
1269
1270 int get_header( PGZ1 gz1, int in )
1271 {
1272 uch flags;
1273 char magic[2];
1274 ulg stamp;
1275 unsigned len;
1276 unsigned part;
1277
1278 if ( gz1->force && gz1->to_stdout )
1279 {
1280 magic[0] = (char)try_byte();
1281 magic[1] = (char)try_byte();
1282 }
1283 else
1284 {
1285 magic[0] = (char)get_byte();
1286 magic[1] = (char)get_byte();
1287 }
1288
1289 gz1->method = -1;
1290 gz1->header_bytes = 0;
1291 gz1->last_member = RECORD_IO;
1292 gz1->part_nb++;
1293
1294 if ( memcmp(magic, GZIP_MAGIC, 2 ) == 0 ||
1295 memcmp(magic, OLD_GZIP_MAGIC, 2 ) == 0 )
1296 {
1297 gz1->method = (int)get_byte();
1298
1299 if ( gz1->method != DEFLATED )
1300 {
1301 gz1->exit_code = LZ1_ERROR;
1302
1303 return -1;
1304 }
1305
1306 return -1;
1307
1308 if ((flags & ENCRYPTED) != 0)
1309 {
1310 gz1->exit_code = LZ1_ERROR;
1311 return -1;
1312 }
1313
1314 if ((flags & CONTINUATION) != 0)
1315 {
1316 gz1->exit_code = LZ1_ERROR;
1317 if ( gz1->force <= 1) return -1;
1318 }
1319
1320 if ((flags & RESERVED) != 0)
1321 {
1322 gz1->exit_code = LZ1_ERROR;
1323 if ( gz1->force <= 1)
1324 return -1;
1325 }
1326
1327 stamp = (ulg)get_byte();
1328 stamp |= ((ulg)get_byte()) << 8;
1329 stamp |= ((ulg)get_byte()) << 16;
1330 stamp |= ((ulg)get_byte()) << 24;
1331
1332 if ( stamp != 0 && !gz1->no_time )
1333 {
1334 gz1->time_stamp = stamp;
1335 }
1336
1337 (void)get_byte();
1338 (void)get_byte();
1339
1340 if ((flags & CONTINUATION) != 0)
1341 {
1342 part = (unsigned) get_byte();
1343 part |= ((unsigned) get_byte())<<8;
1344 }
1345
1346 if ((flags & EXTRA_FIELD) != 0)
1347 {
1348 len = (unsigned) get_byte();
1349 len |= ((unsigned) get_byte())<<8;
1350
1351 while (len--) (void)get_byte();
1352 }
1353
1354 if ((flags & COMMENT) != 0)
1355 {
1356 while (get_char() != 0) ;
1357 }
1358
1359 if ( gz1->part_nb == 1 )
1360 {
1361 gz1->header_bytes = gz1->inptr + 2*sizeof(long);
1362 }
1363 }
1364
1365 return gz1->method;
1366 }
1367
1368 int fill_inbuf( PGZ1 gz1, int eof_ok )
1369 {
1370 int len;
1371 int bytes_to_copy;
1372
1373 gz1->insize = 0;
1374 errno = 0;
1375
1376 do {
1377 if ( gz1->input_ismem )
1378 {
1379 if ( gz1->input_bytesleft > 0 )
1380 {
1381 bytes_to_copy = INBUFSIZ - gz1->insize;
1382
1383 if ( bytes_to_copy > gz1->input_bytesleft )
1384 {
1385 bytes_to_copy = gz1->input_bytesleft;
1386 }
1387
1388 memcpy(
1389 (char*)gz1->inbuf+gz1->insize,
1390 gz1->input_ptr,
1391 bytes_to_copy
1392 );
1393
1394 gz1->input_ptr += bytes_to_copy;
1395 gz1->input_bytesleft -= bytes_to_copy;
1396
1397 len = bytes_to_copy;
1398 }
1399 else
1400 {
1401 len = 0;
1402 }
1403 }
1404 else
1405 {
1406 len =
1407 read(
1408 gz1->ifd,
1409 (char*)gz1->inbuf+gz1->insize,
1410 INBUFSIZ-gz1->insize
1411 );
1412 }
1413
1414 if (len == 0 || len == EOF) break;
1415
1416 gz1->insize += len;
1417
1418 } while( gz1->insize < INBUFSIZ );
1419
1420 if ( gz1->insize == 0 )
1421 {
1422 if( eof_ok ) return EOF;
1423 read_error( gz1 );
1424 }
1425
1426 gz1->bytes_in += (ulg) gz1->insize;
1427 gz1->inptr = 1;
1428
1429 return gz1->inbuf[0];
1430 }
1431
1432 ulg updcrc(
1433 PGZ1 gz1,
1434 uch *s,
1435 unsigned n
1436 )
1437 {
1438 register ulg c;
1439
1440 if ( s == NULL )
1441 {
1442 c = 0xffffffffL;
1443 }
1444 else
1445 {
1446 c = gz1->crc;
1447
1448 if ( n )
1449 {
1450 do{
1451 c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
1452
1453 } while( --n );
1454 }
1455 }
1456
1457 gz1->crc = c;
1458
1459 return( c ^ 0xffffffffL );
1460 }
1461
1462 void read_error( PGZ1 gz1 )
1463 {
1464 gz1->abortflag = 1;
1465 }
1466
1467 void mod_gzip_strlwr( char *s )
1468 {
1469 char *p1=s;
1470
1471 if ( s == 0 ) return;
1472
1473 while ( *p1 != 0 )
1474 {
1475 if ( *p1 > 96 ) *p1 = *p1 - 32;
1476 p1++;
1477 }
1478 }
1479
1480 #ifdef __BORLANDC__
1481 #pragma argsused
1482 #endif
1483
1484 char *gz1_basename( PGZ1 gz1, char *fname )
1485 {
1486 char *p;
1487 if ((p = strrchr(fname, PATH_SEP)) != NULL) fname = p+1;
1488 #ifdef PATH_SEP2
1489 if ((p = strrchr(fname, PATH_SEP2)) != NULL) fname = p+1;
1490 #endif
1491 #ifdef PATH_SEP3
1492 if ((p = strrchr(fname, PATH_SEP3)) != NULL) fname = p+1;
1493 #endif
1494 #ifdef SUFFIX_SEP
1495 if ((p = strrchr(fname, SUFFIX_SEP)) != NULL) *p = '\0';
1496 #endif
1497 if (casemap('A') == 'a') mod_gzip_strlwr(fname);
1498 return fname;
1499 }
1500
1501 void write_buf( PGZ1 gz1, int fd, voidp buf, unsigned cnt )
1502 {
1503 unsigned n;
1504
1505 if ( gz1->output_ismem )
1506 {
1507 if ( ( gz1->bytes_out + cnt ) < gz1->output_maxlen )
1508 {
1509 memcpy( gz1->output_ptr, buf, cnt );
1510 gz1->output_ptr += cnt;
1511 }
1512 else
1513 {
1514 write_error( gz1 );
1515 }
1516 }
1517 else
1518 {
1519 while ((n = write(fd, buf, cnt)) != cnt)
1520 {
1521 if (n == (unsigned)(-1))
1522 {
1523 write_error( gz1 );
1524 }
1525 cnt -= n;
1526 buf = (voidp)((char*)buf+n);
1527 }
1528 }
1529 }
1530
1531 void write_error( PGZ1 gz1 )
1532 {
1533 gz1->abortflag = 1;
1534 }
1535
1536 #ifdef __TURBOC__
1537 #ifndef BC55
1538
1539 static ush ptr_offset = 0;
1540
1541 void * fcalloc(
1542 unsigned items,
1543 unsigned size
1544 )
1545 {
1546 void * buf = farmalloc((ulg)items*size + 16L);
1547
1548 if (buf == NULL) return NULL;
1549
1550 if (ptr_offset == 0)
1551 {
1552 ptr_offset = (ush)((uch*)buf-0);
1553 }
1554 else if (ptr_offset != (ush)((uch*)buf-0))
1555 {
1556 error("inconsistent ptr_offset");
1557 }
1558
1559 *((ush*)&buf+1) += (ptr_offset + 15) >> 4;
1560 *(ush*)&buf = 0;
1561
1562 return buf;
1563 }
1564
1565 void fcfree( void *ptr )
1566 {
1567 *((ush*)&ptr+1) -= (ptr_offset + 15) >> 4;
1568 *(ush*)&ptr = ptr_offset;
1569
1570 farfree(ptr);
1571 }
1572
1573 #endif
1574 #endif
1575
1576 int zip(
1577 PGZ1 gz1,
1578 int in,
1579 int out
1580 )
1581 {
1582 uch flags = 0;
1583 ush attr = 0;
1584 ush deflate_flags = 0;
1585
1586 gz1->ifd = in;
1587 gz1->ofd = out;
1588 gz1->outcnt = 0;
1589
1590 gz1->method = DEFLATED;
1591
1592 put_byte(GZIP_MAGIC[0]);
1593 put_byte(GZIP_MAGIC[1]);
1594 put_byte(DEFLATED);
1595
1596 if ( gz1->save_orig_name )
1597 {
1598 flags |= ORIG_NAME;
1599 }
1600
1601 put_byte(flags);
1602 put_long(gz1->time_stamp);
1603
1604 gz1->crc = -1;
1605
1606 updcrc( gz1, NULL, 0 );
1607
1608 bi_init( gz1, out );
1609 mod_gzip_ct_init( gz1, &attr, &gz1->method );
1610 lm_init( gz1, gz1->level, &deflate_flags );
1611
1612 put_byte((uch)deflate_flags);
1613
1614 put_byte(OS_CODE);
1615
1616 if ( gz1->save_orig_name )
1617 {
1618 char *p = gz1_basename( gz1, gz1->ifname );
1619
1620 do {
1621 put_char(*p);
1622
1623 } while (*p++);
1624 }
1625
1626 gz1->header_bytes = (long)gz1->outcnt;
1627
1628 (void) gz1_deflate( gz1 );
1629
1630 put_long( gz1->crc );
1631 put_long( gz1->bytes_in );
1632
1633 gz1->header_bytes += 2*sizeof(long);
1634
1635 flush_outbuf( gz1 );
1636
1637 return OK;
1638 }
1639
1640 ulg gz1_deflate( PGZ1 gz1 )
1641 {
1642 unsigned hash_head;
1643 unsigned prev_match;
1644 int flush;
1645 int match_available = 0;
1646 register unsigned match_length = MIN_MATCH-1;
1647 #ifdef DEBUG
1648 long isize;
1649 #endif
1650
1651 if (gz1->compr_level <= 3)
1652 {
1653 return gz1_deflate_fast(gz1);
1654 }
1655
1656 while (gz1->lookahead != 0)
1657 {
1658 gz1->ins_h =
1659 (((gz1->ins_h)<<H_SHIFT) ^ (gz1->window[gz1->strstart+MIN_MATCH-1])) & HASH_MASK;
1660
1661 prev[ gz1->strstart & WMASK ] = hash_head = head[ gz1->ins_h ];
1662
1663 head[ gz1->ins_h ] = gz1->strstart;
1664
1665 gz1->prev_length = match_length, prev_match = gz1->match_start;
1666 match_length = MIN_MATCH-1;
1667
1668 if (hash_head != NIL && gz1->prev_length < gz1->max_lazy_match &&
1669 gz1->strstart - hash_head <= MAX_DIST) {
1670
1671 match_length = longest_match( gz1, hash_head );
1672
1673 if (match_length > gz1->lookahead) match_length = gz1->lookahead;
1674
1675 if (match_length == MIN_MATCH && gz1->strstart-gz1->match_start > TOO_FAR){
1676
1677 match_length--;
1678 }
1679 }
1680
1681 if (gz1->prev_length >= MIN_MATCH && match_length <= gz1->prev_length) {
1682
1683 flush = ct_tally(gz1,gz1->strstart-1-prev_match, gz1->prev_length - MIN_MATCH);
1684
1685 gz1->lookahead -= ( gz1->prev_length - 1 );
1686 gz1->prev_length -= 2;
1687
1688 do {
1689 gz1->strstart++;
1690
1691 gz1->ins_h =
1692 (((gz1->ins_h)<<H_SHIFT) ^ (gz1->window[ gz1->strstart + MIN_MATCH-1])) & HASH_MASK;
1693
1694 prev[ gz1->strstart & WMASK ] = hash_head = head[gz1->ins_h];
1695
1696 head[ gz1->ins_h ] = gz1->strstart;
1697
1698 } while (--gz1->prev_length != 0);
1699 match_available = 0;
1700 match_length = MIN_MATCH-1;
1701 gz1->strstart++;
1702 if (flush) FLUSH_BLOCK(0), gz1->block_start = gz1->strstart;
1703
1704 } else if (match_available) {
1705
1706 if (ct_tally( gz1, 0, gz1->window[gz1->strstart-1] )) {
1707 FLUSH_BLOCK(0), gz1->block_start = gz1->strstart;
1708 }
1709 gz1->strstart++;
1710 gz1->lookahead--;
1711 } else {
1712
1713 match_available = 1;
1714 gz1->strstart++;
1715 gz1->lookahead--;
1716 }
1717
1718 while (gz1->lookahead < MIN_LOOKAHEAD && !gz1->eofile) fill_window(gz1);
1719 }
1720 if (match_available) ct_tally( gz1, 0, gz1->window[gz1->strstart-1] );
1721
1722 return FLUSH_BLOCK(1);
1723
1724 return 0;
1725 }
1726
1727 void flush_outbuf( PGZ1 gz1 )
1728 {
1729 if ( gz1->outcnt == 0 )
1730 {
1731 return;
1732 }
1733
1734 write_buf( gz1, gz1->ofd, (char *)gz1->outbuf, gz1->outcnt );
1735
1736 gz1->bytes_out += (ulg)gz1->outcnt;
1737 gz1->outcnt = 0;
1738 }
1739
1740 void lm_init(
1741 PGZ1 gz1,
1742 int pack_level,
1743 ush *flags
1744 )
1745 {
1746 register unsigned j;
1747
1748 if ( pack_level < 1 || pack_level > 9 )
1749 {
1750 error("bad pack level");
1751 }
1752
1753 gz1->compr_level = pack_level;
1754
1755 #if defined(MAXSEG_64K) && HASH_BITS == 15
1756 for (j = 0; j < HASH_SIZE; j++) head[j] = NIL;
1757 #else
1758 memset( (char*)head, 0, (HASH_SIZE*sizeof(*head)) );
1759 #endif
1760
1761 gz1->max_lazy_match = configuration_table[pack_level].max_lazy;
1762 gz1->good_match = configuration_table[pack_level].good_length;
1763 #ifndef FULL_SEARCH
1764 gz1->nice_match = configuration_table[pack_level].nice_length;
1765 #endif
1766 gz1->max_chain_length = configuration_table[pack_level].max_chain;
1767
1768 if ( pack_level == 1 )
1769 {
1770 *flags |= FAST;
1771 }
1772 else if ( pack_level == 9 )
1773 {
1774 *flags |= SLOW;
1775 }
1776
1777 gz1->strstart = 0;
1778 gz1->block_start = 0L;
1779 #ifdef ASMV
1780 match_init();
1781 #endif
1782
1783 gz1->lookahead = read_buf(gz1,(char*)gz1->window,
1784 sizeof(int) <= 2 ? (unsigned)WSIZE : 2*WSIZE);
1785
1786 if (gz1->lookahead == 0 || gz1->lookahead == (unsigned)EOF)
1787 {
1788 gz1->eofile = 1, gz1->lookahead = 0;
1789 return;
1790 }
1791
1792 gz1->eofile = 0;
1793
1794 while (gz1->lookahead < MIN_LOOKAHEAD && !gz1->eofile)
1795 {
1796 fill_window(gz1);
1797 }
1798
1799 gz1->ins_h = 0;
1800
1801 for ( j=0; j<MIN_MATCH-1; j++ )
1802 {
1803 gz1->ins_h =
1804 (((gz1->ins_h)<<H_SHIFT) ^ (gz1->window[j])) & HASH_MASK;
1805 }
1806 }
1807
1808 void fill_window( PGZ1 gz1 )
1809 {
1810 register unsigned n, m;
1811
1812 unsigned more =
1813 (unsigned)( gz1->window_size - (ulg)gz1->lookahead - (ulg)gz1->strstart );
1814
1815 if ( more == (unsigned)EOF)
1816 {
1817 more--;
1818 }
1819 else if ( gz1->strstart >= WSIZE+MAX_DIST )
1820 {
1821 memcpy((char*)gz1->window, (char*)gz1->window+WSIZE, (unsigned)WSIZE);
1822
1823 gz1->match_start -= WSIZE;
1824 gz1->strstart -= WSIZE;
1825
1826 gz1->block_start -= (long) WSIZE;
1827
1828 for ( n = 0; n < HASH_SIZE; n++ )
1829 {
1830 m = head[n];
1831 head[n] = (ush)(m >= WSIZE ? m-WSIZE : NIL);
1832 }
1833
1834 for ( n = 0; n < WSIZE; n++ )
1835 {
1836 m = prev[n];
1837
1838 prev[n] = (ush)(m >= WSIZE ? m-WSIZE : NIL);
1839 }
1840
1841 more += WSIZE;
1842 }
1843
1844 if ( !gz1->eofile )
1845 {
1846 n = read_buf(gz1,(char*)gz1->window+gz1->strstart+gz1->lookahead, more);
1847
1848 if ( n == 0 || n == (unsigned)EOF )
1849 {
1850 gz1->eofile = 1;
1851 }
1852 else
1853 {
1854 gz1->lookahead += n;
1855 }
1856 }
1857 }
1858
1859 ulg gz1_deflate_fast( PGZ1 gz1 )
1860 {
1861 unsigned hash_head;
1862 int flush;
1863 unsigned match_length = 0;
1864
1865 gz1->prev_length = MIN_MATCH-1;
1866
1867 while (gz1->lookahead != 0)
1868 {
1869 gz1->ins_h =
1870 (((gz1->ins_h)<<H_SHIFT) ^ (gz1->window[ gz1->strstart + MIN_MATCH-1])) & HASH_MASK;
1871
1872 prev[ gz1->strstart & WMASK ] = hash_head = head[ gz1->ins_h ];
1873
1874 head[ gz1->ins_h ] = gz1->strstart;
1875
1876 if (hash_head != NIL && gz1->strstart - hash_head <= MAX_DIST) {
1877
1878 match_length = longest_match( gz1, hash_head );
1879
1880 if (match_length > gz1->lookahead) match_length = gz1->lookahead;
1881 }
1882 if (match_length >= MIN_MATCH) {
1883
1884 flush = ct_tally(gz1,gz1->strstart-gz1->match_start, match_length - MIN_MATCH);
1885
1886 gz1->lookahead -= match_length;
1887
1888 if (match_length <= gz1->max_lazy_match )
1889 {
1890 match_length--;
1891
1892 do {
1893 gz1->strstart++;
1894
1895 gz1->ins_h =
1896 (((gz1->ins_h)<<H_SHIFT) ^ (gz1->window[ gz1->strstart + MIN_MATCH-1])) & HASH_MASK;
1897
1898 prev[ gz1->strstart & WMASK ] = hash_head = head[ gz1->ins_h ];
1899
1900 head[ gz1->ins_h ] = gz1->strstart;
1901
1902 } while (--match_length != 0);
1903 gz1->strstart++;
1904 } else {
1905 gz1->strstart += match_length;
1906 match_length = 0;
1907 gz1->ins_h = gz1->window[gz1->strstart];
1908
1909 gz1->ins_h =
1910 (((gz1->ins_h)<<H_SHIFT) ^ (gz1->window[gz1->strstart+1])) & HASH_MASK;
1911
1912 #if MIN_MATCH != 3
1913 Call UPDATE_HASH() MIN_MATCH-3 more times
1914 #endif
1915 }
1916 } else {
1917
1918 flush = ct_tally(gz1, 0, gz1->window[gz1->strstart]);
1919 gz1->lookahead--;
1920 gz1->strstart++;
1921 }
1922 if (flush) FLUSH_BLOCK(0), gz1->block_start = gz1->strstart;
1923
1924 while (gz1->lookahead < MIN_LOOKAHEAD && !gz1->eofile) fill_window(gz1);
1925 }
1926
1927 return FLUSH_BLOCK(1);
1928 }
1929
1930 void mod_gzip_ct_init(
1931 PGZ1 gz1,
1932 ush *attr,
1933 int *methodp
1934 )
1935 {
1936 #ifdef DD1
1937 int i,ii;
1938 #endif
1939
1940 int n;
1941 int bits;
1942 int length;
1943 int code;
1944 int dist;
1945
1946 gz1->file_type = attr;
1947 gz1->file_method = methodp;
1948 gz1->compressed_len = gz1->input_len = 0L;
1949
1950 if ( gz1->static_dtree[0].dl.len != 0 )
1951 {
1952 return;
1953 }
1954
1955 length = 0;
1956
1957 for ( code = 0; code < LENGTH_CODES-1; code++ )
1958 {
1959 gz1->base_length[code] = length;
1960
1961 for ( n = 0; n < (1<<extra_lbits[code]); n++ )
1962 {
1963 gz1->length_code[length++] = (uch)code;
1964 }
1965 }
1966
1967 gz1->length_code[length-1] = (uch)code;
1968
1969 dist = 0;
1970
1971 for ( code = 0 ; code < 16; code++ )
1972 {
1973 gz1->base_dist[code] = dist;
1974
1975 for ( n = 0; n < (1<<extra_dbits[code]); n++ )
1976 {
1977 gz1->dist_code[dist++] = (uch)code;
1978 }
1979 }
1980
1981 dist >>= 7;
1982
1983 for ( ; code < D_CODES; code++ )
1984 {
1985 gz1->base_dist[code] = dist << 7;
1986
1987 for ( n = 0; n < (1<<(extra_dbits[code]-7)); n++ )
1988 {
1989 gz1->dist_code[256 + dist++] = (uch)code;
1990 }
1991 }
1992
1993 for ( bits = 0; bits <= MAX_BITS; bits++ )
1994 {
1995 gz1->bl_count[bits] = 0;
1996 }
1997
1998 n = 0;
1999
2000 while (n <= 143) gz1->static_ltree[n++].dl.len = 8, gz1->bl_count[8]++;
2001 while (n <= 255) gz1->static_ltree[n++].dl.len = 9, gz1->bl_count[9]++;
2002 while (n <= 279) gz1->static_ltree[n++].dl.len = 7, gz1->bl_count[7]++;
2003 while (n <= 287) gz1->static_ltree[n++].dl.len = 8, gz1->bl_count[8]++;
2004
2005 gen_codes(gz1,(ct_data *)gz1->static_ltree, L_CODES+1);
2006
2007 for ( n = 0; n < D_CODES; n++ )
2008 {
2009 gz1->static_dtree[n].dl.len = 5;
2010 gz1->static_dtree[n].fc.code = bi_reverse( gz1, n, 5 );
2011 }
2012
2013 init_block( gz1 );
2014 }
2015
2016 ulg flush_block(
2017 PGZ1 gz1,
2018 char *buf,
2019 ulg stored_len,
2020 int eof
2021 )
2022 {
2023 ulg opt_lenb;
2024 ulg static_lenb;
2025 int max_blindex;
2026
2027 gz1->flag_buf[gz1->last_flags] = gz1->flags;
2028
2029 if (*gz1->file_type == (ush)UNKNOWN) set_file_type(gz1);
2030
2031 build_tree( gz1, (tree_desc *)(&gz1->l_desc) );
2032 build_tree( gz1, (tree_desc *)(&gz1->d_desc) );
2033
2034 max_blindex = build_bl_tree( gz1 );
2035
2036 opt_lenb = (gz1->opt_len+3+7)>>3;
2037 static_lenb = (gz1->static_len+3+7)>>3;
2038 gz1->input_len += stored_len;
2039
2040 if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
2041
2042 #ifdef FORCE_METHOD
2043
2044 if ( level == 1 && eof && gz1->compressed_len == 0L )
2045 #else
2046 if (stored_len <= opt_lenb && eof && gz1->compressed_len == 0L && 0 )
2047 #endif
2048 {
2049 if (buf == (char*)0) error ("block vanished");
2050
2051 copy_block( gz1, buf, (unsigned)stored_len, 0 );
2052
2053 gz1->compressed_len = stored_len << 3;
2054 *gz1->file_method = STORED;
2055
2056 #ifdef FORCE_METHOD
2057 } else if (level == 2 && buf != (char*)0) {
2058 #else
2059 } else if (stored_len+4 <= opt_lenb && buf != (char*)0) {
2060
2061 #endif
2062
2063 send_bits(gz1,(STORED_BLOCK<<1)+eof, 3);
2064 gz1->compressed_len = (gz1->compressed_len + 3 + 7) & ~7L;
2065 gz1->compressed_len += (stored_len + 4) << 3;
2066
2067 copy_block(gz1, buf, (unsigned)stored_len, 1);
2068
2069 #ifdef FORCE_METHOD
2070 } else if (level == 3) {
2071 #else
2072 } else if (static_lenb == opt_lenb) {
2073 #endif
2074 send_bits(gz1,(STATIC_TREES<<1)+eof, 3);
2075
2076 compress_block(
2077 gz1,
2078 (ct_data *)gz1->static_ltree,
2079 (ct_data *)gz1->static_dtree
2080 );
2081
2082 gz1->compressed_len += 3 + gz1->static_len;
2083 }
2084 else
2085 {
2086 send_bits(gz1,(DYN_TREES<<1)+eof, 3);
2087
2088 send_all_trees(
2089 gz1,
2090 gz1->l_desc.max_code+1,
2091 gz1->d_desc.max_code+1,
2092 max_blindex+1
2093 );
2094
2095 compress_block(
2096 gz1,
2097 (ct_data *)gz1->dyn_ltree,
2098 (ct_data *)gz1->dyn_dtree
2099 );
2100
2101 gz1->compressed_len += 3 + gz1->opt_len;
2102 }
2103
2104 init_block( gz1 );
2105
2106 if ( eof )
2107 {
2108 bi_windup( gz1 );
2109
2110 gz1->compressed_len += 7;
2111 }
2112
2113 return gz1->compressed_len >> 3;
2114 }
2115
2116 #ifdef __BORLANDC__
2117 #pragma argsused
2118 #endif
2119
2120 unsigned bi_reverse(
2121 PGZ1 gz1,
2122 unsigned code,
2123 int len
2124 )
2125 {
2126 register unsigned res = 0;
2127
2128 do {
2129 res |= code & 1;
2130 code >>= 1, res <<= 1;
2131
2132 } while (--len > 0);
2133
2134 return res >> 1;
2135 }
2136
2137 void set_file_type( PGZ1 gz1 )
2138 {
2139 int n = 0;
2140 unsigned ascii_freq = 0;
2141 unsigned bin_freq = 0;
2142
2143 while (n < 7) bin_freq += gz1->dyn_ltree[n++].fc.freq;
2144 while (n < 128) ascii_freq += gz1->dyn_ltree[n++].fc.freq;
2145 while (n < LITERALS) bin_freq += gz1->dyn_ltree[n++].fc.freq;
2146
2147 *gz1->file_type = bin_freq > (ascii_freq >> 2) ? BINARY : ASCII;
2148 }
2149
2150 void init_block( PGZ1 gz1 )
2151 {
2152 int n;
2153
2154 for (n = 0; n < L_CODES; n++) gz1->dyn_ltree[n].fc.freq = 0;
2155 for (n = 0; n < D_CODES; n++) gz1->dyn_dtree[n].fc.freq = 0;
2156 for (n = 0; n < BL_CODES; n++) gz1->bl_tree[n].fc.freq = 0;
2157
2158 gz1->dyn_ltree[END_BLOCK].fc.freq = 1;
2159
2160 gz1->opt_len = 0L;
2161 gz1->static_len = 0L;
2162 gz1->last_lit = 0;
2163 gz1->last_dist = 0;
2164 gz1->last_flags = 0;
2165 gz1->flags = 0;
2166 gz1->flag_bit = 1;
2167 }
2168
2169 void bi_init( PGZ1 gz1, gz1_file_t zipfile )
2170 {
2171 gz1->zfile = zipfile;
2172 gz1->bi_buf = 0;
2173 gz1->bi_valid = 0;
2174
2175 if ( gz1->zfile != NO_FILE )
2176 {
2177 read_buf = file_read;
2178 }
2179 }
2180
2181 int ct_tally(
2182 PGZ1 gz1,
2183 int dist,
2184 int lc
2185 )
2186 {
2187 int dcode;
2188
2189 gz1->inbuf[gz1->last_lit++] = (uch)lc;
2190
2191 if ( dist == 0 )
2192 {
2193 gz1->dyn_ltree[lc].fc.freq++;
2194 }
2195 else
2196 {
2197 dist--;
2198
2199 gz1->dyn_ltree[gz1->length_code[lc]+LITERALS+1].fc.freq++;
2200 gz1->dyn_dtree[d_code(dist)].fc.freq++;
2201 gz1->d_buf[gz1->last_dist++] = (ush)dist;
2202 gz1->flags |= gz1->flag_bit;
2203 }
2204
2205 gz1->flag_bit <<= 1;
2206
2207 if ( (gz1->last_lit & 7) == 0 )
2208 {
2209 gz1->flag_buf[gz1->last_flags++] = gz1->flags;
2210 gz1->flags = 0, gz1->flag_bit = 1;
2211 }
2212
2213 if ( gz1->level > 2 && (gz1->last_lit & 0xfff) == 0)
2214 {
2215 ulg out_length = (ulg) ( gz1->last_lit * 8L );
2216 ulg in_length = (ulg) ( gz1->strstart - gz1->block_start );
2217
2218 for ( dcode = 0; dcode < D_CODES; dcode++ )
2219 {
2220 out_length += (ulg) ((gz1->dyn_dtree[dcode].fc.freq)*(5L+extra_dbits[dcode]));
2221 }
2222
2223 out_length >>= 3;
2224
2225 if ( gz1->last_dist < gz1->last_lit/2 && out_length < in_length/2 )
2226 {
2227 return 1;
2228 }
2229 }
2230
2231 return( gz1->last_lit == LIT_BUFSIZE-1 || gz1->last_dist == DIST_BUFSIZE );
2232 }
2233
2234 void compress_block(
2235 PGZ1 gz1,
2236 ct_data *ltree,
2237 ct_data *dtree
2238 )
2239 {
2240 unsigned dist;
2241 int lc;
2242 unsigned lx = 0;
2243 unsigned dx = 0;
2244 unsigned fx = 0;
2245 uch flag = 0;
2246 unsigned code;
2247 int extra;
2248
2249 if (gz1->last_lit != 0) do {
2250 if ((lx & 7) == 0) flag = gz1->flag_buf[fx++];
2251 lc = gz1->inbuf[lx++];
2252 if ((flag & 1) == 0) {
2253 send_code(lc, ltree);
2254 } else {
2255
2256 code = gz1->length_code[lc];
2257 send_code(code+LITERALS+1, ltree);
2258 extra = extra_lbits[code];
2259 if (extra != 0) {
2260 lc -= gz1->base_length[code];
2261 send_bits(gz1,lc, extra);
2262 }
2263 dist = gz1->d_buf[dx++];
2264
2265 code = d_code(dist);
2266
2267 send_code(code, dtree);
2268 extra = extra_dbits[code];
2269 if (extra != 0) {
2270 dist -= gz1->base_dist[code];
2271 send_bits(gz1,dist, extra);
2272 }
2273 }
2274 flag >>= 1;
2275 } while (lx < gz1->last_lit);
2276
2277 send_code(END_BLOCK, ltree);
2278 }
2279
2280 #ifndef ASMV
2281
2282 int longest_match( PGZ1 gz1, unsigned cur_match )
2283 {
2284 unsigned chain_length = gz1->max_chain_length;
2285 register uch *scan = gz1->window + gz1->strstart;
2286 register uch *match;
2287 register int len;
2288 int best_len = gz1->prev_length;
2289 unsigned limit = gz1->strstart > (unsigned)MAX_DIST ? gz1->strstart - (unsigned)MAX_DIST : NIL;
2290
2291 #if HASH_BITS < 8 || MAX_MATCH != 258
2292 error: Code too clever
2293 #endif
2294
2295 #ifdef UNALIGNED_OK
2296
2297 register uch *strend = gz1->window + gz1->strstart + MAX_MATCH - 1;
2298 register ush scan_start = *(ush*)scan;
2299 register ush scan_end = *(ush*)(scan+best_len-1);
2300 #else
2301 register uch *strend = gz1->window + gz1->strstart + MAX_MATCH;
2302 register uch scan_end1 = scan[best_len-1];
2303 register uch scan_end = scan[best_len];
2304 #endif
2305
2306 if (gz1->prev_length >= gz1->good_match) {
2307 chain_length >>= 2;
2308 }
2309
2310 do {
2311 match = gz1->window + cur_match;
2312
2313 #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
2314
2315 if (*(ush*)(match+best_len-1) != scan_end ||
2316 *(ush*)match != scan_start) continue;
2317
2318 scan++, match++;
2319 do {
2320 } while (*(ush*)(scan+=2) == *(ush*)(match+=2) &&
2321 *(ush*)(scan+=2) == *(ush*)(match+=2) &&
2322 *(ush*)(scan+=2) == *(ush*)(match+=2) &&
2323 *(ush*)(scan+=2) == *(ush*)(match+=2) &&
2324 scan < strend);
2325
2326 if (*scan == *match) scan++;
2327
2328 len = (MAX_MATCH - 1) - (int)(strend-scan);
2329 scan = strend - (MAX_MATCH-1);
2330 #else
2331 if (match[best_len] != scan_end ||
2332 match[best_len-1] != scan_end1 ||
2333 *match != *scan ||
2334 *++match != scan[1]) continue;
2335
2336 scan += 2, match++;
2337
2338 do {
2339 } while (*++scan == *++match && *++scan == *++match &&
2340 *++scan == *++match && *++scan == *++match &&
2341 *++scan == *++match && *++scan == *++match &&
2342 *++scan == *++match && *++scan == *++match &&
2343 scan < strend);
2344
2345 len = MAX_MATCH - (int)(strend - scan);
2346 scan = strend - MAX_MATCH;
2347 #endif
2348 if (len > best_len) {
2349 gz1->match_start = cur_match;
2350 best_len = len;
2351 if (len >= gz1->nice_match) break;
2352 #ifdef UNALIGNED_OK
2353 scan_end = *(ush*)(scan+best_len-1);
2354 #else
2355 scan_end1 = scan[best_len-1];
2356 scan_end = scan[best_len];
2357 #endif
2358 }
2359 } while ((cur_match = prev[cur_match & WMASK]) > limit
2360 && --chain_length != 0);
2361
2362 return best_len;
2363 }
2364 #endif
2365
2366 void send_bits(
2367 PGZ1 gz1,
2368 int value,
2369 int length
2370 )
2371 {
2372 if ( gz1->bi_valid > (int) BUFSIZE - length )
2373 {
2374 gz1->bi_buf |= (value << gz1->bi_valid);
2375
2376 put_short(gz1->bi_buf);
2377
2378 gz1->bi_buf = (ush)value >> (BUFSIZE - gz1->bi_valid);
2379 gz1->bi_valid += length - BUFSIZE;
2380 }
2381 else
2382 {
2383 gz1->bi_buf |= value << gz1->bi_valid;
2384 gz1->bi_valid += length;
2385 }
2386 }
2387
2388 void build_tree(
2389 PGZ1 gz1,
2390 tree_desc *desc
2391 )
2392 {
2393 int elems = desc->elems;
2394 ct_data *tree = desc->dyn_tree;
2395 ct_data *stree = desc->static_tree;
2396
2397 int n;
2398 int m;
2399 int max_code = -1;
2400 int node = elems;
2401 int new1;
2402
2403 gz1->heap_len = 0, gz1->heap_max = HEAP_SIZE;
2404
2405 for (n = 0; n < elems; n++) {
2406 if (tree[n].fc.freq != 0) {
2407 gz1->heap[++gz1->heap_len] = max_code = n;
2408 gz1->depth[n] = 0;
2409 } else {
2410 tree[n].dl.len = 0;
2411 }
2412 }
2413
2414 while (gz1->heap_len < 2) {
2415 new1 = gz1->heap[++gz1->heap_len] = (max_code < 2 ? ++max_code : 0);
2416 tree[new1].fc.freq = 1;
2417 gz1->depth[new1] = 0;
2418 gz1->opt_len--; if (stree) gz1->static_len -= stree[new1].dl.len;
2419 }
2420 desc->max_code = max_code;
2421
2422 for (n = gz1->heap_len/2; n >= 1; n--) pqdownheap(gz1, tree, n);
2423
2424 do {
2425 n = gz1->heap[SMALLEST];
2426 gz1->heap[SMALLEST] = gz1->heap[gz1->heap_len--];
2427 pqdownheap(gz1, tree, SMALLEST);
2428 m = gz1->heap[SMALLEST];
2429 gz1->heap[--gz1->heap_max] = n;
2430 gz1->heap[--gz1->heap_max] = m;
2431 tree[node].fc.freq = tree[n].fc.freq + tree[m].fc.freq;
2432 gz1->depth[node] = (uch) (GZ1_MAX(gz1->depth[n], gz1->depth[m]) + 1);
2433 tree[n].dl.dad = tree[m].dl.dad = (ush)node;
2434 gz1->heap[SMALLEST] = node++;
2435 pqdownheap(gz1, tree, SMALLEST);
2436
2437 } while (gz1->heap_len >= 2);
2438
2439 gz1->heap[--gz1->heap_max] = gz1->heap[SMALLEST];
2440
2441 gen_bitlen(gz1,(tree_desc *)desc);
2442
2443 gen_codes(gz1,(ct_data *)tree, max_code);
2444 }
2445
2446 int build_bl_tree( PGZ1 gz1 )
2447 {
2448 int max_blindex;
2449
2450 scan_tree( gz1, (ct_data *)gz1->dyn_ltree, gz1->l_desc.max_code );
2451 scan_tree( gz1, (ct_data *)gz1->dyn_dtree, gz1->d_desc.max_code );
2452
2453 build_tree( gz1, (tree_desc *)(&gz1->bl_desc) );
2454
2455 for ( max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex-- )
2456 {
2457 if (gz1->bl_tree[bl_order[max_blindex]].dl.len != 0) break;
2458 }
2459
2460 gz1->opt_len += 3*(max_blindex+1) + 5+5+4;
2461
2462 return max_blindex;
2463 }
2464
2465 void gen_codes(
2466 PGZ1 gz1,
2467 ct_data *tree,
2468 int max_code
2469 )
2470 {
2471 ush next_code[MAX_BITS+1];
2472 ush code = 0;
2473 int bits;
2474 int n;
2475
2476 for ( bits = 1; bits <= MAX_BITS; bits++ )
2477 {
2478 next_code[bits] = code = (code + gz1->bl_count[bits-1]) << 1;
2479 }
2480
2481 for ( n = 0; n <= max_code; n++ )
2482 {
2483 int len = tree[n].dl.len;
2484 if (len == 0) continue;
2485
2486 tree[n].fc.code = bi_reverse( gz1, next_code[len]++, len );
2487 }
2488
2489 return;
2490 }
2491
2492 void gen_bitlen(
2493 PGZ1 gz1,
2494 tree_desc *desc
2495 )
2496 {
2497 ct_data *tree = desc->dyn_tree;
2498 int *extra = desc->extra_bits;
2499 int base = desc->extra_base;
2500 int max_code = desc->max_code;
2501 int max_length = desc->max_length;
2502 ct_data *stree = desc->static_tree;
2503 int h;
2504 int n, m;
2505 int bits;
2506 int xbits;
2507 ush f;
2508 int overflow = 0;
2509
2510 for (bits = 0; bits <= MAX_BITS; bits++) gz1->bl_count[bits] = 0;
2511
2512 tree[gz1->heap[gz1->heap_max]].dl.len = 0;
2513
2514 for (h = gz1->heap_max+1; h < HEAP_SIZE; h++) {
2515 n = gz1->heap[h];
2516 bits = tree[tree[n].dl.dad].dl.len + 1;
2517 if (bits > max_length) bits = max_length, overflow++;
2518 tree[n].dl.len = (ush)bits;
2519
2520 if (n > max_code) continue;
2521
2522 gz1->bl_count[bits]++;
2523 xbits = 0;
2524 if (n >= base) xbits = extra[n-base];
2525 f = tree[n].fc.freq;
2526 gz1->opt_len += (ulg)f * (bits + xbits);
2527 if (stree) gz1->static_len += (ulg)f * (stree[n].dl.len + xbits);
2528 }
2529 if (overflow == 0) return;
2530
2531 do {
2532 bits = max_length-1;
2533 while (gz1->bl_count[bits] == 0) bits--;
2534 gz1->bl_count[bits]--;
2535 gz1->bl_count[bits+1] += 2;
2536 gz1->bl_count[max_length]--;
2537
2538 overflow -= 2;
2539 } while (overflow > 0);
2540
2541 for (bits = max_length; bits != 0; bits--) {
2542 n = gz1->bl_count[bits];
2543 while (n != 0) {
2544 m = gz1->heap[--h];
2545 if (m > max_code) continue;
2546 if (tree[m].dl.len != (unsigned) bits) {
2547 gz1->opt_len += ((long)bits-(long)tree[m].dl.len)*(long)tree[m].fc.freq;
2548 tree[m].dl.len = (ush)bits;
2549 }
2550 n--;
2551 }
2552 }
2553 }
2554
2555 void copy_block(
2556 PGZ1 gz1,
2557 char *buf,
2558 unsigned len,
2559 int header
2560 )
2561 {
2562 #ifdef CRYPT
2563 int t;
2564 #endif
2565
2566 bi_windup( gz1 );
2567
2568 if ( header )
2569 {
2570 put_short((ush)len);
2571 put_short((ush)~len);
2572 }
2573
2574 while( len-- )
2575 {
2576 #ifdef CRYPT
2577 if (key) zencode(*buf, t);
2578 #endif
2579
2580 put_byte(*buf++);
2581 }
2582 }
2583
2584 int file_read( PGZ1 gz1, char *buf, unsigned size )
2585 {
2586 unsigned len = 0;
2587 unsigned bytes_to_copy = 0;
2588
2589 if ( gz1->input_ismem )
2590 {
2591 if ( gz1->input_bytesleft > 0 )
2592 {
2593 bytes_to_copy = size;
2594
2595 if ( bytes_to_copy > (unsigned) gz1->input_bytesleft )
2596 {
2597 bytes_to_copy = (unsigned) gz1->input_bytesleft;
2598 }
2599
2600 memcpy( buf, gz1->input_ptr, bytes_to_copy );
2601
2602 gz1->input_ptr += bytes_to_copy;
2603 gz1->input_bytesleft -= bytes_to_copy;
2604
2605 len = bytes_to_copy;
2606 }
2607 else
2608 {
2609 len = 0;
2610 }
2611 }
2612 else
2613 {
2614 len = read( gz1->ifd, buf, size );
2615 }
2616
2617 if ( len == (unsigned)(-1) || len == 0 )
2618 {
2619 gz1->crc = gz1->crc ^ 0xffffffffL;
2620 return (int)len;
2621 }
2622
2623 updcrc( gz1, (uch*)buf, len );
2624 gz1->bytes_in += (ulg)len;
2625
2626 return (int)len;
2627 }
2628
2629 void bi_windup( PGZ1 gz1 )
2630 {
2631 if ( gz1->bi_valid > 8 )
2632 {
2633 put_short(gz1->bi_buf);
2634 }
2635 else if ( gz1->bi_valid > 0 )
2636 {
2637 put_byte(gz1->bi_buf);
2638 }
2639
2640 gz1->bi_buf = 0;
2641 gz1->bi_valid = 0;
2642 }
2643
2644 void send_all_trees(
2645 PGZ1 gz1,
2646 int lcodes,
2647 int dcodes,
2648 int blcodes
2649 )
2650 {
2651 int rank;
2652
2653 send_bits(gz1,lcodes-257, 5);
2654 send_bits(gz1,dcodes-1, 5);
2655 send_bits(gz1,blcodes-4, 4);
2656
2657 for ( rank = 0; rank < blcodes; rank++ )
2658 {
2659 send_bits(gz1,gz1->bl_tree[bl_order[rank]].dl.len, 3 );
2660 }
2661
2662 send_tree(gz1,(ct_data *)gz1->dyn_ltree, lcodes-1);
2663 send_tree(gz1,(ct_data *)gz1->dyn_dtree, dcodes-1);
2664 }
2665
2666 void send_tree(
2667 PGZ1 gz1,
2668 ct_data *tree,
2669 int max_code
2670 )
2671 {
2672 int n;
2673 int prevlen = -1;
2674 int curlen;
2675 int nextlen = tree[0].dl.len;
2676 int count = 0;
2677 int max_count = 7;
2678 int min_count = 4;
2679
2680 if (nextlen == 0) max_count = 138, min_count = 3;
2681
2682 for ( n = 0; n <= max_code; n++ )
2683 {
2684 curlen = nextlen;
2685 nextlen = tree[n+1].dl.len;
2686
2687 if (++count < max_count && curlen == nextlen)
2688 {
2689 continue;
2690 }
2691 else if (count < min_count)
2692 {
2693 do { send_code(curlen, gz1->bl_tree); } while (--count != 0);
2694 }
2695 else if (curlen != 0)
2696 {
2697 if ( curlen != prevlen )
2698 {
2699 send_code(curlen, gz1->bl_tree); count--;
2700 }
2701
2702 send_code( REP_3_6, gz1->bl_tree ); send_bits(gz1,count-3, 2);
2703 }
2704 else if (count <= 10)
2705 {
2706 send_code(REPZ_3_10, gz1->bl_tree); send_bits(gz1,count-3, 3);
2707 }
2708 else
2709 {
2710 send_code(REPZ_11_138, gz1->bl_tree); send_bits(gz1,count-11, 7);
2711 }
2712
2713 count = 0;
2714 prevlen = curlen;
2715
2716 if (nextlen == 0)
2717 {
2718 max_count = 138, min_count = 3;
2719 }
2720 else if (curlen == nextlen)
2721 {
2722 max_count = 6, min_count = 3;
2723 }
2724 else
2725 {
2726 max_count = 7, min_count = 4;
2727 }
2728 }
2729 }
2730
2731 void scan_tree(
2732 PGZ1 gz1,
2733 ct_data *tree,
2734 int max_code
2735 )
2736 {
2737 int n;
2738 int prevlen = -1;
2739 int curlen;
2740 int nextlen = tree[0].dl.len;
2741 int count = 0;
2742 int max_count = 7;
2743 int min_count = 4;
2744
2745 if (nextlen == 0) max_count = 138, min_count = 3;
2746
2747 tree[max_code+1].dl.len = (ush)0xffff;
2748
2749 for ( n = 0; n <= max_code; n++ )
2750 {
2751 curlen = nextlen;
2752 nextlen = tree[n+1].dl.len;
2753
2754 if ( ++count < max_count && curlen == nextlen )
2755 {
2756 continue;
2757 }
2758 else if ( count < min_count )
2759 {
2760 gz1->bl_tree[curlen].fc.freq += count;
2761 }
2762 else if ( curlen != 0 )
2763 {
2764 if ( curlen != prevlen ) gz1->bl_tree[curlen].fc.freq++;
2765 gz1->bl_tree[REP_3_6].fc.freq++;
2766 }
2767 else if ( count <= 10 )
2768 {
2769 gz1->bl_tree[REPZ_3_10].fc.freq++;
2770 }
2771 else
2772 {
2773 gz1->bl_tree[REPZ_11_138].fc.freq++;
2774 }
2775
2776 count = 0;
2777 prevlen = curlen;
2778
2779 if ( nextlen == 0 )
2780 {
2781 max_count = 138;
2782 min_count = 3;
2783 }
2784 else if (curlen == nextlen)
2785 {
2786 max_count = 6;
2787 min_count = 3;
2788 }
2789 else
2790 {
2791 max_count = 7;
2792 min_count = 4;
2793 }
2794 }
2795 }
2796
2797 void pqdownheap(
2798 PGZ1 gz1,
2799 ct_data *tree,
2800 int k
2801 )
2802 {
2803 int v = gz1->heap[k];
2804 int j = k << 1;
2805
2806 while( j <= gz1->heap_len )
2807 {
2808 if (j < gz1->heap_len && smaller(tree, gz1->heap[j+1], gz1->heap[j])) j++;
2809
2810 if (smaller(tree, v, gz1->heap[j])) break;
2811
2812 gz1->heap[k] = gz1->heap[j]; k = j;
2813
2814 j <<= 1;
2815 }
2816
2817 gz1->heap[k] = v;
2818 }
2819
2820 #define GZS_ZIP1 1
2821 #define GZS_ZIP2 2
2822 #define GZS_DEFLATE1 3
2823 #define GZS_DEFLATE2 4
2824
2825 int gzs_fsp ( PGZ1 gz1 );
2826 int gzs_zip1 ( PGZ1 gz1 );
2827 int gzs_zip2 ( PGZ1 gz1 );
2828 int gzs_deflate1( PGZ1 gz1 );
2829 int gzs_deflate2( PGZ1 gz1 );
2830
2831 int gzp_main( request_rec *r, GZP_CONTROL *gzp )
2832 {
2833 char cn[]="gzp_main()";
2834
2835 PGZ1 gz1 = 0;
2836 int rc = 0;
2837 int final_exit_code = 0;
2838 int ofile_flags = O_RDWR | O_CREAT | O_TRUNC | O_BINARY;
2839
2840 gzp->result_code = 0;
2841 gzp->bytes_out = 0;
2842
2843 gz1 = (PGZ1) gz1_init();
2844
2845 if ( gz1 == 0 )
2846 {
2847 return 0;
2848 }
2849
2850 gz1->decompress = gzp->decompress;
2851
2852 mod_gzip_strcpy( gz1->ifname, gzp->input_filename );
2853 mod_gzip_strcpy( gz1->ofname, gzp->output_filename );
2854
2855 gz1->input_ismem = gzp->input_ismem;
2856 gz1->input_ptr = gzp->input_ismem_ibuf + gzp->input_offset;
2857 gz1->input_bytesleft = gzp->input_ismem_ibuflen;
2858
2859 gz1->output_ismem = gzp->output_ismem;
2860 gz1->output_ptr = gzp->output_ismem_obuf;
2861 gz1->output_maxlen = gzp->output_ismem_obuflen;
2862
2863 if ( gz1->no_time < 0 ) gz1->no_time = gz1->decompress;
2864 if ( gz1->no_name < 0 ) gz1->no_name = gz1->decompress;
2865
2866 work = zip;
2867
2868 if ( !gz1->input_ismem )
2869 {
2870 errno = 0;
2871
2872 rc = stat( gz1->ifname, &gz1->istat );
2873
2874 if ( rc != 0 )
2875 {
2876 ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server,
2877 "%s: stat(gz1->ifname=%s) FAILED", cn, gz1->ifname );
2878
2879 gz1_cleanup( gz1 );
2880
2881 return 0;
2882 }
2883
2884 gz1->ifile_size = ( gz1->istat.st_size - gzp->input_offset );
2885
2886 if ( gz1->ifile_size < 0 ) gz1->ifile_size = 0;
2887
2888 gz1->ifd =
2889 OPEN(
2890 gz1->ifname,
2891 gz1->ascii && !gz1->decompress ? O_RDONLY : O_RDONLY | O_BINARY,
2892 RW_USER
2893 );
2894
2895 if ( gz1->ifd == -1 )
2896 {
2897 ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server,
2898 "%s: OPEN(gz1->ifname=%s) FAILED", cn, gz1->ifname );
2899
2900 gz1_cleanup( gz1 );
2901
2902 return 0;
2903 }
2904
2905 if ( gzp->input_offset > 0 )
2906 {
2907 SEEKFORWARD( gz1->ifd, gzp->input_offset );
2908 }
2909 }
2910
2911 if ( !gz1->output_ismem )
2912 {
2913 if ( gz1->ascii && gz1->decompress )
2914 {
2915 ofile_flags &= ~O_BINARY;
2916 }
2917
2918 gz1->ofd = OPEN( gz1->ofname, ofile_flags, RW_USER );
2919
2920 if ( gz1->ofd == -1 )
2921 {
2922 ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server,
2923 "%s: OPEN(gz1->ofname=%s) FAILED", cn, gz1->ofname );
2924
2925 if ( gz1->ifd )
2926 {
2927 close( gz1->ifd );
2928 gz1->ifd = 0;
2929 }
2930
2931 gz1_cleanup( gz1 );
2932
2933 return 0;
2934 }
2935 }
2936
2937 gz1->outcnt = 0;
2938 gz1->insize = 0;
2939 gz1->inptr = 0;
2940 gz1->bytes_in = 0L;
2941 gz1->bytes_out = 0L;
2942 gz1->part_nb = 0;
2943
2944 if ( gz1->decompress )
2945 {
2946 gz1->method = get_header( gz1, gz1->ifd );
2947
2948 if ( gz1->method < 0 )
2949 {
2950 if ( gz1->ifd )
2951 {
2952 close( gz1->ifd );
2953 gz1->ifd = 0;
2954 }
2955
2956 if ( gz1->ofd )
2957 {
2958 close( gz1->ofd );
2959 gz1->ofd = 0;
2960 }
2961
2962 return 0;
2963 }
2964 }
2965
2966 gz1->save_orig_name = 0;
2967
2968 gz1->state = GZS_ZIP1;
2969
2970 for (;;)
2971 {
2972 gzs_fsp( gz1 );
2973
2974 if ( gz1->done == 1 ) break;
2975 }
2976
2977 if ( gz1->ifd )
2978 {
2979 close( gz1->ifd );
2980 gz1->ifd = 0;
2981 }
2982
2983 if ( gz1->ofd )
2984 {
2985 close( gz1->ofd );
2986 gz1->ofd = 0;
2987 }
2988
2989 gzp->result_code = gz1->exit_code;
2990 gzp->bytes_out = gz1->bytes_out;
2991
2992 final_exit_code = (int) gz1->exit_code;
2993
2994 gz1_cleanup( gz1 );
2995
2996 return final_exit_code;
2997 }
2998
2999 int gzs_fsp( PGZ1 gz1 )
3000 {
3001 int rc=0;
3002
3003 switch( gz1->state )
3004 {
3005 case GZS_ZIP1:
3006
3007 rc = gzs_zip1( gz1 );
3008
3009 break;
3010
3011 case GZS_ZIP2:
3012
3013 rc = gzs_zip2( gz1 );
3014
3015 break;
3016
3017 case GZS_DEFLATE1:
3018
3019 rc = gzs_deflate1( gz1 );
3020
3021 break;
3022
3023 case GZS_DEFLATE2:
3024
3025 rc = gzs_deflate2( gz1 );
3026
3027 break;
3028
3029 default:
3030
3031 gz1->done = 1;
3032
3033 break;
3034 }
3035
3036 return( rc );
3037 }
3038
3039 int gzs_zip1( PGZ1 gz1 )
3040 {
3041 uch flags = 0;
3042
3043 #ifdef FUTURE_USE
3044 ush attr = 0;
3045 ush deflate_flags = 0;
3046 #endif
3047
3048 gz1->outcnt = 0;
3049
3050 gz1->method = DEFLATED;
3051
3052 put_byte(GZIP_MAGIC[0]);
3053 put_byte(GZIP_MAGIC[1]);
3054 put_byte(DEFLATED);
3055
3056 if ( gz1->save_orig_name )
3057 {
3058 flags |= ORIG_NAME;
3059 }
3060
3061 put_byte(flags);
3062 put_long(gz1->time_stamp);
3063
3064 gz1->crc = -1;
3065
3066 updcrc( gz1, NULL, 0 );
3067
3068 gz1->state = GZS_ZIP2;
3069
3070 return 0;
3071 }
3072
3073 int gzs_zip2( PGZ1 gz1 )
3074 {
3075 #ifdef FUTURE_USE
3076 uch flags = 0;
3077 #endif
3078
3079 ush attr = 0;
3080 ush deflate_flags = 0;
3081
3082 bi_init( gz1, gz1->ofd );
3083 mod_gzip_ct_init( gz1, &attr, &gz1->method );
3084 lm_init( gz1, gz1->level, &deflate_flags );
3085 put_byte((uch)deflate_flags);
3086
3087 put_byte(OS_CODE);
3088
3089 if ( gz1->save_orig_name )
3090 {
3091 char *p = gz1_basename( gz1, gz1->ifname );
3092
3093 do {
3094 put_char(*p);
3095
3096 } while (*p++);
3097 }
3098
3099 gz1->header_bytes = (long)gz1->outcnt;
3100
3101 gz1->state = GZS_DEFLATE1;
3102
3103 return 0;
3104 }
3105
3106 int gzs_deflate1( PGZ1 gz1 )
3107 {
3108 if ( !gz1->deflate1_initialized )
3109 {
3110 gz1->deflate1_match_available = 0;
3111 gz1->deflate1_match_length = MIN_MATCH-1;
3112 gz1->deflate1_initialized = 1;
3113 }
3114
3115 if ( gz1->compr_level <= 3 )
3116 {
3117 gz1->done = 1;
3118
3119 return 0;
3120 }
3121
3122 if ( gz1->lookahead == 0 )
3123 {
3124 if ( gz1->deflate1_match_available )
3125 {
3126 ct_tally( gz1, 0, gz1->window[gz1->strstart-1] );
3127 }
3128
3129 gz1->state = GZS_DEFLATE2;
3130
3131 return (int) FLUSH_BLOCK(1);
3132 }
3133
3134 #ifdef STAY_HERE_FOR_A_CERTAIN_AMOUNT_OF_ITERATIONS
3135
3136 while( iterations < max_iterations_per_yield )
3137 {
3138 #endif
3139
3140 gz1->ins_h =
3141 (((gz1->ins_h)<<H_SHIFT) ^ (gz1->window[gz1->strstart+MIN_MATCH-1])) & HASH_MASK;
3142
3143 prev[ gz1->strstart & WMASK ] = gz1->deflate1_hash_head = head[ gz1->ins_h ];
3144
3145 head[ gz1->ins_h ] = gz1->strstart;
3146
3147 gz1->prev_length = gz1->deflate1_match_length, gz1->deflate1_prev_match = gz1->match_start;
3148 gz1->deflate1_match_length = MIN_MATCH-1;
3149
3150 if ( gz1->deflate1_hash_head != NIL && gz1->prev_length < gz1->max_lazy_match &&
3151 gz1->strstart - gz1->deflate1_hash_head <= MAX_DIST)
3152 {
3153 gz1->deflate1_match_length = longest_match( gz1, gz1->deflate1_hash_head );
3154
3155 if ( gz1->deflate1_match_length > gz1->lookahead )
3156 {
3157 gz1->deflate1_match_length = gz1->lookahead;
3158 }
3159
3160 if (gz1->deflate1_match_length == MIN_MATCH && gz1->strstart-gz1->match_start > TOO_FAR)
3161 {
3162 gz1->deflate1_match_length--;
3163 }
3164 }
3165
3166 if ( gz1->prev_length >= MIN_MATCH && gz1->deflate1_match_length <= gz1->prev_length )
3167 {
3168 gz1->deflate1_flush =
3169 ct_tally(gz1,gz1->strstart-1-gz1->deflate1_prev_match, gz1->prev_length - MIN_MATCH);
3170
3171 gz1->lookahead -= ( gz1->prev_length - 1 );
3172 gz1->prev_length -= 2;
3173
3174 do {
3175 gz1->strstart++;
3176
3177 gz1->ins_h =
3178 (((gz1->ins_h)<<H_SHIFT) ^ (gz1->window[ gz1->strstart + MIN_MATCH-1])) & HASH_MASK;
3179
3180 prev[ gz1->strstart & WMASK ] = gz1->deflate1_hash_head = head[gz1->ins_h];
3181
3182 head[ gz1->ins_h ] = gz1->strstart;
3183
3184 } while (--gz1->prev_length != 0);
3185
3186 gz1->deflate1_match_available = 0;
3187 gz1->deflate1_match_length = MIN_MATCH-1;
3188
3189 gz1->strstart++;
3190
3191 if (gz1->deflate1_flush) FLUSH_BLOCK(0), gz1->block_start = gz1->strstart;
3192 }
3193
3194 else
3195 {
3196 if ( gz1->deflate1_match_available )
3197 {
3198 if ( ct_tally( gz1, 0, gz1->window[gz1->strstart-1] ) )
3199 {
3200 FLUSH_BLOCK(0), gz1->block_start = gz1->strstart;
3201 }
3202
3203 gz1->strstart++;
3204 gz1->lookahead--;
3205 }
3206 else
3207 {
3208 gz1->deflate1_match_available = 1;
3209 gz1->strstart++;
3210 gz1->lookahead--;
3211 }
3212
3213 while (gz1->lookahead < MIN_LOOKAHEAD && !gz1->eofile )
3214 {
3215 fill_window(gz1);
3216 }
3217 }
3218
3219 return 0;
3220 }
3221
3222 int gzs_deflate2( PGZ1 gz1 )
3223 {
3224 #if !defined(NO_SIZE_CHECK) && !defined(RECORD_IO)
3225 if (gz1->ifile_size != -1L && gz1->isize != (ulg)gz1->ifile_size)
3226 {
3227 }
3228 #endif
3229
3230 put_long( gz1->crc );
3231 put_long( gz1->bytes_in );
3232
3233 gz1->header_bytes += 2*sizeof(long);
3234
3235 flush_outbuf( gz1 );
3236
3237 gz1->done = 1;
3238
3239 return OK;
3240 }
3241
3242 /*--------------------------------------------------------------------------*/
3243 /* COMPRESSION_SUPPORT: END */
3244 /*--------------------------------------------------------------------------*/