Merge tag 'upstream/1.5'
authorBdale Garbee <bdale@gag.com>
Tue, 19 Jun 2012 20:01:51 +0000 (14:01 -0600)
committerBdale Garbee <bdale@gag.com>
Tue, 19 Jun 2012 20:01:51 +0000 (14:01 -0600)
Upstream version 1.5

Conflicts:
deflate.c
gzip.1
gzip.c
gzip.doc
lib/getdtablesize.c
lib/sys_stat.in.h
m4/getdtablesize.m4
zless.in

1  2 
configure.ac
deflate.c
doc/gzip.texi
gzip.1
gzip.c
gzip.h

diff --combined configure.ac
index 0919132cc5a43de9621a237c6bf589ef12c01dff,4705ce4b386a68bfc2d730fc3ab0c77791a39905..50cb427731c12a9305d67226f31732a85b90a9c1
@@@ -1,6 -1,6 +1,6 @@@
  # Configure template for gzip.
  
- # Copyright (C) 1999-2002, 2006-2007, 2009-2010 Free Software Foundation, Inc.
+ # Copyright (C) 1999-2002, 2006-2007, 2009-2012 Free Software Foundation, Inc.
  
  # Copyright (C) 1992-1993 Jean-loup Gailly
  
@@@ -21,8 -21,8 +21,8 @@@
  
  AC_PREREQ([2.60])
  AC_INIT([gzip],
-       m4_esyscmd([build-aux/git-version-gen .tarball-version]),
-       [bug-gzip@gnu.org])
+         m4_esyscmd([build-aux/git-version-gen .tarball-version]),
+         [bug-gzip@gnu.org])
  
  AC_CONFIG_SRCDIR(gzip.c)
  AC_CONFIG_AUX_DIR(build-aux)
@@@ -39,7 -39,6 +39,6 @@@ AC_PROG_RANLI
  AC_PROG_SHELL
  
  gl_EARLY
- AC_SYS_LARGEFILE
  
  gl_INIT
  
@@@ -104,6 -103,8 +103,8 @@@ if test "$gl_gcc_warnings" = yes; the
    gl_WARN_ADD([-Wno-unused-parameter]) # Too many warnings for now
    gl_WARN_ADD([-Wno-overflow])         # util.c
    gl_WARN_ADD([-Wno-type-limits])      # util.c
+   gl_WARN_ADD([-Wno-format-nonliteral])
+   gl_WARN_ADD([-Wno-unsuffixed-float-constants])
  
    # In spite of excluding -Wlogical-op above, it is enabled, as of
    # gcc 4.5.0 20090517, and it provokes warnings in cat.c, dd.c, truncate.c
    AC_SUBST([GNULIB_WARN_CFLAGS])
  fi
  
 +gl_FUNC_GETDTABLESIZE
 +if test $HAVE_GETDTABLESIZE = 0; then
 +  AC_LIBOBJ([getdtablesize])
 +fi
 +gl_UNISTD_MODULE_INDICATOR([getdtablesize])
 +
  # cc -E produces incorrect asm files on SVR4, so postprocess it.
- ASCPPPOST="sed '/^ *#/d; s,//.*,,; s/% /%/g; s/\\. /./g'"
+ ASCPPPOST="sed '/^ *\\#/d; s,//.*,,; s/% /%/g; s/\\. /./g'"
  AC_SUBST([ASCPPPOST])
  
  AC_CACHE_CHECK([for underline in external names], [gzip_cv_underline],
    [gzip_cv_underline=yes
     AC_TRY_COMPILE([int foo() {return 0;}], [],
       [$NM conftest.$OBJEXT | grep _foo >/dev/null 2>&1 ||
-       gzip_cv_underline=no])])
+         gzip_cv_underline=no])])
  ASCPPFLAGS=
  if test $gzip_cv_underline = no; then
    ASCPPFLAGS='-DNO_UNDERLINE'
@@@ -160,21 -155,21 +161,21 @@@ AC_CACHE_CHECK([for an assembler synta
     *' NO_ASM '*) ;;
     *)
       if cp $srcdir/lib/match.c _match.S &&
-       eval "$CPP $CPPFLAGS $ASCPPFLAGS _match.S > _match.i" 2>/dev/null &&
-       eval "$ASCPPPOST < _match.i > match_.s" 2>/dev/null; then
+         eval "$CPP $CPPFLAGS $ASCPPFLAGS _match.S > _match.i" &&
+         eval "$ASCPPPOST < _match.i > match_.s"; then
         if test ! -s match_.s || grep error < match_.s > /dev/null; then
-        :
-        elif eval "$CC $CPPFLAGS $CFLAGS -c match_.s >/dev/null 2>&1" &&
-           test -f match_.$OBJEXT; then
-        rm -f match_.$OBJEXT
-        gzip_cv_assembler=yes
-        if echo 'void foo (void) {}' > conftest.c &&
-           eval "$CC $CPPFLAGS $CFLAGS -S conftest.c >/dev/null 2>&1" &&
-           grep '\.note\.GNU-stack' conftest.s >/dev/null 2>&1 &&
-           eval "$CC $CPPFLAGS $CFLAGS -c -Wa,--noexecstack match_.s >/dev/null 2>&1" &&
-           test -f match_.$OBJEXT; then
-          gzip_cv_assembler='yes, with -Wa,--noexecstack'
-        fi
+          :
+        elif eval "$CC $CPPFLAGS $CFLAGS -c match_.s >/dev/null" &&
+             test -f match_.$OBJEXT; then
+          rm -f match_.$OBJEXT
+          gzip_cv_assembler=yes
+          if echo 'void foo (void) {}' > conftest.c &&
+             eval "$CC $CPPFLAGS $CFLAGS -S conftest.c >/dev/null" &&
+             grep '\.note\.GNU-stack' conftest.s >/dev/null &&
+             eval "$CC $CPPFLAGS $CFLAGS -c -Wa,--noexecstack match_.s >/dev/null" &&
+             test -f match_.$OBJEXT; then
+            gzip_cv_assembler='yes, with -Wa,--noexecstack'
+          fi
         fi
       fi
       rm -f conftest* _match.i _match.S match_.s match_.$OBJEXT;;
@@@ -201,5 -196,5 +202,5 @@@ AC_TYPE_SIGNA
  AC_TYPE_SIZE_T
  AC_TYPE_OFF_T
  
- AC_CONFIG_FILES([Makefile doc/Makefile lib/Makefile])
+ AC_CONFIG_FILES([Makefile doc/Makefile lib/Makefile tests/Makefile])
  AC_OUTPUT
diff --combined deflate.c
index a551fa3a409d640905fed9e329d10038731f13a5,5405f10eff3f1ec546d00dfe4a57aeb9e4f04243..4a0f3d37b28278a00695d6440c7993d91e6e5845
+++ b/deflate.c
@@@ -1,6 -1,6 +1,6 @@@
  /* deflate.c -- compress data using the deflation algorithm
  
-    Copyright (C) 1999, 2006, 2009-2010 Free Software Foundation, Inc.
+    Copyright (C) 1999, 2006, 2009-2012 Free Software Foundation, Inc.
     Copyright (C) 1992-1993 Jean-loup Gailly
  
     This program is free software; you can redistribute it and/or modify
  #endif
  /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
  
 +#ifndef RSYNC_WIN
 +#  define RSYNC_WIN 8192
 +#endif
 +/* Size of rsync window, must be < MAX_DIST */
 +
 +#define RSYNC_SUM_MATCH(sum) (((sum) & (RSYNC_WIN - 1)) == 0)
 +/* Whether window sum matches magic value */
 +
  /* ===========================================================================
   * Local data used by the "longest match" routines.
   */
@@@ -169,7 -161,7 +169,7 @@@ typedef unsigned IPos
  /* DECLARE(Pos, head, 1<<HASH_BITS); */
  /* Heads of the hash chains or NIL. */
  
- ulg window_size = (ulg)2*WSIZE;
static ulg window_size = (ulg)2*WSIZE;
  /* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the
   * input file length plus MIN_LOOKAHEAD.
   */
@@@ -188,7 -180,7 +188,7 @@@ local unsigned ins_h;  /* hash index o
   *   H_SHIFT * MIN_MATCH >= HASH_BITS
   */
  
- unsigned int near prev_length;
       unsigned int near prev_length;
  /* Length of the best match at previous step. Matches not greater than this
   * are discarded. This is used in the lazy match evaluation.
   */
  local int           eofile;        /* flag set at end of input file */
  local unsigned      lookahead;     /* number of valid bytes ahead in window */
  
unsigned near max_chain_length;
       unsigned max_chain_length;
  /* To speed up deflation, hash chains are never searched beyond this length.
   * A higher limit improves compression ratio but degrades the speed.
   */
@@@ -217,11 -209,9 +217,11 @@@ local unsigned int max_lazy_match
  local int compr_level;
  /* compression level (1..9) */
  
- unsigned near good_match;
+ unsigned good_match;
  /* Use a faster search when the previous match is longer than this */
  
 +local ulg rsync_sum;  /* rolling sum of rsync window */
 +local ulg rsync_chunk_end; /* next rsync sequence point */
  
  /* Values for max_lazy_match, good_match and max_chain_length, depending on
   * the desired pack level (0..9). The values given below have been tuned to
@@@ -236,10 -226,17 +236,17 @@@ typedef struct config 
     ush max_chain;
  } config;
  
+ #ifdef ASMV
+ # define static_unless_ASMV
+ #else
+ # define static_unless_ASMV static
+ #endif
  #ifdef  FULL_SEARCH
  # define nice_match MAX_MATCH
  #else
-   int near nice_match; /* Stop searching when current match exceeds this */
+   /* Stop searching when current match exceeds this */
+   static_unless_ASMV int nice_match;
  #endif
  
  local config configuration_table[10] = {
  /* ===========================================================================
   *  Prototypes for local functions.
   */
- local void fill_window   OF((void));
- local off_t deflate_fast OF((void));
+ local void fill_window   (void);
+ local off_t deflate_fast (void);
  
-       int  longest_match OF((IPos cur_match));
  #ifdef ASMV
-       void match_init OF((void)); /* asm code initialization */
+       int  longest_match (IPos cur_match);
+       void match_init (void); /* asm code initialization */
  #endif
  
  #ifdef DEBUG
- local  void check_match OF((IPos start, IPos match, int length));
+ local  void check_match (IPos start, IPos match, int length);
  #endif
  
  /* ===========================================================================
   * Update a hash value with the given input byte
-  * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+  * IN  assertion: all calls to UPDATE_HASH are made with consecutive
   *    input characters, so that a running hash key can be computed from the
   *    previous key instead of complete recalculation each time.
   */
   * Insert string s in the dictionary and set match_head to the previous head
   * of the hash chain (the most recent string with same hash key). Return
   * the previous length of the hash chain.
-  * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+  * IN  assertion: all calls to INSERT_STRING are made with consecutive
   *    input characters and the first MIN_MATCH bytes of s are valid
   *    (except for the last MIN_MATCH-1 bytes of the input file).
   */
@@@ -317,10 -314,6 +324,10 @@@ void lm_init (pack_level, flags
  #endif
      /* prev will be initialized on the fly */
  
 +    /* rsync params */
 +    rsync_chunk_end = 0xFFFFFFFFUL;
 +    rsync_sum = 0;
 +
      /* Set the default configuration parameters:
       */
      max_lazy_match   = configuration_table[pack_level].max_lazy;
  
      strstart = 0;
      block_start = 0L;
 +    rsync_chunk_end = 0xFFFFFFFFUL;
  #ifdef ASMV
      match_init(); /* initialize the asm code */
  #endif
  
      lookahead = read_buf((char*)window,
-                        sizeof(int) <= 2 ? (unsigned)WSIZE : 2*WSIZE);
+                          sizeof(int) <= 2 ? (unsigned)WSIZE : 2*WSIZE);
  
      if (lookahead == 0 || lookahead == (unsigned)EOF) {
         eofile = 1, lookahead = 0;
   * match.s. The code is functionally equivalent, so you can use the C version
   * if desired.
   */
- int longest_match(cur_match)
-     IPos cur_match;                             /* current match */
+ static int
+ longest_match(IPos cur_match)
  {
      unsigned chain_length = max_chain_length;   /* max hash chain length */
      register uch *scan = window + strstart;     /* current string */
  #endif
          }
      } while ((cur_match = prev[cur_match & WMASK]) > limit
-            && --chain_length != 0);
+              && --chain_length != 0);
  
      return best_len;
  }
@@@ -558,8 -550,6 +565,8 @@@ local void fill_window(
          memcpy((char*)window, (char*)window+WSIZE, (unsigned)WSIZE);
          match_start -= WSIZE;
          strstart    -= WSIZE; /* we now have strstart >= MAX_DIST: */
 +      if (rsync_chunk_end != 0xFFFFFFFFUL)
 +          rsync_chunk_end -= WSIZE;
  
          block_start -= (long) WSIZE;
  
      }
  }
  
 +local void rsync_roll(start, num)
 +    unsigned start;
 +    unsigned num;
 +{
 +    unsigned i;
 +
 +    if (start < RSYNC_WIN) {
 +      /* before window fills. */
 +      for (i = start; i < RSYNC_WIN; i++) {
 +          if (i == start + num) return;
 +          rsync_sum += (ulg)window[i];
 +      }
 +      num -= (RSYNC_WIN - start);
 +      start = RSYNC_WIN;
 +    }
 +
 +    /* buffer after window full */
 +    for (i = start; i < start+num; i++) {
 +      /* New character in */
 +      rsync_sum += (ulg)window[i];
 +      /* Old character out */
 +      rsync_sum -= (ulg)window[i - RSYNC_WIN];
 +      if (rsync_chunk_end == 0xFFFFFFFFUL && RSYNC_SUM_MATCH(rsync_sum))
 +          rsync_chunk_end = i;
 +    }
 +}
 +
 +/* ===========================================================================
 + * Set rsync_chunk_end if window sum matches magic value.
 + */
 +#define RSYNC_ROLL(s, n) \
 +   do { if (rsync) rsync_roll((s), (n)); } while(0)
 +
  /* ===========================================================================
   * Flush the current block, with given end-of-file flag.
   * IN assertion: strstart is set to the end of the current match.
@@@ -653,7 -610,7 +660,7 @@@ local off_t deflate_fast(
           * At this point we have always match_length < MIN_MATCH
           */
          if (hash_head != NIL && strstart - hash_head <= MAX_DIST
-           && strstart <= window_size - MIN_LOOKAHEAD) {
+             && strstart <= window_size - MIN_LOOKAHEAD) {
              /* To simplify the code, we prevent matches with the string
               * of window index 0 (in particular we have to avoid a match
               * of the string with itself at the start of the input file).
  
              lookahead -= match_length;
  
 -            /* Insert new strings in the hash table only if the match length
 +          RSYNC_ROLL(strstart, match_length);
 +          /* Insert new strings in the hash table only if the match length
               * is not too large. This saves time but degrades compression.
               */
              if (match_length <= max_insert_length) {
                       * the next lookahead bytes will be emitted as literals.
                       */
                  } while (--match_length != 0);
-               strstart++;
+                 strstart++;
              } else {
-               strstart += match_length;
-               match_length = 0;
-               ins_h = window[strstart];
-               UPDATE_HASH(ins_h, window[strstart+1]);
+                 strstart += match_length;
+                 match_length = 0;
+                 ins_h = window[strstart];
+                 UPDATE_HASH(ins_h, window[strstart+1]);
  #if MIN_MATCH != 3
                  Call UPDATE_HASH() MIN_MATCH-3 more times
  #endif
              /* No match, output a literal byte */
              Tracevv((stderr,"%c",window[strstart]));
              flush = ct_tally (0, window[strstart]);
 +          RSYNC_ROLL(strstart, 1);
              lookahead--;
-           strstart++;
+             strstart++;
          }
 +        if (rsync && strstart > rsync_chunk_end) {
 +            ush  attr = 0;          /* ascii/binary flag */
 +
 +            flush = 1;
 +            /* Reset huffman tree */
 +            ct_init(&attr, &method);
 +            rsync_chunk_end = 0xFFFFFFFFUL;
 +        }
          if (flush) FLUSH_BLOCK(0), block_start = strstart;
  
          /* Make sure that we always have enough lookahead, except
@@@ -783,7 -730,6 +790,7 @@@ off_t deflate(
               */
              lookahead -= prev_length-1;
              prev_length -= 2;
 +          RSYNC_ROLL(strstart, prev_length+1);
              do {
                  strstart++;
                  INSERT_STRING(strstart, hash_head);
              match_available = 0;
              match_length = MIN_MATCH-1;
              strstart++;
 -            if (flush) FLUSH_BLOCK(0), block_start = strstart;
  
 +          if (rsync && strstart > rsync_chunk_end) {
 +              ush  attr = 0;          /* ascii/binary flag */
 +
 +              /* Reset huffman tree */
 +              ct_init(&attr, &method);
 +              rsync_chunk_end = 0xFFFFFFFFUL;
 +              flush = 1;
 +          }
 +            if (flush) FLUSH_BLOCK(0), block_start = strstart;
          } else if (match_available) {
              /* If there was no match at the previous position, output a
               * single literal. If there was a match but the current match
               * is longer, truncate the previous match to a single literal.
               */
              Tracevv((stderr,"%c",window[strstart-1]));
 -            if (ct_tally (0, window[strstart-1])) {
 -                FLUSH_BLOCK(0), block_start = strstart;
 -            }
 +          flush = ct_tally (0, window[strstart-1]);
 +          if (rsync && strstart > rsync_chunk_end) {
 +              ush  attr = 0;          /* ascii/binary flag */
 +
 +              /* Reset huffman tree */
 +              ct_init(&attr, &method);
 +              rsync_chunk_end = 0xFFFFFFFFUL;
 +
 +              flush = 1;
 +          }
 +            if (flush) FLUSH_BLOCK(0), block_start = strstart;
 +          RSYNC_ROLL(strstart, 1);
              strstart++;
              lookahead--;
          } else {
              /* There is no previous match to compare with, wait for
               * the next step to decide.
               */
 +          if (rsync && strstart > rsync_chunk_end) {
 +              ush  attr = 0;          /* ascii/binary flag */
 +
 +              /* Reset huffman tree */
 +              ct_init(&attr, &method);
 +              rsync_chunk_end = 0xFFFFFFFFUL;
 +
 +              FLUSH_BLOCK(0), block_start = strstart;
 +          }
              match_available = 1;
 +          RSYNC_ROLL(strstart, 1);
              strstart++;
              lookahead--;
          }
diff --combined doc/gzip.texi
index ecd4e00b74e6a5f74ca8bc1134671dd68a193d57,8220960326b622a4f76a232a1ea61654f96459a0..7f3d4523cf15542ef16d5668a7f1d37b2d5d04f1
@@@ -11,7 -11,7 +11,7 @@@ This manual is for GNU Gzi
  (version @value{VERSION}, @value{UPDATED}),
  and documents commands for compressing and decompressing data.
  
- Copyright @copyright{} 1998-1999, 2001-2002, 2006-2007, 2009-2010 Free Software
+ Copyright @copyright{} 1998-1999, 2001-2002, 2006-2007, 2009-2012 Free Software
  Foundation, Inc.
  
  Copyright @copyright{} 1992, 1993 Jean-loup Gailly
@@@ -207,7 -207,6 +207,7 @@@ Mandatory arguments to long options ar
    -V, --version     display version number
    -1, --fast        compress faster
    -9, --best        compress better
 +    --rsyncable   Make rsync-friendly archive
  
  With no FILE, or when FILE is -, read standard input.
  
@@@ -229,7 -228,7 +229,7 @@@ stopping on the first failure
  find . -name '*
  *' -prune -o -name '*.gz' -type f -print |
    sed "
-     s/'/'\\''/g
+     s/'/'\\\\''/g
      s/^\\(.*\\)\\.gz$/gunzip <'\\1.gz' >'\\1'/
    " |
    sh -e
@@@ -354,22 -353,6 +354,22 @@@ specified on the command line are direc
  into the directory and compress all the files it finds there (or
  decompress them in the case of @command{gunzip}).
  
 +@item --rsyncable
 +While compressing, synchronize the output occasionally based on the
 +input.  This can reduce the compression slightly in some cases, but
 +means that the @code{rsync} program can take advantage of similarities
 +in the uncompressed input when syncronizing two files compressed with
 +this flag.  @code{gunzip} cannot tell the difference between a
 +compressed file created with this option, and one created without it.
 +
 +@item --rsyncable
 +While compressing, synchronize the output occasionally based on
 +the input.  This increases size by less than 1 percent most
 +cases, but means that the @command{rsync} program can much more efficiently
 +synchronize files compressed with this flag.  @command{gunzip}
 +cannot tell the difference between a compressed file created
 +with this option, and one created without it.
 +
  @item --suffix @var{suf}
  @itemx -S @var{suf}
  Use suffix @var{suf} instead of @samp{.gz}.  Any suffix can be
diff --combined gzip.1
index 17f94ad035ce54ec2978cb29a9e10198501a5eb4,8db327d58c82924694ba4cf0a19a501bcc89ceb7..7dbcb0283eebd5f5a87fb306f037f0c03a2201b2
--- 1/gzip.1
--- 2/gzip.1
+++ b/gzip.1
@@@ -180,12 -180,12 +180,12 @@@ or decompressing
  The
  .I gzip
  file format is specified in P. Deutsch, \s-1GZIP\s0 file format
 -specification version 4.3, <ftp://ftp.isi.edu/in-notes/rfc1952.txt>,
 +specification version 4.3, <http://www.ietf.org/rfc/rfc1952.txt>,
  Internet RFC 1952 (May 1996).  The
  .I zip
  deflation format is specified in P. Deutsch, \s-1DEFLATE\s0 Compressed
  Data Format Specification version 1.3,
 -<ftp://ftp.isi.edu/in-notes/rfc1951.txt>, Internet RFC 1951 (May 1996).
 +<http://www.ietf.org/rfc/rfc1951.txt>, Internet RFC 1951 (May 1996).
  
  .SH OPTIONS
  .TP
@@@ -291,16 -291,15 +291,15 @@@ will descend into the directory and com
  ).
  .TP
  .B \-S .suf   --suffix .suf
- Use suffix .suf instead of .gz. Any suffix can be given, but suffixes
+ When compressing, use suffix .suf instead of .gz.
+ Any non-empty suffix can be given, but suffixes
  other than .z and .gz should be avoided to avoid confusion when files
- are transferred to other systems.  A null suffix forces gunzip to  try
- decompression on all given files regardless of suffix, as in:
+ are transferred to other systems.
  
-     gunzip -S "" *       (*.* for MSDOS)
+ When decompressing, add .suf to the beginning of the list of
+ suffixes to try, when deriving an output file name from an input file name.
  
- Previous versions of gzip used
- the .z suffix. This was changed to avoid a conflict with
- .I pack.
+ .IR pack "(1)".
  .TP
  .B \-t --test
  Test. Check the compressed file integrity.
@@@ -383,19 -382,20 +382,19 @@@ explicit command line parameters. For e
  On Vax/VMS, the name of the environment variable is GZIP_OPT, to
  avoid a conflict with the symbol set for invocation of the program.
  .SH "SEE ALSO"
 -znew(1), zcmp(1), zmore(1), zforce(1), gzexe(1), zip(1), unzip(1), compress(1),
 -pack(1), compact(1)
 +znew(1), zcmp(1), zmore(1), zforce(1), gzexe(1), zip(1), unzip(1), compress(1)
  .PP
  The
  .I gzip
  file format is specified in P. Deutsch, \s-1GZIP\s0 file format
  specification version 4.3,
 -.BR <ftp://ftp.isi.edu/in-notes/rfc1952.txt> ,
 +.BR <http://www.ietf.org/rfc/rfc1952.txt> ,
  Internet RFC 1952 (May 1996).
  The
  .I zip
  deflation format is specified in P. Deutsch, \s-1DEFLATE\s0 Compressed
  Data Format Specification version 1.3,
 -.BR <ftp://ftp.isi.edu/in-notes/rfc1951.txt> ,
 +.BR <http://www.ietf.org/rfc/rfc1951.txt> ,
  Internet RFC 1951 (May 1996).
  .SH "DIAGNOSTICS"
  Exit status is normally 0;
diff --combined gzip.c
index b867350f08ef11bc43ee344a64f2091c52b9dbe8,35b36031f4f3f9739c442578f7e308e7894eed53..38e1373e474edd30a0a71825b7281d8429948a9c
--- 1/gzip.c
--- 2/gzip.c
+++ b/gzip.c
@@@ -1,6 -1,6 +1,6 @@@
  /* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface
  
-    Copyright (C) 1999, 2001-2002, 2006-2007, 2009-2010 Free Software
+    Copyright (C) 1999, 2001-2002, 2006-2007, 2009-2012 Free Software
     Foundation, Inc.
     Copyright (C) 1992-1993 Jean-loup Gailly
  
@@@ -29,7 -29,7 +29,7 @@@
   */
  
  static char const *const license_msg[] = {
- "Copyright (C) 2007 Free Software Foundation, Inc.",
+ "Copyright (C) 2007, 2010, 2011 Free Software Foundation, Inc.",
  "Copyright (C) 1993 Jean-loup Gailly.",
  "This is free software.  You may redistribute copies of it under the terms of",
  "the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.",
@@@ -58,6 -58,7 +58,7 @@@
  #include <ctype.h>
  #include <sys/types.h>
  #include <signal.h>
+ #include <stdbool.h>
  #include <sys/stat.h>
  #include <errno.h>
  
  #include "gzip.h"
  #include "lzw.h"
  #include "revision.h"
+ #include "timespec.h"
  
  #include "fcntl-safer.h"
  #include "getopt.h"
  #include "ignore-value.h"
  #include "stat-time.h"
+ #include "version.h"
  
-               /* configuration */
+                 /* configuration */
  
  #include <fcntl.h>
  #include <limits.h>
  #endif
  #if !NO_DIR
  # include <dirent.h>
- # ifndef _D_EXACT_NAMLEN
- #  define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name)
- # endif
- #endif
- #ifdef CLOSEDIR_VOID
- # define CLOSEDIR(d) (closedir(d), 0)
- #else
- # define CLOSEDIR(d) closedir(d)
+ # include <savedir.h>
  #endif
  
  #ifndef NO_UTIME
  #endif
  
  #ifdef off_t
-   off_t lseek OF((int fd, off_t offset, int whence));
+   off_t lseek (int fd, off_t offset, int whence);
  #endif
  
  #ifndef OFF_T_MIN
  # define HAVE_WORKING_O_NOFOLLOW 0
  #endif
  
- #ifndef ELOOP
- # define ELOOP EINVAL
- #endif
  /* Separator for file name parts (see shorten_name()) */
  #ifdef NO_MULTIPLE_DOTS
  #  define PART_SEP "-"
  #  define PART_SEP "."
  #endif
  
-               /* global buffers */
+                 /* global buffers */
  
  DECLARE(uch, inbuf,  INBUFSIZ +INBUF_EXTRA);
  DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA);
@@@ -165,35 -156,39 +156,39 @@@ DECLARE(uch, window, 2L*WSIZE)
      DECLARE(ush, tab_prefix1, 1L<<(BITS-1));
  #endif
  
-               /* local variables */
- int ascii = 0;        /* convert end-of-lines to local OS conventions */
- int to_stdout = 0;    /* output to stdout (-c) */
- int decompress = 0;   /* decompress (-d) */
- int force = 0;        /* don't ask questions, compress links (-f) */
- int no_name = -1;     /* don't save or restore the original file name */
- int no_time = -1;     /* don't save or restore the original file time */
- int recursive = 0;    /* recurse through directories (-r) */
- int list = 0;         /* list the file contents (-l) */
- int verbose = 0;      /* be verbose (-v) */
- int quiet = 0;        /* be very quiet (-q) */
- int do_lzw = 0;       /* generate output compatible with old compress (-Z) */
- int test = 0;         /* test .gz file integrity */
- int foreground = 0;   /* set if program run in foreground */
- char *program_name;   /* program name */
- int maxbits = BITS;   /* max bits per code for LZW */
- int method = DEFLATED;/* compression method */
- int level = 6;        /* compression level */
- int exit_code = OK;   /* program exit code */
- int save_orig_name;   /* set if original name must be saved */
- int last_member;      /* set for .zip and .Z files */
- int part_nb;          /* number of parts in .gz file */
- struct timespec time_stamp; /* original time stamp (modification time) */
- off_t ifile_size;      /* input file size, -1 for devices (debug only) */
- char *env;            /* contents of GZIP env variable */
- char **args = NULL;   /* argv pointer if GZIP env variable defined */
- char const *z_suffix; /* default suffix (can be set with --suffix) */
- size_t z_len;         /* strlen(z_suffix) */
+                 /* local variables */
+ /* If true, pretend that standard input is a tty.  This option
+    is deliberately not documented, and only for testing.  */
+ static bool presume_input_tty;
+ static int ascii = 0;        /* convert end-of-lines to local OS conventions */
+        int to_stdout = 0;    /* output to stdout (-c) */
+ static int decompress = 0;   /* decompress (-d) */
+ static int force = 0;        /* don't ask questions, compress links (-f) */
+ static int no_name = -1;     /* don't save or restore the original file name */
+ static int no_time = -1;     /* don't save or restore the original file time */
+ static int recursive = 0;    /* recurse through directories (-r) */
+ static int list = 0;         /* list the file contents (-l) */
+        int verbose = 0;      /* be verbose (-v) */
+        int quiet = 0;        /* be very quiet (-q) */
+ static int do_lzw = 0;       /* generate output compatible with old compress (-Z) */
+        int test = 0;         /* test .gz file integrity */
+ static int foreground = 0;   /* set if program run in foreground */
+        char *program_name;   /* program name */
+        int maxbits = BITS;   /* max bits per code for LZW */
+        int method = DEFLATED;/* compression method */
+        int level = 6;        /* compression level */
+        int exit_code = OK;   /* program exit code */
+        int save_orig_name;   /* set if original name must be saved */
+ static int last_member;      /* set for .zip and .Z files */
+ static int part_nb;          /* number of parts in .gz file */
+        struct timespec time_stamp; /* original time stamp (modification time) */
+        off_t ifile_size;      /* input file size, -1 for devices (debug only) */
+ static char *env;            /* contents of GZIP env variable */
+ static char **args = NULL;   /* argv pointer if GZIP env variable defined */
+ static char const *z_suffix; /* default suffix (can be set with --suffix) */
+ static size_t z_len;         /* strlen(z_suffix) */
  
  /* The set of signals that are caught.  */
  static sigset_t caught_signals;
@@@ -208,17 -203,16 +203,17 @@@ static int volatile remove_ofname_fd = 
  
  off_t bytes_in;             /* number of input bytes */
  off_t bytes_out;            /* number of output bytes */
off_t total_in;                   /* input bytes for all files */
off_t total_out;          /* output bytes for all files */
static off_t total_in;      /* input bytes for all files */
static off_t total_out;           /* output bytes for all files */
  char ifname[MAX_PATH_LEN]; /* input file name */
  char ofname[MAX_PATH_LEN]; /* output file name */
- struct stat istat;         /* status for input file */
+ static struct stat istat;         /* status for input file */
  int  ifd;                  /* input file descriptor */
  int  ofd;                  /* output file descriptor */
  unsigned insize;           /* valid bytes in inbuf */
  unsigned inptr;            /* index of next byte to be processed in inbuf */
  unsigned outcnt;           /* bytes in output buffer */
 +int rsync = 0;             /* make ryncable chunks */
  
  static int handled_sig[] =
    {
  #ifdef SIGHUP
      , SIGHUP
  #endif
- #ifdef SIGPIPE
      , SIGPIPE
- #else
- # define SIGPIPE 0
- #endif
  #ifdef SIGTERM
      , SIGTERM
  #endif
  #endif
    };
  
- struct option longopts[] =
+ /* For long options that have no equivalent short option, use a
+    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
+ enum
+ {
+   PRESUME_INPUT_TTY_OPTION = CHAR_MAX + 1
+ };
+ static const struct option longopts[] =
  {
   /* { name  has_arg  *flag  val } */
      {"ascii",      0, 0, 'a'}, /* ascii text mode */
      {"license",    0, 0, 'L'}, /* display software license */
      {"no-name",    0, 0, 'n'}, /* don't save or restore original name & time */
      {"name",       0, 0, 'N'}, /* save or restore original name & time */
+     {"-presume-input-tty", no_argument, NULL, PRESUME_INPUT_TTY_OPTION},
      {"quiet",      0, 0, 'q'}, /* quiet mode */
      {"silent",     0, 0, 'q'}, /* quiet mode */
      {"recursive",  0, 0, 'r'}, /* recurse through directories */
      {"best",       0, 0, '9'}, /* compress better */
      {"lzw",        0, 0, 'Z'}, /* make output compatible with old compress */
      {"bits",       1, 0, 'b'}, /* max number of bits per code (implies -Z) */
 -
 +    {"rsyncable",  0, 0, 'R'}, /* make rsync-friendly archive */
      { 0, 0, 0, 0 }
  };
  
  /* local functions */
  
- local void try_help     OF((void)) ATTRIBUTE_NORETURN;
- local void help         OF((void));
- local void license      OF((void));
- local void version      OF((void));
- local int input_eof   OF((void));
- local void treat_stdin  OF((void));
- local void treat_file   OF((char *iname));
- local int create_outfile OF((void));
- local char *get_suffix  OF((char *name));
- local int  open_input_file OF((char *iname, struct stat *sbuf));
- local int  make_ofname  OF((void));
- local void shorten_name  OF((char *name));
- local int  get_method   OF((int in));
- local void do_list      OF((int ifd, int method));
- local int  check_ofname OF((void));
- local void copy_stat    OF((struct stat *ifstat));
- local void install_signal_handlers OF((void));
- local void remove_output_file OF((void));
- local RETSIGTYPE abort_gzip_signal OF((int));
- local void do_exit      OF((int exitcode)) ATTRIBUTE_NORETURN;
-       int main          OF((int argc, char **argv));
- int (*work) OF((int infile, int outfile)) = zip; /* function to call */
+ local void try_help     (void) ATTRIBUTE_NORETURN;
+ local void help         (void);
+ local void license      (void);
+ local void version      (void);
+ local int input_eof   (void);
+ local void treat_stdin  (void);
+ local void treat_file   (char *iname);
+ local int create_outfile (void);
+ local char *get_suffix  (char *name);
+ local int  open_input_file (char *iname, struct stat *sbuf);
+ local void discard_input_bytes (size_t nbytes, unsigned int flags);
+ local int  make_ofname  (void);
+ local void shorten_name  (char *name);
+ local int  get_method   (int in);
+ local void do_list      (int ifd, int method);
+ local int  check_ofname (void);
+ local void copy_stat    (struct stat *ifstat);
+ local void install_signal_handlers (void);
+ local void remove_output_file (void);
+ local RETSIGTYPE abort_gzip_signal (int);
+ local void do_exit      (int exitcode) ATTRIBUTE_NORETURN;
+       int main          (int argc, char **argv);
+ static int (*work) (int infile, int outfile) = zip; /* function to call */
  
  #if ! NO_DIR
- local void treat_dir    OF((int fd, char *dir));
+ local void treat_dir    (int fd, char *dir);
  #endif
  
  #define strequ(s1, s2) (strcmp((s1),(s2)) == 0)
@@@ -311,7 -310,7 +311,7 @@@ static voi
  try_help ()
  {
    fprintf (stderr, "Try `%s --help' for more information.\n",
-          program_name);
+            program_name);
    do_exit (ERROR);
  }
  
@@@ -354,7 -353,6 +354,7 @@@ local void help(
   "  -Z, --lzw         produce output compatible with old compress",
   "  -b, --bits=BITS   max number of bits per code (implies -Z)",
  #endif
 + "  --rsyncable       Make rsync-friendly archive",
   "",
   "With no FILE, or when FILE is -, read standard input.",
   "",
@@@ -371,7 -369,7 +371,7 @@@ local void license(
  {
      char const *const *p = license_msg;
  
-     printf ("%s %s\n", program_name, VERSION);
+     printf ("%s %s\n", program_name, Version);
      while (*p) printf ("%s\n", *p++);
  }
  
@@@ -426,96 -424,95 +426,98 @@@ int main (int argc, char **argv
       * Ignore an .exe extension for MSDOS, OS/2 and VMS.
       */
      if (strncmp (program_name, "un",  2) == 0     /* ungzip, uncompress */
-       || strncmp (program_name, "gun", 3) == 0) /* gunzip */
-       decompress = 1;
+         || strncmp (program_name, "gun", 3) == 0) /* gunzip */
+         decompress = 1;
      else if (strequ (program_name + 1, "cat")     /* zcat, pcat, gcat */
-            || strequ (program_name, "gzcat"))   /* gzcat */
-       decompress = to_stdout = 1;
+              || strequ (program_name, "gzcat"))   /* gzcat */
+         decompress = to_stdout = 1;
  #endif
  
      z_suffix = Z_SUFFIX;
      z_len = strlen(z_suffix);
  
      while ((optc = getopt_long (argc, argv, "ab:cdfhH?lLmMnNqrS:tvVZ123456789",
-                               longopts, (int *)0)) != -1) {
-       switch (optc) {
+                                 longopts, (int *)0)) != -1) {
+         switch (optc) {
          case 'a':
              ascii = 1; break;
-       case 'b':
-           maxbits = atoi(optarg);
-           for (; *optarg; optarg++)
-             if (! ('0' <= *optarg && *optarg <= '9'))
-               {
-                 fprintf (stderr, "%s: -b operand is not an integer\n",
-                          program_name);
-                 try_help ();
-               }
-           break;
-       case 'c':
-           to_stdout = 1; break;
-       case 'd':
-           decompress = 1; break;
-       case 'f':
-           force++; break;
-       case 'h': case 'H':
-           help(); do_exit(OK); break;
-       case 'l':
-           list = decompress = to_stdout = 1; break;
-       case 'L':
-           license(); do_exit(OK); break;
-       case 'm': /* undocumented, may change later */
-           no_time = 1; break;
-       case 'M': /* undocumented, may change later */
-           no_time = 0; break;
-       case 'n':
-           no_name = no_time = 1; break;
-       case 'N':
-           no_name = no_time = 0; break;
-       case 'q':
-           quiet = 1; verbose = 0; break;
-       case 'r':
+         case 'b':
+             maxbits = atoi(optarg);
+             for (; *optarg; optarg++)
+               if (! ('0' <= *optarg && *optarg <= '9'))
+                 {
+                   fprintf (stderr, "%s: -b operand is not an integer\n",
+                            program_name);
+                   try_help ();
+                 }
+             break;
+         case 'c':
+             to_stdout = 1; break;
+         case 'd':
+             decompress = 1; break;
+         case 'f':
+             force++; break;
+         case 'h': case 'H':
+             help(); do_exit(OK); break;
+         case 'l':
+             list = decompress = to_stdout = 1; break;
+         case 'L':
+             license(); do_exit(OK); break;
+         case 'm': /* undocumented, may change later */
+             no_time = 1; break;
+         case 'M': /* undocumented, may change later */
+             no_time = 0; break;
+         case 'n':
+             no_name = no_time = 1; break;
+         case 'N':
+             no_name = no_time = 0; break;
+         case PRESUME_INPUT_TTY_OPTION:
+             presume_input_tty = true; break;
+         case 'q':
+             quiet = 1; verbose = 0; break;
+         case 'r':
  #if NO_DIR
-           fprintf (stderr, "%s: -r not supported on this system\n",
-                    program_name);
-           try_help ();
+             fprintf (stderr, "%s: -r not supported on this system\n",
+                      program_name);
+             try_help ();
  #else
-           recursive = 1;
+             recursive = 1;
  #endif
 -            break;
 -        case 'S':
 +          break;
 +        case 'R':
 +          rsync = 1; break;
 +
 +      case 'S':
  #ifdef NO_MULTIPLE_DOTS
              if (*optarg == '.') optarg++;
  #endif
              z_len = strlen(optarg);
-           z_suffix = optarg;
+             z_suffix = optarg;
              break;
-       case 't':
-           test = decompress = to_stdout = 1;
-           break;
-       case 'v':
-           verbose++; quiet = 0; break;
-       case 'V':
-           version(); do_exit(OK); break;
-       case 'Z':
+         case 't':
+             test = decompress = to_stdout = 1;
+             break;
+         case 'v':
+             verbose++; quiet = 0; break;
+         case 'V':
+             version(); do_exit(OK); break;
+         case 'Z':
  #ifdef LZW
-           do_lzw = 1; break;
+             do_lzw = 1; break;
  #else
-           fprintf(stderr, "%s: -Z not supported in this version\n",
-                   program_name);
-           try_help ();
-           break;
+             fprintf(stderr, "%s: -Z not supported in this version\n",
+                     program_name);
+             try_help ();
+             break;
  #endif
-       case '1':  case '2':  case '3':  case '4':
-       case '5':  case '6':  case '7':  case '8':  case '9':
-           level = optc - '0';
-           break;
-       default:
-           /* Error message already emitted by getopt_long. */
-           try_help ();
-       }
+         case '1':  case '2':  case '3':  case '4':
+         case '5':  case '6':  case '7':  case '8':  case '9':
+             level = optc - '0';
+             break;
+         default:
+             /* Error message already emitted by getopt_long. */
+             try_help ();
+         }
      } /* loop on all arguments */
  
      /* By default, save name and timestamp on compression but do not
  #if O_BINARY
  #else
      if (ascii && !quiet) {
-       fprintf(stderr, "%s: option --ascii ignored on this system\n",
-               program_name);
+         fprintf(stderr, "%s: option --ascii ignored on this system\n",
+                 program_name);
      }
  #endif
-     if ((z_len == 0 && !decompress) || z_len > MAX_SUFFIX) {
-         fprintf(stderr, "%s: incorrect suffix '%s'\n",
-                 program_name, z_suffix);
+     if (z_len == 0 || z_len > MAX_SUFFIX) {
+         fprintf(stderr, "%s: invalid suffix '%s'\n", program_name, z_suffix);
          do_exit(ERROR);
      }
      if (do_lzw && !decompress) work = lzw;
  
      /* Allocate all global buffers (for DYN_ALLOC option) */
  
      /* And get to work */
      if (file_count != 0) {
-       if (to_stdout && !test && !list && (!decompress || !ascii)) {
-           SET_BINARY_MODE(fileno(stdout));
-       }
+         if (to_stdout && !test && !list && (!decompress || !ascii)) {
+             SET_BINARY_MODE(fileno(stdout));
+         }
          while (optind < argc) {
-           treat_file(argv[optind++]);
-       }
+             treat_file(argv[optind++]);
+         }
      } else {  /* Standard input */
-       treat_stdin();
+         treat_stdin();
      }
      if (list && !quiet && file_count > 1) {
-       do_list(-1, -1); /* print totals */
+         do_list(-1, -1); /* print totals */
      }
      do_exit(exit_code);
      return exit_code; /* just to avoid lint warning */
@@@ -583,7 -580,7 +585,7 @@@ input_eof (
    if (inptr == insize)
      {
        if (insize != INBUFSIZ || fill_inbuf (1) == EOF)
-       return 1;
+         return 1;
  
        /* Unget the char that fill_inbuf got.  */
        inptr = 0;
   */
  local void treat_stdin()
  {
-     if (!force && !list &&
-       isatty(fileno((FILE *)(decompress ? stdin : stdout)))) {
-       /* Do not send compressed data to the terminal or read it from
-        * the terminal. We get here when user invoked the program
-        * without parameters, so be helpful. According to the GNU standards:
-        *
-        *   If there is one behavior you think is most useful when the output
-        *   is to a terminal, and another that you think is most useful when
-        *   the output is a file or a pipe, then it is usually best to make
-        *   the default behavior the one that is useful with output to a
-        *   terminal, and have an option for the other behavior.
-        *
-        * Here we use the --force option to get the other behavior.
-        */
-       fprintf(stderr,
-     "%s: compressed data not %s a terminal. Use -f to force %scompression.\n",
-               program_name, decompress ? "read from" : "written to",
-               decompress ? "de" : "");
-       fprintf (stderr, "For help, type: %s -h\n", program_name);
-       do_exit(ERROR);
+     if (!force && !list
+         && (presume_input_tty
+             || isatty(fileno((FILE *)(decompress ? stdin : stdout))))) {
+         /* Do not send compressed data to the terminal or read it from
+          * the terminal. We get here when user invoked the program
+          * without parameters, so be helpful. According to the GNU standards:
+          *
+          *   If there is one behavior you think is most useful when the output
+          *   is to a terminal, and another that you think is most useful when
+          *   the output is a file or a pipe, then it is usually best to make
+          *   the default behavior the one that is useful with output to a
+          *   terminal, and have an option for the other behavior.
+          *
+          * Here we use the --force option to get the other behavior.
+          */
+         if (! quiet)
+           fprintf (stderr,
+                    ("%s: compressed data not %s a terminal."
+                     " Use -f to force %scompression.\n"
+                     "For help, type: %s -h\n"),
+                    program_name,
+                    decompress ? "read from" : "written to",
+                    decompress ? "de" : "",
+                    program_name);
+         do_exit(ERROR);
      }
  
      if (decompress || !ascii) {
-       SET_BINARY_MODE(fileno(stdin));
+         SET_BINARY_MODE(fileno(stdin));
      }
      if (!test && !list && (!decompress || !ascii)) {
-       SET_BINARY_MODE(fileno(stdout));
+         SET_BINARY_MODE(fileno(stdout));
      }
      strcpy(ifname, "stdin");
      strcpy(ofname, "stdout");
      /* Get the file's time stamp and size.  */
      if (fstat (fileno (stdin), &istat) != 0)
        {
-       progerror ("standard input");
-       do_exit (ERROR);
+         progerror ("standard input");
+         do_exit (ERROR);
        }
      ifile_size = S_ISREG (istat.st_mode) ? istat.st_size : -1;
      time_stamp.tv_nsec = -1;
      if (!no_time || list)
-       time_stamp = get_stat_mtime (&istat);
+       {
+         if (S_ISREG (istat.st_mode))
+           time_stamp = get_stat_mtime (&istat);
+         else
+           gettime (&time_stamp);
+       }
  
      clear_bufs(); /* clear input and output buffers */
      to_stdout = 1;
      ifd = fileno(stdin);
  
      if (decompress) {
-       method = get_method(ifd);
-       if (method < 0) {
-           do_exit(exit_code); /* error message already emitted */
-       }
+         method = get_method(ifd);
+         if (method < 0) {
+             do_exit(exit_code); /* error message already emitted */
+         }
      }
      if (list) {
          do_list(ifd, method);
      /* Actually do the compression/decompression. Loop over zipped members.
       */
      for (;;) {
-       if ((*work)(fileno(stdin), fileno(stdout)) != OK) return;
+         if ((*work)(fileno(stdin), fileno(stdout)) != OK) return;
  
-       if (input_eof ())
-         break;
+         if (input_eof ())
+           break;
  
-       method = get_method(ifd);
-       if (method < 0) return; /* error message already emitted */
-       bytes_out = 0;            /* required for length check */
+         method = get_method(ifd);
+         if (method < 0) return; /* error message already emitted */
+         bytes_out = 0;            /* required for length check */
      }
  
      if (verbose) {
-       if (test) {
-           fprintf(stderr, " OK\n");
+         if (test) {
+             fprintf(stderr, " OK\n");
  
-       } else if (!decompress) {
-           display_ratio(bytes_in-(bytes_out-header_bytes), bytes_in, stderr);
-           fprintf(stderr, "\n");
+         } else if (!decompress) {
+             display_ratio(bytes_in-(bytes_out-header_bytes), bytes_in, stderr);
+             fprintf(stderr, "\n");
  #ifdef DISPLAY_STDIN_RATIO
-       } else {
-           display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out,stderr);
-           fprintf(stderr, "\n");
+         } else {
+             display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out,stderr);
+             fprintf(stderr, "\n");
  #endif
-       }
+         }
      }
  }
  
@@@ -692,10 -699,10 +704,10 @@@ local void treat_file(iname
  {
      /* Accept "-" as synonym for stdin */
      if (strequ(iname, "-")) {
-       int cflag = to_stdout;
-       treat_stdin();
-       to_stdout = cflag;
-       return;
+         int cflag = to_stdout;
+         treat_stdin();
+         to_stdout = cflag;
+         return;
      }
  
      /* Check if the input file is present, set ifname and istat: */
      /* If the input name is that of a directory, recurse or ignore: */
      if (S_ISDIR(istat.st_mode)) {
  #if ! NO_DIR
-       if (recursive) {
-           treat_dir (ifd, iname);
-           /* Warning: ifname is now garbage */
-           return;
-       }
+         if (recursive) {
+             treat_dir (ifd, iname);
+             /* Warning: ifname is now garbage */
+             return;
+         }
  #endif
-       close (ifd);
-       WARN ((stderr, "%s: %s is a directory -- ignored\n",
-              program_name, ifname));
-       return;
+         close (ifd);
+         WARN ((stderr, "%s: %s is a directory -- ignored\n",
+                program_name, ifname));
+         return;
      }
  
      if (! to_stdout)
        {
-       if (! S_ISREG (istat.st_mode))
-         {
-           WARN ((stderr,
-                  "%s: %s is not a directory or a regular file - ignored\n",
-                  program_name, ifname));
-           close (ifd);
-           return;
-         }
-       if (istat.st_mode & S_ISUID)
-         {
-           WARN ((stderr, "%s: %s is set-user-ID on execution - ignored\n",
-                  program_name, ifname));
-           close (ifd);
-           return;
-         }
-       if (istat.st_mode & S_ISGID)
-         {
-           WARN ((stderr, "%s: %s is set-group-ID on execution - ignored\n",
-                  program_name, ifname));
-           close (ifd);
-           return;
-         }
-       if (! force)
-         {
-           if (istat.st_mode & S_ISVTX)
-             {
-               WARN ((stderr,
-                      "%s: %s has the sticky bit set - file ignored\n",
-                      program_name, ifname));
-               close (ifd);
-               return;
-             }
-           if (2 <= istat.st_nlink)
-             {
-               WARN ((stderr, "%s: %s has %lu other link%c -- unchanged\n",
-                      program_name, ifname,
-                      (unsigned long int) istat.st_nlink - 1,
-                      istat.st_nlink == 2 ? ' ' : 's'));
-               close (ifd);
-               return;
-             }
-         }
+         if (! S_ISREG (istat.st_mode))
+           {
+             WARN ((stderr,
+                    "%s: %s is not a directory or a regular file - ignored\n",
+                    program_name, ifname));
+             close (ifd);
+             return;
+           }
+         if (istat.st_mode & S_ISUID)
+           {
+             WARN ((stderr, "%s: %s is set-user-ID on execution - ignored\n",
+                    program_name, ifname));
+             close (ifd);
+             return;
+           }
+         if (istat.st_mode & S_ISGID)
+           {
+             WARN ((stderr, "%s: %s is set-group-ID on execution - ignored\n",
+                    program_name, ifname));
+             close (ifd);
+             return;
+           }
+         if (! force)
+           {
+             if (istat.st_mode & S_ISVTX)
+               {
+                 WARN ((stderr,
+                        "%s: %s has the sticky bit set - file ignored\n",
+                        program_name, ifname));
+                 close (ifd);
+                 return;
+               }
+             if (2 <= istat.st_nlink)
+               {
+                 WARN ((stderr, "%s: %s has %lu other link%c -- unchanged\n",
+                        program_name, ifname,
+                        (unsigned long int) istat.st_nlink - 1,
+                        istat.st_nlink == 2 ? ' ' : 's'));
+                 close (ifd);
+                 return;
+               }
+           }
        }
  
      ifile_size = S_ISREG (istat.st_mode) ? istat.st_size : -1;
       * without a valid gzip suffix (check done in make_ofname).
       */
      if (to_stdout && !list && !test) {
-       strcpy(ofname, "stdout");
+         strcpy(ofname, "stdout");
  
      } else if (make_ofname() != OK) {
-       close (ifd);
-       return;
+         close (ifd);
+         return;
      }
  
      clear_bufs(); /* clear input and output buffers */
      part_nb = 0;
  
      if (decompress) {
-       method = get_method(ifd); /* updates ofname if original given */
-       if (method < 0) {
-           close(ifd);
-           return;               /* error message already emitted */
-       }
+         method = get_method(ifd); /* updates ofname if original given */
+         if (method < 0) {
+             close(ifd);
+             return;               /* error message already emitted */
+         }
      }
      if (list) {
          do_list(ifd, method);
          if (close (ifd) != 0)
-         read_error ();
+           read_error ();
          return;
      }
  
       * a new ofname and save the original name in the compressed file.
       */
      if (to_stdout) {
-       ofd = fileno(stdout);
-       /* Keep remove_ofname_fd negative.  */
+         ofd = fileno(stdout);
+         /* Keep remove_ofname_fd negative.  */
      } else {
-       if (create_outfile() != OK) return;
+         if (create_outfile() != OK) return;
  
-       if (!decompress && save_orig_name && !verbose && !quiet) {
-           fprintf(stderr, "%s: %s compressed to %s\n",
-                   program_name, ifname, ofname);
-       }
+         if (!decompress && save_orig_name && !verbose && !quiet) {
+             fprintf(stderr, "%s: %s compressed to %s\n",
+                     program_name, ifname, ofname);
+         }
      }
      /* Keep the name even if not truncated except with --no-name: */
      if (!save_orig_name) save_orig_name = !no_name;
  
      if (verbose) {
-       fprintf(stderr, "%s:\t", ifname);
+         fprintf(stderr, "%s:\t", ifname);
      }
  
      /* Actually do the compression/decompression. Loop over zipped members.
       */
      for (;;) {
-       if ((*work)(ifd, ofd) != OK) {
-           method = -1; /* force cleanup */
-           break;
-       }
+         if ((*work)(ifd, ofd) != OK) {
+             method = -1; /* force cleanup */
+             break;
+         }
  
-       if (input_eof ())
-         break;
+         if (input_eof ())
+           break;
  
-       method = get_method(ifd);
-       if (method < 0) break;    /* error message already emitted */
-       bytes_out = 0;            /* required for length check */
+         method = get_method(ifd);
+         if (method < 0) break;    /* error message already emitted */
+         bytes_out = 0;            /* required for length check */
      }
  
      if (close (ifd) != 0)
  
      if (!to_stdout)
        {
-       sigset_t oldset;
-       int unlink_errno;
-       copy_stat (&istat);
-       if (close (ofd) != 0)
-         write_error ();
-       sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
-       remove_ofname_fd = -1;
-       unlink_errno = xunlink (ifname) == 0 ? 0 : errno;
-       sigprocmask (SIG_SETMASK, &oldset, NULL);
-       if (unlink_errno)
-         {
-           WARN ((stderr, "%s: ", program_name));
-           if (!quiet)
-             {
-               errno = unlink_errno;
-               perror (ifname);
-             }
-         }
+         sigset_t oldset;
+         int unlink_errno;
+         copy_stat (&istat);
+         if (close (ofd) != 0)
+           write_error ();
+         sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
+         remove_ofname_fd = -1;
+         unlink_errno = xunlink (ifname) == 0 ? 0 : errno;
+         sigprocmask (SIG_SETMASK, &oldset, NULL);
+         if (unlink_errno)
+           {
+             WARN ((stderr, "%s: ", program_name));
+             if (!quiet)
+               {
+                 errno = unlink_errno;
+                 perror (ifname);
+               }
+           }
        }
  
      if (method == -1) {
-       if (!to_stdout)
-         remove_output_file ();
-       return;
+         if (!to_stdout)
+           remove_output_file ();
+         return;
      }
  
      /* Display statistics */
      if(verbose) {
-       if (test) {
-           fprintf(stderr, " OK");
-       } else if (decompress) {
-           display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out,stderr);
-       } else {
-           display_ratio(bytes_in-(bytes_out-header_bytes), bytes_in, stderr);
-       }
-       if (!test && !to_stdout) {
-           fprintf(stderr, " -- replaced with %s", ofname);
-       }
-       fprintf(stderr, "\n");
+         if (test) {
+             fprintf(stderr, " OK");
+         } else if (decompress) {
+             display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out,stderr);
+         } else {
+             display_ratio(bytes_in-(bytes_out-header_bytes), bytes_in, stderr);
+         }
+         if (!test && !to_stdout) {
+             fprintf(stderr, " -- replaced with %s", ofname);
+         }
+         fprintf(stderr, "\n");
      }
  }
  
@@@ -899,7 -906,7 +911,7 @@@ local int create_outfile(
  {
    int name_shortened = 0;
    int flags = (O_WRONLY | O_CREAT | O_EXCL
-              | (ascii && decompress ? 0 : O_BINARY));
+                | (ascii && decompress ? 0 : O_BINARY));
  
    for (;;)
      {
        sigprocmask (SIG_SETMASK, &oldset, NULL);
  
        if (0 <= ofd)
-       break;
+         break;
  
        switch (open_errno)
-       {
+         {
  #ifdef ENAMETOOLONG
-       case ENAMETOOLONG:
-         shorten_name (ofname);
-         name_shortened = 1;
-         break;
+         case ENAMETOOLONG:
+           shorten_name (ofname);
+           name_shortened = 1;
+           break;
  #endif
  
-       case EEXIST:
-         if (check_ofname () != OK)
-           {
-             close (ifd);
-             return ERROR;
-           }
-         break;
-       default:
-         progerror (ofname);
-         close (ifd);
-         return ERROR;
-       }
+         case EEXIST:
+           if (check_ofname () != OK)
+             {
+               close (ifd);
+               return ERROR;
+             }
+           break;
+         default:
+           progerror (ofname);
+           close (ifd);
+           return ERROR;
+         }
      }
  
    if (name_shortened && decompress)
      {
        /* name might be too long if an original name was saved */
        WARN ((stderr, "%s: %s: warning, name truncated\n",
-            program_name, ofname));
+              program_name, ofname));
      }
  
    return OK;
@@@ -979,8 -986,8 +991,8 @@@ local char *get_suffix(name
  #ifdef SUFFIX_SEP
      /* strip a version number from the file name */
      {
-       char *v = strrchr(name, SUFFIX_SEP);
-       if (v != NULL) *v = '\0';
+         char *v = strrchr(name, SUFFIX_SEP);
+         if (v != NULL) *v = '\0';
      }
  #endif
      nlen = strlen(name);
@@@ -1015,19 -1022,19 +1027,19 @@@ open_and_stat (char *name, int flags, m
    if (!to_stdout && !force)
      {
        if (HAVE_WORKING_O_NOFOLLOW)
-       flags |= O_NOFOLLOW;
+         flags |= O_NOFOLLOW;
        else
-       {
+         {
  #if HAVE_LSTAT || defined lstat
-         if (lstat (name, st) != 0)
-           return -1;
-         else if (S_ISLNK (st->st_mode))
-           {
-             errno = ELOOP;
-             return -1;
-           }
+           if (lstat (name, st) != 0)
+             return -1;
+           else if (S_ISLNK (st->st_mode))
+             {
+               errno = ELOOP;
+               return -1;
+             }
  #endif
-       }
+         }
      }
  
    fd = OPEN (name, flags, mode);
@@@ -1064,12 -1071,12 +1076,12 @@@ open_input_file (iname, sbuf
  #endif
      int fd;
      int open_flags = (O_RDONLY | O_NONBLOCK | O_NOCTTY
-                     | (ascii && !decompress ? 0 : O_BINARY));
+                       | (ascii && !decompress ? 0 : O_BINARY));
  
      *suf = z_suffix;
  
      if (sizeof ifname - 1 <= strlen (iname))
-       goto name_too_long;
+         goto name_too_long;
  
      strcpy(ifname, iname);
  
        return fd;
  
      if (!decompress || errno != ENOENT) {
-       progerror(ifname);
-       return -1;
+         progerror(ifname);
+         return -1;
      }
      /* file.ext doesn't exist, try adding a suffix (after removing any
       * version number for VMS).
       */
      s = get_suffix(ifname);
      if (s != NULL) {
-       progerror(ifname); /* ifname already has z suffix and does not exist */
-       return -1;
+         progerror(ifname); /* ifname already has z suffix and does not exist */
+         return -1;
      }
  #ifdef NO_MULTIPLE_DOTS
      dot = strrchr(ifname, '.');
          if (*dot == '\0') strcpy (dot, ".");
  #endif
  #ifdef MAX_EXT_CHARS
-       if (MAX_EXT_CHARS < strlen (s) + strlen (dot + 1))
-         dot[MAX_EXT_CHARS + 1 - strlen (s)] = '\0';
+         if (MAX_EXT_CHARS < strlen (s) + strlen (dot + 1))
+           dot[MAX_EXT_CHARS + 1 - strlen (s)] = '\0';
  #endif
-       if (sizeof ifname <= ilen + strlen (s))
-         goto name_too_long;
+         if (sizeof ifname <= ilen + strlen (s))
+           goto name_too_long;
          strcat(ifname, s);
-       fd = open_and_stat (ifname, open_flags, RW_USER, sbuf);
-       if (0 <= fd)
-         return fd;
-       if (errno != ENOENT)
-         {
-           progerror (ifname);
-           return -1;
-         }
-       if (strequ (s0, z_suffix))
-         z_suffix_errno = errno;
+         fd = open_and_stat (ifname, open_flags, RW_USER, sbuf);
+         if (0 <= fd)
+           return fd;
+         if (errno != ENOENT)
+           {
+             progerror (ifname);
+             return -1;
+           }
+         if (strequ (s0, z_suffix))
+           z_suffix_errno = errno;
      } while (*++suf != NULL);
  
      /* No suffix found, complain using z_suffix: */
@@@ -1160,52 -1167,52 +1172,52 @@@ local int make_ofname(
      suff = get_suffix(ofname);
  
      if (decompress) {
-       if (suff == NULL) {
-           /* With -t or -l, try all files (even without .gz suffix)
-            * except with -r (behave as with just -dr).
+         if (suff == NULL) {
+             /* With -t or -l, try all files (even without .gz suffix)
+              * except with -r (behave as with just -dr).
               */
              if (!recursive && (list || test)) return OK;
  
-           /* Avoid annoying messages with -r */
-           if (verbose || (!recursive && !quiet)) {
-               WARN((stderr,"%s: %s: unknown suffix -- ignored\n",
-                     program_name, ifname));
-           }
-           return WARNING;
-       }
-       /* Make a special case for .tgz and .taz: */
-       strlwr(suff);
-       if (strequ(suff, ".tgz") || strequ(suff, ".taz")) {
-           strcpy(suff, ".tar");
-       } else {
-           *suff = '\0'; /* strip the z suffix */
-       }
+             /* Avoid annoying messages with -r */
+             if (verbose || (!recursive && !quiet)) {
+                 WARN((stderr,"%s: %s: unknown suffix -- ignored\n",
+                       program_name, ifname));
+             }
+             return WARNING;
+         }
+         /* Make a special case for .tgz and .taz: */
+         strlwr(suff);
+         if (strequ(suff, ".tgz") || strequ(suff, ".taz")) {
+             strcpy(suff, ".tar");
+         } else {
+             *suff = '\0'; /* strip the z suffix */
+         }
          /* ofname might be changed later if infile contains an original name */
  
      } else if (suff && ! force) {
-       /* Avoid annoying messages with -r (see treat_dir()) */
-       if (verbose || (!recursive && !quiet)) {
-           /* Don't use WARN, as it affects exit status.  */
-           fprintf (stderr, "%s: %s already has %s suffix -- unchanged\n",
-                    program_name, ifname, suff);
-       }
-       return WARNING;
+         /* Avoid annoying messages with -r (see treat_dir()) */
+         if (verbose || (!recursive && !quiet)) {
+             /* Don't use WARN, as it affects exit status.  */
+             fprintf (stderr, "%s: %s already has %s suffix -- unchanged\n",
+                      program_name, ifname, suff);
+         }
+         return WARNING;
      } else {
          save_orig_name = 0;
  
  #ifdef NO_MULTIPLE_DOTS
-       suff = strrchr(ofname, '.');
-       if (suff == NULL) {
-           if (sizeof ofname <= strlen (ofname) + 1)
-               goto name_too_long;
+         suff = strrchr(ofname, '.');
+         if (suff == NULL) {
+             if (sizeof ofname <= strlen (ofname) + 1)
+                 goto name_too_long;
              strcat(ofname, ".");
  #  ifdef MAX_EXT_CHARS
-           if (strequ(z_suffix, "z")) {
-               if (sizeof ofname <= strlen (ofname) + 2)
-                   goto name_too_long;
-               strcat(ofname, "gz"); /* enough room */
-               return OK;
-           }
+             if (strequ(z_suffix, "z")) {
+                 if (sizeof ofname <= strlen (ofname) + 2)
+                     goto name_too_long;
+                 strcat(ofname, "gz"); /* enough room */
+                 return OK;
+             }
          /* On the Atari and some versions of MSDOS,
           * ENAMETOOLONG does not work correctly.  So we
           * must truncate here.
  #  endif
          }
  #endif /* NO_MULTIPLE_DOTS */
-       if (sizeof ofname <= strlen (ofname) + z_len)
-           goto name_too_long;
-       strcat(ofname, z_suffix);
+         if (sizeof ofname <= strlen (ofname) + z_len)
+             goto name_too_long;
+         strcat(ofname, z_suffix);
  
      } /* decompress ? */
      return OK;
      return WARNING;
  }
  
+ /* Discard NBYTES input bytes from the input, or up through the next
+    zero byte if NBYTES == (size_t) -1.  If FLAGS say that the header
+    CRC should be computed, update the CRC accordingly.  */
+ static void
+ discard_input_bytes (nbytes, flags)
+     size_t nbytes;
+     unsigned int flags;
+ {
+   while (nbytes != 0)
+     {
+       uch c = get_byte ();
+       if (flags & HEADER_CRC)
+         updcrc (&c, 1);
+       if (nbytes != (size_t) -1)
+         nbytes--;
+       else if (! c)
+         break;
+     }
+ }
  
  /* ========================================================================
   * Check the magic number of the input file and update ofname if an
@@@ -1244,7 -1270,8 +1275,8 @@@ local int get_method(in
      int in;        /* input file descriptor */
  {
      uch flags;     /* compression flags */
-     char magic[2]; /* magic header */
+     uch magic[10]; /* magic header */
+     int imagic0;   /* first magic byte or EOF */
      int imagic1;   /* like magic[1], but can represent EOF */
      ulg stamp;     /* time stamp */
  
       * premature end of file: use try_byte instead of get_byte.
       */
      if (force && to_stdout) {
-       magic[0] = (char)try_byte();
-       imagic1 = try_byte ();
-       magic[1] = (char) imagic1;
-       /* If try_byte returned EOF, magic[1] == (char) EOF.  */
+         imagic0 = try_byte();
+         magic[0] = imagic0;
+         imagic1 = try_byte ();
+         magic[1] = imagic1;
+         /* If try_byte returned EOF, magic[1] == (char) EOF.  */
      } else {
-       magic[0] = (char)get_byte();
-       if (magic[0]) {
-           magic[1] = (char)get_byte();
-           imagic1 = 0; /* avoid lint warning */
-       } else {
-           imagic1 = try_byte ();
-           magic[1] = (char) imagic1;
-       }
+         magic[0] = get_byte ();
+         imagic0 = 0;
+         if (magic[0]) {
+             magic[1] = get_byte ();
+             imagic1 = 0; /* avoid lint warning */
+         } else {
+             imagic1 = try_byte ();
+             magic[1] = imagic1;
+         }
      }
      method = -1;                 /* unknown yet */
      part_nb++;                   /* number of parts in gzip file */
      if (memcmp(magic, GZIP_MAGIC, 2) == 0
          || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) {
  
-       method = (int)get_byte();
-       if (method != DEFLATED) {
-           fprintf(stderr,
-                   "%s: %s: unknown method %d -- not supported\n",
-                   program_name, ifname, method);
-           exit_code = ERROR;
-           return -1;
-       }
-       work = unzip;
-       flags  = (uch)get_byte();
-       if ((flags & ENCRYPTED) != 0) {
-           fprintf(stderr,
-                   "%s: %s is encrypted -- not supported\n",
-                   program_name, ifname);
-           exit_code = ERROR;
-           return -1;
-       }
-       if ((flags & CONTINUATION) != 0) {
-           fprintf(stderr,
-                   "%s: %s is a multi-part gzip file -- not supported\n",
-                   program_name, ifname);
-           exit_code = ERROR;
-           if (force <= 1) return -1;
-       }
-       if ((flags & RESERVED) != 0) {
-           fprintf(stderr,
-                   "%s: %s has flags 0x%x -- not supported\n",
-                   program_name, ifname, flags);
-           exit_code = ERROR;
-           if (force <= 1) return -1;
-       }
-       stamp  = (ulg)get_byte();
-       stamp |= ((ulg)get_byte()) << 8;
-       stamp |= ((ulg)get_byte()) << 16;
-       stamp |= ((ulg)get_byte()) << 24;
-       if (stamp != 0 && !no_time)
-         {
-           time_stamp.tv_sec = stamp;
-           time_stamp.tv_nsec = 0;
-         }
-       (void)get_byte();  /* Ignore extra flags for the moment */
-       (void)get_byte();  /* Ignore OS type for the moment */
-       if ((flags & CONTINUATION) != 0) {
-           unsigned part = (unsigned)get_byte();
-           part |= ((unsigned)get_byte())<<8;
-           if (verbose) {
-               fprintf(stderr,"%s: %s: part number %u\n",
-                       program_name, ifname, part);
-           }
-       }
-       if ((flags & EXTRA_FIELD) != 0) {
-           unsigned len = (unsigned)get_byte();
-           len |= ((unsigned)get_byte())<<8;
-           if (verbose) {
-               fprintf(stderr,"%s: %s: extra field of %u bytes ignored\n",
-                       program_name, ifname, len);
-           }
-           while (len--) (void)get_byte();
-       }
-       /* Get original file name if it was truncated */
-       if ((flags & ORIG_NAME) != 0) {
-           if (no_name || (to_stdout && !list) || part_nb > 1) {
-               /* Discard the old name */
-               char c; /* dummy used for NeXTstep 3.0 cc optimizer bug */
-               do {c=get_byte();} while (c != 0);
-           } else {
-               /* Copy the base name. Keep a directory prefix intact. */
+         method = (int)get_byte();
+         if (method != DEFLATED) {
+             fprintf(stderr,
+                     "%s: %s: unknown method %d -- not supported\n",
+                     program_name, ifname, method);
+             exit_code = ERROR;
+             return -1;
+         }
+         work = unzip;
+         flags  = (uch)get_byte();
+         if ((flags & ENCRYPTED) != 0) {
+             fprintf(stderr,
+                     "%s: %s is encrypted -- not supported\n",
+                     program_name, ifname);
+             exit_code = ERROR;
+             return -1;
+         }
+         if ((flags & RESERVED) != 0) {
+             fprintf(stderr,
+                     "%s: %s has flags 0x%x -- not supported\n",
+                     program_name, ifname, flags);
+             exit_code = ERROR;
+             if (force <= 1) return -1;
+         }
+         stamp  = (ulg)get_byte();
+         stamp |= ((ulg)get_byte()) << 8;
+         stamp |= ((ulg)get_byte()) << 16;
+         stamp |= ((ulg)get_byte()) << 24;
+         if (stamp != 0 && !no_time)
+           {
+             time_stamp.tv_sec = stamp;
+             time_stamp.tv_nsec = 0;
+           }
+         magic[8] = get_byte ();  /* Ignore extra flags.  */
+         magic[9] = get_byte ();  /* Ignore OS type.  */
+         if (flags & HEADER_CRC)
+           {
+             magic[2] = DEFLATED;
+             magic[3] = flags;
+             magic[4] = stamp & 0xff;
+             magic[5] = (stamp >> 8) & 0xff;
+             magic[6] = (stamp >> 16) & 0xff;
+             magic[7] = stamp >> 24;
+             updcrc (NULL, 0);
+             updcrc (magic, 10);
+           }
+         if ((flags & EXTRA_FIELD) != 0) {
+             uch lenbuf[2];
+             unsigned int len = lenbuf[0] = get_byte ();
+             len |= (lenbuf[1] = get_byte ()) << 8;
+             if (verbose) {
+                 fprintf(stderr,"%s: %s: extra field of %u bytes ignored\n",
+                         program_name, ifname, len);
+             }
+             if (flags & HEADER_CRC)
+               updcrc (lenbuf, 2);
+             discard_input_bytes (len, flags);
+         }
+         /* Get original file name if it was truncated */
+         if ((flags & ORIG_NAME) != 0) {
+             if (no_name || (to_stdout && !list) || part_nb > 1) {
+                 /* Discard the old name */
+                 discard_input_bytes (-1, flags);
+             } else {
+                 /* Copy the base name. Keep a directory prefix intact. */
                  char *p = gzip_base_name (ofname);
                  char *base = p;
-               for (;;) {
-                   *p = (char)get_char();
-                   if (*p++ == '\0') break;
-                   if (p >= ofname+sizeof(ofname)) {
-                       gzip_error ("corrupted input -- file name too large");
-                   }
-               }
-               p = gzip_base_name (base);
-               memmove (base, p, strlen (p) + 1);
+                 for (;;) {
+                     *p = (char) get_byte ();
+                     if (*p++ == '\0') break;
+                     if (p >= ofname+sizeof(ofname)) {
+                         gzip_error ("corrupted input -- file name too large");
+                     }
+                 }
+                 if (flags & HEADER_CRC)
+                   updcrc ((uch *) base, p - base);
+                 p = gzip_base_name (base);
+                 memmove (base, p, strlen (p) + 1);
                  /* If necessary, adapt the name to local OS conventions: */
                  if (!list) {
                     MAKE_LEGAL_NAME(base);
-                  if (base) list=0; /* avoid warning about unused variable */
+                    if (base) list=0; /* avoid warning about unused variable */
                  }
-           } /* no_name || to_stdout */
-       } /* ORIG_NAME */
+             } /* no_name || to_stdout */
+         } /* ORIG_NAME */
  
-       /* Discard file comment if any */
-       if ((flags & COMMENT) != 0) {
-           while (get_char() != 0) /* null */ ;
-       }
-       if (part_nb == 1) {
-           header_bytes = inptr + 2*sizeof(long); /* include crc and size */
-       }
+         /* Discard file comment if any */
+         if ((flags & COMMENT) != 0) {
+             discard_input_bytes (-1, flags);
+         }
+         if (flags & HEADER_CRC)
+           {
+             unsigned int crc16 = updcrc (magic, 0) & 0xffff;
+             unsigned int header16 = get_byte ();
+             header16 |= ((unsigned int) get_byte ()) << 8;
+             if (header16 != crc16)
+               {
+                 fprintf (stderr,
+                          "%s: %s: header checksum 0x%04x != computed checksum 0x%04x\n",
+                          program_name, ifname, header16, crc16);
+                 exit_code = ERROR;
+                 if (force <= 1)
+                   return -1;
+               }
+           }
+         if (part_nb == 1) {
+             header_bytes = inptr + 2*4; /* include crc and size */
+         }
  
      } else if (memcmp(magic, PKZIP_MAGIC, 2) == 0 && inptr == 2
-           && memcmp((char*)inbuf, PKZIP_MAGIC, 4) == 0) {
-       /* To simplify the code, we support a zip file when alone only.
+             && memcmp((char*)inbuf, PKZIP_MAGIC, 4) == 0) {
+         /* To simplify the code, we support a zip file when alone only.
           * We are thus guaranteed that the entire local header fits in inbuf.
           */
          inptr = 0;
-       work = unzip;
-       if (check_zipfile(in) != OK) return -1;
-       /* check_zipfile may get ofname from the local header */
-       last_member = 1;
+         work = unzip;
+         if (check_zipfile(in) != OK) return -1;
+         /* check_zipfile may get ofname from the local header */
+         last_member = 1;
  
      } else if (memcmp(magic, PACK_MAGIC, 2) == 0) {
-       work = unpack;
-       method = PACKED;
+         work = unpack;
+         method = PACKED;
  
      } else if (memcmp(magic, LZW_MAGIC, 2) == 0) {
-       work = unlzw;
-       method = COMPRESSED;
-       last_member = 1;
+         work = unlzw;
+         method = COMPRESSED;
+         last_member = 1;
  
      } else if (memcmp(magic, LZH_MAGIC, 2) == 0) {
-       work = unlzh;
-       method = LZHED;
-       last_member = 1;
+         work = unlzh;
+         method = LZHED;
+         last_member = 1;
  
      } else if (force && to_stdout && !list) { /* pass input unchanged */
-       method = STORED;
-       work = copy;
-         inptr = 0;
-       last_member = 1;
+         method = STORED;
+         work = copy;
+         if (imagic1 != EOF)
+             inptr--;
+         last_member = 1;
+         if (imagic0 != EOF) {
+             write_buf(fileno(stdout), magic, 1);
+             bytes_out++;
+         }
      }
      if (method >= 0) return method;
  
      if (part_nb == 1) {
-       fprintf (stderr, "\n%s: %s: not in gzip format\n",
-                program_name, ifname);
-       exit_code = ERROR;
-       return -1;
+         fprintf (stderr, "\n%s: %s: not in gzip format\n",
+                  program_name, ifname);
+         exit_code = ERROR;
+         return -1;
      } else {
-       if (magic[0] == 0)
-         {
-           int inbyte;
-           for (inbyte = imagic1;  inbyte == 0;  inbyte = try_byte ())
-             continue;
-           if (inbyte == EOF)
-             {
-               if (verbose)
-                 WARN ((stderr, "\n%s: %s: decompression OK, trailing zero bytes ignored\n",
-                        program_name, ifname));
-               return -3;
-             }
-         }
-       WARN((stderr, "\n%s: %s: decompression OK, trailing garbage ignored\n",
-             program_name, ifname));
-       return -2;
+         if (magic[0] == 0)
+           {
+             int inbyte;
+             for (inbyte = imagic1;  inbyte == 0;  inbyte = try_byte ())
+               continue;
+             if (inbyte == EOF)
+               {
+                 if (verbose)
+                   WARN ((stderr, "\n%s: %s: decompression OK, trailing zero bytes ignored\n",
+                          program_name, ifname));
+                 return -3;
+               }
+           }
+         WARN((stderr, "\n%s: %s: decompression OK, trailing garbage ignored\n",
+               program_name, ifname));
+         return -2;
      }
  }
  
@@@ -1454,43 -1506,42 +1511,42 @@@ local void do_list(ifd, method
      off_t o;
  
      for (o = OFF_T_MAX;  9 < o;  o /= 10) {
-       positive_off_t_width++;
+         positive_off_t_width++;
      }
  
      if (first_time && method >= 0) {
-       first_time = 0;
-       if (verbose)  {
-           printf("method  crc     date  time  ");
-       }
-       if (!quiet) {
-           printf("%*.*s %*.*s  ratio uncompressed_name\n",
-                  positive_off_t_width, positive_off_t_width, "compressed",
-                  positive_off_t_width, positive_off_t_width, "uncompressed");
-       }
+         first_time = 0;
+         if (verbose)  {
+             printf("method  crc     date  time  ");
+         }
+         if (!quiet) {
+             printf("%*.*s %*.*s  ratio uncompressed_name\n",
+                    positive_off_t_width, positive_off_t_width, "compressed",
+                    positive_off_t_width, positive_off_t_width, "uncompressed");
+         }
      } else if (method < 0) {
-       if (total_in <= 0 || total_out <= 0) return;
-       if (verbose) {
-           printf("                            ");
-       }
-       if (verbose || !quiet) {
-           fprint_off(stdout, total_in, positive_off_t_width);
-           printf(" ");
-           fprint_off(stdout, total_out, positive_off_t_width);
-           printf(" ");
-       }
-       display_ratio(total_out-(total_in-header_bytes), total_out, stdout);
-       /* header_bytes is not meaningful but used to ensure the same
-        * ratio if there is a single file.
-        */
-       printf(" (totals)\n");
-       return;
+         if (total_in <= 0 || total_out <= 0) return;
+         if (verbose) {
+             printf("                            ");
+         }
+         if (verbose || !quiet) {
+             fprint_off(stdout, total_in, positive_off_t_width);
+             printf(" ");
+             fprint_off(stdout, total_out, positive_off_t_width);
+             printf(" ");
+         }
+         display_ratio(total_out-(total_in-header_bytes), total_out, stdout);
+         /* header_bytes is not meaningful but used to ensure the same
+          * ratio if there is a single file.
+          */
+         printf(" (totals)\n");
+         return;
      }
      crc = (ulg)~0; /* unknown */
      bytes_out = -1L;
      bytes_in = ifile_size;
  
- #if RECORD_IO == 0
-     if (method == DEFLATED && !last_member) {
+     if (!RECORD_IO && method == DEFLATED && !last_member) {
          /* Get the crc and uncompressed size for gzip'ed (not zip'ed) files.
           * If the lseek fails, we could use read() to get to the end, but
           * --list is used to get quick results.
                  read_error();
              }
              crc       = LG(buf);
-           bytes_out = LG(buf+4);
-       }
+             bytes_out = LG(buf+4);
+         }
      }
- #endif /* RECORD_IO */
      if (verbose)
        {
-       struct tm *tm = localtime (&time_stamp.tv_sec);
-       printf ("%5s %08lx ", methods[method], crc);
-       if (tm)
-         printf ("%s%3d %02d:%02d ",
-                 ("Jan\0Feb\0Mar\0Apr\0May\0Jun\0Jul\0Aug\0Sep\0Oct\0Nov\0Dec"
-                  + 4 * tm->tm_mon),
-                 tm->tm_mday, tm->tm_hour, tm->tm_min);
-       else
-         printf ("??? ?? ??:?? ");
+         struct tm *tm = localtime (&time_stamp.tv_sec);
+         printf ("%5s %08lx ", methods[method], crc);
+         if (tm)
+           printf ("%s%3d %02d:%02d ",
+                   ("Jan\0Feb\0Mar\0Apr\0May\0Jun\0Jul\0Aug\0Sep\0Oct\0Nov\0Dec"
+                    + 4 * tm->tm_mon),
+                   tm->tm_mday, tm->tm_hour, tm->tm_min);
+         else
+           printf ("??? ?? ??:?? ");
        }
      fprint_off(stdout, bytes_in, positive_off_t_width);
      printf(" ");
      fprint_off(stdout, bytes_out, positive_off_t_width);
      printf(" ");
      if (bytes_in  == -1L) {
-       total_in = -1L;
-       bytes_in = bytes_out = header_bytes = 0;
+         total_in = -1L;
+         bytes_in = bytes_out = header_bytes = 0;
      } else if (total_in >= 0) {
-       total_in  += bytes_in;
+         total_in  += bytes_in;
      }
      if (bytes_out == -1L) {
-       total_out = -1L;
-       bytes_in = bytes_out = header_bytes = 0;
+         total_out = -1L;
+         bytes_in = bytes_out = header_bytes = 0;
      } else if (total_out >= 0) {
-       total_out += bytes_out;
+         total_out += bytes_out;
      }
      display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out, stdout);
      printf(" %s\n", ofname);
@@@ -1561,10 -1612,10 +1617,10 @@@ local void shorten_name(name
  
      len = strlen(name);
      if (decompress) {
-       if (len <= 1)
-         gzip_error ("name too short");
-       name[len-1] = '\0';
-       return;
+         if (len <= 1)
+           gzip_error ("name too short");
+         name[len-1] = '\0';
+         return;
      }
      p = get_suffix(name);
      if (! p)
  
      /* compress 1234567890.tar to 1234567890.tgz */
      if (len > 4 && strequ(p-4, ".tar")) {
-       strcpy(p-4, ".tgz");
-       return;
+         strcpy(p-4, ".tgz");
+         return;
      }
      /* Try keeping short extensions intact:
       * 1234.678.012.gz -> 123.678.012.gz
       */
      do {
-       p = strrchr(name, PATH_SEP);
-       p = p ? p+1 : name;
-       while (*p) {
-           plen = strcspn(p, PART_SEP);
-           p += plen;
-           if (plen > min_part) trunc = p-1;
-           if (*p) p++;
-       }
+         p = strrchr(name, PATH_SEP);
+         p = p ? p+1 : name;
+         while (*p) {
+             plen = strcspn(p, PART_SEP);
+             p += plen;
+             if (plen > min_part) trunc = p-1;
+             if (*p) p++;
+         }
      } while (trunc == NULL && --min_part != 0);
  
      if (trunc != NULL) {
-       do {
-           trunc[0] = trunc[1];
-       } while (*trunc++);
-       trunc--;
+         do {
+             trunc[0] = trunc[1];
+         } while (*trunc++);
+         trunc--;
      } else {
-       trunc = strrchr(name, PART_SEP[0]);
-       if (!trunc)
-         gzip_error ("internal error in shorten_name");
-       if (trunc[1] == '\0') trunc--; /* force truncation */
+         trunc = strrchr(name, PART_SEP[0]);
+         if (!trunc)
+           gzip_error ("internal error in shorten_name");
+         if (trunc[1] == '\0') trunc--; /* force truncation */
      }
      strcpy(trunc, z_suffix);
  }
@@@ -1613,22 -1664,22 +1669,22 @@@ local int check_ofname(
  {
      /* Ask permission to overwrite the existing file */
      if (!force) {
-       int ok = 0;
-       fprintf (stderr, "%s: %s already exists;", program_name, ofname);
-       if (foreground && isatty(fileno(stdin))) {
-           fprintf(stderr, " do you wish to overwrite (y or n)? ");
-           fflush(stderr);
-           ok = yesno();
-       }
-       if (!ok) {
-           fprintf(stderr, "\tnot overwritten\n");
-           if (exit_code == OK) exit_code = WARNING;
-           return ERROR;
-       }
+         int ok = 0;
+         fprintf (stderr, "%s: %s already exists;", program_name, ofname);
+         if (foreground && (presume_input_tty || isatty(fileno(stdin)))) {
+             fprintf(stderr, " do you wish to overwrite (y or n)? ");
+             fflush(stderr);
+             ok = yesno();
+         }
+         if (!ok) {
+             fprintf(stderr, "\tnot overwritten\n");
+             if (exit_code == OK) exit_code = WARNING;
+             return ERROR;
+         }
      }
      if (xunlink (ofname)) {
-       progerror(ofname);
-       return ERROR;
+         progerror(ofname);
+         return ERROR;
      }
      return OK;
  }
@@@ -1650,24 -1701,24 +1706,24 @@@ local void copy_stat(ifstat
      timespec[1] = get_stat_mtime (ifstat);
  
      if (decompress && 0 <= time_stamp.tv_nsec
-       && ! (timespec[1].tv_sec == time_stamp.tv_sec
-             && timespec[1].tv_nsec == time_stamp.tv_nsec))
+         && ! (timespec[1].tv_sec == time_stamp.tv_sec
+               && timespec[1].tv_nsec == time_stamp.tv_nsec))
        {
-       timespec[1] = time_stamp;
-       if (verbose > 1) {
-           fprintf(stderr, "%s: time stamp restored\n", ofname);
-       }
+         timespec[1] = time_stamp;
+         if (verbose > 1) {
+             fprintf(stderr, "%s: time stamp restored\n", ofname);
+         }
        }
  
-     if (gl_futimens (ofd, ofname, timespec) != 0)
+     if (fdutimens (ofd, ofname, timespec) != 0)
        {
-       int e = errno;
-       WARN ((stderr, "%s: ", program_name));
-       if (!quiet)
-         {
-           errno = e;
-           perror (ofname);
-         }
+         int e = errno;
+         WARN ((stderr, "%s: ", program_name));
+         if (!quiet)
+           {
+             errno = e;
+             perror (ofname);
+           }
        }
  #endif
  
      r = chmod (ofname, mode);
  #endif
      if (r != 0) {
-       int e = errno;
-       WARN ((stderr, "%s: ", program_name));
-       if (!quiet) {
-           errno = e;
-           perror(ofname);
-       }
+         int e = errno;
+         WARN ((stderr, "%s: ", program_name));
+         if (!quiet) {
+             errno = e;
+             perror(ofname);
+         }
      }
  }
  
  #if ! NO_DIR
  
  /* ========================================================================
-  * Recurse through the given directory. This code is taken from ncompress.
+  * Recurse through the given directory.
   */
  local void treat_dir (fd, dir)
      int fd;
      char *dir;
  {
-     struct dirent *dp;
      DIR      *dirp;
      char     nbuf[MAX_PATH_LEN];
-     int      len;
+     char *entries;
+     char const *entry;
+     size_t entrylen;
  
      dirp = fdopendir (fd);
  
      if (dirp == NULL) {
-       progerror(dir);
-       close (fd);
-       return ;
+         progerror(dir);
+         close (fd);
+         return ;
      }
-     /*
-      ** WARNING: the following algorithm could occasionally cause
-      ** compress to produce error warnings of the form "<filename>.gz
-      ** already has .gz suffix - ignored". This occurs when the
-      ** .gz output file is inserted into the directory below
-      ** readdir's current pointer.
-      ** These warnings are harmless but annoying, so they are suppressed
-      ** with option -r (except when -v is on). An alternative
-      ** to allowing this would be to store the entire directory
-      ** list in memory, then compress the entries in the stored
-      ** list. Given the depth-first recursive algorithm used here,
-      ** this could use up a tremendous amount of memory. I don't
-      ** think it's worth it. -- Dave Mack
-      ** (An other alternative might be two passes to avoid depth-first.)
-      */
  
-     while ((errno = 0, dp = readdir(dirp)) != NULL) {
+     entries = streamsavedir (dirp);
+     if (! entries)
+       progerror (dir);
+     if (closedir (dirp) != 0)
+       progerror (dir);
+     if (! entries)
+       return;
  
-       if (strequ(dp->d_name,".") || strequ(dp->d_name,"..")) {
-           continue;
-       }
-       len = strlen(dir);
-       if (len + _D_EXACT_NAMLEN (dp) + 1 < MAX_PATH_LEN - 1) {
-           strcpy(nbuf,dir);
-           if (len != 0 /* dir = "" means current dir on Amiga */
+     for (entry = entries; *entry; entry += entrylen + 1) {
+         size_t len = strlen (dir);
+         entrylen = strlen (entry);
+         if (strequ (entry, ".") || strequ (entry, ".."))
+           continue;
+         if (len + entrylen < MAX_PATH_LEN - 2) {
+             strcpy(nbuf,dir);
+             if (len != 0 /* dir = "" means current dir on Amiga */
  #ifdef PATH_SEP2
-               && dir[len-1] != PATH_SEP2
+                 && dir[len-1] != PATH_SEP2
  #endif
  #ifdef PATH_SEP3
-               && dir[len-1] != PATH_SEP3
+                 && dir[len-1] != PATH_SEP3
  #endif
-           ) {
-               nbuf[len++] = PATH_SEP;
-           }
-           strcpy(nbuf+len, dp->d_name);
-           treat_file(nbuf);
-       } else {
-           fprintf(stderr,"%s: %s/%s: pathname too long\n",
-                   program_name, dir, dp->d_name);
-           exit_code = ERROR;
-       }
+             ) {
+                 nbuf[len++] = PATH_SEP;
+             }
+             strcpy (nbuf + len, entry);
+             treat_file(nbuf);
+         } else {
+             fprintf(stderr,"%s: %s/%s: pathname too long\n",
+                     program_name, dir, entry);
+             exit_code = ERROR;
+         }
      }
-     if (errno != 0)
-       progerror(dir);
-     if (CLOSEDIR(dirp) != 0)
-       progerror(dir);
+     free (entries);
  }
  #endif /* ! NO_DIR */
  
@@@ -1782,7 -1823,7 +1828,7 @@@ install_signal_handlers (
      {
        sigaction (handled_sig[i], NULL, &act);
        if (act.sa_handler != SIG_IGN)
-       sigaddset (&caught_signals, handled_sig[i]);
+         sigaddset (&caught_signals, handled_sig[i]);
      }
  
    act.sa_handler = abort_gzip_signal;
    for (i = 0; i < nsigs; i++)
      if (sigismember (&caught_signals, handled_sig[i]))
        {
-       if (i == 0)
-         foreground = 1;
-       sigaction (handled_sig[i], &act, NULL);
+         if (i == 0)
+           foreground = 1;
+         sigaction (handled_sig[i], &act, NULL);
        }
  #else
    for (i = 0; i < nsigs; i++)
      if (signal (handled_sig[i], SIG_IGN) != SIG_IGN)
        {
-       if (i == 0)
-         foreground = 1;
-       signal (handled_sig[i], abort_gzip_signal);
-       siginterrupt (handled_sig[i], 1);
+         if (i == 0)
+           foreground = 1;
+         signal (handled_sig[i], abort_gzip_signal);
+         siginterrupt (handled_sig[i], 1);
        }
  #endif
  }
diff --combined gzip.h
index 5270c56a4d90c7d223abfefc0a22054b89028773,e6fac710c1216c113a167ada1fc2695bb6354b11..711ff662a674ee1d292e0566265de7576d3dde5d
--- 1/gzip.h
--- 2/gzip.h
+++ b/gzip.h
@@@ -1,6 -1,6 +1,6 @@@
  /* gzip.h -- common declarations for all gzip modules
  
-    Copyright (C) 1997-1999, 2001, 2006-2007, 2009-2010 Free Software
+    Copyright (C) 1997-1999, 2001, 2006-2007, 2009-2012 Free Software
     Foundation, Inc.
  
     Copyright (C) 1992-1993 Jean-loup Gailly.
     along with this program; if not, write to the Free Software Foundation,
     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
  
- #if defined(__STDC__) || defined(PROTO)
- #  define OF(args)  args
- #else
- #  define OF(args)  ()
- #endif
  #ifdef __STDC__
     typedef void *voidp;
  #else
@@@ -146,7 -140,6 +140,7 @@@ EXTERN(uch, window);         /* Slidin
  extern unsigned insize; /* valid bytes in inbuf */
  extern unsigned inptr;  /* index of next byte to be processed in inbuf */
  extern unsigned outcnt; /* bytes in output buffer */
 +extern int rsync;  /* deflate into rsyncable chunks */
  
  extern off_t bytes_in;   /* number of input bytes */
  extern off_t bytes_out;  /* number of output bytes */
@@@ -173,7 -166,7 +167,7 @@@ typedef int file_t;     /* Do not use s
  
  /* gzip flag byte */
  #define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
- #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+ #define HEADER_CRC   0x02 /* bit 1 set: CRC16 for the gzip header */
  #define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
  #define ORIG_NAME    0x08 /* bit 3 set: original file name present */
  #define COMMENT      0x10 /* bit 4 set: file comment present */
   * distances are limited to MAX_DIST instead of WSIZE.
   */
  
- extern int decrypt;        /* flag to turn on decryption */
  extern int exit_code;      /* program exit code */
  extern int verbose;        /* be verbose (-v) */
  extern int quiet;          /* be quiet (-q) */
@@@ -269,66 -261,66 +262,66 @@@ extern int save_orig_name; /* set if or
  #endif
  
  #define WARN(msg) {if (!quiet) fprintf msg ; \
-                  if (exit_code == OK) exit_code = WARNING;}
+                    if (exit_code == OK) exit_code = WARNING;}
  
-       /* in zip.c: */
- extern int zip        OF((int in, int out));
- extern int file_read  OF((char *buf,  unsigned size));
+         /* in zip.c: */
+ extern int zip        (int in, int out);
+ extern int file_read  (char *buf,  unsigned size);
  
-       /* in unzip.c */
- extern int unzip      OF((int in, int out));
- extern int check_zipfile OF((int in));
+         /* in unzip.c */
+ extern int unzip      (int in, int out);
+ extern int check_zipfile (int in);
  
-       /* in unpack.c */
- extern int unpack     OF((int in, int out));
+         /* in unpack.c */
+ extern int unpack     (int in, int out);
  
-       /* in unlzh.c */
- extern int unlzh      OF((int in, int out));
+         /* in unlzh.c */
+ extern int unlzh      (int in, int out);
  
-       /* in gzip.c */
void abort_gzip OF((void)) ATTRIBUTE_NORETURN;
+         /* in gzip.c */
extern void abort_gzip (void) ATTRIBUTE_NORETURN;
  
          /* in deflate.c */
void lm_init OF((int pack_level, ush *flags));
off_t deflate OF((void));
extern void lm_init (int pack_level, ush *flags);
extern off_t deflate (void);
  
          /* in trees.c */
void ct_init     OF((ush *attr, int *method));
int  ct_tally    OF((int dist, int lc));
off_t flush_block OF((char *buf, ulg stored_len, int eof));
extern void ct_init     (ush *attr, int *method);
extern int  ct_tally    (int dist, int lc);
extern off_t flush_block (char *buf, ulg stored_len, int eof);
  
          /* in bits.c */
void     bi_init    OF((file_t zipfile));
void     send_bits  OF((int value, int length));
unsigned bi_reverse OF((unsigned value, int length));
void     bi_windup  OF((void));
void     copy_block OF((char *buf, unsigned len, int header));
- extern   int (*read_buf) OF((char *buf, unsigned size));
-       /* in util.c: */
- extern int copy           OF((int in, int out));
- extern ulg  updcrc        OF((uch *s, unsigned n));
- extern void clear_bufs    OF((void));
- extern int  fill_inbuf    OF((int eof_ok));
- extern void flush_outbuf  OF((void));
- extern void flush_window  OF((void));
- extern void write_buf     OF((int fd, voidp buf, unsigned cnt));
- extern int read_buffer    OF((int fd, voidp buf, unsigned int cnt));
- extern char *strlwr       OF((char *s));
- extern char *gzip_base_name OF((char *fname));
- extern int xunlink        OF((char *fname));
- extern void make_simple_name OF((char *name));
- extern char *add_envopt   OF((int *argcp, char ***argvp, char const *env));
- extern void gzip_error    OF((char const *m)) ATTRIBUTE_NORETURN;
- extern void xalloc_die    OF((void)) ATTRIBUTE_NORETURN;
- extern void warning       OF((char const *m));
- extern void read_error    OF((void)) ATTRIBUTE_NORETURN;
- extern void write_error   OF((void)) ATTRIBUTE_NORETURN;
- extern void display_ratio OF((off_t num, off_t den, FILE *file));
- extern void fprint_off    OF((FILE *, off_t, int));
-       /* in inflate.c */
- extern int inflate OF((void));
-       /* in yesno.c */
- extern int yesno OF((void));
extern void     bi_init    (file_t zipfile);
extern void     send_bits  (int value, int length);
extern unsigned bi_reverse (unsigned value, int length) _GL_ATTRIBUTE_CONST;
extern void     bi_windup  (void);
extern void     copy_block (char *buf, unsigned len, int header);
+ extern int     (*read_buf) (char *buf, unsigned size);
+         /* in util.c: */
+ extern int copy           (int in, int out);
+ extern ulg  updcrc        (uch *s, unsigned n);
+ extern void clear_bufs    (void);
+ extern int  fill_inbuf    (int eof_ok);
+ extern void flush_outbuf  (void);
+ extern void flush_window  (void);
+ extern void write_buf     (int fd, voidp buf, unsigned cnt);
+ extern int read_buffer    (int fd, voidp buf, unsigned int cnt);
+ extern char *strlwr       (char *s);
+ extern char *gzip_base_name (char *fname) _GL_ATTRIBUTE_PURE;
+ extern int xunlink        (char *fname);
+ extern void make_simple_name (char *name);
+ extern char *add_envopt   (int *argcp, char ***argvp, char const *env);
+ extern void gzip_error    (char const *m) ATTRIBUTE_NORETURN;
+ extern void xalloc_die    (void) ATTRIBUTE_NORETURN;
+ extern void warning       (char const *m);
+ extern void read_error    (void) ATTRIBUTE_NORETURN;
+ extern void write_error   (void) ATTRIBUTE_NORETURN;
+ extern void display_ratio (off_t num, off_t den, FILE *file);
+ extern void fprint_off    (FILE *, off_t, int);
+         /* in inflate.c */
+ extern int inflate (void);
+         /* in yesno.c */
+ extern int yesno (void);