2002-05-11  Juan Manuel Guerrero  <st001906@hrz1.hrz.tu-darmstadt.de>

	*** still far from be complete. ***

	* djgpp/README: New file. DJGPP support added.

	* djgpp/diffs: New file. DJGPP specific changes to sources.

	* djgpp/config.bat: New file. DJGPP support added.

	* djgpp/fix_script.bat: New file. DJGPP support added.

	* djgpp/config.sed: New file. DJGPP support added.

	* djgpp/config.site: New file. DJGPP support added.

	* djgpp/gzexe_in.sed: New file. DJGPP support added.

	* djgpp/zdiff_in.sed: New file. DJGPP support added.

	* djgpp/zforce_in.sed: New file. DJGPP support added.

	* djgpp/zgrep_in.sed: New file. DJGPP support added.

	* djgpp/znew_in.sed: New file. DJGPP support added.

	* djgpp/zless_in.sed: New file. DJGPP support added.

	* djgpp/zmore_in.sed: New file. DJGPP support added.

	* gzip.c [PART_SEP]: Only define it if not defined previously.
	(get_suffix) [MAX_EXT_CHARS]: New array known_dosish_suffixes.
	(get_suffix) [MAX_EXT_CHARS]: If the file name doesn't have a dot
	in its basename, don't check the DOSish suffixes.
	(get_suffix) [MAX_EXT_CHARS] [HAVE_LONG_NAMES]: If long file names are
	supported, only check DOSish truncated suffixes when decompressing.
	(get_istat): 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
	and later versions), so we try both the normal concatenation,
	like .tar.gz, and the DOS-ish truncated .tgz etc.; this will make
	happy those people who move DOS files to Windows filesystems or
	set up dual-boot DOS/Windows systems.
	(make_ofname) [HAVE_LONG_NAMES]: DJGPP port of gzip will decide at
	runtime if LFN or SFN will be used.

	* gzip.h [HAVE_TIME_H]: Look for time_t definition in time.h or
	sys/time.h if not found in sys/types.h.

	* gzip.texi: Replace @samp{.some extension} with @file{.some extension}.

	* msdos/tailor.c [DJGPP] (make_valid_dosw32_name): New function.
	Replace characters that aren't allowed in file names, and rename
	files whose names are reserved by character device drivers.

	* tailor.h: New macros for DJGPP 2.x support.

	* util.c (base_name): Minimize amount of if-clause and strrchr calls.




diff -acrpNC3 gzip-1.3.5.orig/gzip.c gzip-1.3.5.djgpp/gzip.c
*** gzip-1.3.5.orig/gzip.c	Sat Sep 28 07:38:42 2002
--- gzip-1.3.5.djgpp/gzip.c	Sun Jan 19 00:17:02 2003
*************** typedef RETSIGTYPE (*sig_type) OF((int))
*** 195,203 ****
  
  /* Separator for file name parts (see shorten_name()) */
  #ifdef NO_MULTIPLE_DOTS
! #  define PART_SEP "-"
  #else
! #  define PART_SEP "."
  #endif
  
  		/* global buffers */
--- 195,207 ----
  
  /* Separator for file name parts (see shorten_name()) */
  #ifdef NO_MULTIPLE_DOTS
! #  ifndef PART_SEP
! #    define PART_SEP "-"
! #  endif
  #else
! #  ifndef PART_SEP
! #    define PART_SEP "."
! #  endif
  #endif
  
  		/* global buffers */
*************** local char *get_suffix(name)
*** 997,1007 ****
      int nlen, slen;
      char suffix[MAX_SUFFIX+3]; /* last chars of name, forced to lower case */
      static char *known_suffixes[] =
!        {NULL, ".gz", ".z", ".taz", ".tgz", "-gz", "-z", "_z",
  #ifdef MAX_EXT_CHARS
!           "z",
  #endif
-           NULL};
      char **suf = known_suffixes;
  
      *suf = z_suffix;
--- 1001,1010 ----
      int nlen, slen;
      char suffix[MAX_SUFFIX+3]; /* last chars of name, forced to lower case */
      static char *known_suffixes[] =
!        {NULL, ".gz", ".z", ".taz", ".tgz", "-gz", "-z", "_z", NULL};
  #ifdef MAX_EXT_CHARS
!     static char *known_dosish_suffixes[] = {"gz", "z", NULL};
  #endif
      char **suf = known_suffixes;
  
      *suf = z_suffix;
*************** local char *get_suffix(name)
*** 1029,1034 ****
--- 1032,1064 ----
             return name+nlen-s;
         }
      } while (*++suf != NULL);
+ #ifdef MAX_EXT_CHARS
+ # ifdef 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.  */
+     {
+        int e = errno;	/* HAVE_LONG_NAMES might set errno */
+        if (HAVE_LONG_NAMES(name) && !decompress) {
+          errno = e;
+          return NULL;
+        }
+        errno = e;
+     }
+ # endif /* HAVE_LONG_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(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;
  }
*************** local char *get_suffix(name)
*** 1038,1044 ****
   * 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.
   * Return OK or ERROR.
   */
  local int get_istat(iname, sbuf)
--- 1068,1079 ----
   * 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 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
!  * truncated .tgz etc.; this will make happy those people who move DOS
!  * files to Windows filesystems or set up dual-boot DOS/Windows systems.
   * Return OK or ERROR.
   */
  local int get_istat(iname, sbuf)
*************** local int get_istat(iname, sbuf)
*** 1050,1057 ****
      static char *suffixes[] = {NULL, ".gz", ".z", "-z", ".Z", NULL};
      char **suf = suffixes;
      char *s;
! #ifdef NO_MULTIPLE_DOTS
!     char *dot; /* pointer to ifname extension, or NULL */
  #endif
  
      *suf = z_suffix;
--- 1085,1092 ----
      static char *suffixes[] = {NULL, ".gz", ".z", "-z", ".Z", NULL};
      char **suf = suffixes;
      char *s;
! #if defined(MAX_EXT_CHARS) || defined(NO_MULTIPLE_DOTS)
!     char *dot = NULL; /* pointer to ifname extension, or NULL */
  #endif
  
      *suf = z_suffix;
*************** local int get_istat(iname, sbuf)
*** 1076,1095 ****
  	progerror(ifname); /* ifname already has z suffix and does not exist */
  	return ERROR;
      }
- #ifdef NO_MULTIPLE_DOTS
-     dot = strrchr(ifname, '.');
-     if (dot == NULL) {
-         strcat(ifname, ".");
-         dot = strrchr(ifname, '.');
-     }
- #endif
      ilen = strlen(ifname);
!     if (strequ(z_suffix, ".gz")) suf++;
  
      /* Search for all suffixes */
      do {
          char *s0 = s = *suf;
          strcpy (ifname, iname);
  #ifdef NO_MULTIPLE_DOTS
          if (*s == '.') s++;
          if (*dot == '\0') strcpy (dot, ".");
--- 1111,1133 ----
  	progerror(ifname); /* ifname already has z suffix and does not exist */
  	return ERROR;
      }
      ilen = strlen(ifname);
! #if defined(MAX_EXT_CHARS) || defined(NO_MULTIPLE_DOTS)
!     dot = strrchr(base_name(ifname), '.');
!     if (dot == NULL)
!       dot = ifname + ilen;
! #endif
!     if (strequ(z_suffix, suffixes[1])) suf++;
  
      /* Search for all suffixes */
      do {
          char *s0 = s = *suf;
          strcpy (ifname, iname);
+ #ifdef LONG_FILE_NAMES
+         strcat(ifname, s);
+         if (do_stat(ifname, sbuf) == 0) return OK;
+         ifname[ilen] = '\0';
+ #endif
  #ifdef NO_MULTIPLE_DOTS
          if (*s == '.') s++;
          if (*dot == '\0') strcpy (dot, ".");
*************** local int get_istat(iname, sbuf)
*** 1109,1115 ****
      /* 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))
--- 1147,1153 ----
      /* No suffix found, complain using z_suffix: */
      strcpy(ifname, iname);
  #ifdef NO_MULTIPLE_DOTS
!     if (*dot == '\0' && z_suffix[0] != '.') strcpy(dot, ".");
  #endif
  #ifdef MAX_EXT_CHARS
      if (MAX_EXT_CHARS < z_len + strlen (dot + 1))
*************** local int make_ofname()
*** 1169,1184 ****
  	}
  	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;
              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 */
--- 1207,1239 ----
  	}
  	return WARNING;
      } else {
+         char *z_suff = z_suffix;
+         int z_length = z_len;
+ 
          save_orig_name = 0;
  
! #if defined(NO_MULTIPLE_DOTS) || defined(MAX_EXT_CHARS)
! #  ifdef HAVE_LONG_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_NAMES(ofname)) {
!             strcat(ofname, z_suff);
!             return OK;
!         }
! #  endif
! 	if (*z_suff == '.') {
! 	    z_suff++;
! 	    z_length--;
! 	}
! 	suff = strrchr(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_suff, "z")) {
  		if (sizeof ofname <= strlen (ofname) + 2)
  		    goto name_too_long;
  		strcat(ofname, "gz"); /* enough room */
*************** local int make_ofname()
*** 1188,1202 ****
           * does not work correctly because of a bug in stat(). So we
           * must truncate here.
           */
!         } else if (strlen(suff)-1 + z_len > MAX_SUFFIX) {
!             suff[MAX_SUFFIX+1-z_len] = '\0';
              save_orig_name = 1;
  #  endif
          }
  #endif /* NO_MULTIPLE_DOTS */
! 	if (sizeof ofname <= strlen (ofname) + z_len)
  	    goto name_too_long;
! 	strcat(ofname, z_suffix);
  
      } /* decompress ? */
      return OK;
--- 1243,1257 ----
           * does not work correctly because of a bug in stat(). So we
           * must truncate here.
           */
!         } else if (strlen(suff) - 1 + z_length > MAX_SUFFIX) {
!             suff[MAX_SUFFIX + 1 - z_length] = '\0';
              save_orig_name = 1;
  #  endif
          }
  #endif /* NO_MULTIPLE_DOTS */
! 	if (sizeof ofname <= strlen (ofname) + z_length)
  	    goto name_too_long;
! 	strcat(ofname, z_suff);
  
      } /* decompress ? */
      return OK;
*************** local int name_too_long(name, statb)
*** 1533,1543 ****
  {
      int s = strlen(name);
      char c = name[s-1];
!     struct stat	tstat; /* stat for truncated name */
      int res;
  
      tstat = *statb;      /* Just in case OS does not fill all fields */
!     name[s-1] = '\0';
      res = lstat(name, &tstat) == 0 && same_file(statb, &tstat);
      name[s-1] = c;
      Trace((stderr, " too_long(%s) => %d\n", name, res));
--- 1588,1609 ----
  {
      int s = strlen(name);
      char c = name[s-1];
!     struct stat	tstat; /* stat buf for a file name with last char replaced */
      int res;
  
      tstat = *statb;      /* Just in case OS does not fill all fields */
!     /* Windows 9X VFAT and NTFS filesystems create two names for each
!        file: the original long name, and a short 8+3 alias (for consumption
!        by legacy DOS programs).  In some cases, the short alias is a proper
!        truncation of the long name; for example, `foobar.shar' gets an
!        alias `foobar.sha', and both names point to the same file.  For this
!        reason, checking whether a truncated name points to the same file
!        will produce false alarms for some file names.  To work around these
!        cases, we instead REPLACE the last character of the original file
!        name with a different character and stat the name thus produced to see
!        whether it points to the same file.  The replacement character is
!        deliberately chosen to be one that should be allowed on every OS.  */
!     name[s-1] = c == 'a' ? 'b' : 'a';
      res = lstat(name, &tstat) == 0 && same_file(statb, &tstat);
      name[s-1] = c;
      Trace((stderr, " too_long(%s) => %d\n", name, res));
*************** local void shorten_name(name)
*** 1582,1589 ****
       * 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;
--- 1648,1654 ----
       * 1234.678.012.gz -> 123.678.012.gz
       */
      do {
! 	p = base_name(name);
  	while (*p) {
  	    plen = strcspn(p, PART_SEP);
  	    p += plen;
*************** local void shorten_name(name)
*** 1598,1604 ****
  	} while (*trunc++);
  	trunc--;
      } else {
! 	trunc = strrchr(name, PART_SEP[0]);
  	if (trunc == NULL) error("internal error in shorten_name");
  	if (trunc[1] == '\0') trunc--; /* force truncation */
      }
--- 1663,1669 ----
  	} while (*trunc++);
  	trunc--;
      } else {
! 	trunc = strrchr(base_name(name), PART_SEP[0]);
  	if (trunc == NULL) error("internal error in shorten_name");
  	if (trunc[1] == '\0') trunc--; /* force truncation */
      }
diff -acrpNC3 gzip-1.3.5.orig/gzip.h gzip-1.3.5.djgpp/gzip.h
*** gzip-1.3.5.orig/gzip.h	Mon Oct  1 06:53:40 2001
--- gzip-1.3.5.djgpp/gzip.h	Sun Jan 19 00:17:02 2003
***************
*** 22,27 ****
--- 22,32 ----
   */
  #include <stdio.h>
  #include <sys/types.h> /* for off_t, time_t */
+ #ifdef HAVE_TIME_H
+ #  include <time.h>     /* some systems only have time_t here */
+ #else
+ #  include <sys/time.h> /* some systems only have time_t here */
+ #endif
  #if defined HAVE_STRING_H || defined STDC_HEADERS
  #  include <string.h>
  #  if !defined STDC_HEADERS && defined HAVE_MEMORY_H && !defined __GNUC__
diff -acrpNC3 gzip-1.3.5.orig/gzip.texi gzip-1.3.5.djgpp/gzip.texi
*** gzip-1.3.5.orig/gzip.texi	Mon Sep 30 06:57:28 2002
--- gzip-1.3.5.djgpp/gzip.texi	Sun Jan 19 00:17:02 2003
*************** Software Foundation raise funds for GNU 
*** 82,90 ****
  
  @code{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
! modification times.  (The default extension is @samp{-gz} for VMS,
! @samp{z} for MSDOS, OS/2 FAT and Atari.)  If no files are specified or
  if a file name is "-", the standard input is compressed to the standard
  output. @code{gzip} will only attempt to compress regular files.  In
  particular, it will ignore symbolic links.
--- 82,90 ----
  
  @code{gzip} reduces the size of the named files using Lempel-Ziv coding
  (LZ77).  Whenever possible, each file is replaced by one with the
! extension @file{.gz}, while keeping the same ownership modes, access and
! modification times.  (The default extension is @file{-gz} for VMS,
! @file{z} for MSDOS, OS/2 FAT and Atari.)  If no files are specified or
  if a file name is "-", the standard input is compressed to the standard
  output. @code{gzip} will only attempt to compress regular files.  In
  particular, it will ignore symbolic links.
*************** If the new file name is too long for its
*** 93,101 ****
  truncates it.  @code{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.
  
  By default, @code{gzip} keeps the original file name and timestamp in
  the compressed file. These are used when decompressing the file with the
--- 93,101 ----
  truncates it.  @code{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,
! @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, @code{gzip} keeps the original file name and timestamp in
  the compressed file. These are used when decompressing the file with the
*************** compressed file is not suitable for its 
*** 109,121 ****
  constructed from the original one to make it legal.
  
  @code{gunzip} takes a list of files on its command line and replaces
! each file whose name ends with @samp{.gz}, @samp{.z}, @samp{.Z},
! @samp{-gz}, @samp{-z} or @samp{_z} and which begins with the correct
  magic number with an uncompressed file without the original extension.
! @code{gunzip} also recognizes the special extensions @samp{.tgz} and
! @samp{.taz} as shorthands for @samp{.tar.gz} and @samp{.tar.Z}
! respectively. When compressing, @code{gzip} uses the @samp{.tgz}
! extension if necessary instead of truncating a file with a @samp{.tar}
  extension.
  
  @code{gunzip} can currently decompress files created by @code{gzip},
--- 109,121 ----
  constructed from the original one to make it legal.
  
  @code{gunzip} takes a list of files on its command line and replaces
! each file whose name ends with @file{.gz}, @file{.z}, @file{.Z},
! @file{-gz}, @file{-z} or @file{_z} and which begins with the correct
  magic number with an uncompressed file without the original extension.
! @code{gunzip} also recognizes the special extensions @file{.tgz} and
! @file{.taz} as shorthands for @file{.tar.gz} and @file{.tar.Z}
! respectively. When compressing, @code{gzip} uses the @file{.tgz}
! extension if necessary instead of truncating a file with a @file{.tar}
  extension.
  
  @code{gunzip} can currently decompress files created by @code{gzip},
*************** format is automatic.  When using the fir
*** 124,131 ****
  checks a 32 bit CRC (cyclic redundancy check). For @code{pack},
  @code{gunzip} checks the uncompressed length. The @code{compress} format
  was not designed to allow consistency checks. However @code{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
  correct simply because the standard @code{uncompress} does not complain.
  This generally means that the standard @code{uncompress} does not check
  its input, and happily generates garbage output.  The SCO @samp{compress
--- 124,131 ----
  checks a 32 bit CRC (cyclic redundancy check). For @code{pack},
  @code{gunzip} checks the uncompressed length. The @code{compress} format
  was not designed to allow consistency checks. However @code{gunzip} 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 @code{uncompress} does not complain.
  This generally means that the standard @code{uncompress} does not check
  its input, and happily generates garbage output.  The SCO @samp{compress
*************** members, use @code{unzip} instead of @co
*** 144,150 ****
  uncompresses either a list of files on the command line or its standard
  input and writes the uncompressed data on standard output.  @code{zcat}
  will uncompress files that have the correct magic number whether they
! have a @samp{.gz} suffix or not.
  
  @code{gzip} uses the Lempel-Ziv algorithm used in @code{zip} and PKZIP.
  The amount of compression obtained depends on the size of the input and
--- 144,150 ----
  uncompresses either a list of files on the command line or its standard
  input and writes the uncompressed data on standard output.  @code{zcat}
  will uncompress files that have the correct magic number whether they
! have a @file{.gz} suffix or not.
  
  @code{gzip} uses the Lempel-Ziv algorithm used in @code{zip} and PKZIP.
  The amount of compression obtained depends on the size of the input and
*************** uncompressed_name: name of the uncompres
*** 269,275 ****
  @end example
  
  The uncompressed size is given as @samp{-1} for files not in @code{gzip}
! format, such as compressed @samp{.Z} files. To get the uncompressed size for
  such a file, you can use:
  
  @example
--- 269,275 ----
  @end example
  
  The uncompressed size is given as @samp{-1} for files not in @code{gzip}
! format, such as compressed @file{.Z} files. To get the uncompressed size for
  such a file, you can use:
  
  @example
*************** decompress them in the case of @code{gun
*** 336,343 ****
  
  @item --suffix @var{suf}
  @itemx -S @var{suf}
! Use suffix @samp{@var{suf}} instead of @samp{.gz}. Any suffix can be
! given, but suffixes other than @samp{.z} and @samp{.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:
--- 336,343 ----
  
  @item --suffix @var{suf}
  @itemx -S @var{suf}
! Use suffix @file{@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:
*************** regardless of suffix, as in:
*** 346,352 ****
  gunzip -S "" *        (*.* for MSDOS)
  @end example
  
! Previous versions of gzip used the @samp{.z} suffix. This was changed to
  avoid a conflict with @code{pack}.
  
  @item --test
--- 346,352 ----
  gunzip -S "" *        (*.* for MSDOS)
  @end example
  
! Previous versions of gzip used the @file{.z} suffix. This was changed to
  avoid a conflict with @code{pack}.
  
  @item --test
*************** is equivalent to
*** 401,407 ****
  cat file1 file2
  @end example
  
! In case of damage to one member of a @samp{.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:
  
--- 401,407 ----
  cat file1 file2
  @end example
  
! 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:
  
diff -acrpNC3 gzip-1.3.5.orig/msdos/tailor.c gzip-1.3.5.djgpp/msdos/tailor.c
*** gzip-1.3.5.orig/msdos/tailor.c	Wed Jul  7 22:54:50 1993
--- gzip-1.3.5.djgpp/msdos/tailor.c	Sun Jan 19 00:17:02 2003
*************** void fcfree(ptr)
*** 56,58 ****
--- 56,114 ----
   }
  
  #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_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 -acrpNC3 gzip-1.3.5.orig/tailor.h gzip-1.3.5.djgpp/tailor.h
*** gzip-1.3.5.orig/tailor.h	Wed Sep 25 21:21:30 2002
--- gzip-1.3.5.djgpp/tailor.h	Sun Jan 19 00:17:02 2003
***************
*** 27,40 ****
       /* 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.
        */
  #    define near
  #  else
  #    define MAXSEG_64K
  #    ifdef __TURBOC__
  #      define off_t long
  #      ifdef __BORLANDC__
  #        define HAVE_DIRENT_H
  #        define HAVE_UTIME
--- 27,75 ----
       /* DJGPP version 1.09+ on MS-DOS.
        * The DJGPP 1.09 stat() function must be upgraded before gzip will
        * fully work.
        */
  #    define near
+ #    define DIRENT
+ #    define fcalloc(items,size) malloc((size_t)(items)*(size_t)(size))
+ #    define fcfree(ptr) free(ptr)
+ #    if __DJGPP__ >= 2
+        /* DJGPP version 2.x or later supports long file names on Windows.  */
+ #      define LONG_FILE_NAMES
+ #      define HAVE_LONG_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_NAMES(ifname) ? 0x0e : 0x00)
+ #      define NO_FSTAT
+ #      define PART_SEP              "._- "
+ #      define MAKE_LEGAL_NAME(name) make_valid_dosw32_name(name)
+ #    else /* DJGPP version 1.x */
+ #      define HAVE_LIMITS_H
+ #      define HAVE_UNISTD_H
+ #      define STDC_HEADERS
+ #      define MAX_PATH_LEN  128
+ #      define NO_MULTIPLE_DOTS
+ #      define MAX_EXT_CHARS 3
+ #      define Z_SUFFIX "z"
+ #      define OS_CODE            0x00
+ #    endif
  #  else
+ #    define STDC_HEADERS
  #    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
  #        define HAVE_UTIME
***************
*** 42,62 ****
  #      define HAVE_UTIME_H
  #    else /* MSC */
  #      define HAVE_SYS_UTIME_H
  #    endif
  #  endif
  #  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
  #  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)
  #  if !defined(NO_ASM) && !defined(ASMV)
  #    define ASMV
--- 77,92 ----
  #      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
  #  define PATH_SEP2 '\\'
  #  define PATH_SEP3 ':'
  #  define PROTO
  #  define casemap(c) tolow(c) /* Force file names to lower case */
  #  include <io.h>
  #  define SET_BINARY_MODE(fd) setmode(fd, O_BINARY)
  #  if !defined(NO_ASM) && !defined(ASMV)
  #    define ASMV
***************
*** 125,143 ****
  #  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
  #  ifdef MAXSEG_64K
  #    define fcalloc(items,size) calloc((items),(size))
  #  else
--- 155,161 ----
  #  define OS_CODE  0x0b
  #endif
  
! #ifndef MSDOS
  #  ifdef MAXSEG_64K
  #    define fcalloc(items,size) calloc((items),(size))
  #  else
***************
*** 272,280 ****
  #endif
  
  #ifdef MAX_EXT_CHARS
! #  define MAX_SUFFIX  MAX_EXT_CHARS
  #else
  #  define MAX_SUFFIX  30
  #endif
  
  #ifndef MAKE_LEGAL_NAME
--- 290,301 ----
  #endif
  
  #ifdef 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
diff -acrpNC3 gzip-1.3.5.orig/util.c gzip-1.3.5.djgpp/util.c
*** gzip-1.3.5.orig/util.c	Mon Sep 30 08:36:40 2002
--- gzip-1.3.5.djgpp/util.c	Sun Jan 19 00:17:02 2003
*************** char *strlwr(s)
*** 195,214 ****
  char *base_name(fname)
      char *fname;
  {
!     char *p;
  
!     if ((p = strrchr(fname, PATH_SEP))  != NULL) fname = p+1;
  #ifdef PATH_SEP2
!     if ((p = strrchr(fname, PATH_SEP2)) != NULL) fname = p+1;
  #endif
  #ifdef PATH_SEP3
!     if ((p = strrchr(fname, PATH_SEP3)) != NULL) fname = p+1;
  #endif
! #ifdef SUFFIX_SEP
!     if ((p = strrchr(fname, SUFFIX_SEP)) != NULL) *p = '\0';
! #endif
!     if (casemap('A') == 'a') strlwr(fname);
!     return fname;
  }
  
  /* ========================================================================
--- 195,219 ----
  char *base_name(fname)
      char *fname;
  {
!     register char *p = fname;
  
!     for (p += 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
!           || p[-1] == PATH_SEP2
  #endif
  #ifdef PATH_SEP3
!           || p[-1] == PATH_SEP3
  #endif
!          )
!         break;
!     }
!     return (casemap('A') == 'a') ? strlwr(p) : p;
  }
  
  /* ========================================================================
