183d2307dSDag-Erling Smørgrav /* THIS FILE HAS BEEN MODIFIED FROM THE ORIGINAL OPENBSD SOURCE */ 283d2307dSDag-Erling Smørgrav /* Changes: Removed mktemp */ 383d2307dSDag-Erling Smørgrav 4021d409fSDag-Erling Smørgrav /* $OpenBSD: mktemp.c,v 1.19 2005/08/08 08:05:36 espie Exp $ */ 583d2307dSDag-Erling Smørgrav /* 683d2307dSDag-Erling Smørgrav * Copyright (c) 1987, 1993 783d2307dSDag-Erling Smørgrav * The Regents of the University of California. All rights reserved. 883d2307dSDag-Erling Smørgrav * 983d2307dSDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 1083d2307dSDag-Erling Smørgrav * modification, are permitted provided that the following conditions 1183d2307dSDag-Erling Smørgrav * are met: 1283d2307dSDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 1383d2307dSDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer. 1483d2307dSDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 1583d2307dSDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 1683d2307dSDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 17d95e11bfSDag-Erling Smørgrav * 3. Neither the name of the University nor the names of its contributors 1883d2307dSDag-Erling Smørgrav * may be used to endorse or promote products derived from this software 1983d2307dSDag-Erling Smørgrav * without specific prior written permission. 2083d2307dSDag-Erling Smørgrav * 2183d2307dSDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2283d2307dSDag-Erling Smørgrav * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2383d2307dSDag-Erling Smørgrav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2483d2307dSDag-Erling Smørgrav * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2583d2307dSDag-Erling Smørgrav * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2683d2307dSDag-Erling Smørgrav * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2783d2307dSDag-Erling Smørgrav * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2883d2307dSDag-Erling Smørgrav * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2983d2307dSDag-Erling Smørgrav * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3083d2307dSDag-Erling Smørgrav * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3183d2307dSDag-Erling Smørgrav * SUCH DAMAGE. 3283d2307dSDag-Erling Smørgrav */ 3383d2307dSDag-Erling Smørgrav 34021d409fSDag-Erling Smørgrav /* OPENBSD ORIGINAL: lib/libc/stdio/mktemp.c */ 35021d409fSDag-Erling Smørgrav 3683d2307dSDag-Erling Smørgrav #include "includes.h" 3783d2307dSDag-Erling Smørgrav 38d0c8c0bcSDag-Erling Smørgrav #if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) 3983d2307dSDag-Erling Smørgrav 4083d2307dSDag-Erling Smørgrav static int _gettemp(char *, int *, int, int); 4183d2307dSDag-Erling Smørgrav 4283d2307dSDag-Erling Smørgrav int 43021d409fSDag-Erling Smørgrav mkstemps(char *path, int slen) 4483d2307dSDag-Erling Smørgrav { 4583d2307dSDag-Erling Smørgrav int fd; 4683d2307dSDag-Erling Smørgrav 4783d2307dSDag-Erling Smørgrav return (_gettemp(path, &fd, 0, slen) ? fd : -1); 4883d2307dSDag-Erling Smørgrav } 4983d2307dSDag-Erling Smørgrav 5083d2307dSDag-Erling Smørgrav int 51021d409fSDag-Erling Smørgrav mkstemp(char *path) 5283d2307dSDag-Erling Smørgrav { 5383d2307dSDag-Erling Smørgrav int fd; 5483d2307dSDag-Erling Smørgrav 5583d2307dSDag-Erling Smørgrav return (_gettemp(path, &fd, 0, 0) ? fd : -1); 5683d2307dSDag-Erling Smørgrav } 5783d2307dSDag-Erling Smørgrav 5883d2307dSDag-Erling Smørgrav char * 59021d409fSDag-Erling Smørgrav mkdtemp(char *path) 6083d2307dSDag-Erling Smørgrav { 6183d2307dSDag-Erling Smørgrav return(_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL); 6283d2307dSDag-Erling Smørgrav } 6383d2307dSDag-Erling Smørgrav 6483d2307dSDag-Erling Smørgrav static int 6583d2307dSDag-Erling Smørgrav _gettemp(path, doopen, domkdir, slen) 6683d2307dSDag-Erling Smørgrav char *path; 6783d2307dSDag-Erling Smørgrav register int *doopen; 6883d2307dSDag-Erling Smørgrav int domkdir; 6983d2307dSDag-Erling Smørgrav int slen; 7083d2307dSDag-Erling Smørgrav { 7183d2307dSDag-Erling Smørgrav register char *start, *trv, *suffp; 7283d2307dSDag-Erling Smørgrav struct stat sbuf; 7383d2307dSDag-Erling Smørgrav int rval; 7483d2307dSDag-Erling Smørgrav pid_t pid; 7583d2307dSDag-Erling Smørgrav 7683d2307dSDag-Erling Smørgrav if (doopen && domkdir) { 7783d2307dSDag-Erling Smørgrav errno = EINVAL; 7883d2307dSDag-Erling Smørgrav return(0); 7983d2307dSDag-Erling Smørgrav } 8083d2307dSDag-Erling Smørgrav 8183d2307dSDag-Erling Smørgrav for (trv = path; *trv; ++trv) 8283d2307dSDag-Erling Smørgrav ; 8383d2307dSDag-Erling Smørgrav trv -= slen; 8483d2307dSDag-Erling Smørgrav suffp = trv; 8583d2307dSDag-Erling Smørgrav --trv; 8683d2307dSDag-Erling Smørgrav if (trv < path) { 8783d2307dSDag-Erling Smørgrav errno = EINVAL; 8883d2307dSDag-Erling Smørgrav return (0); 8983d2307dSDag-Erling Smørgrav } 9083d2307dSDag-Erling Smørgrav pid = getpid(); 914b17dab0SDag-Erling Smørgrav while (trv >= path && *trv == 'X' && pid != 0) { 9283d2307dSDag-Erling Smørgrav *trv-- = (pid % 10) + '0'; 9383d2307dSDag-Erling Smørgrav pid /= 10; 9483d2307dSDag-Erling Smørgrav } 954b17dab0SDag-Erling Smørgrav while (trv >= path && *trv == 'X') { 9683d2307dSDag-Erling Smørgrav char c; 9783d2307dSDag-Erling Smørgrav 9883d2307dSDag-Erling Smørgrav pid = (arc4random() & 0xffff) % (26+26); 9983d2307dSDag-Erling Smørgrav if (pid < 26) 10083d2307dSDag-Erling Smørgrav c = pid + 'A'; 10183d2307dSDag-Erling Smørgrav else 10283d2307dSDag-Erling Smørgrav c = (pid - 26) + 'a'; 10383d2307dSDag-Erling Smørgrav *trv-- = c; 10483d2307dSDag-Erling Smørgrav } 10583d2307dSDag-Erling Smørgrav start = trv + 1; 10683d2307dSDag-Erling Smørgrav 10783d2307dSDag-Erling Smørgrav /* 10883d2307dSDag-Erling Smørgrav * check the target directory; if you have six X's and it 10983d2307dSDag-Erling Smørgrav * doesn't exist this runs for a *very* long time. 11083d2307dSDag-Erling Smørgrav */ 11183d2307dSDag-Erling Smørgrav if (doopen || domkdir) { 11283d2307dSDag-Erling Smørgrav for (;; --trv) { 11383d2307dSDag-Erling Smørgrav if (trv <= path) 11483d2307dSDag-Erling Smørgrav break; 11583d2307dSDag-Erling Smørgrav if (*trv == '/') { 11683d2307dSDag-Erling Smørgrav *trv = '\0'; 11783d2307dSDag-Erling Smørgrav rval = stat(path, &sbuf); 11883d2307dSDag-Erling Smørgrav *trv = '/'; 11983d2307dSDag-Erling Smørgrav if (rval != 0) 12083d2307dSDag-Erling Smørgrav return(0); 12183d2307dSDag-Erling Smørgrav if (!S_ISDIR(sbuf.st_mode)) { 12283d2307dSDag-Erling Smørgrav errno = ENOTDIR; 12383d2307dSDag-Erling Smørgrav return(0); 12483d2307dSDag-Erling Smørgrav } 12583d2307dSDag-Erling Smørgrav break; 12683d2307dSDag-Erling Smørgrav } 12783d2307dSDag-Erling Smørgrav } 12883d2307dSDag-Erling Smørgrav } 12983d2307dSDag-Erling Smørgrav 13083d2307dSDag-Erling Smørgrav for (;;) { 13183d2307dSDag-Erling Smørgrav if (doopen) { 13283d2307dSDag-Erling Smørgrav if ((*doopen = 13383d2307dSDag-Erling Smørgrav open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) 13483d2307dSDag-Erling Smørgrav return(1); 13583d2307dSDag-Erling Smørgrav if (errno != EEXIST) 13683d2307dSDag-Erling Smørgrav return(0); 13783d2307dSDag-Erling Smørgrav } else if (domkdir) { 13883d2307dSDag-Erling Smørgrav if (mkdir(path, 0700) == 0) 13983d2307dSDag-Erling Smørgrav return(1); 14083d2307dSDag-Erling Smørgrav if (errno != EEXIST) 14183d2307dSDag-Erling Smørgrav return(0); 14283d2307dSDag-Erling Smørgrav } else if (lstat(path, &sbuf)) 14383d2307dSDag-Erling Smørgrav return(errno == ENOENT ? 1 : 0); 14483d2307dSDag-Erling Smørgrav 14583d2307dSDag-Erling Smørgrav /* tricky little algorithm for backward compatibility */ 14683d2307dSDag-Erling Smørgrav for (trv = start;;) { 14783d2307dSDag-Erling Smørgrav if (!*trv) 14883d2307dSDag-Erling Smørgrav return (0); 14983d2307dSDag-Erling Smørgrav if (*trv == 'Z') { 15083d2307dSDag-Erling Smørgrav if (trv == suffp) 15183d2307dSDag-Erling Smørgrav return (0); 15283d2307dSDag-Erling Smørgrav *trv++ = 'a'; 15383d2307dSDag-Erling Smørgrav } else { 15483d2307dSDag-Erling Smørgrav if (isdigit(*trv)) 15583d2307dSDag-Erling Smørgrav *trv = 'a'; 15683d2307dSDag-Erling Smørgrav else if (*trv == 'z') /* inc from z to A */ 15783d2307dSDag-Erling Smørgrav *trv = 'A'; 15883d2307dSDag-Erling Smørgrav else { 15983d2307dSDag-Erling Smørgrav if (trv == suffp) 16083d2307dSDag-Erling Smørgrav return (0); 16183d2307dSDag-Erling Smørgrav ++*trv; 16283d2307dSDag-Erling Smørgrav } 16383d2307dSDag-Erling Smørgrav break; 16483d2307dSDag-Erling Smørgrav } 16583d2307dSDag-Erling Smørgrav } 16683d2307dSDag-Erling Smørgrav } 16783d2307dSDag-Erling Smørgrav /*NOTREACHED*/ 16883d2307dSDag-Erling Smørgrav } 16983d2307dSDag-Erling Smørgrav 170d0c8c0bcSDag-Erling Smørgrav #endif /* !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) */ 171