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