Annotation of embedaddon/sudo/compat/mktemp.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (c) 2001, 2003, 2004, 2008-2011
3: * Todd C. Miller <Todd.Miller@courtesan.com>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17:
18: #include <config.h>
19:
20: #include <sys/types.h>
21: #include <sys/time.h>
22: #include <sys/stat.h>
23:
24: #include <errno.h>
25: #include <fcntl.h>
26: #include <limits.h>
27: #include <stdio.h>
28: #ifdef HAVE_STDLIB_H
29: # include <stdlib.h>
30: #endif /* HAVE_STDLIB_H */
31: #include <ctype.h>
32: #ifdef HAVE_UNISTD_H
33: # include <unistd.h>
34: #endif /* HAVE_UNISTD_H */
35: #if TIME_WITH_SYS_TIME
36: # include <time.h>
37: #endif
38:
39: #include "missing.h"
40:
41: #define MKTEMP_FILE 1
42: #define MKTEMP_DIR 2
43:
44: #define TEMPCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
45: #define NUM_CHARS (sizeof(TEMPCHARS) - 1)
46:
47: #ifndef INT_MAX
48: #define INT_MAX 0x7fffffff
49: #endif
50:
51: #ifdef HAVE_RANDOM
52: # define RAND random
53: # define SRAND srandom
54: # define SEED_T unsigned int
55: #else
56: # ifdef HAVE_LRAND48
57: # define RAND lrand48
58: # define SRAND srand48
59: # define SEED_T long
60: # else
61: # define RAND rand
62: # define SRAND srand
63: # define SEED_T unsigned int
64: # endif
65: #endif
66:
67: static void
68: seed_random(void)
69: {
70: SEED_T seed;
71: struct timeval tv;
72:
73: /*
74: * Seed from time of day and process id multiplied by small primes.
75: */
76: (void) gettimeofday(&tv, NULL);
77: seed = (tv.tv_sec % 10000) * 523 + tv.tv_usec * 13 +
78: (getpid() % 1000) * 983;
79: SRAND(seed);
80: }
81:
82: static unsigned int
83: get_random(void)
84: {
85: static int initialized;
86:
87: if (!initialized) {
88: seed_random();
89: initialized = 1;
90: }
91:
92: return RAND() & 0xffffffff;
93: }
94:
95: static int
96: mktemp_internal(char *path, int slen, int mode)
97: {
98: char *start, *cp, *ep;
99: const char *tempchars = TEMPCHARS;
100: unsigned int r, tries;
101: int fd;
102:
103: for (ep = path; *ep; ep++)
104: ;
105: if (path + slen >= ep) {
106: errno = EINVAL;
107: return -1;
108: }
109: ep -= slen;
110:
111: tries = 1;
112: for (start = ep; start > path && start[-1] == 'X'; start--) {
113: if (tries < INT_MAX / NUM_CHARS)
114: tries *= NUM_CHARS;
115: }
116: tries *= 2;
117:
118: do {
119: for (cp = start; *cp; cp++) {
120: r = get_random() % NUM_CHARS;
121: *cp = tempchars[r];
122: }
123:
124: switch (mode) {
125: case MKTEMP_FILE:
126: fd = open(path, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
127: if (fd != -1 || errno != EEXIST)
128: return fd;
129: break;
130: case MKTEMP_DIR:
131: if (mkdir(path, S_IRWXU) == 0)
132: return 0;
133: if (errno != EEXIST)
134: return -1;
135: break;
136: }
137: } while (--tries);
138:
139: errno = EEXIST;
140: return -1;
141: }
142:
143: #ifndef HAVE_MKSTEMPS
144: int
145: mkstemps(char *path, int slen)
146: {
147: return mktemp_internal(path, slen, MKTEMP_FILE);
148: }
149: #endif /* HAVE_MKSTEMPS */
150:
151: #ifndef HAVE_MKDTEMP
152: char *
153: mkdtemp(char *path)
154: {
155: if (mktemp_internal(path, 0, MKTEMP_DIR) == -1)
156: return NULL;
157: return path;
158: }
159: #endif /* HAVE_MKDTEMP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>