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