summaryrefslogtreecommitdiff
path: root/usr/src/lib/libcmd/common/mktemp.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libcmd/common/mktemp.c')
-rw-r--r--usr/src/lib/libcmd/common/mktemp.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/usr/src/lib/libcmd/common/mktemp.c b/usr/src/lib/libcmd/common/mktemp.c
new file mode 100644
index 0000000000..2936a56e22
--- /dev/null
+++ b/usr/src/lib/libcmd/common/mktemp.c
@@ -0,0 +1,164 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1992-2009 AT&T Intellectual Property *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.opensource.org/licenses/cpl1.0.txt *
+* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+static const char usage[] =
+"[-?\n@(#)$Id: mktemp (AT&T Research) 2009-06-19 $\n]"
+USAGE_LICENSE
+"[+NAME?mktemp - make temporary file or directory]"
+"[+DESCRIPTION?\bmktemp\b creates a temporary file with optional base "
+ "name prefix \aprefix\a. If \aprefix\a is omitted then \btmp_\b is used "
+ "and \b--tmp\b is implied. If \aprefix\a contains a directory prefix "
+ "then that directory overrides any of the directories described below. A "
+ "temporary file will have mode \brw-------\b and a temporary directory "
+ "will have mode \brwx------\b, subject to \bumask\b(1). Generated paths "
+ "have these attributes:]"
+ "{"
+ "[+*?Lower case to avoid clashes on case ignorant filesystems.]"
+ "[+*?Pseudo-random part to deter denial of service attacks.]"
+ "[+*?Pseudo-random part is \a3-chars\a.\a3-chars\a to accomodate "
+ "8.3 filesystems.]"
+ "}"
+"[+?A consecutive sequence of \bX\b's in \aprefix\a is replaced by the "
+ "pseudo-random part. If there are no \bX\b's then the pseudo-random part "
+ "is appended to the prefix.]"
+"[d:directory?Create a directory instead of a regular file.]"
+"[m:mode]:[mode?Set the mode of the created temporary to \amode\a. "
+ "\amode\a is symbolic or octal mode as in \bchmod\b(1). Relative modes "
+ "assume an initial mode of \bu=rwx\b.]"
+"[p:default?Use \adirectory\a if the \bTMPDIR\b environment variable is "
+ "not defined. Implies \b--tmp\b.]:[directory]"
+"[q:quiet?Suppress file and directory error diagnostics.]"
+"[t:tmp|temporary-directory?Create a path rooted in a temporary "
+ "directory.]"
+"[u:unsafe|dry-run?Check for file/directory existence but do not create. "
+ "Who would want to do that.]"
+"\n"
+"\n[ prefix ]\n"
+"\n"
+"[+SEE ALSO?\bmkdir\b(1), \bpathtemp\b(3), \bmktemp\b(3)]"
+;
+
+#include <cmd.h>
+#include <ls.h>
+
+int
+b_mktemp(int argc, char** argv, void* context)
+{
+ mode_t mode = 0;
+ mode_t mask;
+ int fd;
+ int i;
+ int quiet = 0;
+ int unsafe = 0;
+ int* fdp = &fd;
+ char* dir = "";
+ char* pfx;
+ char* t;
+ char path[PATH_MAX];
+
+ cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY);
+ for (;;)
+ {
+ switch (optget(argv, usage))
+ {
+ case 0:
+ break;
+ case 'd':
+ fdp = 0;
+ continue;
+ case 'm':
+ mode = strperm(pfx = opt_info.arg, &opt_info.arg, S_IRWXU);
+ if (*opt_info.arg)
+ error(ERROR_exit(0), "%s: invalid mode", pfx);
+ continue;
+ case 'p':
+ if ((t = getenv("TMPDIR")) && *t)
+ dir = 0;
+ else
+ dir = opt_info.arg;
+ continue;
+ case 'q':
+ quiet = 1;
+ continue;
+ case 't':
+ dir = 0;
+ continue;
+ case 'u':
+ unsafe = 1;
+ fdp = 0;
+ continue;
+ case ':':
+ error(2, "%s", opt_info.arg);
+ continue;
+ case '?':
+ error(ERROR_usage(2), "%s", opt_info.arg);
+ continue;
+ }
+ break;
+ }
+ argv += opt_info.index;
+ if (error_info.errors || (pfx = *argv++) && *argv)
+ error(ERROR_usage(2), "%s", optusage(NiL));
+ mask = umask(0);
+ if (!mode)
+ mode = (fdp ? (S_IRUSR|S_IWUSR) : S_IRWXU) & ~mask;
+ umask(~mode & (S_IRWXU|S_IRWXG|S_IRWXO));
+ if (!pfx)
+ {
+ pfx = "tmp_";
+ if (dir && !*dir)
+ dir = 0;
+ }
+ if (t = strrchr(pfx, '/'))
+ {
+ i = ++t - pfx;
+ dir = fmtbuf(i);
+ memcpy(dir, pfx, i);
+ dir[i] = 0;
+ pfx = t;
+ }
+ for (;;)
+ {
+ if (!pathtemp(path, sizeof(path), dir, pfx, fdp))
+ {
+ if (quiet)
+ error_info.errors++;
+ else
+ error(ERROR_SYSTEM|2, "cannot create temporary path");
+ break;
+ }
+ if (fdp || unsafe || !mkdir(path, mode))
+ {
+ if (fdp)
+ close(*fdp);
+ sfputr(sfstdout, path, '\n');
+ break;
+ }
+ if (sh_checksig(context))
+ {
+ error_info.errors++;
+ break;
+ }
+ }
+ umask(mask);
+ return error_info.errors != 0;
+}