1 /* $OpenBSD: mktemp.c,v 1.14 2008/05/26 09:22:30 sobrado 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 #ifndef lint 20 static const char rcsid[] = "$OpenBSD: mktemp.c,v 1.14 2008/05/26 09:22:30 sobrado Exp $"; 21 #endif /* not lint */ 22 23 #include <paths.h> 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <unistd.h> 28 #include <err.h> 29 30 __dead void usage(void); 31 32 int 33 main(int argc, char *argv[]) 34 { 35 int ch, fd, uflag = 0, quiet = 0, tflag = 0, makedir = 0; 36 char *cp, *template, *tempfile, *prefix = _PATH_TMP; 37 int plen; 38 39 while ((ch = getopt(argc, argv, "dp:qtu")) != -1) 40 switch(ch) { 41 case 'd': 42 makedir = 1; 43 break; 44 case 'p': 45 prefix = optarg; 46 tflag = 1; 47 break; 48 case 'q': 49 quiet = 1; 50 break; 51 case 't': 52 tflag = 1; 53 break; 54 case 'u': 55 uflag = 1; 56 break; 57 default: 58 usage(); 59 } 60 61 /* If no template specified use a default one (implies -t mode) */ 62 switch (argc - optind) { 63 case 1: 64 template = argv[optind]; 65 break; 66 case 0: 67 template = "tmp.XXXXXXXXXX"; 68 tflag = 1; 69 break; 70 default: 71 usage(); 72 } 73 74 if (tflag) { 75 if (strchr(template, '/')) { 76 if (!quiet) 77 warnx("template must not contain directory " 78 "separators in -t mode"); 79 exit(1); 80 } 81 82 cp = getenv("TMPDIR"); 83 if (cp != NULL && *cp != '\0') 84 prefix = cp; 85 plen = strlen(prefix); 86 while (plen != 0 && prefix[plen - 1] == '/') 87 plen--; 88 89 if (asprintf(&tempfile, "%.*s/%s", plen, prefix, template) < 0) 90 tempfile = NULL; 91 } else 92 tempfile = strdup(template); 93 if (tempfile == NULL) { 94 if (!quiet) 95 warnx("cannot allocate memory"); 96 exit(1); 97 } 98 99 if (makedir) { 100 if (mkdtemp(tempfile) == NULL) { 101 if (!quiet) 102 warn("cannot make temp dir %s", tempfile); 103 exit(1); 104 } 105 106 if (uflag) 107 (void)rmdir(tempfile); 108 } else { 109 if ((fd = mkstemp(tempfile)) < 0) { 110 if (!quiet) 111 warn("cannot make temp file %s", tempfile); 112 exit(1); 113 } 114 (void)close(fd); 115 116 if (uflag) 117 (void)unlink(tempfile); 118 } 119 120 (void)puts(tempfile); 121 free(tempfile); 122 123 exit(0); 124 } 125 126 __dead void 127 usage(void) 128 { 129 extern char *__progname; 130 131 (void)fprintf(stderr, 132 "usage: %s [-dqtu] [-p directory] [template]\n", __progname); 133 exit(1); 134 } 135