]> git.ipfire.org Git - thirdparty/squid.git/blame - compat/tempnam.c
Source Format Enforcement (#1234)
[thirdparty/squid.git] / compat / tempnam.c
CommitLineData
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 57static 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 118char *
119tempnam(const char *dir, const char *pfx)
120{
6ad85e8a 121 return _tmpnam();
30a4f2a8 122}
123