summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio
diff options
context:
space:
mode:
authorkris <kris@FreeBSD.org>2000-11-10 23:27:55 +0000
committerkris <kris@FreeBSD.org>2000-11-10 23:27:55 +0000
commit919c3e124ed41242fbbd60029a9e5158ab8a15ea (patch)
treebe9a5763903a207460182b2e38a63887daf403de /lib/libc/stdio
parentfd17851060a93753f322c9e45673f13bb2c85d2a (diff)
downloadFreeBSD-src-919c3e124ed41242fbbd60029a9e5158ab8a15ea.zip
FreeBSD-src-919c3e124ed41242fbbd60029a9e5158ab8a15ea.tar.gz
Increase the size of the mktemp() filename space by dropping the PID from
the encoding and using the character set [a-zA-Z0-9]. This gives a total of 62^6 = 56800235584 possible temporary filenames for the usual default invocation of 6 X's (compared to as few as 52 possibilities for the previous algorithm where up to 5 characters were wasted by the PID). Update some apparently bitrotten comments to reflect reality. Audited by: eivind, freebsd-audit Reviewed by: freebsd-current (a while ago) Originally submitted by: Peter Jeremy <Peter.Jeremy@alcatel.com.au>
Diffstat (limited to 'lib/libc/stdio')
-rw-r--r--lib/libc/stdio/mktemp.c42
1 files changed, 17 insertions, 25 deletions
diff --git a/lib/libc/stdio/mktemp.c b/lib/libc/stdio/mktemp.c
index 13e15d4..870e4db 100644
--- a/lib/libc/stdio/mktemp.c
+++ b/lib/libc/stdio/mktemp.c
@@ -45,6 +45,7 @@ static const char rcsid[] =
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <ctype.h>
#include <unistd.h>
@@ -52,6 +53,9 @@ char *_mktemp __P((char *));
static int _gettemp __P((char *, int *, int, int));
+static const unsigned char padchar[] =
+"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
int
mkstemps(path, slen)
char *path;
@@ -103,8 +107,10 @@ _gettemp(path, doopen, domkdir, slen)
int slen;
{
register char *start, *trv, *suffp;
+ char *pad;
struct stat sbuf;
- int pid, rval;
+ int rval;
+ uint32_t rand;
if (doopen && domkdir) {
errno = EINVAL;
@@ -120,26 +126,16 @@ _gettemp(path, doopen, domkdir, slen)
errno = EINVAL;
return (0);
}
- pid = getpid();
- while (*trv == 'X' && pid != 0) {
- *trv-- = (pid % 10) + '0';
- pid /= 10;
- }
+
+ /* Fill space with random characters */
while (*trv == 'X') {
- char c;
-
- pid = (arc4random() & 0xffff) % (26+26);
- if (pid < 26)
- c = pid + 'A';
- else
- c = (pid - 26) + 'a';
- *trv-- = c;
+ rand = arc4random() % (sizeof(padchar) - 1);
+ *trv-- = padchar[rand];
}
start = trv + 1;
/*
- * check the target directory; if you have six X's and it
- * doesn't exist this runs for a *very* long time.
+ * check the target directory.
*/
if (doopen || domkdir) {
for (;; --trv) {
@@ -175,19 +171,15 @@ _gettemp(path, doopen, domkdir, slen)
} else if (lstat(path, &sbuf))
return(errno == ENOENT ? 1 : 0);
- /* tricky little algorithm for backward compatibility */
+ /* If we have a collision, cycle through the space of filenames */
for (trv = start;;) {
if (*trv == '\0' || trv == suffp)
return(0);
- if (*trv == 'Z')
- *trv++ = 'a';
+ pad = strchr(padchar, *trv);
+ if (pad == NULL || !*++pad)
+ *trv++ = padchar[0];
else {
- if (isdigit((unsigned char)*trv))
- *trv = 'a';
- else if (*trv == 'z') /* inc from z to A */
- *trv = 'A';
- else
- ++*trv;
+ *trv++ = *pad;
break;
}
}
OpenPOWER on IntegriCloud