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