|
|
1.1 root 1: /*
2: * Copyright (c) 1987 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #if defined(LIBC_SCCS) && !defined(lint)
21: static char sccsid[] = "@(#)mktemp.c 5.9 (Berkeley) 6/1/90";
22: #endif /* LIBC_SCCS and not lint */
23:
24: #include <sys/types.h>
25: #include <sys/file.h>
26: #include <sys/stat.h>
27: #include <errno.h>
28: #include <stdio.h>
29: #include <ctype.h>
30:
31: mkstemp(path)
32: char *path;
33: {
34: int fd;
35:
36: return (_gettemp(path, &fd) ? fd : -1);
37: }
38:
39: char *
40: mktemp(path)
41: char *path;
42: {
43: return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
44: }
45:
46: static
47: _gettemp(path, doopen)
48: char *path;
49: register int *doopen;
50: {
51: extern int errno;
52: register char *start, *trv;
53: struct stat sbuf;
54: u_int pid;
55:
56: pid = getpid();
57: for (trv = path; *trv; ++trv); /* extra X's get set to 0's */
58: while (*--trv == 'X') {
59: *trv = (pid % 10) + '0';
60: pid /= 10;
61: }
62:
63: /*
64: * check the target directory; if you have six X's and it
65: * doesn't exist this runs for a *very* long time.
66: */
67: for (start = trv + 1;; --trv) {
68: if (trv <= path)
69: break;
70: if (*trv == '/') {
71: *trv = '\0';
72: if (stat(path, &sbuf))
73: return(0);
74: if (!S_ISDIR(sbuf.st_mode)) {
75: errno = ENOTDIR;
76: return(0);
77: }
78: *trv = '/';
79: break;
80: }
81: }
82:
83: for (;;) {
84: if (doopen) {
85: if ((*doopen =
86: open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
87: return(1);
88: if (errno != EEXIST)
89: return(0);
90: }
91: else if (stat(path, &sbuf))
92: return(errno == ENOENT ? 1 : 0);
93:
94: /* tricky little algorithm for backward compatibility */
95: for (trv = start;;) {
96: if (!*trv)
97: return(0);
98: if (*trv == 'z')
99: *trv++ = 'a';
100: else {
101: if (isdigit(*trv))
102: *trv = 'a';
103: else
104: ++*trv;
105: break;
106: }
107: }
108: }
109: /*NOTREACHED*/
110: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.