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