File: tempnam.c

package info (click to toggle)
squid 7.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 33,440 kB
  • sloc: cpp: 184,513; ansic: 12,442; sh: 5,688; makefile: 5,247; perl: 2,560; sql: 326; python: 240; awk: 141; sed: 1
file content (123 lines) | stat: -rw-r--r-- 2,713 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
 *
 * Squid software is distributed under GPLv2+ license and includes
 * contributions from numerous individuals and organizations.
 * Please see the COPYING and CONTRIBUTORS files for details.
 */

/* A reasonably functional tmpnam. */

/* Originally by Tom Hageman, tom@basil.icce.rug.nl */

/*
 * This tmpnam() was changed by Gerben_Wierda@RnA.nl to serve as
 * tempnam() for squid-1.1.6. It ignores the directory parameter, every
 * temp file is written in /tmp.
 */

#include "squid.h"
#include "compat/tempnam.h"

#if HAVE_LIBC_H
#include <libc.h>
#endif
#if HAVE_LIMITS_H
#include <limits.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif

#undef TMP_MAX

#define _tmp        "/tmp/"
#define lengthof_tmp    5

#ifndef LONG_BIT
#define LONG_BIT    (CHAR_BIT * 4)  /* assume sizeof(long) == 4 */
#endif

#define L_tmpmin    (lengthof_tmp + 5)  /* 5 chars for pid. */

#if (L_tmpnam > L_tmpmin)
#if (L_tmpnam > L_tmpmin + LONG_BIT / 6)    /* base 64 */
#define TMP_MAX ULONG_MAX
#else
#define TMP_MAX ((1L << (6 * (L_tmpnam - L_tmpmin))) - 1)
#endif
#else
#ifndef L_tmpnam
#error "tmpnam: L_tmpnam undefined"
#else
#error "tmpnam: L_tmpnam too small"
#endif
#endif

static char *
_tmpnam(void)
{
    static const char digits[] =
#if (L_tmpnam >= L_tmpmin + LONG_BIT / 4)
        "0123456789abcdef";
#define TMP_BASE    16
#else
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-";
#define TMP_BASE    64
#endif
    static unsigned long lastcount = 0;
    static char buffer[L_tmpnam + 1];
    char *s = buffer;
    unsigned long count = lastcount;
    pid_t pid = getpid();

    if (sizeof(_tmp) - 1 != lengthof_tmp)
        abort();        /* Consistency error. */

    for (;;) {
        register int i = L_tmpnam;
        register unsigned long c;
        register unsigned int p;

        /* Build filename. (the hard way) */
        s += i;
        *s = '\0';

        c = (count == TMP_MAX) ? 0 : ++count;
        do {
            *--s = digits[c % TMP_BASE];
            c /= TMP_BASE;
        } while (--i > L_tmpmin);

        p = (unsigned int) pid;
        do {
            *--s = digits[p % 10];
            p /= 10;
        } while (--i > lengthof_tmp);

        do {
            *--s = _tmp[--i];
        } while (i > 0);

        /* Check that the file doesn't exist. */
        if (access(s, 0) != 0)
            break;

        /* It exists; retry unless we tried them all. */
        if (count == lastcount) {
            s = NULL;
            break;
        }
    }

    lastcount = count;

    return s;
}

char *
tempnam(const char *dir, const char *pfx)
{
    return _tmpnam();
}