Changeset View
Changeset View
Standalone View
Standalone View
usr.bin/mktemp/mktemp.c
Show All 33 Lines | |||||
* etc style hacks. | * etc style hacks. | ||||
* A cleanup, misc options and mkdtemp() calls were added to try and work | * A cleanup, misc options and mkdtemp() calls were added to try and work | ||||
* more like the OpenBSD version - which was first to publish the interface. | * more like the OpenBSD version - which was first to publish the interface. | ||||
*/ | */ | ||||
#include <err.h> | #include <err.h> | ||||
#include <getopt.h> | #include <getopt.h> | ||||
#include <paths.h> | #include <paths.h> | ||||
#include <stdbool.h> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#ifndef lint | #ifndef lint | ||||
static const char rcsid[] = | static const char rcsid[] = | ||||
"$FreeBSD$"; | "$FreeBSD$"; | ||||
#endif /* not lint */ | #endif /* not lint */ | ||||
static void usage(void); | static void usage(void); | ||||
static const struct option long_opts[] = { | static const struct option long_opts[] = { | ||||
{"directory", no_argument, NULL, 'd'}, | {"directory", no_argument, NULL, 'd'}, | ||||
{"tmpdir", optional_argument, NULL, 'p'}, | |||||
{"quiet", no_argument, NULL, 'q'}, | {"quiet", no_argument, NULL, 'q'}, | ||||
{"dry-run", no_argument, NULL, 'u'}, | {"dry-run", no_argument, NULL, 'u'}, | ||||
{NULL, no_argument, NULL, 0}, | {NULL, no_argument, NULL, 0}, | ||||
}; | }; | ||||
int | int | ||||
main(int argc, char **argv) | main(int argc, char **argv) | ||||
{ | { | ||||
int c, fd, ret; | int c, fd, ret; | ||||
char *tmpdir; | const char *prefix, *tmpdir; | ||||
const char *prefix; | |||||
char *name; | char *name; | ||||
int dflag, qflag, tflag, uflag; | int dflag, qflag, tflag, uflag; | ||||
bool prefer_tmpdir; | |||||
ret = dflag = qflag = tflag = uflag = 0; | ret = dflag = qflag = tflag = uflag = 0; | ||||
prefer_tmpdir = true; | |||||
prefix = "mktemp"; | prefix = "mktemp"; | ||||
name = NULL; | name = NULL; | ||||
tmpdir = NULL; | |||||
while ((c = getopt_long(argc, argv, "dqt:u", long_opts, NULL)) != -1) | while ((c = getopt_long(argc, argv, "dp:qt:u", long_opts, NULL)) != -1) | ||||
switch (c) { | switch (c) { | ||||
case 'd': | case 'd': | ||||
dflag++; | dflag++; | ||||
break; | break; | ||||
case 'p': | |||||
tmpdir = optarg; | |||||
if (tmpdir == NULL || *tmpdir == '\0') | |||||
tmpdir = getenv("TMPDIR"); | |||||
break; | |||||
case 'q': | case 'q': | ||||
qflag++; | qflag++; | ||||
break; | break; | ||||
case 't': | case 't': | ||||
prefix = optarg; | prefix = optarg; | ||||
tflag++; | tflag++; | ||||
break; | break; | ||||
case 'u': | case 'u': | ||||
uflag++; | uflag++; | ||||
break; | break; | ||||
default: | default: | ||||
usage(); | usage(); | ||||
} | } | ||||
argc -= optind; | argc -= optind; | ||||
argv += optind; | argv += optind; | ||||
if (!tflag && argc < 1) { | if (!tflag && argc < 1) { | ||||
tflag = 1; | tflag = 1; | ||||
prefix = "tmp"; | prefix = "tmp"; | ||||
/* | |||||
* For this implied -t mode, we actually want to swap the usual | |||||
* order of precedence: -p, then TMPDIR, then /tmp. | |||||
*/ | |||||
prefer_tmpdir = false; | |||||
} | } | ||||
if (tflag) { | if (tflag) { | ||||
tmpdir = getenv("TMPDIR"); | const char *envtmp; | ||||
envtmp = NULL; | |||||
/* | |||||
* $TMPDIR preferred over `-p` if specified, for compatibility. | |||||
*/ | |||||
if (prefer_tmpdir || tmpdir == NULL) | |||||
envtmp = getenv("TMPDIR"); | |||||
if (envtmp != NULL) | |||||
tmpdir = envtmp; | |||||
if (tmpdir == NULL) | if (tmpdir == NULL) | ||||
asprintf(&name, "%s%s.XXXXXXXXXX", _PATH_TMP, prefix); | asprintf(&name, "%s%s.XXXXXXXXXX", _PATH_TMP, prefix); | ||||
else | else | ||||
asprintf(&name, "%s/%s.XXXXXXXXXX", tmpdir, prefix); | asprintf(&name, "%s/%s.XXXXXXXXXX", tmpdir, prefix); | ||||
/* if this fails, the program is in big trouble already */ | /* if this fails, the program is in big trouble already */ | ||||
if (name == NULL) { | if (name == NULL) { | ||||
if (qflag) | if (qflag) | ||||
return (1); | return (1); | ||||
else | else | ||||
errx(1, "cannot generate template"); | errx(1, "cannot generate template"); | ||||
} | } | ||||
} | } | ||||
/* generate all requested files */ | /* generate all requested files */ | ||||
while (name != NULL || argc > 0) { | while (name != NULL || argc > 0) { | ||||
if (name == NULL) { | if (name == NULL) { | ||||
if (!tflag && tmpdir != NULL) | |||||
asprintf(&name, "%s/%s", tmpdir, argv[0]); | |||||
else | |||||
name = strdup(argv[0]); | name = strdup(argv[0]); | ||||
if (name == NULL) | |||||
err(1, "%s", argv[0]); | |||||
argv++; | argv++; | ||||
argc--; | argc--; | ||||
} | } | ||||
if (dflag) { | if (dflag) { | ||||
if (mkdtemp(name) == NULL) { | if (mkdtemp(name) == NULL) { | ||||
ret = 1; | ret = 1; | ||||
if (!qflag) | if (!qflag) | ||||
Show All 22 Lines | main(int argc, char **argv) | ||||
} | } | ||||
return (ret); | return (ret); | ||||
} | } | ||||
static void | static void | ||||
usage(void) | usage(void) | ||||
{ | { | ||||
fprintf(stderr, | fprintf(stderr, | ||||
"usage: mktemp [-d] [-q] [-t prefix] [-u] template ...\n"); | "usage: mktemp [-d] [-p tmpdir] [-q] [-t prefix] [-u] template " | ||||
"...\n"); | |||||
fprintf(stderr, | fprintf(stderr, | ||||
" mktemp [-d] [-q] [-u] -t prefix \n"); | " mktemp [-d] [-p tmpdir] [-q] [-u] -t prefix \n"); | ||||
exit (1); | exit (1); | ||||
} | } |