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