1bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* THIS FILE HAS BEEN MODIFIED FROM THE ORIGINAL OPENBSD SOURCE */ 2bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* Changes: Removed mktemp */ 3bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 4d059297112922cabb0c674840589be8db821fd9aAdam Langley/* $OpenBSD: mktemp.c,v 1.30 2010/03/21 23:09:30 schwarze Exp $ */ 5bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 6d059297112922cabb0c674840589be8db821fd9aAdam Langley * Copyright (c) 1996-1998, 2008 Theo de Raadt 7d059297112922cabb0c674840589be8db821fd9aAdam Langley * Copyright (c) 1997, 2008-2009 Todd C. Miller 8bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 9d059297112922cabb0c674840589be8db821fd9aAdam Langley * Permission to use, copy, modify, and distribute this software for any 10d059297112922cabb0c674840589be8db821fd9aAdam Langley * purpose with or without fee is hereby granted, provided that the above 11d059297112922cabb0c674840589be8db821fd9aAdam Langley * copyright notice and this permission notice appear in all copies. 12bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 13d059297112922cabb0c674840589be8db821fd9aAdam Langley * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14d059297112922cabb0c674840589be8db821fd9aAdam Langley * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15d059297112922cabb0c674840589be8db821fd9aAdam Langley * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16d059297112922cabb0c674840589be8db821fd9aAdam Langley * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17d059297112922cabb0c674840589be8db821fd9aAdam Langley * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18d059297112922cabb0c674840589be8db821fd9aAdam Langley * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19d059297112922cabb0c674840589be8db821fd9aAdam Langley * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 21bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 22bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* OPENBSD ORIGINAL: lib/libc/stdio/mktemp.c */ 23bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 24bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "includes.h" 25bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 26bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/types.h> 27bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/stat.h> 28d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <errno.h> 29bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <fcntl.h> 30d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <limits.h> 31d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <stdio.h> 32d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <stdlib.h> 33d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <string.h> 34bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <ctype.h> 35bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <unistd.h> 36bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 37bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) 38bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 39d059297112922cabb0c674840589be8db821fd9aAdam Langley#define MKTEMP_NAME 0 40d059297112922cabb0c674840589be8db821fd9aAdam Langley#define MKTEMP_FILE 1 41d059297112922cabb0c674840589be8db821fd9aAdam Langley#define MKTEMP_DIR 2 42bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 43d059297112922cabb0c674840589be8db821fd9aAdam Langley#define TEMPCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" 44d059297112922cabb0c674840589be8db821fd9aAdam Langley#define NUM_CHARS (sizeof(TEMPCHARS) - 1) 45d059297112922cabb0c674840589be8db821fd9aAdam Langley 46d059297112922cabb0c674840589be8db821fd9aAdam Langleystatic int 47d059297112922cabb0c674840589be8db821fd9aAdam Langleymktemp_internal(char *path, int slen, int mode) 48bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 49d059297112922cabb0c674840589be8db821fd9aAdam Langley char *start, *cp, *ep; 50d059297112922cabb0c674840589be8db821fd9aAdam Langley const char *tempchars = TEMPCHARS; 51d059297112922cabb0c674840589be8db821fd9aAdam Langley unsigned int r, tries; 52d059297112922cabb0c674840589be8db821fd9aAdam Langley struct stat sb; 53d059297112922cabb0c674840589be8db821fd9aAdam Langley size_t len; 54bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int fd; 55bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 56d059297112922cabb0c674840589be8db821fd9aAdam Langley len = strlen(path); 57d059297112922cabb0c674840589be8db821fd9aAdam Langley if (len == 0 || slen < 0 || (size_t)slen >= len) { 58d059297112922cabb0c674840589be8db821fd9aAdam Langley errno = EINVAL; 59d059297112922cabb0c674840589be8db821fd9aAdam Langley return(-1); 60d059297112922cabb0c674840589be8db821fd9aAdam Langley } 61d059297112922cabb0c674840589be8db821fd9aAdam Langley ep = path + len - slen; 62d059297112922cabb0c674840589be8db821fd9aAdam Langley 63d059297112922cabb0c674840589be8db821fd9aAdam Langley tries = 1; 64d059297112922cabb0c674840589be8db821fd9aAdam Langley for (start = ep; start > path && start[-1] == 'X'; start--) { 65d059297112922cabb0c674840589be8db821fd9aAdam Langley if (tries < INT_MAX / NUM_CHARS) 66d059297112922cabb0c674840589be8db821fd9aAdam Langley tries *= NUM_CHARS; 67d059297112922cabb0c674840589be8db821fd9aAdam Langley } 68d059297112922cabb0c674840589be8db821fd9aAdam Langley tries *= 2; 69d059297112922cabb0c674840589be8db821fd9aAdam Langley 70d059297112922cabb0c674840589be8db821fd9aAdam Langley do { 71d059297112922cabb0c674840589be8db821fd9aAdam Langley for (cp = start; cp != ep; cp++) { 72d059297112922cabb0c674840589be8db821fd9aAdam Langley r = arc4random_uniform(NUM_CHARS); 73d059297112922cabb0c674840589be8db821fd9aAdam Langley *cp = tempchars[r]; 74d059297112922cabb0c674840589be8db821fd9aAdam Langley } 75d059297112922cabb0c674840589be8db821fd9aAdam Langley 76d059297112922cabb0c674840589be8db821fd9aAdam Langley switch (mode) { 77d059297112922cabb0c674840589be8db821fd9aAdam Langley case MKTEMP_NAME: 78d059297112922cabb0c674840589be8db821fd9aAdam Langley if (lstat(path, &sb) != 0) 79d059297112922cabb0c674840589be8db821fd9aAdam Langley return(errno == ENOENT ? 0 : -1); 80d059297112922cabb0c674840589be8db821fd9aAdam Langley break; 81d059297112922cabb0c674840589be8db821fd9aAdam Langley case MKTEMP_FILE: 82d059297112922cabb0c674840589be8db821fd9aAdam Langley fd = open(path, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR); 83d059297112922cabb0c674840589be8db821fd9aAdam Langley if (fd != -1 || errno != EEXIST) 84d059297112922cabb0c674840589be8db821fd9aAdam Langley return(fd); 85d059297112922cabb0c674840589be8db821fd9aAdam Langley break; 86d059297112922cabb0c674840589be8db821fd9aAdam Langley case MKTEMP_DIR: 87d059297112922cabb0c674840589be8db821fd9aAdam Langley if (mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR) == 0) 88d059297112922cabb0c674840589be8db821fd9aAdam Langley return(0); 89d059297112922cabb0c674840589be8db821fd9aAdam Langley if (errno != EEXIST) 90d059297112922cabb0c674840589be8db821fd9aAdam Langley return(-1); 91d059297112922cabb0c674840589be8db821fd9aAdam Langley break; 92d059297112922cabb0c674840589be8db821fd9aAdam Langley } 93d059297112922cabb0c674840589be8db821fd9aAdam Langley } while (--tries); 94d059297112922cabb0c674840589be8db821fd9aAdam Langley 95d059297112922cabb0c674840589be8db821fd9aAdam Langley errno = EEXIST; 96d059297112922cabb0c674840589be8db821fd9aAdam Langley return(-1); 97bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 98bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 99d059297112922cabb0c674840589be8db821fd9aAdam Langley#if 0 100d059297112922cabb0c674840589be8db821fd9aAdam Langleychar *_mktemp(char *); 101bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 102d059297112922cabb0c674840589be8db821fd9aAdam Langleychar * 103d059297112922cabb0c674840589be8db821fd9aAdam Langley_mktemp(char *path) 104d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 105d059297112922cabb0c674840589be8db821fd9aAdam Langley if (mktemp_internal(path, 0, MKTEMP_NAME) == -1) 106d059297112922cabb0c674840589be8db821fd9aAdam Langley return(NULL); 107d059297112922cabb0c674840589be8db821fd9aAdam Langley return(path); 108bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 109bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 110d059297112922cabb0c674840589be8db821fd9aAdam Langley__warn_references(mktemp, 111d059297112922cabb0c674840589be8db821fd9aAdam Langley "warning: mktemp() possibly used unsafely; consider using mkstemp()"); 112d059297112922cabb0c674840589be8db821fd9aAdam Langley 113bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanchar * 114d059297112922cabb0c674840589be8db821fd9aAdam Langleymktemp(char *path) 115bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 116d059297112922cabb0c674840589be8db821fd9aAdam Langley return(_mktemp(path)); 117bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 118d059297112922cabb0c674840589be8db821fd9aAdam Langley#endif 119bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 120d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 121d059297112922cabb0c674840589be8db821fd9aAdam Langleymkstemp(char *path) 122bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 123d059297112922cabb0c674840589be8db821fd9aAdam Langley return(mktemp_internal(path, 0, MKTEMP_FILE)); 124d059297112922cabb0c674840589be8db821fd9aAdam Langley} 125bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 126d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 127d059297112922cabb0c674840589be8db821fd9aAdam Langleymkstemps(char *path, int slen) 128d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 129d059297112922cabb0c674840589be8db821fd9aAdam Langley return(mktemp_internal(path, slen, MKTEMP_FILE)); 130d059297112922cabb0c674840589be8db821fd9aAdam Langley} 131bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 132d059297112922cabb0c674840589be8db821fd9aAdam Langleychar * 133d059297112922cabb0c674840589be8db821fd9aAdam Langleymkdtemp(char *path) 134d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 135d059297112922cabb0c674840589be8db821fd9aAdam Langley int error; 136bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 137d059297112922cabb0c674840589be8db821fd9aAdam Langley error = mktemp_internal(path, 0, MKTEMP_DIR); 138d059297112922cabb0c674840589be8db821fd9aAdam Langley return(error ? NULL : path); 139bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 140bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 141bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) */ 142