Annotation of embedaddon/sudo/compat/mktemp.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (c) 2001, 2003, 2004, 2008-2011
! 3: * Todd C. Miller <Todd.Miller@courtesan.com>
! 4: *
! 5: * Permission to use, copy, modify, and distribute this software for any
! 6: * purpose with or without fee is hereby granted, provided that the above
! 7: * copyright notice and this permission notice appear in all copies.
! 8: *
! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
! 15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 16: */
! 17:
! 18: #include <config.h>
! 19:
! 20: #include <sys/types.h>
! 21: #include <sys/time.h>
! 22: #include <sys/stat.h>
! 23:
! 24: #include <errno.h>
! 25: #include <fcntl.h>
! 26: #include <limits.h>
! 27: #include <stdio.h>
! 28: #ifdef HAVE_STDLIB_H
! 29: # include <stdlib.h>
! 30: #endif /* HAVE_STDLIB_H */
! 31: #include <ctype.h>
! 32: #ifdef HAVE_UNISTD_H
! 33: # include <unistd.h>
! 34: #endif /* HAVE_UNISTD_H */
! 35: #if TIME_WITH_SYS_TIME
! 36: # include <time.h>
! 37: #endif
! 38:
! 39: #include "missing.h"
! 40:
! 41: #define MKTEMP_FILE 1
! 42: #define MKTEMP_DIR 2
! 43:
! 44: #define TEMPCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
! 45: #define NUM_CHARS (sizeof(TEMPCHARS) - 1)
! 46:
! 47: #ifndef INT_MAX
! 48: #define INT_MAX 0x7fffffff
! 49: #endif
! 50:
! 51: #ifdef HAVE_RANDOM
! 52: # define RAND random
! 53: # define SRAND srandom
! 54: # define SEED_T unsigned int
! 55: #else
! 56: # ifdef HAVE_LRAND48
! 57: # define RAND lrand48
! 58: # define SRAND srand48
! 59: # define SEED_T long
! 60: # else
! 61: # define RAND rand
! 62: # define SRAND srand
! 63: # define SEED_T unsigned int
! 64: # endif
! 65: #endif
! 66:
! 67: static void
! 68: seed_random(void)
! 69: {
! 70: SEED_T seed;
! 71: struct timeval tv;
! 72:
! 73: /*
! 74: * Seed from time of day and process id multiplied by small primes.
! 75: */
! 76: (void) gettimeofday(&tv, NULL);
! 77: seed = (tv.tv_sec % 10000) * 523 + tv.tv_usec * 13 +
! 78: (getpid() % 1000) * 983;
! 79: SRAND(seed);
! 80: }
! 81:
! 82: static unsigned int
! 83: get_random(void)
! 84: {
! 85: static int initialized;
! 86:
! 87: if (!initialized) {
! 88: seed_random();
! 89: initialized = 1;
! 90: }
! 91:
! 92: return RAND() & 0xffffffff;
! 93: }
! 94:
! 95: static int
! 96: mktemp_internal(char *path, int slen, int mode)
! 97: {
! 98: char *start, *cp, *ep;
! 99: const char *tempchars = TEMPCHARS;
! 100: unsigned int r, tries;
! 101: int fd;
! 102:
! 103: for (ep = path; *ep; ep++)
! 104: ;
! 105: if (path + slen >= ep) {
! 106: errno = EINVAL;
! 107: return -1;
! 108: }
! 109: ep -= slen;
! 110:
! 111: tries = 1;
! 112: for (start = ep; start > path && start[-1] == 'X'; start--) {
! 113: if (tries < INT_MAX / NUM_CHARS)
! 114: tries *= NUM_CHARS;
! 115: }
! 116: tries *= 2;
! 117:
! 118: do {
! 119: for (cp = start; *cp; cp++) {
! 120: r = get_random() % NUM_CHARS;
! 121: *cp = tempchars[r];
! 122: }
! 123:
! 124: switch (mode) {
! 125: case MKTEMP_FILE:
! 126: fd = open(path, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
! 127: if (fd != -1 || errno != EEXIST)
! 128: return fd;
! 129: break;
! 130: case MKTEMP_DIR:
! 131: if (mkdir(path, S_IRWXU) == 0)
! 132: return 0;
! 133: if (errno != EEXIST)
! 134: return -1;
! 135: break;
! 136: }
! 137: } while (--tries);
! 138:
! 139: errno = EEXIST;
! 140: return -1;
! 141: }
! 142:
! 143: #ifndef HAVE_MKSTEMPS
! 144: int
! 145: mkstemps(char *path, int slen)
! 146: {
! 147: return mktemp_internal(path, slen, MKTEMP_FILE);
! 148: }
! 149: #endif /* HAVE_MKSTEMPS */
! 150:
! 151: #ifndef HAVE_MKDTEMP
! 152: char *
! 153: mkdtemp(char *path)
! 154: {
! 155: if (mktemp_internal(path, 0, MKTEMP_DIR) == -1)
! 156: return NULL;
! 157: return path;
! 158: }
! 159: #endif /* HAVE_MKDTEMP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>