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