xref: /freebsd/usr.bin/mktemp/mktemp.c (revision c0206f33f75aaf2c86505c60385dc21a1d9534e6)
14ca332d5SPeter Wemm /*-
24ca332d5SPeter Wemm  * Copyright (c) 1994, 1995, 1996, 1998 Peter Wemm <peter@netplex.com.au>
34ca332d5SPeter Wemm  * All rights reserved.
44ca332d5SPeter Wemm  *
54ca332d5SPeter Wemm  * Redistribution and use in source and binary forms, with or without
64ca332d5SPeter Wemm  * modification, are permitted provided that the following conditions
74ca332d5SPeter Wemm  * are met:
84ca332d5SPeter Wemm  * 1. Redistributions of source code must retain the above copyright
94ca332d5SPeter Wemm  *    notice, this list of conditions and the following disclaimer.
104ca332d5SPeter Wemm  * 2. Redistributions in binary form must reproduce the above copyright
114ca332d5SPeter Wemm  *    notice, this list of conditions and the following disclaimer in the
124ca332d5SPeter Wemm  *    documentation and/or other materials provided with the distribution.
134ca332d5SPeter Wemm  *
144ca332d5SPeter Wemm  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
154ca332d5SPeter Wemm  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
164ca332d5SPeter Wemm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
174ca332d5SPeter Wemm  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
184ca332d5SPeter Wemm  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
194ca332d5SPeter Wemm  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
204ca332d5SPeter Wemm  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
214ca332d5SPeter Wemm  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
224ca332d5SPeter Wemm  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
234ca332d5SPeter Wemm  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
244ca332d5SPeter Wemm  * SUCH DAMAGE.
254ca332d5SPeter Wemm  *
264ca332d5SPeter Wemm  */
274ca332d5SPeter Wemm 
284ca332d5SPeter Wemm /*
294ca332d5SPeter Wemm  * This program was originally written long ago, originally for a non
304ca332d5SPeter Wemm  * BSD-like OS without mkstemp().  It's been modified over the years
314ca332d5SPeter Wemm  * to use mkstemp() rather than the original O_CREAT|O_EXCL/fstat/lstat
324ca332d5SPeter Wemm  * etc style hacks.
334ca332d5SPeter Wemm  * A cleanup, misc options and mkdtemp() calls were added to try and work
344ca332d5SPeter Wemm  * more like the OpenBSD version - which was first to publish the interface.
354ca332d5SPeter Wemm  */
364ca332d5SPeter Wemm 
37d4eaae7aSPhilippe Charnier #include <err.h>
38d4eaae7aSPhilippe Charnier #include <paths.h>
394ca332d5SPeter Wemm #include <stdio.h>
404ca332d5SPeter Wemm #include <stdlib.h>
414ca332d5SPeter Wemm #include <string.h>
42d4eaae7aSPhilippe Charnier #include <unistd.h>
43d4eaae7aSPhilippe Charnier 
44d4eaae7aSPhilippe Charnier #ifndef lint
45d4eaae7aSPhilippe Charnier static const char rcsid[] =
46d4eaae7aSPhilippe Charnier 	"$FreeBSD$";
47d4eaae7aSPhilippe Charnier #endif /* not lint */
48d4eaae7aSPhilippe Charnier 
49d4eaae7aSPhilippe Charnier static void usage __P((void));
504ca332d5SPeter Wemm 
514ca332d5SPeter Wemm int
524ca332d5SPeter Wemm main(int argc, char **argv)
534ca332d5SPeter Wemm {
544ca332d5SPeter Wemm 	int c, fd, ret;
554ca332d5SPeter Wemm 	char *tmpdir, *prefix;
564ca332d5SPeter Wemm 	char *name;
574ca332d5SPeter Wemm 	int dflag, qflag, tflag, uflag;
584ca332d5SPeter Wemm 
594ca332d5SPeter Wemm 	ret = dflag = qflag = tflag = uflag = 0;
60d4eaae7aSPhilippe Charnier 	prefix = "mktemp";
614ca332d5SPeter Wemm 	name = NULL;
624ca332d5SPeter Wemm 
634ca332d5SPeter Wemm 	while ((c = getopt(argc, argv, "dqt:u")) != -1)
644ca332d5SPeter Wemm 		switch (c) {
654ca332d5SPeter Wemm 		case 'd':
664ca332d5SPeter Wemm 			dflag++;
674ca332d5SPeter Wemm 			break;
684ca332d5SPeter Wemm 
694ca332d5SPeter Wemm 		case 'q':
704ca332d5SPeter Wemm 			qflag++;
714ca332d5SPeter Wemm 			break;
724ca332d5SPeter Wemm 
734ca332d5SPeter Wemm 		case 't':
744ca332d5SPeter Wemm 			prefix = optarg;
754ca332d5SPeter Wemm 			tflag++;
764ca332d5SPeter Wemm 			break;
774ca332d5SPeter Wemm 
784ca332d5SPeter Wemm 		case 'u':
794ca332d5SPeter Wemm 			uflag++;
804ca332d5SPeter Wemm 			break;
814ca332d5SPeter Wemm 
824ca332d5SPeter Wemm 		default:
83d4eaae7aSPhilippe Charnier 			usage();
844ca332d5SPeter Wemm 		}
854ca332d5SPeter Wemm 
864ca332d5SPeter Wemm 	argc -= optind;
874ca332d5SPeter Wemm 	argv += optind;
884ca332d5SPeter Wemm 
894ca332d5SPeter Wemm 	if (tflag) {
904ca332d5SPeter Wemm 		tmpdir = getenv("TMPDIR");
914ca332d5SPeter Wemm 		if (tmpdir == NULL)
924ca332d5SPeter Wemm 			asprintf(&name, "%s%s.XXXXXXXX", _PATH_TMP, prefix);
934ca332d5SPeter Wemm 		else
944ca332d5SPeter Wemm 			asprintf(&name, "%s/%s.XXXXXXXX", tmpdir, prefix);
954ca332d5SPeter Wemm 		/* if this fails, the program is in big trouble already */
964ca332d5SPeter Wemm 		if (name == NULL) {
974ca332d5SPeter Wemm 			if (qflag)
984ca332d5SPeter Wemm 				return (1);
994ca332d5SPeter Wemm 			else
100d4eaae7aSPhilippe Charnier 				errx(1, "cannot generate template");
1014ca332d5SPeter Wemm 		}
1024ca332d5SPeter Wemm 	} else if (argc < 1) {
103d4eaae7aSPhilippe Charnier 		usage();
1044ca332d5SPeter Wemm 	}
1054ca332d5SPeter Wemm 
1064ca332d5SPeter Wemm 	/* generate all requested files */
1074ca332d5SPeter Wemm 	while (name != NULL || argc > 0) {
1084ca332d5SPeter Wemm 		if (name == NULL) {
1094ca332d5SPeter Wemm 			name = strdup(argv[0]);
1104ca332d5SPeter Wemm 			argv++;
1114ca332d5SPeter Wemm 			argc--;
1124ca332d5SPeter Wemm 		}
1134ca332d5SPeter Wemm 
1144ca332d5SPeter Wemm 		if (dflag) {
1154ca332d5SPeter Wemm 			if (mkdtemp(name) == NULL) {
1164ca332d5SPeter Wemm 				ret = 1;
1174ca332d5SPeter Wemm 				if (!qflag)
1184ca332d5SPeter Wemm 					warn("mkdtemp failed on %s", name);
1194ca332d5SPeter Wemm 			} else {
1204ca332d5SPeter Wemm 				printf("%s\n", name);
1214ca332d5SPeter Wemm 				if (uflag)
1224ca332d5SPeter Wemm 					rmdir(name);
1234ca332d5SPeter Wemm 			}
1244ca332d5SPeter Wemm 		} else {
1254ca332d5SPeter Wemm 			fd = mkstemp(name);
1264ca332d5SPeter Wemm 			if (fd < 0) {
1274ca332d5SPeter Wemm 				ret = 1;
1284ca332d5SPeter Wemm 				if (!qflag)
1294ca332d5SPeter Wemm 					warn("mkstemp failed on %s", name);
1304ca332d5SPeter Wemm 			} else {
1314ca332d5SPeter Wemm 				close(fd);
1324ca332d5SPeter Wemm 				if (uflag)
1334ca332d5SPeter Wemm 					unlink(name);
1344ca332d5SPeter Wemm 				printf("%s\n", name);
1354ca332d5SPeter Wemm 			}
1364ca332d5SPeter Wemm 		}
1374ca332d5SPeter Wemm 		if (name)
1384ca332d5SPeter Wemm 			free(name);
1394ca332d5SPeter Wemm 		name = NULL;
1404ca332d5SPeter Wemm 	}
1414ca332d5SPeter Wemm 	return (ret);
1424ca332d5SPeter Wemm }
143d4eaae7aSPhilippe Charnier 
144d4eaae7aSPhilippe Charnier static void
145d4eaae7aSPhilippe Charnier usage()
146d4eaae7aSPhilippe Charnier {
147d4eaae7aSPhilippe Charnier 	fprintf(stderr,
148c0206f33SAlexander Langer 		"usage: mktemp [-d] [-q] [-t prefix] [-u] template ...\n");
149c0206f33SAlexander Langer 	fprintf(stderr,
150c0206f33SAlexander Langer 		"       mktemp [-d] [-q] [-u] -t prefix \n");
151d4eaae7aSPhilippe Charnier 	exit (1);
152d4eaae7aSPhilippe Charnier }
153