1 /* $OpenBSD: mktemp.c,v 1.15 2009/10/27 23:59:40 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1996, 1997, 2001 Todd C. Miller <Todd.Miller@courtesan.com> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <paths.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <unistd.h> 24 #include <err.h> 25 26 __dead void usage(void); 27 28 int 29 main(int argc, char *argv[]) 30 { 31 int ch, fd, uflag = 0, quiet = 0, tflag = 0, makedir = 0; 32 char *cp, *template, *tempfile, *prefix = _PATH_TMP; 33 int plen; 34 35 while ((ch = getopt(argc, argv, "dp:qtu")) != -1) 36 switch(ch) { 37 case 'd': 38 makedir = 1; 39 break; 40 case 'p': 41 prefix = optarg; 42 tflag = 1; 43 break; 44 case 'q': 45 quiet = 1; 46 break; 47 case 't': 48 tflag = 1; 49 break; 50 case 'u': 51 uflag = 1; 52 break; 53 default: 54 usage(); 55 } 56 57 /* If no template specified use a default one (implies -t mode) */ 58 switch (argc - optind) { 59 case 1: 60 template = argv[optind]; 61 break; 62 case 0: 63 template = "tmp.XXXXXXXXXX"; 64 tflag = 1; 65 break; 66 default: 67 usage(); 68 } 69 70 if (tflag) { 71 if (strchr(template, '/')) { 72 if (!quiet) 73 warnx("template must not contain directory " 74 "separators in -t mode"); 75 exit(1); 76 } 77 78 cp = getenv("TMPDIR"); 79 if (cp != NULL && *cp != '\0') 80 prefix = cp; 81 plen = strlen(prefix); 82 while (plen != 0 && prefix[plen - 1] == '/') 83 plen--; 84 85 if (asprintf(&tempfile, "%.*s/%s", plen, prefix, template) < 0) 86 tempfile = NULL; 87 } else 88 tempfile = strdup(template); 89 if (tempfile == NULL) { 90 if (!quiet) 91 warnx("cannot allocate memory"); 92 exit(1); 93 } 94 95 if (makedir) { 96 if (mkdtemp(tempfile) == NULL) { 97 if (!quiet) 98 warn("cannot make temp dir %s", tempfile); 99 exit(1); 100 } 101 102 if (uflag) 103 (void)rmdir(tempfile); 104 } else { 105 if ((fd = mkstemp(tempfile)) < 0) { 106 if (!quiet) 107 warn("cannot make temp file %s", tempfile); 108 exit(1); 109 } 110 (void)close(fd); 111 112 if (uflag) 113 (void)unlink(tempfile); 114 } 115 116 (void)puts(tempfile); 117 free(tempfile); 118 119 exit(0); 120 } 121 122 __dead void 123 usage(void) 124 { 125 extern char *__progname; 126 127 (void)fprintf(stderr, 128 "usage: %s [-dqtu] [-p directory] [template]\n", __progname); 129 exit(1); 130 } 131