Annotation of embedaddon/sudo/compat/mktemp.c, revision 1.1.1.3
1.1 misho 1: /*
1.1.1.2 misho 2: * Copyright (c) 2001, 2003, 2004, 2008-2011, 2013
1.1 misho 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:
1.1.1.2 misho 20: #if !defined(HAVE_MKSTEMPS) || !defined(HAVE_MKDTEMP)
21:
1.1 misho 22: #include <sys/types.h>
23: #include <sys/time.h>
24: #include <sys/stat.h>
25:
26: #include <errno.h>
27: #include <fcntl.h>
28: #include <limits.h>
29: #include <stdio.h>
30: #ifdef HAVE_STDLIB_H
31: # include <stdlib.h>
32: #endif /* HAVE_STDLIB_H */
33: #include <ctype.h>
34: #ifdef HAVE_UNISTD_H
35: # include <unistd.h>
36: #endif /* HAVE_UNISTD_H */
1.1.1.3 ! misho 37: #ifdef TIME_WITH_SYS_TIME
1.1 misho 38: # include <time.h>
39: #endif
40:
41: #include "missing.h"
42:
43: #define MKTEMP_FILE 1
44: #define MKTEMP_DIR 2
45:
46: #define TEMPCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
47: #define NUM_CHARS (sizeof(TEMPCHARS) - 1)
48:
49: #ifndef INT_MAX
50: #define INT_MAX 0x7fffffff
51: #endif
52:
53: #ifdef HAVE_RANDOM
54: # define RAND random
55: # define SRAND srandom
56: # define SEED_T unsigned int
57: #else
58: # ifdef HAVE_LRAND48
59: # define RAND lrand48
60: # define SRAND srand48
61: # define SEED_T long
62: # else
63: # define RAND rand
64: # define SRAND srand
65: # define SEED_T unsigned int
66: # endif
67: #endif
68:
69: static void
70: seed_random(void)
71: {
72: SEED_T seed;
73: struct timeval tv;
74:
75: /*
76: * Seed from time of day and process id multiplied by small primes.
77: */
78: (void) gettimeofday(&tv, NULL);
79: seed = (tv.tv_sec % 10000) * 523 + tv.tv_usec * 13 +
80: (getpid() % 1000) * 983;
81: SRAND(seed);
82: }
83:
84: static unsigned int
85: get_random(void)
86: {
87: static int initialized;
88:
89: if (!initialized) {
90: seed_random();
91: initialized = 1;
92: }
93:
94: return RAND() & 0xffffffff;
95: }
96:
97: static int
98: mktemp_internal(char *path, int slen, int mode)
99: {
100: char *start, *cp, *ep;
101: const char *tempchars = TEMPCHARS;
102: unsigned int r, tries;
103: int fd;
104:
105: for (ep = path; *ep; ep++)
106: ;
107: if (path + slen >= ep) {
108: errno = EINVAL;
109: return -1;
110: }
111: ep -= slen;
112:
113: tries = 1;
114: for (start = ep; start > path && start[-1] == 'X'; start--) {
115: if (tries < INT_MAX / NUM_CHARS)
116: tries *= NUM_CHARS;
117: }
118: tries *= 2;
119:
120: do {
121: for (cp = start; *cp; cp++) {
122: r = get_random() % NUM_CHARS;
123: *cp = tempchars[r];
124: }
125:
126: switch (mode) {
127: case MKTEMP_FILE:
128: fd = open(path, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
129: if (fd != -1 || errno != EEXIST)
130: return fd;
131: break;
132: case MKTEMP_DIR:
133: if (mkdir(path, S_IRWXU) == 0)
134: return 0;
135: if (errno != EEXIST)
136: return -1;
137: break;
138: }
139: } while (--tries);
140:
141: errno = EEXIST;
142: return -1;
143: }
144:
145: #ifndef HAVE_MKSTEMPS
146: int
147: mkstemps(char *path, int slen)
148: {
149: return mktemp_internal(path, slen, MKTEMP_FILE);
150: }
151: #endif /* HAVE_MKSTEMPS */
152:
153: #ifndef HAVE_MKDTEMP
154: char *
155: mkdtemp(char *path)
156: {
157: if (mktemp_internal(path, 0, MKTEMP_DIR) == -1)
158: return NULL;
159: return path;
160: }
161: #endif /* HAVE_MKDTEMP */
1.1.1.2 misho 162: #endif /* !HAVE_MKSTEMPS || !HAVE_MKDTEMP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>