You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.7 KiB
92 lines
2.7 KiB
/* mktemp.c - Create a temporary file or directory.
|
|
*
|
|
* Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com>
|
|
*
|
|
* http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/mktemp.html
|
|
|
|
USE_MKTEMP(NEWTOY(mktemp, ">1(tmpdir);:uqd(directory)p:t", TOYFLAG_BIN))
|
|
|
|
config MKTEMP
|
|
bool "mktemp"
|
|
default y
|
|
help
|
|
usage: mktemp [-dqu] [-p DIR] [TEMPLATE]
|
|
|
|
Safely create a new file "DIR/TEMPLATE" and print its name.
|
|
|
|
-d Create directory instead of file (--directory)
|
|
-p Put new file in DIR (--tmpdir)
|
|
-q Quiet, no error messages
|
|
-t Prefer $TMPDIR > DIR > /tmp (default DIR > $TMPDIR > /tmp)
|
|
-u Don't create anything, just print what would be created
|
|
|
|
Each X in TEMPLATE is replaced with a random printable character. The
|
|
default TEMPLATE is tmp.XXXXXXXXXX.
|
|
*/
|
|
|
|
#define FOR_mktemp
|
|
#include "toys.h"
|
|
|
|
GLOBALS(
|
|
char *p, *tmpdir;
|
|
)
|
|
|
|
void mktemp_main(void)
|
|
{
|
|
char *template = *toys.optargs, *dir, *te = getenv("TMPDIR");
|
|
int len;
|
|
|
|
// --tmpdir's argument is optional's but -p is mandatory, so can't combine
|
|
if (!TT.p && FLAG(tmpdir)) {
|
|
TT.p = TT.tmpdir ? TT.tmpdir : "";
|
|
toys.optflags |= FLAG_p;
|
|
}
|
|
dir = TT.p;
|
|
// if template, no prefix unless -pt. if !template, always prefix
|
|
if (!dir || !*dir || (FLAG(t) && te && *te)) dir = te;
|
|
if (!dir || !*dir) dir = "/tmp";
|
|
if (!template) template = "tmp.XXXXXXXXXX";
|
|
else {
|
|
if (*template == '/' && TT.p && *TT.p) perror_exit("-p + /template");
|
|
if (!FLAG(p)&&!FLAG(t)) dir = 0;
|
|
}
|
|
|
|
// TODO: coreutils cleans paths, so -p /t/// would result in /t/xxx...
|
|
template = dir ? xmprintf("%s/%s", dir, template) : xstrdup(template);
|
|
len = strlen(template);
|
|
if (len<3 || strcmp(template+len-3, "XXX")) perror_exit("need XXX");
|
|
|
|
// In theory you just xputs(mktemp(template)) for -u, in practice there's
|
|
// link-time deprecation warnings if you do that. So we fake up our own:
|
|
if (FLAG(u)) {
|
|
long long rr;
|
|
char *s = template+len;
|
|
|
|
// Fall back to random-ish if xgetrandom fails.
|
|
if (!xgetrandom(&rr, sizeof(rr), WARN_ONLY)) {
|
|
struct timespec ts;
|
|
|
|
clock_gettime(CLOCK_REALTIME, &ts);
|
|
rr = ts.tv_nsec*65537+(long)template+getpid()+(long)&template;
|
|
}
|
|
// Replace X with 64 chars from posix portable character set (all but "_").
|
|
while (--s>template) {
|
|
if (*s != 'X') break;
|
|
*s = '-'+(rr&63);
|
|
if (*s>'.') ++*s;
|
|
if (*s>'9') (*s) += 7;
|
|
if (*s>'Z') (*s) += 6;
|
|
rr>>=6;
|
|
}
|
|
} else if (FLAG(d) ? !mkdtemp(template) : mkstemp(template) == -1) {
|
|
if (FLAG(q)) {
|
|
toys.exitval = 1;
|
|
return;
|
|
} else perror_exit("Failed to create %s %s",
|
|
FLAG(d) ? "directory" : "file", template);
|
|
}
|
|
|
|
xputs(template);
|
|
if (CFG_TOYBOX_FREE) free(template);
|
|
}
|