]>
Commit | Line | Data |
---|---|---|
0e2cd867 | 1 | /* |
262a0e14 | 2 | * $Id$ |
0e2cd867 | 3 | */ |
be335c22 | 4 | |
6ad85e8a | 5 | /* A reasonably functional tmpnam. */ |
30a4f2a8 | 6 | |
6ad85e8a | 7 | /* Originally by Tom Hageman, tom@basil.icce.rug.nl */ |
30a4f2a8 | 8 | |
6ad85e8a | 9 | /* |
10 | * This tmpnam() was changed by Gerben_Wierda@RnA.nl to serve as | |
11 | * tempnam() for squid-1.1.6. It ignores the directory parameter, every | |
12 | * temp file is written in /tmp. | |
13 | */ | |
30a4f2a8 | 14 | |
6ad85e8a | 15 | #include "config.h" |
a8f7d3ee | 16 | |
88738790 | 17 | #if HAVE_LIBC_H |
18 | #include <libc.h> | |
19 | #endif | |
30a4f2a8 | 20 | #if HAVE_STDIO_H |
21 | #include <stdio.h> | |
22 | #endif | |
88738790 | 23 | #if HAVE_TYPES_H |
24 | #include <sys/types.h> | |
25 | #endif | |
6ad85e8a | 26 | #if HAVE_LIMITS_H |
27 | #include <limits.h> | |
30a4f2a8 | 28 | #endif |
29 | #if HAVE_UNISTD_H | |
30 | #include <unistd.h> | |
31 | #endif | |
32 | ||
6ad85e8a | 33 | #undef TMP_MAX |
30a4f2a8 | 34 | |
6ad85e8a | 35 | #define _tmp "/tmp/" |
36 | #define lengthof_tmp 5 | |
30a4f2a8 | 37 | |
6ad85e8a | 38 | #ifndef LONG_BIT |
39 | #define LONG_BIT (CHAR_BIT * 4) /* assume sizeof(long) == 4 */ | |
40 | #endif | |
30a4f2a8 | 41 | |
6ad85e8a | 42 | #define L_tmpmin (lengthof_tmp + 5) /* 5 chars for pid. */ |
30a4f2a8 | 43 | |
6ad85e8a | 44 | #if (L_tmpnam > L_tmpmin) |
45 | #if (L_tmpnam > L_tmpmin + LONG_BIT / 6) /* base 64 */ | |
46 | #define TMP_MAX ULONG_MAX | |
47 | #else | |
48 | #define TMP_MAX ((1L << (6 * (L_tmpnam - L_tmpmin))) - 1) | |
49 | #endif | |
50 | #else | |
51 | #ifndef L_tmpnam | |
52 | #error "tmpnam: L_tmpnam undefined" | |
53 | #else | |
54 | #error "tmpnam: L_tmpnam too small" | |
55 | #endif | |
56 | #endif | |
30a4f2a8 | 57 | |
b8d8561b | 58 | |
59 | static char * | |
6ad85e8a | 60 | _tmpnam(void) |
b8d8561b | 61 | { |
6ad85e8a | 62 | static const char digits[] = |
63 | #if (L_tmpnam >= L_tmpmin + LONG_BIT / 4) | |
26ac0430 | 64 | "0123456789abcdef"; |
6ad85e8a | 65 | #define TMP_BASE 16 |
66 | #else | |
26ac0430 | 67 | "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"; |
6ad85e8a | 68 | #define TMP_BASE 64 |
69 | #endif | |
70 | static unsigned long lastcount = 0; | |
71 | static char buffer[L_tmpnam + 1]; | |
72 | char *s = buffer; | |
73 | unsigned long count = lastcount; | |
30a4f2a8 | 74 | pid_t pid = getpid(); |
30a4f2a8 | 75 | |
6ad85e8a | 76 | if (sizeof(_tmp) - 1 != lengthof_tmp) |
26ac0430 | 77 | abort(); /* Consistency error. */ |
30a4f2a8 | 78 | |
30a4f2a8 | 79 | for (;;) { |
26ac0430 AJ |
80 | register int i = L_tmpnam; |
81 | register unsigned long c; | |
82 | register unsigned int p; | |
83 | ||
84 | /* Build filename. (the hard way) */ | |
85 | s += i; | |
86 | *s = '\0'; | |
87 | ||
88 | c = (count == TMP_MAX) ? 0 : ++count; | |
89 | do { | |
90 | *--s = digits[c % TMP_BASE]; | |
91 | c /= TMP_BASE; | |
92 | } while (--i > L_tmpmin); | |
93 | ||
94 | p = (unsigned int) pid; | |
95 | do { | |
96 | *--s = digits[p % 10]; | |
97 | p /= 10; | |
98 | } while (--i > lengthof_tmp); | |
99 | ||
100 | do { | |
101 | *--s = _tmp[--i]; | |
102 | } while (i > 0); | |
103 | ||
104 | /* Check that the file doesn't exist. */ | |
105 | if (access(s, 0) != 0) | |
106 | break; | |
107 | ||
108 | /* It exists; retry unless we tried them all. */ | |
109 | if (count == lastcount) { | |
110 | s = NULL; | |
111 | break; | |
112 | } | |
30a4f2a8 | 113 | } |
114 | ||
6ad85e8a | 115 | lastcount = count; |
30a4f2a8 | 116 | |
6ad85e8a | 117 | return s; |
30a4f2a8 | 118 | } |
119 | ||
b8d8561b | 120 | char * |
121 | tempnam(const char *dir, const char *pfx) | |
122 | { | |
6ad85e8a | 123 | return _tmpnam(); |
30a4f2a8 | 124 | } |
125 | ||
6ad85e8a | 126 | #ifdef TEST |
127 | int | |
128 | main() | |
129 | { | |
130 | char *t; | |
131 | int n = 0; | |
132 | while ((t = tempnam(NULL, NULL))) { | |
26ac0430 AJ |
133 | printf("%s\n", t); |
134 | if (++n == 1000) | |
135 | break; | |
6ad85e8a | 136 | } |
137 | return 1; | |
138 | } | |
139 | #endif |