"Fossies" - the Fresh Open Source Software Archive

Member "mod_gzip-1.3.26.1a/mod_gzip_compress.c" (1 Oct 2002, 71415 Bytes) of package /linux/www/apache_httpd_modules/old/mod_gzip-1.3.26.1a.tgz:


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 /*--------------------------------------------------------------------------*/