]>
Commit | Line | Data |
---|---|---|
59e0d9fe A |
1 | --- mktemp.c.orig Tue Mar 30 22:56:07 2004 |
2 | +++ mktemp.c Tue Mar 30 23:39:22 2004 | |
3 | @@ -40,6 +40,7 @@ | |
4 | #include "namespace.h" | |
5 | #include <sys/types.h> | |
6 | #include <sys/stat.h> | |
7 | +#include <sys/syslimits.h> | |
8 | #include <fcntl.h> | |
9 | #include <errno.h> | |
10 | #include <stdio.h> | |
11 | @@ -106,13 +107,14 @@ | |
12 | int domkdir; | |
13 | int slen; | |
14 | { | |
15 | - char *start, *trv, *suffp; | |
16 | + char *start, *trv, *suffp, *carryp; | |
17 | char *pad; | |
18 | struct stat sbuf; | |
19 | int rval; | |
20 | uint32_t rand; | |
21 | + char carrybuf[NAME_MAX]; | |
22 | ||
23 | - if (doopen != NULL && domkdir) { | |
24 | + if ((doopen != NULL && domkdir) || slen < 0) { | |
25 | errno = EINVAL; | |
26 | return (0); | |
27 | } | |
28 | @@ -122,7 +124,7 @@ | |
29 | trv -= slen; | |
30 | suffp = trv; | |
31 | --trv; | |
32 | - if (trv < path) { | |
33 | + if (trv < path || NULL != strchr(suffp, '/')) { | |
34 | errno = EINVAL; | |
35 | return (0); | |
36 | } | |
37 | @@ -134,6 +136,9 @@ | |
38 | } | |
39 | start = trv + 1; | |
40 | ||
41 | + /* save first combination of random characters */ | |
42 | + memcpy(carrybuf, start, suffp - start); | |
43 | + | |
44 | /* | |
45 | * check the target directory. | |
46 | */ | |
47 | @@ -170,14 +175,25 @@ | |
48 | return (errno == ENOENT); | |
49 | ||
50 | /* If we have a collision, cycle through the space of filenames */ | |
51 | - for (trv = start;;) { | |
52 | - if (*trv == '\0' || trv == suffp) | |
53 | - return (0); | |
54 | + for (trv = start, carryp = carrybuf;;) { | |
55 | + /* have we tried all possible permutations? */ | |
56 | + if (trv == suffp) | |
57 | + return (0); /* yes - exit with EEXIST */ | |
58 | pad = strchr(padchar, *trv); | |
59 | - if (pad == NULL || *++pad == '\0') | |
60 | - *trv++ = padchar[0]; | |
61 | - else { | |
62 | - *trv++ = *pad; | |
63 | + if (pad == NULL) { | |
64 | + /* this should never happen */ | |
65 | + errno = EIO; | |
66 | + return (0); | |
67 | + } | |
68 | + /* increment character */ | |
69 | + *trv = (*++pad == '\0') ? padchar[0] : *pad; | |
70 | + /* carry to next position? */ | |
71 | + if (*trv == *carryp) { | |
72 | + /* increment position and loop */ | |
73 | + ++trv; | |
74 | + ++carryp; | |
75 | + } else { | |
76 | + /* try with new name */ | |
77 | break; | |
78 | } | |
79 | } |