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