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