1*7f2fe78bSCy Schubert /* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t -*- */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert * Copyright (c) 1987, 1993
4*7f2fe78bSCy Schubert * The Regents of the University of California. All rights reserved.
5*7f2fe78bSCy Schubert *
6*7f2fe78bSCy Schubert * Redistribution and use in source and binary forms, with or without
7*7f2fe78bSCy Schubert * modification, are permitted provided that the following conditions
8*7f2fe78bSCy Schubert * are met:
9*7f2fe78bSCy Schubert * 1. Redistributions of source code must retain the above copyright
10*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer.
11*7f2fe78bSCy Schubert * 2. Redistributions in binary form must reproduce the above copyright
12*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer in the
13*7f2fe78bSCy Schubert * documentation and/or other materials provided with the distribution.
14*7f2fe78bSCy Schubert * 3. All advertising materials mentioning features or use of this software
15*7f2fe78bSCy Schubert * must display the following acknowledgement:
16*7f2fe78bSCy Schubert * This product includes software developed by the University of
17*7f2fe78bSCy Schubert * California, Berkeley and its contributors.
18*7f2fe78bSCy Schubert * 4. Neither the name of the University nor the names of its contributors
19*7f2fe78bSCy Schubert * may be used to endorse or promote products derived from this software
20*7f2fe78bSCy Schubert * without specific prior written permission.
21*7f2fe78bSCy Schubert *
22*7f2fe78bSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23*7f2fe78bSCy Schubert * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24*7f2fe78bSCy Schubert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25*7f2fe78bSCy Schubert * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26*7f2fe78bSCy Schubert * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27*7f2fe78bSCy Schubert * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28*7f2fe78bSCy Schubert * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29*7f2fe78bSCy Schubert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30*7f2fe78bSCy Schubert * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31*7f2fe78bSCy Schubert * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32*7f2fe78bSCy Schubert * SUCH DAMAGE.
33*7f2fe78bSCy Schubert */
34*7f2fe78bSCy Schubert
35*7f2fe78bSCy Schubert #if defined(LIBC_SCCS) && !defined(lint)
36*7f2fe78bSCy Schubert static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93";
37*7f2fe78bSCy Schubert #endif /* LIBC_SCCS and not lint */
38*7f2fe78bSCy Schubert
39*7f2fe78bSCy Schubert #include "k5-platform.h"
40*7f2fe78bSCy Schubert
41*7f2fe78bSCy Schubert #include <sys/types.h>
42*7f2fe78bSCy Schubert #include <sys/stat.h>
43*7f2fe78bSCy Schubert #include <fcntl.h>
44*7f2fe78bSCy Schubert #include <errno.h>
45*7f2fe78bSCy Schubert #include <stdio.h>
46*7f2fe78bSCy Schubert #include <ctype.h>
47*7f2fe78bSCy Schubert #ifdef HAVE_UNISTD_H
48*7f2fe78bSCy Schubert #include <unistd.h>
49*7f2fe78bSCy Schubert #endif
50*7f2fe78bSCy Schubert
51*7f2fe78bSCy Schubert #ifndef O_BINARY
52*7f2fe78bSCy Schubert #define O_BINARY 0
53*7f2fe78bSCy Schubert #endif
54*7f2fe78bSCy Schubert
55*7f2fe78bSCy Schubert #if !defined S_ISDIR
56*7f2fe78bSCy Schubert #if defined S_IFMT
57*7f2fe78bSCy Schubert #define S_ISDIR(MODE) (((MODE) & S_IFMT) == S_IFDIR)
58*7f2fe78bSCy Schubert #elif defined _S_IFMT
59*7f2fe78bSCy Schubert #define S_ISDIR(MODE) (((MODE) & _S_IFMT) == _S_IFDIR)
60*7f2fe78bSCy Schubert #else
61*7f2fe78bSCy Schubert /* Hope that there's a S_ISDIR function defined. */
62*7f2fe78bSCy Schubert #endif
63*7f2fe78bSCy Schubert #endif
64*7f2fe78bSCy Schubert
65*7f2fe78bSCy Schubert static int _gettemp(char *, int *);
66*7f2fe78bSCy Schubert
mkstemp(path)67*7f2fe78bSCy Schubert int mkstemp(path)
68*7f2fe78bSCy Schubert char *path;
69*7f2fe78bSCy Schubert {
70*7f2fe78bSCy Schubert int fd;
71*7f2fe78bSCy Schubert
72*7f2fe78bSCy Schubert return (_gettemp(path, &fd) ? fd : -1);
73*7f2fe78bSCy Schubert }
74*7f2fe78bSCy Schubert
75*7f2fe78bSCy Schubert static int
_gettemp(path,doopen)76*7f2fe78bSCy Schubert _gettemp(path, doopen)
77*7f2fe78bSCy Schubert char *path;
78*7f2fe78bSCy Schubert int *doopen;
79*7f2fe78bSCy Schubert {
80*7f2fe78bSCy Schubert char *start, *trv;
81*7f2fe78bSCy Schubert struct stat sbuf;
82*7f2fe78bSCy Schubert u_int pid;
83*7f2fe78bSCy Schubert
84*7f2fe78bSCy Schubert pid = getpid();
85*7f2fe78bSCy Schubert for (trv = path; *trv; ++trv); /* extra X's get set to 0's */
86*7f2fe78bSCy Schubert while (*--trv == 'X') {
87*7f2fe78bSCy Schubert *trv = (pid % 10) + '0';
88*7f2fe78bSCy Schubert pid /= 10;
89*7f2fe78bSCy Schubert }
90*7f2fe78bSCy Schubert
91*7f2fe78bSCy Schubert /*
92*7f2fe78bSCy Schubert * check the target directory; if you have six X's and it
93*7f2fe78bSCy Schubert * doesn't exist this runs for a *very* long time.
94*7f2fe78bSCy Schubert */
95*7f2fe78bSCy Schubert for (start = trv + 1;; --trv) {
96*7f2fe78bSCy Schubert if (trv <= path)
97*7f2fe78bSCy Schubert break;
98*7f2fe78bSCy Schubert if (*trv == '/') {
99*7f2fe78bSCy Schubert *trv = '\0';
100*7f2fe78bSCy Schubert if (stat(path, &sbuf))
101*7f2fe78bSCy Schubert return(0);
102*7f2fe78bSCy Schubert if (!S_ISDIR(sbuf.st_mode)) {
103*7f2fe78bSCy Schubert errno = ENOTDIR;
104*7f2fe78bSCy Schubert return(0);
105*7f2fe78bSCy Schubert }
106*7f2fe78bSCy Schubert *trv = '/';
107*7f2fe78bSCy Schubert break;
108*7f2fe78bSCy Schubert }
109*7f2fe78bSCy Schubert }
110*7f2fe78bSCy Schubert
111*7f2fe78bSCy Schubert for (;;) {
112*7f2fe78bSCy Schubert if (doopen) {
113*7f2fe78bSCy Schubert if ((*doopen =
114*7f2fe78bSCy Schubert open(path, O_CREAT|O_EXCL|O_RDWR|O_BINARY, 0600)) >= 0)
115*7f2fe78bSCy Schubert return(1);
116*7f2fe78bSCy Schubert if (errno != EEXIST)
117*7f2fe78bSCy Schubert return(0);
118*7f2fe78bSCy Schubert }
119*7f2fe78bSCy Schubert else if (stat(path, &sbuf))
120*7f2fe78bSCy Schubert return(errno == ENOENT ? 1 : 0);
121*7f2fe78bSCy Schubert
122*7f2fe78bSCy Schubert /* tricky little algorithm for backward compatibility */
123*7f2fe78bSCy Schubert for (trv = start;;) {
124*7f2fe78bSCy Schubert if (!*trv)
125*7f2fe78bSCy Schubert return(0);
126*7f2fe78bSCy Schubert if (*trv == 'z')
127*7f2fe78bSCy Schubert *trv++ = 'a';
128*7f2fe78bSCy Schubert else {
129*7f2fe78bSCy Schubert if (isdigit(*trv))
130*7f2fe78bSCy Schubert *trv = 'a';
131*7f2fe78bSCy Schubert else
132*7f2fe78bSCy Schubert ++*trv;
133*7f2fe78bSCy Schubert break;
134*7f2fe78bSCy Schubert }
135*7f2fe78bSCy Schubert }
136*7f2fe78bSCy Schubert }
137*7f2fe78bSCy Schubert /*NOTREACHED*/
138*7f2fe78bSCy Schubert }
139