File: tempnam.c

package info (click to toggle)
squid 2.6.5-6etch5
  • links: PTS
  • area: main
  • in suites: etch
  • size: 12,540 kB
  • ctags: 13,801
  • sloc: ansic: 105,278; sh: 6,083; makefile: 1,297; perl: 1,245; awk: 40
file content (139 lines) | stat: -rw-r--r-- 2,504 bytes parent folder | download | duplicates (10)
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * $Id: tempnam.c,v 1.10 1998/09/23 17:14:24 wessels Exp $
 */

/* 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 "config.h"

#if HAVE_LIBC_H
#include <libc.h>
#endif
#if HAVE_STDIO_H
#include <stdio.h>
#endif
#if HAVE_TYPES_H
#include <sys/types.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();
}

#ifdef TEST
int
main()
{
    char *t;
    int n = 0;
    while ((t = tempnam(NULL, NULL))) {
	printf("%s\n", t);
	if (++n == 1000)
	    break;
    }
    return 1;
}
#endif