]> git.ipfire.org Git - thirdparty/squid.git/blob - lib/tempnam.c
Cleanup: zap CVS Id tags
[thirdparty/squid.git] / lib / tempnam.c
1 /*
2 * $Id$
3 */
4
5 /* A reasonably functional tmpnam. */
6
7 /* Originally by Tom Hageman, tom@basil.icce.rug.nl */
8
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 */
14
15 #include "config.h"
16
17 #if HAVE_LIBC_H
18 #include <libc.h>
19 #endif
20 #if HAVE_STDIO_H
21 #include <stdio.h>
22 #endif
23 #if HAVE_TYPES_H
24 #include <sys/types.h>
25 #endif
26 #if HAVE_LIMITS_H
27 #include <limits.h>
28 #endif
29 #if HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32
33 #undef TMP_MAX
34
35 #define _tmp "/tmp/"
36 #define lengthof_tmp 5
37
38 #ifndef LONG_BIT
39 #define LONG_BIT (CHAR_BIT * 4) /* assume sizeof(long) == 4 */
40 #endif
41
42 #define L_tmpmin (lengthof_tmp + 5) /* 5 chars for pid. */
43
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
57
58
59 static char *
60 _tmpnam(void)
61 {
62 static const char digits[] =
63 #if (L_tmpnam >= L_tmpmin + LONG_BIT / 4)
64 "0123456789abcdef";
65 #define TMP_BASE 16
66 #else
67 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-";
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;
74 pid_t pid = getpid();
75
76 if (sizeof(_tmp) - 1 != lengthof_tmp)
77 abort(); /* Consistency error. */
78
79 for (;;) {
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 }
113 }
114
115 lastcount = count;
116
117 return s;
118 }
119
120 char *
121 tempnam(const char *dir, const char *pfx)
122 {
123 return _tmpnam();
124 }
125
126 #ifdef TEST
127 int
128 main()
129 {
130 char *t;
131 int n = 0;
132 while ((t = tempnam(NULL, NULL))) {
133 printf("%s\n", t);
134 if (++n == 1000)
135 break;
136 }
137 return 1;
138 }
139 #endif