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 7 #if defined(LIBC_SCCS) && !defined(lint) 8 static char sccsid[] = "@(#)mktemp.c 5.3 (Berkeley) 04/10/87"; 9 #endif LIBC_SCCS and not lint 10 11 #include <sys/types.h> 12 #include <sys/file.h> 13 #include <stdio.h> 14 #include <ctype.h> 15 16 #define YES 1 17 #define NO 0 18 19 mkstemp(as) 20 char *as; 21 { 22 int fd; 23 24 return (_gettemp(as, &fd) ? fd : -1); 25 } 26 27 char * 28 mktemp(as) 29 char *as; 30 { 31 return(_gettemp(as, (int *)NULL) ? as : (char *)NULL); 32 } 33 34 static 35 _gettemp(as, doopen) 36 char *as; 37 register int *doopen; 38 { 39 register char *start, *trv; 40 u_int pid; 41 char savech; 42 43 pid = getpid(); 44 45 /* extra X's get set to 0's */ 46 for (trv = as;*trv;++trv); 47 while (*--trv == 'X') { 48 *trv = (pid % 10) + '0'; 49 pid /= 10; 50 } 51 52 /* 53 * check for write permission on target directory; if you have 54 * six X's and you can't write the directory, this will run for 55 * a *very* long time. 56 */ 57 for (start = ++trv;trv > as && *trv != '/';--trv); 58 if (*trv == '/') { 59 savech = *++trv; 60 *trv = '\0'; 61 if (access(as, W_OK)) 62 return(NO); 63 *trv = savech; 64 } 65 else if (access(".", W_OK)) 66 return(NO); 67 68 for (;;) { 69 if (doopen 70 && (*doopen = open(as, O_CREAT|O_EXCL|O_RDWR, 0600)) != -1 71 || access(as, F_OK)) 72 return(YES); 73 /* tricky little algorithm for backward compatibility */ 74 for (trv = start;;) { 75 if (!*trv) 76 return(NO); 77 if (*trv == 'z') 78 *trv++ = 'a'; 79 else { 80 if (isdigit(*trv)) 81 *trv = 'a'; 82 else 83 ++*trv; 84 break; 85 } 86 } 87 } 88 /*NOTREACHED*/ 89 } 90