Commit | Line | Data |
---|---|---|
637a4c81 KB |
1 | /* |
2 | * Copyright (c) 1987 Regents of the University of California. | |
775fdbc2 KB |
3 | * All rights reserved. |
4 | * | |
269a7923 | 5 | * %sccs.include.redist.c% |
637a4c81 KB |
6 | */ |
7 | ||
2ce81398 | 8 | #if defined(LIBC_SCCS) && !defined(lint) |
e1243b93 | 9 | static char sccsid[] = "@(#)mktemp.c 5.11 (Berkeley) %G%"; |
f80aa9c4 | 10 | #endif /* LIBC_SCCS and not lint */ |
55221028 | 11 | |
637a4c81 | 12 | #include <sys/types.h> |
1a452c7d | 13 | #include <sys/stat.h> |
cb631443 | 14 | #include <fcntl.h> |
1a452c7d | 15 | #include <errno.h> |
637a4c81 | 16 | #include <stdio.h> |
e1243b93 | 17 | #include <ctype.h> |
cb631443 KB |
18 | |
19 | static int _gettemp(); | |
637a4c81 | 20 | |
3c501997 KB |
21 | mkstemp(path) |
22 | char *path; | |
637a4c81 | 23 | { |
3c501997 | 24 | int fd; |
637a4c81 | 25 | |
3c501997 | 26 | return (_gettemp(path, &fd) ? fd : -1); |
637a4c81 KB |
27 | } |
28 | ||
55221028 | 29 | char * |
3c501997 KB |
30 | mktemp(path) |
31 | char *path; | |
55221028 | 32 | { |
3c501997 | 33 | return(_gettemp(path, (int *)NULL) ? path : (char *)NULL); |
637a4c81 KB |
34 | } |
35 | ||
36 | static | |
3c501997 KB |
37 | _gettemp(path, doopen) |
38 | char *path; | |
39 | register int *doopen; | |
637a4c81 | 40 | { |
3c501997 KB |
41 | extern int errno; |
42 | register char *start, *trv; | |
43 | struct stat sbuf; | |
44 | u_int pid; | |
55221028 BJ |
45 | |
46 | pid = getpid(); | |
3c501997 | 47 | for (trv = path; *trv; ++trv); /* extra X's get set to 0's */ |
637a4c81 KB |
48 | while (*--trv == 'X') { |
49 | *trv = (pid % 10) + '0'; | |
55221028 BJ |
50 | pid /= 10; |
51 | } | |
637a4c81 KB |
52 | |
53 | /* | |
3c501997 KB |
54 | * check the target directory; if you have six X's and it |
55 | * doesn't exist this runs for a *very* long time. | |
637a4c81 | 56 | */ |
3c501997 KB |
57 | for (start = trv + 1;; --trv) { |
58 | if (trv <= path) | |
59 | break; | |
60 | if (*trv == '/') { | |
61 | *trv = '\0'; | |
62 | if (stat(path, &sbuf)) | |
63 | return(0); | |
64 | if (!S_ISDIR(sbuf.st_mode)) { | |
65 | errno = ENOTDIR; | |
66 | return(0); | |
67 | } | |
68 | *trv = '/'; | |
69 | break; | |
70 | } | |
637a4c81 | 71 | } |
637a4c81 KB |
72 | |
73 | for (;;) { | |
1a452c7d | 74 | if (doopen) { |
3c501997 KB |
75 | if ((*doopen = |
76 | open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) | |
77 | return(1); | |
78 | if (errno != EEXIST) | |
79 | return(0); | |
1a452c7d | 80 | } |
3c501997 KB |
81 | else if (stat(path, &sbuf)) |
82 | return(errno == ENOENT ? 1 : 0); | |
1a452c7d | 83 | |
637a4c81 KB |
84 | /* tricky little algorithm for backward compatibility */ |
85 | for (trv = start;;) { | |
86 | if (!*trv) | |
3c501997 | 87 | return(0); |
637a4c81 KB |
88 | if (*trv == 'z') |
89 | *trv++ = 'a'; | |
90 | else { | |
91 | if (isdigit(*trv)) | |
92 | *trv = 'a'; | |
93 | else | |
94 | ++*trv; | |
95 | break; | |
96 | } | |
97 | } | |
55221028 | 98 | } |
637a4c81 | 99 | /*NOTREACHED*/ |
55221028 | 100 | } |