]> git.ipfire.org Git - thirdparty/squid.git/blame - compat/tempnam.c
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / compat / tempnam.c
CommitLineData
6ad85e8a 1/* A reasonably functional tmpnam. */
30a4f2a8 2
6ad85e8a 3/* Originally by Tom Hageman, tom@basil.icce.rug.nl */
30a4f2a8 4
6ad85e8a 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 */
30a4f2a8 10
f7f3304a 11#include "squid.h"
27bc2077 12#include "compat/tempnam.h"
a8f7d3ee 13
88738790 14#if HAVE_LIBC_H
15#include <libc.h>
16#endif
6ad85e8a 17#if HAVE_LIMITS_H
18#include <limits.h>
30a4f2a8 19#endif
20#if HAVE_UNISTD_H
21#include <unistd.h>
22#endif
23
6ad85e8a 24#undef TMP_MAX
30a4f2a8 25
6ad85e8a 26#define _tmp "/tmp/"
27#define lengthof_tmp 5
30a4f2a8 28
6ad85e8a 29#ifndef LONG_BIT
30#define LONG_BIT (CHAR_BIT * 4) /* assume sizeof(long) == 4 */
31#endif
30a4f2a8 32
6ad85e8a 33#define L_tmpmin (lengthof_tmp + 5) /* 5 chars for pid. */
30a4f2a8 34
6ad85e8a 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
30a4f2a8 48
b8d8561b 49
50static char *
6ad85e8a 51_tmpnam(void)
b8d8561b 52{
6ad85e8a 53 static const char digits[] =
54#if (L_tmpnam >= L_tmpmin + LONG_BIT / 4)
26ac0430 55 "0123456789abcdef";
6ad85e8a 56#define TMP_BASE 16
57#else
26ac0430 58 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-";
6ad85e8a 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;
30a4f2a8 65 pid_t pid = getpid();
30a4f2a8 66
6ad85e8a 67 if (sizeof(_tmp) - 1 != lengthof_tmp)
26ac0430 68 abort(); /* Consistency error. */
30a4f2a8 69
30a4f2a8 70 for (;;) {
26ac0430
AJ
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 }
30a4f2a8 104 }
105
6ad85e8a 106 lastcount = count;
30a4f2a8 107
6ad85e8a 108 return s;
30a4f2a8 109}
110
b8d8561b 111char *
112tempnam(const char *dir, const char *pfx)
113{
6ad85e8a 114 return _tmpnam();
30a4f2a8 115}
116
6ad85e8a 117#ifdef TEST
118int
119main()
120{
121 char *t;
122 int n = 0;
123 while ((t = tempnam(NULL, NULL))) {
26ac0430
AJ
124 printf("%s\n", t);
125 if (++n == 1000)
126 break;
6ad85e8a 127 }
128 return 1;
129}
130#endif