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