-/* $OpenBSD: mktemp.c,v 1.22 2008/08/21 16:54:44 millert Exp $ */
+/* $OpenBSD: mktemp.c,v 1.23 2008/08/22 00:56:13 millert Exp $ */
/*
* Copyright (c) 1987, 1993
* The Regents of the University of California. All rights reserved.
static int
_gettemp(char *path, int *doopen, int domkdir, int slen)
{
- char *start, *trv, *suffp;
+ char *start, *cp, *ep;
struct stat sbuf;
- int rval;
- pid_t pid;
+ size_t len;
+ int r;
if (doopen && domkdir) {
errno = EINVAL;
return(0);
}
- for (trv = path; *trv; ++trv)
- ;
- trv -= slen;
- suffp = trv;
- --trv;
- if (trv < path) {
+ len = strlen(path);
+ if (len == 0 || slen >= len) {
errno = EINVAL;
- return (0);
- }
- pid = getpid();
- while (trv >= path && *trv == 'X' && pid != 0) {
- *trv-- = (pid % 10) + '0';
- pid /= 10;
- }
- while (trv >= path && *trv == 'X') {
- char c;
-
- pid = arc4random_uniform(26+26);
- if (pid < 26)
- c = pid + 'A';
- else
- c = (pid - 26) + 'a';
- *trv-- = c;
+ return(0);
}
- start = trv + 1;
+ ep = path + len - slen;
+
+ for (start = ep; *--start == 'X';)
+ ;
+ start++;
for (;;) {
+ for (cp = start; cp != ep; cp++) {
+ r = arc4random_uniform(26 + 26);
+ if (r < 26)
+ *cp = r + 'A';
+ else
+ *cp = (r - 26) + 'a';
+ }
+
if (doopen) {
if ((*doopen =
open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
return(0);
} else if (lstat(path, &sbuf))
return(errno == ENOENT ? 1 : 0);
-
- /* tricky little algorithm for backward compatibility */
- for (trv = start;;) {
- if (!*trv)
- return (0);
- if (*trv == 'Z') {
- if (trv == suffp)
- return (0);
- *trv++ = 'a';
- } else {
- if (isdigit(*trv))
- *trv = 'a';
- else if (*trv == 'z') /* inc from z to A */
- *trv = 'A';
- else {
- if (trv == suffp)
- return (0);
- ++*trv;
- }
- break;
- }
- }
}
/*NOTREACHED*/
}