130888Sbostic /* 230888Sbostic * Copyright (c) 1987 Regents of the University of California. 332701Sbostic * All rights reserved. 432701Sbostic * 5*42625Sbostic * %sccs.include.redist.c% 630888Sbostic */ 730888Sbostic 826570Sdonn #if defined(LIBC_SCCS) && !defined(lint) 9*42625Sbostic static char sccsid[] = "@(#)mktemp.c 5.9 (Berkeley) 06/01/90"; 1034436Sbostic #endif /* LIBC_SCCS and not lint */ 1113260Sroot 1230888Sbostic #include <sys/types.h> 1330888Sbostic #include <sys/file.h> 1432155Sbostic #include <sys/stat.h> 1532155Sbostic #include <errno.h> 1630888Sbostic #include <stdio.h> 1730888Sbostic #include <ctype.h> 1830888Sbostic 1939307Sbostic mkstemp(path) 2039307Sbostic char *path; 2130888Sbostic { 2239307Sbostic int fd; 2330888Sbostic 2439307Sbostic return (_gettemp(path, &fd) ? fd : -1); 2530888Sbostic } 2630888Sbostic 2713260Sroot char * 2839307Sbostic mktemp(path) 2939307Sbostic char *path; 3013260Sroot { 3139307Sbostic return(_gettemp(path, (int *)NULL) ? path : (char *)NULL); 3230888Sbostic } 3313260Sroot 3430888Sbostic static 3539307Sbostic _gettemp(path, doopen) 3639307Sbostic char *path; 3739307Sbostic register int *doopen; 3830888Sbostic { 3939307Sbostic extern int errno; 4039307Sbostic register char *start, *trv; 4139307Sbostic struct stat sbuf; 4239307Sbostic u_int pid; 4330888Sbostic 4413260Sroot pid = getpid(); 4539307Sbostic for (trv = path; *trv; ++trv); /* extra X's get set to 0's */ 4630888Sbostic while (*--trv == 'X') { 4730888Sbostic *trv = (pid % 10) + '0'; 4813260Sroot pid /= 10; 4913260Sroot } 5030888Sbostic 5130888Sbostic /* 5239307Sbostic * check the target directory; if you have six X's and it 5339307Sbostic * doesn't exist this runs for a *very* long time. 5430888Sbostic */ 5539307Sbostic for (start = trv + 1;; --trv) { 5639307Sbostic if (trv <= path) 5739307Sbostic break; 5839307Sbostic if (*trv == '/') { 5939307Sbostic *trv = '\0'; 6039307Sbostic if (stat(path, &sbuf)) 6139307Sbostic return(0); 6239307Sbostic if (!S_ISDIR(sbuf.st_mode)) { 6339307Sbostic errno = ENOTDIR; 6439307Sbostic return(0); 6539307Sbostic } 6639307Sbostic *trv = '/'; 6739307Sbostic break; 6839307Sbostic } 6913260Sroot } 7030888Sbostic 7130888Sbostic for (;;) { 7232155Sbostic if (doopen) { 7339307Sbostic if ((*doopen = 7439307Sbostic open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) 7539307Sbostic return(1); 7639307Sbostic if (errno != EEXIST) 7739307Sbostic return(0); 7832155Sbostic } 7939307Sbostic else if (stat(path, &sbuf)) 8039307Sbostic return(errno == ENOENT ? 1 : 0); 8132155Sbostic 8230888Sbostic /* tricky little algorithm for backward compatibility */ 8330888Sbostic for (trv = start;;) { 8430888Sbostic if (!*trv) 8539307Sbostic return(0); 8630888Sbostic if (*trv == 'z') 8730888Sbostic *trv++ = 'a'; 8830888Sbostic else { 8930888Sbostic if (isdigit(*trv)) 9030888Sbostic *trv = 'a'; 9130888Sbostic else 9230888Sbostic ++*trv; 9330888Sbostic break; 9430888Sbostic } 9530888Sbostic } 9630888Sbostic } 9730888Sbostic /*NOTREACHED*/ 9813260Sroot } 99