2010-01-31  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* doc/gzip.texi: Replace @samp with @file where appropriate.

	* lib/errno.in.h [__DJGPP__]: EWOULDBLOCK defined to EAGAIN if not defined.
	EOPNOTSUPP defined to the same value than for native windows systems if
	not defined.

	* lib/freadahead.c [__DJGPP__]: Include libc/file.h for the definition
	of _IOERR so that SystemV derived implementations, defined in stdio-impl.h,
	are selected for DJGPP.

	* lib/freading.c [__DJGPP__]: Include libc/file.h for the definition
	of _IOERR so that SystemV derived implementations, defined in stdio-impl.h,
	are selected for DJGPP.

	* lib/fseeko.c [__DJGPP__]: Include libc/file.h for the definition
	of _IOERR so that SystemV derived implementations, defined in stdio-impl.h,
	are selected for DJGPP.

	* lib/fseterr.c [__DJGPP__]: Include libc/file.h for the definition
	of _IOERR so that SystemV derived implementations, defined in stdio-impl.h,
	are selected for DJGPP.

	* lib/mbrtowc.c [__DJGPP__]: Define EILSEQ if not defined.

	* lib/vasnprintf.c [__DJGPP__]: Define EILSEQ if not defined.

	* msdos/tailor.c [__DJGPP__]: New function make_valid_dosw32_name,
	to be called via MAKE_LEGAL_NAME macro.  Replaces all characers not
	allowed by DOS/Windows filesystems, and renames files whose names
	are reserved by character device drivers.

	* tailor.h: [MSDOS, __GNUC__]: Define macros for DJGPP v2.x, so that
	long file names could be supported on Windows 9X, 2000, XP, etc.
	If not defined, define HAVE_DIRENT_H, HAVE_LIMITS_H and HAVE_UNISTD_H.
	Define SET_BINARY_MODE in such a way that if the file descriptor is
	connected to a tty it is never switched to binary (raw) mode.
	(LONG_FILE_NAMES, HAVE_LONG_FILE_NAMES): New macros.
	(MAX_SUFFIX): Define only if not defined above.

	* util.c (gzip_base_name): Eliminate calls of strrchr.  Don't
	downcase the base name; it is now done by those callers which need it.

	* gzip.c [NO_MULTIPLE_DOTS]: Define PART_SEP only if not already
	defined.
	(get_suffix) [MAX_EXT_CHARS]: Remove the DOSish suffixes without a
	leading dot from known_suffixes[] and put them into a separate
	array known_dosish_suffixes[].  Don't check these suffixes when
	compressing if long file names aren't supported, or if the
	base name of the file doesn't have a dot.
	(get_suffix) [SUFFIX_SEP]: Use gzip_base_name to get the file name
	before looking for a suffix.
	(get_suffix) [MAX_EXT_CHARS, HAVE_LONG_NAMES]: If long file names are
	supported, only check DOSish truncated suffixes when decompressing.
	This allows to compress, e.g., foo.baz into foo.baz.gz instead of
	punting.
	(get_suffix) [MAX_EXT_CHARS]: If the file name doesn't have a dot
	in its base name, do not check the DOSish suffixes.  This allows to
	compress foobaz into foobaz.gz and decompress it back.
	(get_suffix) [MAX_EXT_CHARS]: Replace HAVE_LONG_NAMES with the correct
	macro name HAVE_LONG_FILE_NAMES.
	(open_input_file) [MAX_EXT_CHARS]: Use gzip_base_name to get the file
	name from ifname.
	(open_input_file) [NO_MULTIPLE_DOTS]: Append a dot only if z_suffix
	does not already begin with a dot.
	Do not use hardcoded string ".gz" to check for the extension, use
	suffixes[] instead.
	(make_ofname) [NO_MULTIPLE_DOTS, MAX_EXT_CHARS]: Replace
	HAVE_LONG_NAMES with the correct macro name HAVE_LONG_FILE_NAMES.
	(make_ofname) [NO_MULTIPLE_DOTS, MAX_EXT_CHARS]: HAVE_LONG_NAMES; add
	support for systems where the long file name support is only know at
	run time, and depends on the filesystem where the target file OFNAME
	will be written.  DJGPP running on Win32 is an example of such a
	system.
	(shorten_name): Make sure we only shorten the base name of the file
	by working on what gzip_base_name returns.







diff -aprNU5 gzip-1.4.orig/doc/gzip.texi gzip-1.4/doc/gzip.texi
--- gzip-1.4.orig/doc/gzip.texi	2010-01-03 17:26:02 +0000
+++ gzip-1.4/doc/gzip.texi	2010-01-31 15:37:00 +0000
@@ -79,11 +79,11 @@ Free Documentation License''.
 @chapter Overview
 @cindex overview
 
 @command{gzip} reduces the size of the named files using Lempel-Ziv coding
 (LZ77).  Whenever possible, each file is replaced by one with the
-extension @samp{.gz}, while keeping the same ownership modes, access and
+extension @file{.gz}, while keeping the same ownership modes, access and
 modification times.  (The default extension is @samp{-gz} for @abbr{VMS},
 @samp{z} for @abbr{MSDOS}, @abbr{OS/2} @abbr{FAT} and Atari.)
 If no files are specified or
 if a file name is "-", the standard input is compressed to the standard
 output.  @command{gzip} will only attempt to compress regular files.  In
@@ -91,13 +91,13 @@ particular, it will ignore symbolic link
 
 If the new file name is too long for its file system, @command{gzip}
 truncates it.  @command{gzip} attempts to truncate only the parts of the
 file name longer than 3 characters.  (A part is delimited by dots.) If
 the name consists of small parts only, the longest parts are truncated.
-For example, if file names are limited to 14 characters, gzip.msdos.exe
-is compressed to gzi.msd.exe.gz.  Names are not truncated on systems
-which do not have a limit on file name length.
+For example, if file names are limited to 14 characters,
+@file{gzip.msdos.exe} is compressed to @file{gzi.msd.exe.gz}.  Names are
+not truncated on systems which do not have a limit on file name length.
 
 By default, @command{gzip} keeps the original file name and time stamp in
 the compressed file.  These are used when decompressing the file with the
 @option{-N} option.  This is useful when the compressed file name was
 truncated or when the time stamp was not preserved after a file
@@ -113,12 +113,12 @@ Compressed files can be restored to thei
 or @command{gunzip} or @command{zcat}.  If the original name saved in the
 compressed file is not suitable for its file system, a new name is
 constructed from the original one to make it legal.
 
 @command{gunzip} takes a list of files on its command line and replaces
-each file whose name ends with @samp{.gz}, @samp{.z}
-@samp{-gz}, @samp{-z}, or @samp{_z} (ignoring case)
+each file whose name ends with @file{.gz}, @file{.z}
+@file{-gz}, @file{-z}, or @file{_z} (ignoring case)
 and which begins with the correct
 magic number with an uncompressed file without the original extension.
 @command{gunzip} also recognizes the special extensions @samp{.tgz} and
 @samp{.taz} as shorthands for @samp{.tar.gz} and @samp{.tar.Z}
 respectively.  When compressing, @command{gzip} uses the @samp{.tgz}
@@ -129,12 +129,12 @@ extension.
 @command{zip}, @command{compress} or @command{pack}.  The detection of the input
 format is automatic.  When using the first two formats, @command{gunzip}
 checks a 32 bit @abbr{CRC} (cyclic redundancy check).  For @command{pack},
 @command{gunzip} checks the uncompressed length.  The @command{compress} format
 was not designed to allow consistency checks.  However @command{gunzip} is
-sometimes able to detect a bad @samp{.Z} file.  If you get an error when
-uncompressing a @samp{.Z} file, do not assume that the @samp{.Z} file is
+sometimes able to detect a bad @file{.Z} file.  If you get an error when
+uncompressing a @file{.Z} file, do not assume that the @file{.Z} file is
 correct simply because the standard @command{uncompress} does not complain.
 This generally means that the standard @command{uncompress} does not check
 its input, and happily generates garbage output.  The @abbr{SCO} @samp{compress
 -H} format (@abbr{LZH} compression method) does not include a @abbr{CRC} but
 also allows some consistency checks.
@@ -149,11 +149,11 @@ members, use @command{unzip} instead of 
 
 @command{zcat} is identical to @samp{gunzip -c}.  @command{zcat}
 uncompresses either a list of files on the command line or its standard
 input and writes the uncompressed data on standard output.  @command{zcat}
 will uncompress files that have the correct magic number whether they
-have a @samp{.gz} suffix or not.
+have a @file{.gz} suffix or not.
 
 @command{gzip} uses the Lempel-Ziv algorithm used in @command{zip} and
 @abbr{PKZIP}@.
 The amount of compression obtained depends on the size of the input and
 the distribution of common substrings.  Typically, text such as source
@@ -286,11 +286,11 @@ uncompressed size: size of the uncompres
 ratio: compression ratio (0.0% if unknown)
 uncompressed_name: name of the uncompressed file
 @end example
 
 The uncompressed size is given as @minus{}1 for files not in @command{gzip}
-format, such as compressed @samp{.Z} files.  To get the uncompressed size for
+format, such as compressed @file{.Z} files.  To get the uncompressed size for
 such a file, you can use:
 
 @example
 zcat file.Z | wc -c
 @end example
@@ -353,21 +353,21 @@ specified on the command line are direct
 into the directory and compress all the files it finds there (or
 decompress them in the case of @command{gunzip}).
 
 @item --suffix @var{suf}
 @itemx -S @var{suf}
-Use suffix @var{suf} instead of @samp{.gz}.  Any suffix can be
-given, but suffixes other than @samp{.z} and @samp{.gz} should be
+Use suffix @var{suf} instead of @file{.gz}.  Any suffix can be
+given, but suffixes other than @file{.z} and @file{.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:
 
 @example
 gunzip -S "" *        (*.* for MSDOS)
 @end example
 
-Previous versions of gzip used the @samp{.z} suffix.  This was changed to
+Previous versions of gzip used the @file{.z} suffix.  This was changed to
 avoid a conflict with @command{pack}.
 
 @item --test
 @itemx -t
 Test.  Check the compressed file integrity.
@@ -420,11 +420,11 @@ is equivalent to
 
 @example
 cat file1 file2
 @end example
 
-In case of damage to one member of a @samp{.gz} file, other members can
+In case of damage to one member of a @file{.gz} file, other members can
 still be recovered (if the damaged member is removed).  However,
 you can get better compression by compressing all members at once:
 
 @example
 cat file1 file2 | gzip > foo.gz
diff -aprNU5 gzip-1.4.orig/gzip.c gzip-1.4/gzip.c
--- gzip-1.4.orig/gzip.c	2010-01-03 17:26:02 +0000
+++ gzip-1.4/gzip.c	2010-01-31 15:37:00 +0000
@@ -147,11 +147,13 @@ static char const *const license_msg[] =
 
 /* Separator for file name parts (see shorten_name()) */
 #ifdef NO_MULTIPLE_DOTS
 #  define PART_SEP "-"
 #else
-#  define PART_SEP "."
+#  ifndef PART_SEP
+#    define PART_SEP "."
+#  endif
 #endif
 
 		/* global buffers */
 
 DECLARE(uch, inbuf,  INBUFSIZ +INBUF_EXTRA);
@@ -397,10 +399,11 @@ int main (int argc, char **argv)
     int optc;           /* current option */
 
     EXPAND(argc, argv); /* wild card expansion if necessary */
 
     program_name = gzip_base_name (argv[0]);
+    if (casemap('A') == 'a') strlwr(program_name);
     proglen = strlen (program_name);
 
     atexit (close_stdin);
 
     /* Suppress .exe for MSDOS, OS/2 and VMS: */
@@ -958,24 +961,23 @@ local char *get_suffix(name)
     char *name;
 {
     int nlen, slen;
     char suffix[MAX_SUFFIX+3]; /* last chars of name, forced to lower case */
     static char const *known_suffixes[] =
-       {NULL, ".gz", ".z", ".taz", ".tgz", "-gz", "-z", "_z",
+       {NULL, ".gz", ".z", ".taz", ".tgz", "-gz", "-z", "_z", NULL};
 #ifdef MAX_EXT_CHARS
-          "z",
+    static char const *known_dosish_suffixes[] = {"gz", "z", NULL};
 #endif
-          NULL};
     char const **suf = known_suffixes;
 
     *suf = z_suffix;
     if (strequ(z_suffix, "z")) suf++; /* check long suffixes first */
 
 #ifdef SUFFIX_SEP
     /* strip a version number from the file name */
     {
-	char *v = strrchr(name, SUFFIX_SEP);
+ 	char *v = strrchr(gzip_base_name(name), SUFFIX_SEP);
  	if (v != NULL) *v = '\0';
     }
 #endif
     nlen = strlen(name);
     if (nlen <= MAX_SUFFIX+2) {
@@ -990,10 +992,38 @@ local char *get_suffix(name)
        if (slen > s && suffix[slen-s-1] != PATH_SEP
            && strequ(suffix + slen - s, *suf)) {
            return name+nlen-s;
        }
     } while (*++suf != NULL);
+#ifdef MAX_EXT_CHARS
+# ifdef HAVE_LONG_FILE_NAMES
+    /* If long file names are supported, only check DOSish
+       truncated suffixes when decompressing.  This allows to
+       compress, e.g., foo.baz into foo.baz.gz instead of punting.  */
+    {
+       int e = errno;	/* HAVE_LONG_FILE_NAMES might set errno */
+       if (HAVE_LONG_FILE_NAMES(name) && !decompress) {
+           errno = e;
+           return NULL;
+       }
+       errno = e;
+    }
+# endif /* HAVE_LONG_FILE_NAMES */
+    /* If the file name doesn't have a dot in its basename, don't
+       check the DOSish suffixes.  This allows to compress foobaz
+       into foobaz.gz and decompress it back.  */
+    if (strchr(gzip_base_name(name), '.') == NULL)
+        return NULL;
+    suf = known_dosish_suffixes;
+    do {
+       int s = strlen(*suf);
+       if (slen > s && suffix[slen-s-1] != PATH_SEP
+           && strequ(suffix + slen - s, *suf)) {
+           return name+nlen-s;
+       }
+    } while (*++suf != NULL);
+#endif /* MAX_EXT_CHARS */
 
     return NULL;
 }
 
 
@@ -1038,11 +1068,16 @@ open_and_stat (char *name, int flags, mo
 
 /* ========================================================================
  * Set ifname to the input file name (with a suffix appended if necessary)
  * and istat to its stats. For decompression, if no file exists with the
  * original name, try adding successively z_suffix, .gz, .z, -z and .Z.
- * For MSDOS, we try only z_suffix and z.
+ * For systems that disallow multiple dots, remove the dot from each
+ * suffix we try if ifname already has a dot in its basename.
+ * DJGPP supports long file names when they are available (Windows 9X), so
+ * we try both the normal concatenation, like .tar.gz, and the DOS-ish
+ * butchered .tgz etc.; this will make happy those people who move DOS
+ * files to Windows filesystems or set up dual-boot DOS/Windows systems.
  * Return an open file descriptor or -1.
  */
 static int
 open_input_file (iname, sbuf)
     char *iname;
@@ -1051,12 +1086,12 @@ open_input_file (iname, sbuf)
     int ilen;  /* strlen(ifname) */
     int z_suffix_errno = 0;
     static char const *suffixes[] = {NULL, ".gz", ".z", "-z", ".Z", NULL};
     char const **suf = suffixes;
     char const *s;
-#ifdef NO_MULTIPLE_DOTS
-    char *dot; /* pointer to ifname extension, or NULL */
+#if defined(MAX_EXT_CHARS) || defined(NO_MULTIPLE_DOTS)
+    char *dot = NULL; /* pointer to ifname extension, or NULL */
 #endif
     int fd;
     int open_flags = (O_RDONLY | O_NONBLOCK | O_NOCTTY
 		      | (ascii && !decompress ? 0 : O_BINARY));
 
@@ -1082,32 +1117,52 @@ open_input_file (iname, sbuf)
     s = get_suffix(ifname);
     if (s != NULL) {
 	progerror(ifname); /* ifname already has z suffix and does not exist */
 	return -1;
     }
-#ifdef NO_MULTIPLE_DOTS
-    dot = strrchr(ifname, '.');
+    ilen = strlen(ifname);
+#if defined(MAX_EXT_CHARS) || defined(NO_MULTIPLE_DOTS)
+    dot = strrchr(gzip_base_name(ifname), '.');
     if (dot == NULL) {
+        dot = ifname + ilen;
+# ifdef NO_MULTIPLE_DOTS
         strcat(ifname, ".");
-        dot = strrchr(ifname, '.');
+# endif
     }
 #endif
-    ilen = strlen(ifname);
-    if (strequ(z_suffix, ".gz")) suf++;
+    if (strequ(z_suffix, suffixes[1])) suf++;
 
     /* Search for all suffixes */
     do {
         char const *s0 = s = *suf;
-        strcpy (ifname, iname);
 #ifdef NO_MULTIPLE_DOTS
-        if (*s == '.') s++;
-        if (*dot == '\0') strcpy (dot, ".");
+        if (*s == '.' && *dot == '.') s++;
+#endif
+#ifdef LONG_FILE_NAMES
+        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;
+        ifname[ilen] = '\0';
+        if (errno != ENOENT)
+          {
+            progerror (ifname);
+            return -1;
+          }
+        if (strequ (s0, z_suffix))
+          z_suffix_errno = errno;
 #endif
 #ifdef MAX_EXT_CHARS
+# ifndef NO_MULTIPLE_DOTS
+        if (*dot == '\0') continue; /* already tried under LONG_FILE_NAMES */
+# endif
+        if (*dot == '\0') strcpy (dot, ".");
+        if (*s == '.') s++;
 	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;
         strcat(ifname, s);
 	fd = open_and_stat (ifname, open_flags, RW_USER, sbuf);
 	if (0 <= fd)
@@ -1117,14 +1172,15 @@ open_input_file (iname, sbuf)
 	    progerror (ifname);
 	    return -1;
 	  }
 	if (strequ (s0, z_suffix))
 	  z_suffix_errno = errno;
+	strcpy(ifname, iname);
+#endif
     } while (*++suf != NULL);
 
     /* No suffix found, complain using z_suffix: */
-    strcpy(ifname, iname);
 #ifdef NO_MULTIPLE_DOTS
     if (*dot == '\0') strcpy(dot, ".");
 #endif
 #ifdef MAX_EXT_CHARS
     if (MAX_EXT_CHARS < z_len + strlen (dot + 1))
@@ -1183,38 +1239,54 @@ local int make_ofname()
 	    fprintf (stderr, "%s: %s already has %s suffix -- unchanged\n",
 		     program_name, ifname, suff);
 	}
 	return WARNING;
     } else {
+        char const *p_z_suffix = z_suffix;
+        int z_length = z_len;
         save_orig_name = 0;
 
-#ifdef NO_MULTIPLE_DOTS
-	suff = strrchr(ofname, '.');
+#if defined(NO_MULTIPLE_DOTS) || defined(MAX_EXT_CHARS)
+#  ifdef HAVE_LONG_FILE_NAMES
+        /* This is for systems where the availability of the long file name
+           support is only known at run time, and depends on the filesystem
+           where the target file OFNAME will be written.  DJGPP running on
+           Windows 9X is an example of such a system.  */
+        if (HAVE_LONG_FILE_NAMES(ofname)) {
+            strcat(ofname, p_z_suffix);
+            return OK;
+        }
+#  endif
+        if (*p_z_suffix == '.') {
+            p_z_suffix++;
+            z_length--;
+        }
+        suff = strrchr(gzip_base_name(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 (strequ(p_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.
          */
-        } else if (strlen(suff)-1 + z_len > MAX_SUFFIX) {
-            suff[MAX_SUFFIX+1-z_len] = '\0';
+        } else if (strlen(suff)-1 + z_length > MAX_EXT_CHARS) {
+            suff[MAX_EXT_CHARS+1-z_length] = '\0';
             save_orig_name = 1;
 #  endif
         }
 #endif /* NO_MULTIPLE_DOTS */
-	if (sizeof ofname <= strlen (ofname) + z_len)
+	if (sizeof ofname <= strlen (ofname) + z_length)
 	    goto name_too_long;
-	strcat(ofname, z_suffix);
+	strcat(ofname, p_z_suffix);
 
     } /* decompress ? */
     return OK;
 
  name_too_long:
@@ -1573,12 +1645,11 @@ local void shorten_name(name)
     }
     /* Try keeping short extensions intact:
      * 1234.678.012.gz -> 123.678.012.gz
      */
     do {
-	p = strrchr(name, PATH_SEP);
-	p = p ? p+1 : name;
+	p = gzip_base_name(name);
 	while (*p) {
 	    plen = strcspn(p, PART_SEP);
 	    p += plen;
 	    if (plen > min_part) trunc = p-1;
 	    if (*p) p++;
@@ -1589,11 +1660,11 @@ local void shorten_name(name)
 	do {
 	    trunc[0] = trunc[1];
 	} while (*trunc++);
 	trunc--;
     } else {
-	trunc = strrchr(name, PART_SEP[0]);
+	trunc = strrchr(gzip_base_name(name), PART_SEP[0]);
 	if (!trunc)
 	  gzip_error ("internal error in shorten_name");
 	if (trunc[1] == '\0') trunc--; /* force truncation */
     }
     strcpy(trunc, z_suffix);
diff -aprNU5 gzip-1.4.orig/lib/errno.in.h gzip-1.4/lib/errno.in.h
--- gzip-1.4.orig/lib/errno.in.h	2010-01-08 10:33:44 +0000
+++ gzip-1.4/lib/errno.in.h	2010-01-31 15:49:10 +0000
@@ -28,10 +28,22 @@
 #@INCLUDE_NEXT@ @NEXT_ERRNO_H@
 
 #ifndef _GL_ERRNO_H
 #define _GL_ERRNO_H
 
+# ifdef __DJGPP__
+/* POSIX says that EAGAIN and EWOULDBLOCK may have the same value.  */
+#  ifndef EWOULDBLOCK
+#   define EWOULDBLOCK    EAGAIN
+#  endif
+
+/* DJGPP's highst errno is 41 (EILSEQ) so taking the same
+   value than for native windows systems seems to be save.  */
+#  ifndef EOPNOTSUPP
+#   define EOPNOTSUPP     10045
+#  endif
+# endif
 
 /* On native Windows platforms, many macros are not defined.  */
 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
 
 /* POSIX says that EAGAIN and EWOULDBLOCK may have the same value.  */
diff -aprNU5 gzip-1.4.orig/lib/freadahead.c gzip-1.4/lib/freadahead.c
--- gzip-1.4.orig/lib/freadahead.c	2010-01-08 10:33:00 +0000
+++ gzip-1.4/lib/freadahead.c	2010-01-31 15:37:00 +0000
@@ -17,10 +17,19 @@
 #include <config.h>
 
 /* Specification.  */
 #include "freadahead.h"
 
+#if __DJGPP__
+ /*
+  *  Include libc/file.h for _IOERR definition
+  *  so that SystemV derived implementations are
+  *  selected for DJGPP.
+  */
+# include <libc/file.h>
+#endif
+
 #include <stdlib.h>
 #include "stdio-impl.h"
 
 size_t
 freadahead (FILE *fp)
diff -aprNU5 gzip-1.4.orig/lib/freading.c gzip-1.4/lib/freading.c
--- gzip-1.4.orig/lib/freading.c	2010-01-08 10:33:00 +0000
+++ gzip-1.4/lib/freading.c	2010-01-31 15:37:00 +0000
@@ -17,10 +17,19 @@
 #include <config.h>
 
 /* Specification.  */
 #include "freading.h"
 
+#if __DJGPP__
+ /*
+  *  Include libc/file.h for _IOREAD definition
+  *  so that SystemV derived implementations are
+  *  selected for DJGPP.
+  */
+# include <libc/file.h>
+#endif
+
 #include "stdio-impl.h"
 
 /* Don't use glibc's __freading function in glibc < 2.7, see
    <http://sourceware.org/bugzilla/show_bug.cgi?id=4359>  */
 #if !(HAVE___FREADING && (!defined __GLIBC__ || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)))
diff -aprNU5 gzip-1.4.orig/lib/fseeko.c gzip-1.4/lib/fseeko.c
--- gzip-1.4.orig/lib/fseeko.c	2010-01-08 10:33:44 +0000
+++ gzip-1.4/lib/fseeko.c	2010-01-31 15:37:00 +0000
@@ -17,10 +17,19 @@
    with this program; if not, write to the Free Software Foundation,
    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 #include <config.h>
 
+#if __DJGPP__
+ /*
+  *  Include libc/file.h for _IOERR definition
+  *  so that SystemV derived implementations are
+  *  selected for DJGPP.
+  */
+# include <libc/file.h>
+#endif
+
 /* Specification.  */
 #include <stdio.h>
 
 /* Get off_t and lseek.  */
 #include <unistd.h>
diff -aprNU5 gzip-1.4.orig/lib/fseterr.c gzip-1.4/lib/fseterr.c
--- gzip-1.4.orig/lib/fseterr.c	2010-01-08 10:33:00 +0000
+++ gzip-1.4/lib/fseterr.c	2010-01-31 15:37:00 +0000
@@ -17,10 +17,19 @@
 #include <config.h>
 
 /* Specification.  */
 #include "fseterr.h"
 
+#if __DJGPP__
+ /*
+  *  Include libc/file.h for _IOERR definition
+  *  so that SystemV derived implementations are
+  *  selected for DJGPP.
+  */
+# include <libc/file.h>
+#endif
+
 #include <errno.h>
 
 #include "stdio-impl.h"
 
 void
diff -aprNU5 gzip-1.4.orig/lib/mbrtowc.c gzip-1.4/lib/mbrtowc.c
--- gzip-1.4.orig/lib/mbrtowc.c	2010-01-08 10:33:00 +0000
+++ gzip-1.4/lib/mbrtowc.c	2010-01-31 15:37:00 +0000
@@ -15,10 +15,16 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
+#if defined(__DJGPP__) && !defined(EILSEQ)
+# if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined(__STRICT_ANSI__)
+#   define EILSEQ   41
+# endif /* (__STDC_VERSION__ >= 199901L) || !__STRICT_ANSI__ */
+#endif
+
 /* Specification.  */
 #include <wchar.h>
 
 #if GNULIB_defined_mbstate_t
 /* Implement mbrtowc() on top of mbtowc().  */
diff -aprNU5 gzip-1.4.orig/lib/vasnprintf.c gzip-1.4/lib/vasnprintf.c
--- gzip-1.4.orig/lib/vasnprintf.c	2010-01-08 10:33:46 +0000
+++ gzip-1.4/lib/vasnprintf.c	2010-01-31 15:37:00 +0000
@@ -51,10 +51,17 @@
    <features.h>, and once <features.h> has been included, it's too late.  */
 #ifndef _GNU_SOURCE
 # define _GNU_SOURCE    1
 #endif
 
+#if defined(__DJGPP__) && !defined(EILSEQ)
+# if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined(__STRICT_ANSI__)
+#   define EILSEQ   41
+# endif /* (__STDC_VERSION__ >= 199901L) || !__STRICT_ANSI__ */
+#endif
+
+
 #ifndef VASNPRINTF
 # include <config.h>
 #endif
 #ifndef IN_LIBINTL
 # include <alloca.h>
diff -aprNU5 gzip-1.4.orig/msdos/tailor.c gzip-1.4/msdos/tailor.c
--- gzip-1.4.orig/msdos/tailor.c	2010-01-03 17:26:02 +0000
+++ gzip-1.4/msdos/tailor.c	2010-01-31 15:37:00 +0000
@@ -51,5 +51,61 @@ void fcfree(ptr)
     *(ush*)&ptr = ptr_offset;
     farfree(ptr);
  }
 
 #endif /* __TURBOC__ */
+
+#ifdef __DJGPP__
+
+#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* ============================================================
+ * Make a file name valid for file systems supported by DJGPP.
+ * This includes replacing characters that aren't allowed in
+ * file names, and renaming files whose names are reserved by
+ * character device drivers.  Characters that aren't allowed
+ * depend on the filesystem where the file resides.
+ */
+void make_valid_dosw32_name(name)
+    char *name;
+{
+    /* The following characters aren't allowed in DOS file names.
+       Some of them aren't allowed by Windows 9X; these begin at
+       offset 7 (zero-based) in the string below.  */
+    static char disallowed_chars[] = "+, ;=[]|<>\\\":?*";
+    static char replacement_char[] = "x'_`_{}!()%'-^#";
+    int long_names = HAVE_LONG_FILE_NAMES(ofname);
+    struct stat st;
+    register char *p = name;
+
+    /* If the filesystem disallows multiple dots, remove
+       all but the last one.  */
+    if (!long_names)
+      make_simple_name(name);
+
+    /* If there are any more invalid characters, replace them.  */
+    for ( ; *p != '\0'; p++)
+    {
+      register int i;
+
+      for (i = long_names ? 7 : 0; i < sizeof(disallowed_chars); i++)
+        if (*p == disallowed_chars[i])
+        {
+          *p = replacement_char[i];
+          break;
+        }
+    }
+
+    /* The list of character devices is not constant: it depends on
+       what device drivers did they install in their CONFIG.SYS.
+       `stat' will tell us if the file name is a character device.  */
+    if (stat(name, &st) == 0 && S_ISCHR(st.st_mode))
+    {
+      /* If it's a reserved name, prepend a '_' to it.  */
+      memmove(name + 1, name, strlen(name) + 1);
+      name[0] = '_';
+    }
+}
+
+#endif /* __DJGPP__ */
diff -aprNU5 gzip-1.4.orig/tailor.h gzip-1.4/tailor.h
--- gzip-1.4.orig/tailor.h	2010-01-03 17:26:02 +0000
+++ gzip-1.4/tailor.h	2010-01-31 15:37:00 +0000
@@ -34,47 +34,98 @@
 #  undef MSDOS
 #endif
 
 #ifdef MSDOS
 #  ifdef __GNUC__
-     /* DJGPP version 1.09+ on MS-DOS.
-      * The DJGPP 1.09 stat() function must be upgraded before gzip will
-      * fully work.
-      * No need for HAVE_DIRENT_H, since <unistd.h> defines POSIX_SOURCE which
-      * implies HAVE_DIRENT_H.
-      */
+     /* DJGPP on MS-DOS. */
 #    define near
-#  else
+#    ifndef HAVE_DIRENT_H
+#      define HAVE_DIRENT_H
+#    endif
+#    ifndef HAVE_LIMITS_H
+#      define HAVE_LIMITS_H
+#    endif
+#    ifndef HAVE_UNISTD_H
+#      define HAVE_UNISTD_H
+#    endif
+#    define fcalloc(items,size) malloc((size_t)(items)*(size_t)(size))
+#    define fcfree(ptr) free(ptr)
+#    ifdef __DJGPP__
+       /* DJGPP version 2.x or later supports long file names on Windows.  */
+#      define LONG_FILE_NAMES
+#      define HAVE_LONG_FILE_NAMES(f)  (_use_lfn(f))
+#      define MAX_PATH_LEN             PATH_MAX
+#      define MAX_EXT_CHARS            3
+#      define MAX_SUFFIX               30
+#      define OS_CODE                  (HAVE_LONG_FILE_NAMES(ifname) ? 0x0e : 0x00)
+#      define NO_FSTAT
+#      define PART_SEP              "._- "
+       /* Function definition in tailor.c */
+       void make_valid_dosw32_name(char *name);
+#      define MAKE_LEGAL_NAME(name) make_valid_dosw32_name(name)
+#    else /* DJGPP version 1.x */
+       /* The DJGPP 1.09 stat() function must be upgraded before gzip will
+        * fully work.
+        */
+#      define MAX_PATH_LEN  128
+#      define NO_MULTIPLE_DOTS
+#      define MAX_EXT_CHARS 3
+#      define Z_SUFFIX "z"
+#      define OS_CODE            0x00
+#    endif
+#  else /* !__GNUC__ */
 #    define MAXSEG_64K
+#    define MAX_PATH_LEN  128
+#    define NO_MULTIPLE_DOTS
+#    define MAX_EXT_CHARS 3
+#    define Z_SUFFIX "z"
+#    define NO_SIZE_CHECK
+#    define UNLINK_READONLY_BUG
+#    define OS_CODE  0x00
 #    ifdef __TURBOC__
 #      define off_t long
+#      include <alloc.h>
+#      define DYN_ALLOC
+       /* Turbo C 2.0 does not accept static allocations of large arrays */
+       void * fcalloc (unsigned items, unsigned size);
+       void fcfree (void *ptr);
 #      ifdef __BORLANDC__
 #        define HAVE_DIRENT_H
 #      endif
 #      define HAVE_UTIME_H
 #    else /* MSC */
 #      define HAVE_SYS_UTIME_H
+#      include <malloc.h>
+#      define fcalloc(nitems,itemsize) halloc((long)(nitems),(itemsize))
+#      define fcfree(ptr) hfree(ptr)
 #    endif
-#  endif
+#  endif /* !__GNUC__ */
 #  define PATH_SEP2 '\\'
 #  define PATH_SEP3 ':'
-#  define MAX_PATH_LEN  128
-#  define NO_MULTIPLE_DOTS
-#  define MAX_EXT_CHARS 3
-#  define Z_SUFFIX "z"
 #  define PROTO
-#  define STDC_HEADERS
-#  define NO_SIZE_CHECK
-#  define UNLINK_READONLY_BUG
+#  ifndef STDC_HEADERS
+#    define STDC_HEADERS
+#  endif
 #  define casemap(c) tolow(c) /* Force file names to lower case */
 #  include <io.h>
-#  define OS_CODE  0x00
-#  define SET_BINARY_MODE(fd) setmode(fd, O_BINARY)
+#  include <unistd.h>
+   /* Do not ever switch console input into binary mode, even if
+      they've said --force.  Doing so will attempt to read from
+      the console with no echo and no way to signal EOF or even
+      interrupt the program (since special characters like ^Z and ^C
+      are not special in binary mode).  For all practical purposes,
+      a program which does that, wedges the machine.
+      If both stdin and stdout are the console device, don't switch
+      stdout into binary mode either, since that will switch the
+      console device into raw mode, with the same consequences as
+      described above.  */
+#  define SET_BINARY_MODE(fd) \
+     {if (!isatty(fd) || (force && !isatty(fileno(stdin)))) setmode(fd, O_BINARY);}
 #  if !defined(NO_ASM) && !defined(ASMV)
 #    define ASMV
 #  endif
-#else
+#else /* !MSDOS */
 #  define near
 #endif
 
 #ifdef OS2
 #  define PATH_SEP2 '\\'
@@ -134,23 +185,11 @@
 #    define casemap(c) tolow(c) /* Force file names to lower case */
 #  endif
 #  define OS_CODE  0x0b
 #endif
 
-#ifdef MSDOS
-#  ifdef __TURBOC__
-#    include <alloc.h>
-#    define DYN_ALLOC
-     /* Turbo C 2.0 does not accept static allocations of large arrays */
-     void * fcalloc (unsigned items, unsigned size);
-     void fcfree (void *ptr);
-#  else /* MSC */
-#    include <malloc.h>
-#    define fcalloc(nitems,itemsize) halloc((long)(nitems),(itemsize))
-#    define fcfree(ptr) hfree(ptr)
-#  endif
-#else
+#ifndef MSDOS
 #  ifdef MAXSEG_64K
 #    define fcalloc(items,size) calloc((items),(size))
 #  else
 #    define fcalloc(items,size) malloc((size_t)(items)*(size_t)(size))
 #  endif
@@ -272,13 +311,15 @@
 #ifndef Z_SUFFIX
 #  define Z_SUFFIX ".gz"
 #endif
 
 #ifdef MAX_EXT_CHARS
-#  define MAX_SUFFIX  MAX_EXT_CHARS
+#  ifndef MAX_SUFFIX
+#    define MAX_SUFFIX  MAX_EXT_CHARS
+#  endif
 #else
-#  define MAX_SUFFIX  30
+#  define LONG_FILE_NAMES
 #endif
 
 #ifndef MAKE_LEGAL_NAME
 #  ifdef NO_MULTIPLE_DOTS
 #    define MAKE_LEGAL_NAME(name)   make_simple_name(name)
diff -aprNU5 gzip-1.4.orig/util.c gzip-1.4/util.c
--- gzip-1.4.orig/util.c	2010-01-03 17:26:02 +0000
+++ gzip-1.4/util.c	2010-01-31 15:37:00 +0000
@@ -214,30 +214,34 @@ char *strlwr(s)
     return s;
 }
 
 /* ========================================================================
  * Return the base name of a file (remove any directory prefix and
- * any version suffix). For systems with file names that are not
- * case sensitive, force the base name to lower case.
+ * any version suffix).
  */
 char *
 gzip_base_name (fname)
     char *fname;
 {
-    char *p;
+    register char *p;
 
-    if ((p = strrchr(fname, PATH_SEP))  != NULL) fname = p+1;
+    for (p = fname + strlen(fname); p > fname; p--)
+    {
+#ifdef SUFFIX_SEP
+      if (p[-1] == SUFFIX_SEP)
+        p[-1] = '\0';
+#endif
+      if (p[-1] == PATH_SEP
 #ifdef PATH_SEP2
-    if ((p = strrchr(fname, PATH_SEP2)) != NULL) fname = p+1;
+          || p[-1] == PATH_SEP2
 #endif
 #ifdef PATH_SEP3
-    if ((p = strrchr(fname, PATH_SEP3)) != NULL) fname = p+1;
+         || p[-1] == PATH_SEP3
 #endif
-#ifdef SUFFIX_SEP
-    if ((p = strrchr(fname, SUFFIX_SEP)) != NULL) *p = '\0';
-#endif
-    if (casemap('A') == 'a') strlwr(fname);
+         )
+        return p;
+    }
     return fname;
 }
 
 /* ========================================================================
  * Unlink a file, working around the unlink readonly bug (if present).
