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