2010-07-25  Juan Manuell Guerrero  <juan.guerrero@gmx.de>

	* mktemp.c [__DJGPP__]: Define new macros DIR_EXIST, CANONICALIZE_PATH
	and STRIP_FULL_PATH_AND_EXTENSION; for other systems these are no-ops.
	(main) [__DJGPP__]: Use STRIP_FULL_PATH_AND_EXTENSION to strip path
	and extension from argv[0].
	Use CANONICALIZE_PATH to replace DOS-style backslash directory separator
	with unix-style slash directory separtor in the passed prefix.
	Change hardcoded template string pattern with TEMPLATE_PATTERN.
	Change test for hardcoded slash char as dir separator char with
	IS_DIR_SEPARATOR.  For MSDOS this also checks for drive specifier
	prefix.
	(main) [MSDOS]: Check also for TMP and TEMP.  If one of them are set,
	check that the directory exists, if not default to cwd.
	Change test for hardcoded slash char as dir separator char with
	IS_SLASH.
	Change hardcoded slash char as dir separator char with DIR_SEPARATOR.

	* priv_mktemp.c (_mktemp): Use macro IS_TEMPLATE_PATTERN_CHAR to detect
	at runtime what kind of template characters are allowed.  For systems
	with LFN support only 'X' is allowed.  For SFN systems like DOS also
	'.' is allowed.  This allows to use the extension as pattern too.

	* mktemp.man: Add MSDOS/DJGPP specific information.

	* mktemp.mdoc: Add MSDOS/DJGPP specific information.





diff -aprNU5 mktemp-1.7.orig/mktemp.c mktemp-1.7/mktemp.c
--- mktemp-1.7.orig/mktemp.c	2010-04-25 13:31:44 +0000
+++ mktemp-1.7/mktemp.c	2010-07-25 18:34:34 +0000
@@ -47,10 +47,49 @@
 #endif /* HAVE_GETOPT_LONG */
 #include <errno.h>
 
 #include <extern.h>
 
+#ifdef __DJGPP__
+# include <libc/unconst.h>
+
+# undef  IS_DOS_SLASH
+# define IS_DOS_SLASH(c)   ((c) == '/' || (c) == '\\' || (c) == ':')
+# define DIR_EXISTS(path)  (access((path), D_OK) == 0)
+
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)  \
+  ({                                               \
+      char *_dst, *_src;                           \
+      _dst = _src = unconst((file_name), char *);  \
+      while (*_src++)                              \
+        ;                                          \
+      while ((_src - _dst) && (*--_src != '.'))    \
+        ;                                          \
+      for (*_src = '\0'; (_src - _dst); _src--)    \
+        if (IS_DOS_SLASH(*_src))                   \
+          break;                                   \
+      if (_src - _dst)                             \
+        while ((*_dst++ = *++_src))                \
+          ;                                        \
+      (file_name);                                 \
+  })
+# define CANONICALIZE_PATH(path)                   \
+  ({                                               \
+      if ((path))                                  \
+      {                                            \
+        char *_p = unconst((path), char *);        \
+        for (; *_p; _p++)                          \
+          if (*_p == '\\')                         \
+            *_p = '/';                             \
+      }                                            \
+      (path);                                      \
+  })
+#else
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)  (file_name)
+# define CANONICALIZE_PATH(path)                   (path)
+#endif
+
 #ifndef _PATH_TMP
 #define _PATH_TMP "/tmp"
 #endif
 
 #ifdef HAVE_PROGNAME
@@ -84,11 +123,15 @@ main(argc, argv)
 	size_t plen;
 	extern char *optarg;
 	extern int optind;
 
 #ifndef HAVE_PROGNAME
+# ifdef __DJGPP__
+	__progname = STRIP_FULL_PATH_AND_EXTENSION(argv[0]);
+# else
 	__progname = argv[0];
+# endif
 #endif
 
 #ifdef HAVE_GETOPT_LONG
 	while ((ch = getopt_long(argc, argv, "dp:qtuV", longopts, NULL)) != -1)
 #else
@@ -97,20 +140,20 @@ main(argc, argv)
 		switch (ch) {
 		case 'd':
 			makedir = 1;
 			break;
 		case 'p':
-			prefix = optarg;
+			prefix = CANONICALIZE_PATH(optarg);
 			tflag = 1;
 			break;
 		case 'q':
 			quiet = 1;
 			break;
 		case 'T':
 			if (optarg) {
 				Tflag = 1;
-				prefix = optarg;
+				prefix = CANONICALIZE_PATH(optarg);
 			}
 			/* FALLTHROUGH */
 		case 't':
 			tflag = 1;
 			break;
@@ -125,46 +168,57 @@ main(argc, argv)
 	}
 
 	/* If no template specified use a default one (implies -t mode) */
 	switch (argc - optind) {
 	case 1:
-		template = argv[optind];
+		template = CANONICALIZE_PATH(argv[optind]);
 		break;
 	case 0:
-		template = "tmp.XXXXXXXXXX";
+		template = TEMPLATE_PATTERN;
 		tflag = 1;
 		break;
 	default:
 		usage();
 	}
 
 	if (tflag) {
-		if (strchr(template, '/')) {
+		if (IS_DIR_SEPARATOR(template)) {
 			if (!quiet)
 				(void)fprintf(stderr,
 				    "%s: template must not contain directory separators in -t mode\n", __progname);
 			exit(1);
 		}
 
 		if (!Tflag) {
 			cp = getenv("TMPDIR");
+#ifdef MSDOS
+			if (cp == NULL || *cp == '\0' || !DIR_EXISTS(cp)) {
+				cp = getenv("TMP");
+				if (cp == NULL || *cp == '\0' || !DIR_EXISTS(cp)) {
+					cp = getenv("TEMP");
+					if (cp == NULL || *cp == '\0' || !DIR_EXISTS(cp))
+						cp = ".";
+				}
+			}
+#else
 			if (cp != NULL && *cp != '\0')
+#endif
 				prefix = cp;
 		}
 		plen = strlen(prefix);
-		while (plen != 0 && prefix[plen - 1] == '/')
+		while (plen != 0 && IS_SLASH(prefix[plen - 1]))
 			plen--;
 
 		tempfile = (char *)malloc(plen + 1 + strlen(template) + 1);
 		if (tempfile == NULL) {
 			if (!quiet)
 				(void)fprintf(stderr,
 				    "%s: cannot allocate memory\n", __progname);
 			exit(1);
 		}
 		(void)memcpy(tempfile, prefix, plen);
-		tempfile[plen] = '/';
+		tempfile[plen] = DIR_SEPARATOR;
 		(void)strcpy(tempfile + plen + 1, template);	/* SAFE */
 	} else {
 		if ((tempfile = strdup(template)) == NULL) {
 			if (!quiet)
 				(void)fprintf(stderr,
diff -aprNU5 mktemp-1.7.orig/mktemp.man mktemp-1.7/mktemp.man
--- mktemp-1.7.orig/mktemp.man	2010-04-25 13:28:18 +0000
+++ mktemp-1.7/mktemp.man	2010-07-25 19:21:04 +0000
@@ -34,19 +34,27 @@ may be any filename with some number of
 .I /tmp/tfile.XXXXXXXXXX.
 If no
 .I template
 is specified a default of
 .I tmp.XXXXXXXXXX
+if LFN support is available, and
+.I tpXXXXXX.XXX
+if LFN support is not available
 is used and the
 .B \-t
 flag is implied (see below).
 .PP
 The trailing \(gaXs\(aa are replaced with a combination
 of the current process number and random letters.
 The name chosen depends both on the number of \(gaXs\(aa in the
 .I template
 and the number of collisions with pre\-existing files.
+If LFN support is not available, like on plain DOS,
+the number of \(gaXs\(aa in the
+.I template
+is restricted to 6 in the filename
+and 3 more in the extension.
 The number of unique filenames
 .B mktemp
 can return depends on the number of
 \(gaXs\(aa provided; ten \(gaXs\(aa will result in
 .B mktemp
@@ -89,10 +97,21 @@ as a prefix when generating the temporar
 The
 .I directory
 will be overridden by the user's
 .SM TMPDIR
 environment variable if it is set.
+On MSDOS and clones, if
+.SM TMPDIR
+is not set also the environment variables
+.SM TMP
+and
+.SM TEMP
+will be checked in that order.
+If one of the environment variables has been set,
+it will be checked if the directory contained therein can be accessed.
+If this is not possible then the current working directory
+will be used as prefix when generating the temporary filename.
 This option implies the
 .B \-t
 flag (see below).
 .TP
 .B \-q
@@ -106,24 +125,33 @@ This directory is chosen as follows:
 .RS
 .IP \(bu
 If the user's
 .SM TMPDIR
 environment variable is set, the directory contained therein is used.
+On MSDOS and clones also the environment variables
+.SM TMP
+and
+.SM TEMP
+will be checked in that order.
 .IP \(bu
 Otherwise, if the
 .B \-p
 flag was given the specified directory is used.
 .IP \(bu
 If none of the above apply,
 .I /tmp
+(on MSDOS and clones
+.I ./
+)
 is used.
 .RE
 .PP
 In this mode, the
 .I template
 (if specified) should be a directory component (as opposed to a full path)
 and thus should not contain any forward slashes.
+On MSDOS and clones also neither backslashes nor drive letter prefix.
 .TP
 .B \-u
 Operate in "unsafe" mode.
 The temp file will be unlinked before
 .B mktemp
@@ -135,10 +163,15 @@ The
 .B mktemp
 utility
 exits with a value of 0 on success or 1 on failure.
 .SH ENVIRONMENT
 .IP TMPDIR 8
+(or
+.IP TMP 8
+and
+.IP TEMP 8
+on MSDOS and clones)
 directory in which to place the temporary file when in
 .B \-t
 mode
 .SH EXAMPLES
 The following sh(1)
@@ -183,10 +216,15 @@ other than
 .I /tmp.
 In this example the temporary file will be created in
 .I /extra/tmp
 unless the user's
 .SM TMPDIR
+(or
+.SM TMP
+and
+.SM TEMP
+on MSDOS and clones)
 environment variable specifies otherwise.
 .RS
 .nf
 
 TMPFILE=\(gamktemp \-p /extra/tmp example.XXXXXXXXXX\(ga || exit 1
diff -aprNU5 mktemp-1.7.orig/mktemp.mdoc mktemp-1.7/mktemp.mdoc
--- mktemp-1.7.orig/mktemp.mdoc	2010-04-25 13:28:24 +0000
+++ mktemp-1.7/mktemp.mdoc	2010-07-25 20:05:30 +0000
@@ -44,10 +44,13 @@ to it, for example
 .Pa /tmp/tfile.XXXXXXXXXX .
 If no
 .Ar template
 is specified a default of
 .Pa tmp.XXXXXXXXXX
+if LFN support is available and
+.Pa tpXXXXXX.XXX
+if LFN support is not available
 is used and the
 .Fl t
 flag is implied (see below).
 .Pp
 The trailing
@@ -57,10 +60,17 @@ random letters.
 The name chosen depends both on the number of
 .Ql X Ns s
 in the
 .Ar template
 and the number of collisions with pre-existing files.
+If LFN support is not available, like on plain DOS,
+the number of
+.Ql X Ns s
+in the
+.Ar template
+is restricted to 6 in the filename
+and 3 more in the extension.
 The number of unique filenames
 .Nm
 can return depends on the number of
 .Ql X Ns s
 provided; ten
@@ -105,10 +115,21 @@ as a prefix when generating the temporar
 The
 .Ar directory
 will be overridden by the user's
 .Ev TMPDIR
 environment variable if it is set.
+On MSDOS and clones, if
+.Ev TMPDIR
+is not set also the environment variables
+.Ev TMP
+and
+.Ev TEMP
+will be checked in that order.
+If one of the environment variables has been set,
+it will be checked if the directory contained therein can be accessed.
+If this is not possible then the current working directory
+will be used as prefix when generating the temporary filename.
 This option implies the
 .Fl t
 flag (see below).
 .It Fl q
 Fail silently if an error occurs.
@@ -120,24 +141,33 @@ This directory is chosen as follows:
 .Bl -bullet
 .It
 If the user's
 .Ev TMPDIR
 environment variable is set, the directory contained therein is used.
+On MSDOS and clones also the environment variables
+.Ev TMP
+and
+.Ev TEMP
+will be checked in that order.
 .It
 Otherwise, if the
 .Fl p
 flag was given the specified directory is used.
 .It
 If none of the above apply,
 .Pa /tmp
+(on MSDOS and clones
+.Pa ./
+)
 is used.
 .El
 .Pp
 In this mode, the
 .Ar template
 (if specified) should be a directory component (as opposed to a full path)
 and thus should not contain any forward slashes.
+On MSDOS also neither backslashes nor drive letter prefix.
 .It Fl u
 Operate in
 .Dq unsafe
 mode.
 The temp file will be unlinked before
@@ -154,10 +184,15 @@ The
 utility
 exits with a value of 0 on success or 1 on failure.
 .Sh ENVIRONMENT
 .Bl -tag -width TMPDIR
 .It Ev TMPDIR
+(or
+.Ev TMP
+and
+.Ev TEMP 
+on MSDOS and clones)
 directory in which to place the temporary file when in
 .Fl t
 mode
 .El
 .Sh EXAMPLES
@@ -195,10 +230,15 @@ other than
 .Pa /tmp .
 In this example the temporary file will be created in
 .Pa /extra/tmp
 unless the user's
 .Ev TMPDIR
+(or
+.Ev TMP
+and
+.Ev TEMP 
+on MSDOS and clones)
 environment variable specifies otherwise.
 .Bd -literal -offset indent
 TMPFILE=\(gamktemp -p /extra/tmp example.XXXXXXXXXX\(ga || exit 1
 echo "program output" >> $TMPFILE
 .Ed
diff -aprNU5 mktemp-1.7.orig/priv_mktemp.c mktemp-1.7/priv_mktemp.c
--- mktemp-1.7.orig/priv_mktemp.c	2010-04-25 13:32:12 +0000
+++ mktemp-1.7/priv_mktemp.c	2010-07-25 18:50:26 +0000
@@ -63,11 +63,11 @@ mktemp_internal(path, mode)
 	}
 
 	for (start = path; *start; start++)
 		;
 	tries = 1;
-	for (; start > path && start[-1] == 'X'; start--) {
+	for (; start > path && IS_TEMPLATE_PATTERN_CHAR(start[-1]); start--) {
 		if (tries < INT_MAX / NUM_CHARS)
 			tries *= NUM_CHARS;
 	}
 	tries *= 2;
 
