xref: /minix3/usr.bin/mktemp/mktemp.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc /* $NetBSD: mktemp.c,v 1.12 2012/11/03 13:34:08 christos Exp $ */
20b2db08aSThomas Veerman 
30b2db08aSThomas Veerman /*-
40b2db08aSThomas Veerman  * Copyright (c) 1994, 1995, 1996, 1998 Peter Wemm <peter@netplex.com.au>
50b2db08aSThomas Veerman  * All rights reserved.
60b2db08aSThomas Veerman  *
70b2db08aSThomas Veerman  * Redistribution and use in source and binary forms, with or without
80b2db08aSThomas Veerman  * modification, are permitted provided that the following conditions
90b2db08aSThomas Veerman  * are met:
100b2db08aSThomas Veerman  * 1. Redistributions of source code must retain the above copyright
110b2db08aSThomas Veerman  *    notice, this list of conditions and the following disclaimer.
120b2db08aSThomas Veerman  * 2. Redistributions in binary form must reproduce the above copyright
130b2db08aSThomas Veerman  *    notice, this list of conditions and the following disclaimer in the
140b2db08aSThomas Veerman  *    documentation and/or other materials provided with the distribution.
150b2db08aSThomas Veerman  *
160b2db08aSThomas Veerman  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
170b2db08aSThomas Veerman  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
180b2db08aSThomas Veerman  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
190b2db08aSThomas Veerman  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
200b2db08aSThomas Veerman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
210b2db08aSThomas Veerman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
220b2db08aSThomas Veerman  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
230b2db08aSThomas Veerman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
240b2db08aSThomas Veerman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
250b2db08aSThomas Veerman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
260b2db08aSThomas Veerman  * SUCH DAMAGE.
270b2db08aSThomas Veerman  *
280b2db08aSThomas Veerman  */
290b2db08aSThomas Veerman 
300b2db08aSThomas Veerman /*
310b2db08aSThomas Veerman  * This program was originally written long ago, originally for a non
320b2db08aSThomas Veerman  * BSD-like OS without mkstemp().  It's been modified over the years
330b2db08aSThomas Veerman  * to use mkstemp() rather than the original O_CREAT|O_EXCL/fstat/lstat
340b2db08aSThomas Veerman  * etc style hacks.
350b2db08aSThomas Veerman  * A cleanup, misc options and mkdtemp() calls were added to try and work
360b2db08aSThomas Veerman  * more like the OpenBSD version - which was first to publish the interface.
370b2db08aSThomas Veerman  */
380b2db08aSThomas Veerman 
390b2db08aSThomas Veerman #if HAVE_NBTOOL_CONFIG_H
400b2db08aSThomas Veerman #include "nbtool_config.h"
410b2db08aSThomas Veerman #endif
420b2db08aSThomas Veerman 
430b2db08aSThomas Veerman #include <sys/cdefs.h>
440b2db08aSThomas Veerman #include <sys/types.h>
450b2db08aSThomas Veerman #include <err.h>
460b2db08aSThomas Veerman #include <paths.h>
470b2db08aSThomas Veerman #include <stdio.h>
480b2db08aSThomas Veerman #include <stdlib.h>
490b2db08aSThomas Veerman #include <string.h>
500b2db08aSThomas Veerman #include <unistd.h>
510b2db08aSThomas Veerman 
520b2db08aSThomas Veerman #if defined(__RCSID) && !defined(__lint)
53*84d9c625SLionel Sambuc __RCSID("$NetBSD: mktemp.c,v 1.12 2012/11/03 13:34:08 christos Exp $");
540b2db08aSThomas Veerman #endif /* !__lint */
550b2db08aSThomas Veerman 
560b2db08aSThomas Veerman static void usage(void) __dead;
570b2db08aSThomas Veerman 
580b2db08aSThomas Veerman int
main(int argc,char ** argv)590b2db08aSThomas Veerman main(int argc, char **argv)
600b2db08aSThomas Veerman {
610b2db08aSThomas Veerman 	int c, fd, ret;
620b2db08aSThomas Veerman 	char *tmpdir;
630b2db08aSThomas Veerman 	const char *prefix;
640b2db08aSThomas Veerman 	char *name;
650b2db08aSThomas Veerman 	int dflag, qflag, tflag, uflag;
660b2db08aSThomas Veerman 
670b2db08aSThomas Veerman 	setprogname(*argv);
680b2db08aSThomas Veerman 	ret = dflag = qflag = tflag = uflag = 0;
690b2db08aSThomas Veerman 	tmpdir = NULL;
700b2db08aSThomas Veerman 	prefix = "mktemp";
710b2db08aSThomas Veerman 	name = NULL;
720b2db08aSThomas Veerman 
730b2db08aSThomas Veerman 	while ((c = getopt(argc, argv, "dp:qt:u")) != -1)
740b2db08aSThomas Veerman 		switch (c) {
750b2db08aSThomas Veerman 		case 'd':
760b2db08aSThomas Veerman 			dflag++;
770b2db08aSThomas Veerman 			break;
780b2db08aSThomas Veerman 
790b2db08aSThomas Veerman 		case 'p':
800b2db08aSThomas Veerman 			tmpdir = optarg;
810b2db08aSThomas Veerman 			break;
820b2db08aSThomas Veerman 
830b2db08aSThomas Veerman 		case 'q':
840b2db08aSThomas Veerman 			qflag++;
850b2db08aSThomas Veerman 			break;
860b2db08aSThomas Veerman 
870b2db08aSThomas Veerman 		case 't':
880b2db08aSThomas Veerman 			prefix = optarg;
890b2db08aSThomas Veerman 			tflag++;
900b2db08aSThomas Veerman 			break;
910b2db08aSThomas Veerman 
920b2db08aSThomas Veerman 		case 'u':
930b2db08aSThomas Veerman 			uflag++;
940b2db08aSThomas Veerman 			break;
950b2db08aSThomas Veerman 
960b2db08aSThomas Veerman 		default:
970b2db08aSThomas Veerman 			usage();
980b2db08aSThomas Veerman 		}
990b2db08aSThomas Veerman 
1000b2db08aSThomas Veerman 	argc -= optind;
1010b2db08aSThomas Veerman 	argv += optind;
1020b2db08aSThomas Veerman 
103*84d9c625SLionel Sambuc 	if (tflag == 0 && argc < 1)
104*84d9c625SLionel Sambuc 		tflag = 1;
105*84d9c625SLionel Sambuc 
1060b2db08aSThomas Veerman 	if (tflag) {
1070b2db08aSThomas Veerman 		if (tmpdir == NULL)
1080b2db08aSThomas Veerman 			tmpdir = getenv("TMPDIR");
1090b2db08aSThomas Veerman 		if (tmpdir == NULL)
1100b2db08aSThomas Veerman 			(void)asprintf(&name, "%s%s.XXXXXXXX", _PATH_TMP,
1110b2db08aSThomas Veerman 			    prefix);
1120b2db08aSThomas Veerman 		else
1130b2db08aSThomas Veerman 			(void)asprintf(&name, "%s/%s.XXXXXXXX", tmpdir, prefix);
1140b2db08aSThomas Veerman 		/* if this fails, the program is in big trouble already */
1150b2db08aSThomas Veerman 		if (name == NULL) {
1160b2db08aSThomas Veerman 			if (qflag)
1170b2db08aSThomas Veerman 				return 1;
1180b2db08aSThomas Veerman 			else
1190b2db08aSThomas Veerman 				errx(1, "Cannot generate template");
1200b2db08aSThomas Veerman 		}
1210b2db08aSThomas Veerman 	} else if (argc < 1) {
1220b2db08aSThomas Veerman 		usage();
1230b2db08aSThomas Veerman 	}
1240b2db08aSThomas Veerman 
1250b2db08aSThomas Veerman 	/* generate all requested files */
1260b2db08aSThomas Veerman 	while (name != NULL || argc > 0) {
1270b2db08aSThomas Veerman 		if (name == NULL) {
1280b2db08aSThomas Veerman 			if (tmpdir)
1290b2db08aSThomas Veerman 				(void)asprintf(&name, "%s/%s",
1300b2db08aSThomas Veerman 				    tmpdir, argv[0]);
1310b2db08aSThomas Veerman 			else
1320b2db08aSThomas Veerman 				name = strdup(argv[0]);
1330b2db08aSThomas Veerman 			argv++;
1340b2db08aSThomas Veerman 			argc--;
1350b2db08aSThomas Veerman 		}
1360b2db08aSThomas Veerman 
1370b2db08aSThomas Veerman 		if (dflag) {
1380b2db08aSThomas Veerman 			if (mkdtemp(name) == NULL) {
1390b2db08aSThomas Veerman 				ret = 1;
1400b2db08aSThomas Veerman 				if (!qflag)
1410b2db08aSThomas Veerman 					warn("mkdtemp failed on %s", name);
1420b2db08aSThomas Veerman 			} else {
1430b2db08aSThomas Veerman 				(void)printf("%s\n", name);
1440b2db08aSThomas Veerman 				if (uflag)
1450b2db08aSThomas Veerman 					(void)rmdir(name);
1460b2db08aSThomas Veerman 			}
1470b2db08aSThomas Veerman 		} else {
1480b2db08aSThomas Veerman 			fd = mkstemp(name);
1490b2db08aSThomas Veerman 			if (fd < 0) {
1500b2db08aSThomas Veerman 				ret = 1;
1510b2db08aSThomas Veerman 				if (!qflag)
1520b2db08aSThomas Veerman 					warn("mkstemp failed on %s", name);
1530b2db08aSThomas Veerman 			} else {
1540b2db08aSThomas Veerman 				(void)close(fd);
1550b2db08aSThomas Veerman 				if (uflag)
1560b2db08aSThomas Veerman 					(void)unlink(name);
1570b2db08aSThomas Veerman 				(void)printf("%s\n", name);
1580b2db08aSThomas Veerman 			}
1590b2db08aSThomas Veerman 		}
1600b2db08aSThomas Veerman 		if (name)
1610b2db08aSThomas Veerman 			free(name);
1620b2db08aSThomas Veerman 		name = NULL;
1630b2db08aSThomas Veerman 	}
1640b2db08aSThomas Veerman 	return ret;
1650b2db08aSThomas Veerman }
1660b2db08aSThomas Veerman 
1670b2db08aSThomas Veerman static void
usage(void)1680b2db08aSThomas Veerman usage(void)
1690b2db08aSThomas Veerman {
1700b2db08aSThomas Veerman 	(void)fprintf(stderr,
1710b2db08aSThomas Veerman 	    "Usage: %s [-dqu] [-p <tmpdir>] {-t prefix | template ...}\n",
1720b2db08aSThomas Veerman 	    getprogname());
1730b2db08aSThomas Veerman 	exit (1);
1740b2db08aSThomas Veerman }
175