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