xref: /onnv-gate/usr/src/lib/libcmd/common/mktemp.c (revision 12068:08a39a083754)
110898Sroland.mainz@nrubsig.org /***********************************************************************
210898Sroland.mainz@nrubsig.org *                                                                      *
310898Sroland.mainz@nrubsig.org *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1992-2010 AT&T Intellectual Property          *
510898Sroland.mainz@nrubsig.org *                      and is licensed under the                       *
610898Sroland.mainz@nrubsig.org *                  Common Public License, Version 1.0                  *
710898Sroland.mainz@nrubsig.org *                    by AT&T Intellectual Property                     *
810898Sroland.mainz@nrubsig.org *                                                                      *
910898Sroland.mainz@nrubsig.org *                A copy of the License is available at                 *
1010898Sroland.mainz@nrubsig.org *            http://www.opensource.org/licenses/cpl1.0.txt             *
1110898Sroland.mainz@nrubsig.org *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
1210898Sroland.mainz@nrubsig.org *                                                                      *
1310898Sroland.mainz@nrubsig.org *              Information and Software Systems Research               *
1410898Sroland.mainz@nrubsig.org *                            AT&T Research                             *
1510898Sroland.mainz@nrubsig.org *                           Florham Park NJ                            *
1610898Sroland.mainz@nrubsig.org *                                                                      *
1710898Sroland.mainz@nrubsig.org *                 Glenn Fowler <gsf@research.att.com>                  *
1810898Sroland.mainz@nrubsig.org *                  David Korn <dgk@research.att.com>                   *
1910898Sroland.mainz@nrubsig.org *                                                                      *
2010898Sroland.mainz@nrubsig.org ***********************************************************************/
2110898Sroland.mainz@nrubsig.org #pragma prototyped
2210898Sroland.mainz@nrubsig.org 
2310898Sroland.mainz@nrubsig.org static const char usage[] =
24*12068SRoger.Faulkner@Oracle.COM "[-?\n@(#)$Id: mktemp (AT&T Research) 2010-03-05 $\n]"
2510898Sroland.mainz@nrubsig.org USAGE_LICENSE
2610898Sroland.mainz@nrubsig.org "[+NAME?mktemp - make temporary file or directory]"
2710898Sroland.mainz@nrubsig.org "[+DESCRIPTION?\bmktemp\b creates a temporary file with optional base "
2810898Sroland.mainz@nrubsig.org     "name prefix \aprefix\a. If \aprefix\a is omitted then \btmp_\b is used "
2910898Sroland.mainz@nrubsig.org     "and \b--tmp\b is implied. If \aprefix\a contains a directory prefix "
3010898Sroland.mainz@nrubsig.org     "then that directory overrides any of the directories described below. A "
3110898Sroland.mainz@nrubsig.org     "temporary file will have mode \brw-------\b and a temporary directory "
3210898Sroland.mainz@nrubsig.org     "will have mode \brwx------\b, subject to \bumask\b(1). Generated paths "
3310898Sroland.mainz@nrubsig.org     "have these attributes:]"
3410898Sroland.mainz@nrubsig.org     "{"
3510898Sroland.mainz@nrubsig.org         "[+*?Lower case to avoid clashes on case ignorant filesystems.]"
3610898Sroland.mainz@nrubsig.org         "[+*?Pseudo-random part to deter denial of service attacks.]"
37*12068SRoger.Faulkner@Oracle.COM         "[+*?Default pseudo-random part (no specific \bX...\b template) "
38*12068SRoger.Faulkner@Oracle.COM             "formatted to accomodate 8.3 filesystems.]"
3910898Sroland.mainz@nrubsig.org     "}"
40*12068SRoger.Faulkner@Oracle.COM "[+?A consecutive trailing sequence of \bX\b's in \aprefix\a is replaced "
41*12068SRoger.Faulkner@Oracle.COM     "by the pseudo-random part. If there are no \bX\b's then the "
42*12068SRoger.Faulkner@Oracle.COM     "pseudo-random part is appended to the prefix.]"
4310898Sroland.mainz@nrubsig.org "[d:directory?Create a directory instead of a regular file.]"
4410898Sroland.mainz@nrubsig.org "[m:mode]:[mode?Set the mode of the created temporary to \amode\a. "
4510898Sroland.mainz@nrubsig.org     "\amode\a is symbolic or octal mode as in \bchmod\b(1). Relative modes "
4610898Sroland.mainz@nrubsig.org     "assume an initial mode of \bu=rwx\b.]"
4710898Sroland.mainz@nrubsig.org "[p:default?Use \adirectory\a if the \bTMPDIR\b environment variable is "
4810898Sroland.mainz@nrubsig.org     "not defined. Implies \b--tmp\b.]:[directory]"
4910898Sroland.mainz@nrubsig.org "[q:quiet?Suppress file and directory error diagnostics.]"
50*12068SRoger.Faulkner@Oracle.COM "[R:regress?The pseudo random generator is seeded with \aseed\a instead "
51*12068SRoger.Faulkner@Oracle.COM     "of process/system specific transient data. Use for testing "
52*12068SRoger.Faulkner@Oracle.COM     "only. A seed of \b0\b is silently changed to \b1\b.]#[seed]"
5310898Sroland.mainz@nrubsig.org "[t:tmp|temporary-directory?Create a path rooted in a temporary "
5410898Sroland.mainz@nrubsig.org     "directory.]"
5510898Sroland.mainz@nrubsig.org "[u:unsafe|dry-run?Check for file/directory existence but do not create. "
56*12068SRoger.Faulkner@Oracle.COM     "Use this for testing only.]"
5710898Sroland.mainz@nrubsig.org "\n"
5810898Sroland.mainz@nrubsig.org "\n[ prefix ]\n"
5910898Sroland.mainz@nrubsig.org "\n"
6010898Sroland.mainz@nrubsig.org "[+SEE ALSO?\bmkdir\b(1), \bpathtemp\b(3), \bmktemp\b(3)]"
6110898Sroland.mainz@nrubsig.org ;
6210898Sroland.mainz@nrubsig.org 
6310898Sroland.mainz@nrubsig.org #include <cmd.h>
6410898Sroland.mainz@nrubsig.org #include <ls.h>
6510898Sroland.mainz@nrubsig.org 
6610898Sroland.mainz@nrubsig.org int
b_mktemp(int argc,char ** argv,void * context)6710898Sroland.mainz@nrubsig.org b_mktemp(int argc, char** argv, void* context)
6810898Sroland.mainz@nrubsig.org {
6910898Sroland.mainz@nrubsig.org 	mode_t		mode = 0;
7010898Sroland.mainz@nrubsig.org 	mode_t		mask;
7110898Sroland.mainz@nrubsig.org 	int		fd;
7210898Sroland.mainz@nrubsig.org 	int		i;
7310898Sroland.mainz@nrubsig.org 	int		quiet = 0;
7410898Sroland.mainz@nrubsig.org 	int		unsafe = 0;
7510898Sroland.mainz@nrubsig.org 	int*		fdp = &fd;
7610898Sroland.mainz@nrubsig.org 	char*		dir = "";
7710898Sroland.mainz@nrubsig.org 	char*		pfx;
7810898Sroland.mainz@nrubsig.org 	char*		t;
7910898Sroland.mainz@nrubsig.org 	char		path[PATH_MAX];
8010898Sroland.mainz@nrubsig.org 
8110898Sroland.mainz@nrubsig.org 	cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY);
8210898Sroland.mainz@nrubsig.org 	for (;;)
8310898Sroland.mainz@nrubsig.org 	{
8410898Sroland.mainz@nrubsig.org 		switch (optget(argv, usage))
8510898Sroland.mainz@nrubsig.org 		{
8610898Sroland.mainz@nrubsig.org 		case 0:
8710898Sroland.mainz@nrubsig.org 			break;
8810898Sroland.mainz@nrubsig.org 		case 'd':
8910898Sroland.mainz@nrubsig.org 			fdp = 0;
9010898Sroland.mainz@nrubsig.org 			continue;
9110898Sroland.mainz@nrubsig.org 		case 'm':
9210898Sroland.mainz@nrubsig.org 			mode = strperm(pfx = opt_info.arg, &opt_info.arg, S_IRWXU);
9310898Sroland.mainz@nrubsig.org 			if (*opt_info.arg)
9410898Sroland.mainz@nrubsig.org 				error(ERROR_exit(0), "%s: invalid mode", pfx);
9510898Sroland.mainz@nrubsig.org 			continue;
9610898Sroland.mainz@nrubsig.org 		case 'p':
9710898Sroland.mainz@nrubsig.org 			if ((t = getenv("TMPDIR")) && *t)
9810898Sroland.mainz@nrubsig.org 				dir = 0;
9910898Sroland.mainz@nrubsig.org 			else
10010898Sroland.mainz@nrubsig.org 				dir = opt_info.arg;
10110898Sroland.mainz@nrubsig.org 			continue;
10210898Sroland.mainz@nrubsig.org 		case 'q':
10310898Sroland.mainz@nrubsig.org 			quiet = 1;
10410898Sroland.mainz@nrubsig.org 			continue;
10510898Sroland.mainz@nrubsig.org 		case 't':
10610898Sroland.mainz@nrubsig.org 			dir = 0;
10710898Sroland.mainz@nrubsig.org 			continue;
10810898Sroland.mainz@nrubsig.org 		case 'u':
10910898Sroland.mainz@nrubsig.org 			unsafe = 1;
11010898Sroland.mainz@nrubsig.org 			fdp = 0;
11110898Sroland.mainz@nrubsig.org 			continue;
112*12068SRoger.Faulkner@Oracle.COM 		case 'R':
113*12068SRoger.Faulkner@Oracle.COM 			if (!pathtemp(NiL, 0, opt_info.arg, "/seed", NiL))
114*12068SRoger.Faulkner@Oracle.COM 				error(2, "%s: regression test initializtion failed", opt_info.arg);
115*12068SRoger.Faulkner@Oracle.COM 			continue;
11610898Sroland.mainz@nrubsig.org 		case ':':
11710898Sroland.mainz@nrubsig.org 			error(2, "%s", opt_info.arg);
11810898Sroland.mainz@nrubsig.org 			continue;
11910898Sroland.mainz@nrubsig.org 		case '?':
12010898Sroland.mainz@nrubsig.org 			error(ERROR_usage(2), "%s", opt_info.arg);
12110898Sroland.mainz@nrubsig.org 			continue;
12210898Sroland.mainz@nrubsig.org 		}
12310898Sroland.mainz@nrubsig.org 		break;
12410898Sroland.mainz@nrubsig.org 	}
12510898Sroland.mainz@nrubsig.org 	argv += opt_info.index;
12610898Sroland.mainz@nrubsig.org 	if (error_info.errors || (pfx = *argv++) && *argv)
12710898Sroland.mainz@nrubsig.org 		error(ERROR_usage(2), "%s", optusage(NiL));
12810898Sroland.mainz@nrubsig.org 	mask = umask(0);
12910898Sroland.mainz@nrubsig.org 	if (!mode)
13010898Sroland.mainz@nrubsig.org 		mode = (fdp ? (S_IRUSR|S_IWUSR) : S_IRWXU) & ~mask;
13110898Sroland.mainz@nrubsig.org 	umask(~mode & (S_IRWXU|S_IRWXG|S_IRWXO));
13210898Sroland.mainz@nrubsig.org 	if (!pfx)
13310898Sroland.mainz@nrubsig.org 	{
13410898Sroland.mainz@nrubsig.org 		pfx = "tmp_";
13510898Sroland.mainz@nrubsig.org 		if (dir && !*dir)
13610898Sroland.mainz@nrubsig.org 			dir = 0;
13710898Sroland.mainz@nrubsig.org 	}
13810898Sroland.mainz@nrubsig.org 	if (t = strrchr(pfx, '/'))
13910898Sroland.mainz@nrubsig.org 	{
14010898Sroland.mainz@nrubsig.org 		i = ++t - pfx;
14110898Sroland.mainz@nrubsig.org 		dir = fmtbuf(i);
14210898Sroland.mainz@nrubsig.org 		memcpy(dir, pfx, i);
14310898Sroland.mainz@nrubsig.org 		dir[i] = 0;
14410898Sroland.mainz@nrubsig.org 		pfx = t;
14510898Sroland.mainz@nrubsig.org 	}
14610898Sroland.mainz@nrubsig.org 	for (;;)
14710898Sroland.mainz@nrubsig.org 	{
14810898Sroland.mainz@nrubsig.org 		if (!pathtemp(path, sizeof(path), dir, pfx, fdp))
14910898Sroland.mainz@nrubsig.org 		{
15010898Sroland.mainz@nrubsig.org 			if (quiet)
15110898Sroland.mainz@nrubsig.org 				error_info.errors++;
15210898Sroland.mainz@nrubsig.org 			else
15310898Sroland.mainz@nrubsig.org 				error(ERROR_SYSTEM|2, "cannot create temporary path");
15410898Sroland.mainz@nrubsig.org 			break;
15510898Sroland.mainz@nrubsig.org 		}
15610898Sroland.mainz@nrubsig.org 		if (fdp || unsafe || !mkdir(path, mode))
15710898Sroland.mainz@nrubsig.org 		{
15810898Sroland.mainz@nrubsig.org 			if (fdp)
15910898Sroland.mainz@nrubsig.org 				close(*fdp);
16010898Sroland.mainz@nrubsig.org 			sfputr(sfstdout, path, '\n');
16110898Sroland.mainz@nrubsig.org 			break;
16210898Sroland.mainz@nrubsig.org 		}
16310898Sroland.mainz@nrubsig.org 		if (sh_checksig(context))
16410898Sroland.mainz@nrubsig.org 		{
16510898Sroland.mainz@nrubsig.org 			error_info.errors++;
16610898Sroland.mainz@nrubsig.org 			break;
16710898Sroland.mainz@nrubsig.org 		}
16810898Sroland.mainz@nrubsig.org 	}
16910898Sroland.mainz@nrubsig.org 	umask(mask);
17010898Sroland.mainz@nrubsig.org 	return error_info.errors != 0;
17110898Sroland.mainz@nrubsig.org }
172