1 1.12 christos /* $NetBSD: mktemp.c,v 1.12 2012/11/03 13:34:08 christos Exp $ */ 2 1.2 cgd 3 1.1 tron /*- 4 1.1 tron * Copyright (c) 1994, 1995, 1996, 1998 Peter Wemm <peter (at) netplex.com.au> 5 1.1 tron * All rights reserved. 6 1.1 tron * 7 1.1 tron * Redistribution and use in source and binary forms, with or without 8 1.1 tron * modification, are permitted provided that the following conditions 9 1.1 tron * are met: 10 1.1 tron * 1. Redistributions of source code must retain the above copyright 11 1.1 tron * notice, this list of conditions and the following disclaimer. 12 1.1 tron * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 tron * notice, this list of conditions and the following disclaimer in the 14 1.1 tron * documentation and/or other materials provided with the distribution. 15 1.1 tron * 16 1.1 tron * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 1.1 tron * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 1.1 tron * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 1.1 tron * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 1.1 tron * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 1.1 tron * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 1.1 tron * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 1.1 tron * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 1.1 tron * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 1.1 tron * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 1.1 tron * SUCH DAMAGE. 27 1.1 tron * 28 1.1 tron */ 29 1.1 tron 30 1.1 tron /* 31 1.1 tron * This program was originally written long ago, originally for a non 32 1.1 tron * BSD-like OS without mkstemp(). It's been modified over the years 33 1.1 tron * to use mkstemp() rather than the original O_CREAT|O_EXCL/fstat/lstat 34 1.1 tron * etc style hacks. 35 1.1 tron * A cleanup, misc options and mkdtemp() calls were added to try and work 36 1.1 tron * more like the OpenBSD version - which was first to publish the interface. 37 1.1 tron */ 38 1.1 tron 39 1.6 lukem #if HAVE_NBTOOL_CONFIG_H 40 1.6 lukem #include "nbtool_config.h" 41 1.5 thorpej #endif 42 1.5 thorpej 43 1.9 perry #include <sys/cdefs.h> 44 1.5 thorpej #include <sys/types.h> 45 1.1 tron #include <err.h> 46 1.1 tron #include <paths.h> 47 1.1 tron #include <stdio.h> 48 1.1 tron #include <stdlib.h> 49 1.1 tron #include <string.h> 50 1.1 tron #include <unistd.h> 51 1.1 tron 52 1.5 thorpej #if defined(__RCSID) && !defined(__lint) 53 1.12 christos __RCSID("$NetBSD: mktemp.c,v 1.12 2012/11/03 13:34:08 christos Exp $"); 54 1.5 thorpej #endif /* !__lint */ 55 1.1 tron 56 1.10 perry static void usage(void) __dead; 57 1.1 tron 58 1.1 tron int 59 1.1 tron main(int argc, char **argv) 60 1.1 tron { 61 1.1 tron int c, fd, ret; 62 1.7 christos char *tmpdir; 63 1.7 christos const char *prefix; 64 1.1 tron char *name; 65 1.1 tron int dflag, qflag, tflag, uflag; 66 1.1 tron 67 1.7 christos setprogname(*argv); 68 1.1 tron ret = dflag = qflag = tflag = uflag = 0; 69 1.11 christos tmpdir = NULL; 70 1.1 tron prefix = "mktemp"; 71 1.1 tron name = NULL; 72 1.1 tron 73 1.11 christos while ((c = getopt(argc, argv, "dp:qt:u")) != -1) 74 1.1 tron switch (c) { 75 1.1 tron case 'd': 76 1.1 tron dflag++; 77 1.1 tron break; 78 1.1 tron 79 1.11 christos case 'p': 80 1.11 christos tmpdir = optarg; 81 1.11 christos break; 82 1.11 christos 83 1.1 tron case 'q': 84 1.1 tron qflag++; 85 1.1 tron break; 86 1.1 tron 87 1.1 tron case 't': 88 1.1 tron prefix = optarg; 89 1.1 tron tflag++; 90 1.1 tron break; 91 1.1 tron 92 1.1 tron case 'u': 93 1.1 tron uflag++; 94 1.1 tron break; 95 1.1 tron 96 1.1 tron default: 97 1.1 tron usage(); 98 1.1 tron } 99 1.1 tron 100 1.1 tron argc -= optind; 101 1.1 tron argv += optind; 102 1.1 tron 103 1.12 christos if (tflag == 0 && argc < 1) 104 1.12 christos tflag = 1; 105 1.12 christos 106 1.1 tron if (tflag) { 107 1.11 christos if (tmpdir == NULL) 108 1.11 christos tmpdir = getenv("TMPDIR"); 109 1.1 tron if (tmpdir == NULL) 110 1.7 christos (void)asprintf(&name, "%s%s.XXXXXXXX", _PATH_TMP, 111 1.7 christos prefix); 112 1.1 tron else 113 1.7 christos (void)asprintf(&name, "%s/%s.XXXXXXXX", tmpdir, prefix); 114 1.1 tron /* if this fails, the program is in big trouble already */ 115 1.1 tron if (name == NULL) { 116 1.1 tron if (qflag) 117 1.7 christos return 1; 118 1.1 tron else 119 1.7 christos errx(1, "Cannot generate template"); 120 1.1 tron } 121 1.1 tron } else if (argc < 1) { 122 1.1 tron usage(); 123 1.1 tron } 124 1.1 tron 125 1.1 tron /* generate all requested files */ 126 1.1 tron while (name != NULL || argc > 0) { 127 1.1 tron if (name == NULL) { 128 1.11 christos if (tmpdir) 129 1.11 christos (void)asprintf(&name, "%s/%s", 130 1.11 christos tmpdir, argv[0]); 131 1.11 christos else 132 1.11 christos name = strdup(argv[0]); 133 1.1 tron argv++; 134 1.1 tron argc--; 135 1.1 tron } 136 1.1 tron 137 1.1 tron if (dflag) { 138 1.1 tron if (mkdtemp(name) == NULL) { 139 1.1 tron ret = 1; 140 1.1 tron if (!qflag) 141 1.1 tron warn("mkdtemp failed on %s", name); 142 1.1 tron } else { 143 1.7 christos (void)printf("%s\n", name); 144 1.1 tron if (uflag) 145 1.7 christos (void)rmdir(name); 146 1.1 tron } 147 1.1 tron } else { 148 1.1 tron fd = mkstemp(name); 149 1.1 tron if (fd < 0) { 150 1.1 tron ret = 1; 151 1.1 tron if (!qflag) 152 1.1 tron warn("mkstemp failed on %s", name); 153 1.1 tron } else { 154 1.7 christos (void)close(fd); 155 1.1 tron if (uflag) 156 1.7 christos (void)unlink(name); 157 1.7 christos (void)printf("%s\n", name); 158 1.1 tron } 159 1.1 tron } 160 1.1 tron if (name) 161 1.1 tron free(name); 162 1.1 tron name = NULL; 163 1.1 tron } 164 1.7 christos return ret; 165 1.1 tron } 166 1.1 tron 167 1.1 tron static void 168 1.7 christos usage(void) 169 1.1 tron { 170 1.7 christos (void)fprintf(stderr, 171 1.11 christos "Usage: %s [-dqu] [-p <tmpdir>] {-t prefix | template ...}\n", 172 1.11 christos getprogname()); 173 1.1 tron exit (1); 174 1.1 tron } 175