135193Speter/*-
2330449Seadler * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3330449Seadler *
435193Speter * Copyright (c) 1994, 1995, 1996, 1998 Peter Wemm <peter@netplex.com.au>
535193Speter * All rights reserved.
635193Speter *
735193Speter * Redistribution and use in source and binary forms, with or without
835193Speter * modification, are permitted provided that the following conditions
935193Speter * are met:
1035193Speter * 1. Redistributions of source code must retain the above copyright
1135193Speter *    notice, this list of conditions and the following disclaimer.
1235193Speter * 2. Redistributions in binary form must reproduce the above copyright
1335193Speter *    notice, this list of conditions and the following disclaimer in the
1435193Speter *    documentation and/or other materials provided with the distribution.
1535193Speter *
1635193Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1735193Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1835193Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1935193Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2035193Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2135193Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2235193Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2335193Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2435193Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2535193Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2635193Speter * SUCH DAMAGE.
2735193Speter *
2835193Speter */
2935193Speter
3035193Speter/*
3135193Speter * This program was originally written long ago, originally for a non
3235193Speter * BSD-like OS without mkstemp().  It's been modified over the years
3335193Speter * to use mkstemp() rather than the original O_CREAT|O_EXCL/fstat/lstat
3435193Speter * etc style hacks.
3535193Speter * A cleanup, misc options and mkdtemp() calls were added to try and work
3635193Speter * more like the OpenBSD version - which was first to publish the interface.
3735193Speter */
3835193Speter
3935733Scharnier#include <err.h>
4035733Scharnier#include <paths.h>
4135193Speter#include <stdio.h>
4235193Speter#include <stdlib.h>
4335733Scharnier#include <string.h>
4435193Speter#include <unistd.h>
4535193Speter
4635733Scharnier#ifndef lint
4735733Scharnierstatic const char rcsid[] =
4835733Scharnier	"$FreeBSD: stable/11/usr.bin/mktemp/mktemp.c 330449 2018-03-05 07:26:05Z eadler $";
4935733Scharnier#endif /* not lint */
5035733Scharnier
5192921Simpstatic void usage(void);
5235733Scharnier
5335193Speterint
5435193Spetermain(int argc, char **argv)
5535193Speter{
5635193Speter	int c, fd, ret;
5787290Sdwmalone	char *tmpdir;
5887290Sdwmalone	const char *prefix;
5935193Speter	char *name;
6035193Speter	int dflag, qflag, tflag, uflag;
6135193Speter
6235193Speter	ret = dflag = qflag = tflag = uflag = 0;
6335733Scharnier	prefix = "mktemp";
6435193Speter	name = NULL;
6535193Speter
6635193Speter	while ((c = getopt(argc, argv, "dqt:u")) != -1)
6735193Speter		switch (c) {
6835193Speter		case 'd':
6935193Speter			dflag++;
7035193Speter			break;
7135193Speter
7235193Speter		case 'q':
7335193Speter			qflag++;
7435193Speter			break;
7535193Speter
7635193Speter		case 't':
7735193Speter			prefix = optarg;
7835193Speter			tflag++;
7935193Speter			break;
8035193Speter
8135193Speter		case 'u':
8235193Speter			uflag++;
8335193Speter			break;
8435193Speter
8535193Speter		default:
8635733Scharnier			usage();
8735193Speter		}
8835193Speter
8935193Speter	argc -= optind;
9035193Speter	argv += optind;
9135193Speter
92241118Seadler	if (!tflag && argc < 1) {
93241118Seadler		tflag = 1;
94241118Seadler		prefix = "tmp";
95241118Seadler	}
96241118Seadler
9735193Speter	if (tflag) {
9835193Speter		tmpdir = getenv("TMPDIR");
9935193Speter		if (tmpdir == NULL)
10035193Speter			asprintf(&name, "%s%s.XXXXXXXX", _PATH_TMP, prefix);
10135193Speter		else
10235193Speter			asprintf(&name, "%s/%s.XXXXXXXX", tmpdir, prefix);
10335193Speter		/* if this fails, the program is in big trouble already */
10435193Speter		if (name == NULL) {
10535193Speter			if (qflag)
10635193Speter				return (1);
10735193Speter			else
10835733Scharnier				errx(1, "cannot generate template");
10935193Speter		}
11035193Speter	}
11135193Speter
11235193Speter	/* generate all requested files */
11335193Speter	while (name != NULL || argc > 0) {
11435193Speter		if (name == NULL) {
11535193Speter			name = strdup(argv[0]);
11635193Speter			argv++;
11735193Speter			argc--;
11835193Speter		}
11935193Speter
12035193Speter		if (dflag) {
12135193Speter			if (mkdtemp(name) == NULL) {
12235193Speter				ret = 1;
12335193Speter				if (!qflag)
12435193Speter					warn("mkdtemp failed on %s", name);
12535193Speter			} else {
12635193Speter				printf("%s\n", name);
12735193Speter				if (uflag)
12835193Speter					rmdir(name);
12935193Speter			}
13035193Speter		} else {
13135193Speter			fd = mkstemp(name);
13235193Speter			if (fd < 0) {
13335193Speter				ret = 1;
13435193Speter				if (!qflag)
13535193Speter					warn("mkstemp failed on %s", name);
13635193Speter			} else {
13735193Speter				close(fd);
13835193Speter				if (uflag)
13935193Speter					unlink(name);
14035193Speter				printf("%s\n", name);
14135193Speter			}
14235193Speter		}
14335193Speter		if (name)
14435193Speter			free(name);
14535193Speter		name = NULL;
14635193Speter	}
14735193Speter	return (ret);
14835193Speter}
14935733Scharnier
15035733Scharnierstatic void
151200463Sdelphijusage(void)
15235733Scharnier{
15335733Scharnier	fprintf(stderr,
15467162Salex		"usage: mktemp [-d] [-q] [-t prefix] [-u] template ...\n");
15567162Salex	fprintf(stderr,
15667162Salex		"       mktemp [-d] [-q] [-u] -t prefix \n");
15735733Scharnier	exit (1);
15835733Scharnier}
159