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