test/mhshow/test-charset test/mhshow/test-textcharset \
test/mhshow/test-cte-binary test/mhshow/test-qp \
test/mhshow/test-subpart test/mhshow/test-msg-buffer-boundaries \
- test/mhstore/test-mhstore test/new/test-basic \
- test/pick/test-pick test/pick/test-stderr \
+ test/mhstore/test-mhstore test/mkstemp/test-mkstemp \
+ test/new/test-basic test/pick/test-pick test/pick/test-stderr \
test/post/test-post-aliases test/post/test-post-basic \
test/post/test-post-multiple test/post/test-post-bcc \
test/post/test-post-dcc test/post/test-post-fcc \
##
## This is all programs that get installed in the "lib" directory
##
-auxexec_PROGRAMS = uip/ap uip/conflict uip/dp uip/fmtdump uip/mhl uip/post \
- uip/rcvdist uip/rcvpack uip/rcvstore uip/rcvtty uip/slocal \
- uip/viamail uip/mhtest
+auxexec_PROGRAMS = uip/ap uip/conflict uip/dp uip/fmtdump uip/mhl uip/mkstemp \
+ uip/post uip/rcvdist uip/rcvpack uip/rcvstore uip/rcvtty \
+ uip/slocal uip/viamail uip/mhtest
auxexec_SCRIPTS = uip/spost
man/mh-format.5 man/mh-mail.5 man/mh-profile.5 man/mh_profile.5 \
man/mh-sequence.5 man/mh-tailor.5 man/mhbuild.1 man/mhfixmsg.1 \
man/mhl.1 man/mhlist.1 man/mhmail.1 man/mhn.1 man/mhparam.1 \
- man/mhpath.1 man/mhshow.1 man/mhstore.1 man/msgchk.1 man/msh.1 \
- man/mts.conf.5 man/new.1 man/next.1 man/nmh.7 man/packf.1 \
+ man/mhpath.1 man/mhshow.1 man/mhstore.1 man/mkstemp.1 man/msgchk.1 \
+ man/msh.1 man/mts.conf.5 man/new.1 man/next.1 man/nmh.7 man/packf.1 \
man/pick.1 man/post.8 man/prev.1 man/prompter.1 man/rcvdist.1 \
man/rcvpack.1 man/rcvstore.1 man/rcvtty.1 man/refile.1 \
man/repl.1 man/rmf.1 man/rmm.1 man/scan.1 man/send.1 \
man/mh_profile.man man/mh-sequence.man man/mh-tailor.man \
man/mhbuild.man man/mhfixmsg.man man/mhl.man man/mhlist.man \
man/mhmail.man man/mhn.man man/mhparam.man man/mhpath.man \
- man/mhshow.man man/mhstore.man man/msgchk.man man/msh.man \
- man/mts.conf.man man/new.man man/next.man man/nmh.man \
+ man/mhshow.man man/mhstore.man man/mkstemp.man man/msgchk.man \
+ man/msh.man man/mts.conf.man man/new.man man/next.man man/nmh.man \
man/packf.man man/pick.man man/post.man man/prev.man \
man/prompter.man man/rcvdist.man man/rcvpack.man \
man/rcvstore.man man/rcvtty.man man/refile.man man/repl.man \
uip/md5.c
uip_mhtest_LDADD = $(LDADD) $(TERMLIB) $(POSTLINK)
+uip_mkstemp_SOURCES = uip/mkstemp.c
+uip_mkstemp_LDADD = $(LDADD) $(POSTLINK)
+
uip_post_SOURCES = uip/post.c uip/aliasbr.c
uip_post_LDADD = mts/libmts.a $(LDADD) $(SASLLIB) $(TLSLIB) $(POSTLINK)
--- /dev/null
+#!/bin/sh
+##################################
+#
+# Test creation of temporary file.
+#
+##################################
+
+set -e
+
+if test -z "${MH_OBJ_DIR}"; then
+ srcdir=`dirname "$0"`/../..
+ MH_OBJ_DIR=`cd "$srcdir" && pwd`; export MH_OBJ_DIR
+fi
+
+. "$MH_OBJ_DIR/test/common.sh"
+
+setup_test
+
+expected="$MH_TEST_DIR"/$$.expected
+actual="$MH_TEST_DIR"/$$.actual
+
+mkstemp="${MH_LIB_DIR}/mkstemp"
+
+cd "$MHTMPDIR"
+
+
+# check -help
+cat >$expected <<'EOF'
+Usage: mkstemp [switches]
+ switches are:
+ -directory
+ -prefix
+ -suffix
+ -version
+ -help
+EOF
+
+$mkstemp -h >$actual 2>&1
+check $expected $actual
+
+
+# check -version
+# Verified same behavior as compiled mhmail.
+case `$mkstemp -v` in
+ mkstemp\ --*) ;;
+ * ) printf '%s: mkstemp -v generated unexpected output\n' "$0" >&2
+ failed=`expr ${failed:-0} + 1`;;
+esac
+
+
+# check with no switches
+tmpfile=`$mkstemp`
+if [ -f "$tmpfile" ]; then
+ rm "$tmpfile"
+else
+ failed=1
+fi
+
+
+# check -directory
+tmpfile=`$mkstemp -directory "$MHTMPDIR"`
+[ -f "$tmpfile" ] && rm "$tmpfile" || failed=`expr ${failed:-0} + 1`
+check_tmpfile=`echo $tmpfile | grep "^$MHTMPDIR/......$" >/dev/null`
+run_test `echo $check_tmpfile` ''
+
+
+# check -prefix
+tmpfile=`$mkstemp -prefix mkstemptest`
+[ -f "$tmpfile" ] && rm "$tmpfile" || failed=`expr ${failed:-0} + 1`
+check_tmpfile=`echo $tmpfile | grep '^mkstemptest......$' >/dev/null`
+run_test `echo $check_tmpfile` ''
+
+
+# check -suffix
+tmpfile=`$mkstemp -suffix .txt`
+[ -f "$tmpfile" ] && rm "$tmpfile" || failed=`expr ${failed:-0} + 1`
+check_tmpfile=`echo $tmpfile | grep '^......\.txt$' >/dev/null`
+run_test `echo $check_tmpfile` ''
+
+
+exit $failed
--- /dev/null
+/*
+ * mkstemp.c -- create a temporary file
+ *
+ * This code is Copyright (c) 2014 by the authors of nmh.
+ * See the COPYRIGHT file in the root directory of the nmh
+ * distribution for complete copyright information.
+ */
+
+/* define NMH to 0 to remove dependencies on nmh. */
+#ifndef NMH
+# define NMH 1
+#endif /* ! NMH */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#if ! defined HAVE_MKSTEMPS
+# define HAVE_MKSTEMPS 0
+#endif /* ! HAVE_MKSTEMPS */
+
+char *build_template(const char *, const char *, const char *);
+void process_args(int, char **, const char **, const char **, const char **);
+
+/*
+ * Use a template of the form:
+ * [directory/][prefix]XXXXXX[suffix]
+ * where some of those named components might be null. suffix is only
+ * supported if HAVE_MKSTEMPS.
+ */
+
+int
+main(int argc, char *argv[]) {
+ const char *directory = "", *prefix = "", *suffix = "";
+ size_t suffix_len;
+ int fd;
+ char *template;
+
+ process_args(argc, argv, &directory, &prefix, &suffix);
+ if ((template = build_template(directory, prefix, suffix)) == NULL) {
+ return -1;
+ }
+
+ if ((suffix_len = strlen(suffix)) > 0) {
+# if HAVE_MKSTEMPS
+ if ((fd = mkstemps(template, suffix_len)) < 0) { perror("mkstemps"); }
+# endif /* HAVE_MKSTEMPS */
+ } else {
+ if ((fd = mkstemp(template)) < 0) { perror("mkstemp"); }
+ }
+
+ if (fd >= 0) {
+ (void) puts(template);
+ (void) close(fd);
+ }
+
+ free(template);
+
+ return fd >= 0 ? 0 : -1;
+}
+
+
+char *
+build_template(const char *directory, const char *prefix, const char *suffix) {
+ const char pattern[] = "XXXXXX";
+ size_t len, directory_len, pathsep_len, prefix_len, suffix_len;
+ char *template;
+
+ directory_len = strlen(directory);
+ if (directory_len > 0) {
+ pathsep_len = 1;
+ if (directory[directory_len - 1] == '/') {
+ /* Will insert a '/' separately, so truncate the one provided
+ in the directory name. */
+ --directory_len;
+ }
+ } else {
+ pathsep_len = 0;
+ }
+ prefix_len = strlen(prefix);
+ suffix_len = strlen(suffix);
+ /* sizeof pattern includes its final NULL, so don't add another. */
+ len = directory_len + pathsep_len + prefix_len + sizeof pattern +
+ suffix_len;
+
+ if ((template = malloc(len))) {
+ char *tp = template;
+
+ (void) strncpy(tp, directory, directory_len);
+ tp += directory_len;
+
+ if (pathsep_len == 1) { *tp++ = '/'; }
+
+ (void) strncpy(tp, prefix, prefix_len);
+ tp += prefix_len;
+
+ (void) strncpy(tp, pattern, sizeof pattern - 1);
+ tp += sizeof pattern - 1;
+
+ (void) strncpy(tp, suffix, suffix_len);
+ tp += suffix_len;
+
+ template[len-1] = '\0';
+
+ return template;
+ } else {
+ perror("malloc");
+ return NULL;
+ }
+}
+
+
+#if NMH
+#include <h/mh.h>
+
+#if HAVE_MKSTEMPS
+# define MHFIXMSG_SWITCHES \
+ X("directory", 0, DIRECTORYSW) \
+ X("prefix", 0, PREFIXSW) \
+ X("suffix", 0, SUFFIXSW) \
+ X("version", 0, VERSIONSW) \
+ X("help", 0, HELPSW)
+#else /* ! HAVE_MKSTEMPS */
+# define MHFIXMSG_SWITCHES \
+ X("directory", 0, DIRECTORYSW) \
+ X("prefix", 0, PREFIXSW) \
+ X("version", 0, VERSIONSW) \
+ X("help", 0, HELPSW)
+#endif /* ! HAVE_MKSTEMPS */
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MHFIXMSG);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MHFIXMSG, switches);
+#undef X
+
+void
+process_args(int argc, char **argv, const char **directory,
+ const char **prefix, const char **suffix) {
+ char **argp, **arguments, *cp, buf[100];
+# if ! HAVE_MKSTEMPS
+ NMH_UNUSED(suffix);
+# endif /* ! HAVE_MKSTEMPS */
+
+ if (nmh_init(argv[0], 1)) { done(NOTOK); }
+ arguments = getarguments (invo_name, argc, argv, 1);
+ argp = arguments;
+
+ /*
+ * Parse arguments
+ */
+ while ((cp = *argp++)) {
+ if (*cp == '-') {
+ switch (smatch(++cp, switches)) {
+ case AMBIGSW:
+ ambigsw(cp, switches);
+ done(NOTOK);
+ case UNKWNSW:
+ advise (NULL, "-%s unknown", cp);
+ (void) snprintf(buf, sizeof buf, "%s [switches]", invo_name);
+ print_help(buf, switches, 1);
+ done(NOTOK);
+ case HELPSW:
+ (void) snprintf(buf, sizeof buf, "%s [switches]", invo_name);
+ print_help(buf, switches, 1);
+ done(OK);
+ case VERSIONSW:
+ print_version(invo_name);
+ done(OK);
+
+ case DIRECTORYSW:
+ /* Allow the directory to start with '-'. */
+ if ((cp = *argp++) == NULL) {
+ adios(NULL, "missing argument to %s", argp[-2]);
+ }
+ *directory = cp;
+ continue;
+
+ case PREFIXSW:
+ /* Allow the prefix to start with '-'. */
+ if ((cp = *argp++) == NULL) {
+ adios(NULL, "missing argument to %s", argp[-2]);
+ }
+ *prefix = cp;
+ continue;
+
+# if HAVE_MKSTEMPS
+ case SUFFIXSW:
+ /* Allow the suffix to start with '-'. */
+ if ((cp = *argp++) == NULL) {
+ adios(NULL, "missing argument to %s", argp[-2]);
+ }
+ *suffix = cp;
+ continue;
+# endif /* HAVE_MKSTEMPS */
+ }
+ }
+ }
+}
+#else /* ! NMH */
+void
+process_args(int argc, char **argv, const char **directory,
+ const char **prefix, const char **suffix) {
+# if HAVE_MKSTEMPS
+ const char usage[] =
+ "usage: %s [-h] [-d directory] [-p prefix] [-s suffix]\n";
+ const char optstring[] = "d:hp:s:";
+# else /* ! HAVE_MKSTEMPS */
+ const char usage[] = "usage: %s [-h] [-d directory] [-p prefix]\n";
+ const char optstring[] = "d:hp:";
+# endif /* ! HAVE_MKSTEMPS */
+ int opt;
+
+ while ((opt = getopt(argc, argv, optstring)) != -1) {
+ switch (opt) {
+ case 'd':
+ *directory = optarg;
+ break;
+ case 'p':
+ *prefix = optarg;
+ break;
+ case 's':
+ *suffix = optarg;
+ break;
+ case 'h':
+ (void) printf(usage, argv[0]);
+ exit(0);
+ default:
+ (void) fprintf(stderr, usage, argv[0]);
+ exit(-1);
+ }
+ }
+}
+#endif /* ! NMH */