1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 *
25 * Create unique plain files or directories.
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <locale.h>
33
34 static void
usage(void)35 usage(void)
36 {
37 (void) fprintf(stderr,
38 gettext("Usage: mktemp [-dqtu] [-p prefix_dir] [template]\n"));
39 exit(1);
40 /* NOTREACHED */
41 }
42
43 int
main(int argc,char ** argv)44 main(int argc, char **argv)
45 {
46 int opt;
47 char *prefix = NULL;
48 boolean_t dounlink = B_FALSE;
49 boolean_t domkdir = B_FALSE;
50 boolean_t quiet = B_FALSE;
51 boolean_t usetmpdir = B_FALSE;
52 char template[] = "tmp.XXXXXX";
53 char *tmpl;
54
55 (void) setlocale(LC_ALL, "");
56
57 #ifndef TEXT_DOMAIN
58 #define TEXT_DOMAIN "SYS_TEST"
59 #endif
60 (void) textdomain(TEXT_DOMAIN);
61
62 opterr = 0;
63
64 while ((opt = getopt(argc, argv, "dqtup:")) != EOF) {
65 switch (opt) {
66 case 'd':
67 domkdir = B_TRUE;
68 break;
69 case 'q':
70 quiet = B_TRUE;
71 break;
72 case 'p':
73 prefix = optarg;
74 /* FALLTHROUGH - -p implies -t */
75 case 't':
76 usetmpdir = B_TRUE;
77 break;
78 case 'u':
79 dounlink = B_TRUE;
80 break;
81 default:
82 usage();
83 }
84 }
85 argc -= optind;
86 argv += optind;
87 switch (argc) {
88 case 0:
89 tmpl = template;
90 usetmpdir = B_TRUE;
91 break;
92 case 1:
93 tmpl = argv[0];
94 break;
95 default:
96 usage();
97 }
98
99 if (usetmpdir) {
100 char *tmp = getenv("TMPDIR");
101 size_t len;
102
103 if (strchr(tmpl, '/') != NULL) {
104 (void) fprintf(stderr,
105 gettext("mktemp: template argument specified "
106 "with -t/-p option must not contain '/'"
107 "\n"));
108 return (1);
109 }
110 /* TMPDIR overrides -p so that scripts will honor $TMPDIR */
111 if (tmp != NULL)
112 prefix = tmp;
113 else if (prefix == NULL)
114 prefix = "/tmp";
115
116 len = snprintf(NULL, 0, "%s/%s", prefix, tmpl) + 1;
117 tmp = malloc(len);
118 if (tmp == NULL) {
119 perror("malloc");
120 return (1);
121 }
122 (void) snprintf(tmp, len, "%s/%s", prefix, tmpl);
123 tmpl = tmp;
124 }
125
126 if (domkdir) {
127 if (mkdtemp(tmpl) == NULL) {
128 if (!quiet) {
129 (void) fprintf(stderr,
130 gettext("mktemp: failed to create "
131 "directory: %s\n"), tmpl);
132 }
133 return (1);
134 }
135 if (dounlink)
136 (void) rmdir(tmpl);
137 } else {
138 if (mkstemp(tmpl) < 0) {
139 if (!quiet) {
140 (void) fprintf(stderr,
141 gettext("mktemp: failed to create file: "
142 "%s\n"), tmpl);
143 }
144 return (1);
145 }
146 if (dounlink)
147 (void) unlink(tmpl);
148 }
149 (void) puts(tmpl);
150 return (0);
151 }
152