xref: /csrg-svn/lib/libc/stdio/mktemp.c (revision 30888)
1*30888Sbostic /*
2*30888Sbostic  * Copyright (c) 1987 Regents of the University of California.
3*30888Sbostic  * All rights reserved.  The Berkeley software License Agreement
4*30888Sbostic  * specifies the terms and conditions for redistribution.
5*30888Sbostic  */
6*30888Sbostic 
726570Sdonn #if defined(LIBC_SCCS) && !defined(lint)
8*30888Sbostic static char sccsid[] = "@(#)mktemp.c	5.3 (Berkeley) 04/10/87";
926570Sdonn #endif LIBC_SCCS and not lint
1013260Sroot 
11*30888Sbostic #include <sys/types.h>
12*30888Sbostic #include <sys/file.h>
13*30888Sbostic #include <stdio.h>
14*30888Sbostic #include <ctype.h>
15*30888Sbostic 
16*30888Sbostic #define	YES	1
17*30888Sbostic #define	NO	0
18*30888Sbostic 
19*30888Sbostic mkstemp(as)
20*30888Sbostic 	char	*as;
21*30888Sbostic {
22*30888Sbostic 	int	fd;
23*30888Sbostic 
24*30888Sbostic 	return (_gettemp(as, &fd) ? fd : -1);
25*30888Sbostic }
26*30888Sbostic 
2713260Sroot char *
2813260Sroot mktemp(as)
29*30888Sbostic 	char	*as;
3013260Sroot {
31*30888Sbostic 	return(_gettemp(as, (int *)NULL) ? as : (char *)NULL);
32*30888Sbostic }
3313260Sroot 
34*30888Sbostic static
35*30888Sbostic _gettemp(as, doopen)
36*30888Sbostic 	char	*as;
37*30888Sbostic 	register int	*doopen;
38*30888Sbostic {
39*30888Sbostic 	register char	*start, *trv;
40*30888Sbostic 	u_int	pid;
41*30888Sbostic 	char	savech;
42*30888Sbostic 
4313260Sroot 	pid = getpid();
44*30888Sbostic 
45*30888Sbostic 	/* extra X's get set to 0's */
46*30888Sbostic 	for (trv = as;*trv;++trv);
47*30888Sbostic 	while (*--trv == 'X') {
48*30888Sbostic 		*trv = (pid % 10) + '0';
4913260Sroot 		pid /= 10;
5013260Sroot 	}
51*30888Sbostic 
52*30888Sbostic 	/*
53*30888Sbostic 	 * check for write permission on target directory; if you have
54*30888Sbostic 	 * six X's and you can't write the directory, this will run for
55*30888Sbostic 	 * a *very* long time.
56*30888Sbostic 	 */
57*30888Sbostic 	for (start = ++trv;trv > as && *trv != '/';--trv);
58*30888Sbostic 	if (*trv == '/') {
59*30888Sbostic 		savech = *++trv;
60*30888Sbostic 		*trv = '\0';
61*30888Sbostic 		if (access(as, W_OK))
62*30888Sbostic 			return(NO);
63*30888Sbostic 		*trv = savech;
6413260Sroot 	}
65*30888Sbostic 	else if (access(".", W_OK))
66*30888Sbostic 		return(NO);
67*30888Sbostic 
68*30888Sbostic 	for (;;) {
69*30888Sbostic 		if (doopen
70*30888Sbostic 		    && (*doopen = open(as, O_CREAT|O_EXCL|O_RDWR, 0600)) != -1
71*30888Sbostic 		    || access(as, F_OK))
72*30888Sbostic 			return(YES);
73*30888Sbostic 		/* tricky little algorithm for backward compatibility */
74*30888Sbostic 		for (trv = start;;) {
75*30888Sbostic 			if (!*trv)
76*30888Sbostic 				return(NO);
77*30888Sbostic 			if (*trv == 'z')
78*30888Sbostic 				*trv++ = 'a';
79*30888Sbostic 			else {
80*30888Sbostic 				if (isdigit(*trv))
81*30888Sbostic 					*trv = 'a';
82*30888Sbostic 				else
83*30888Sbostic 					++*trv;
84*30888Sbostic 				break;
85*30888Sbostic 			}
86*30888Sbostic 		}
87*30888Sbostic 	}
88*30888Sbostic 	/*NOTREACHED*/
8913260Sroot }
90