appropriate ordinal suffix for numbers. Example: "%(num 22)%(ordinal)"
will output "22nd".
- show and mhl now decode more addresses in header fields.
+- Added warning from all programs that read the profile if the profile
+ contains a post entry, which is ignored, but does not contain a
+ postproc entry. In other words, if you get this warning and want
+ to suppress it, your options include:
+ 1) Remove your post profile entry.
+ 2) Make your post profile entry a comment by prepending it with the #:
+ comment indicator.
+ 3) Add a postproc entry that points to the post that you use. That can
+ be viewed with "mhparam postproc".
-----------------
OBSOLETE FEATURES
Version: %nmhversion%
.fi
.RE
+.RE
.SS "Process Profile Entries"
The following profile elements are used whenever an
.B nmh
and
.BR \-library )
to do address verification.
+.PP
+If the profile contains a
+.B post
+component and a
+.B postproc
+component is not present, a warning message that the
+.B post
+component will be ignored will be displayed by every
+.B nmh
+program that reads the profile and has its stderr associated with a terminal.
.RE
.PP
.BR rmmproc :
/*
* static prototypes
*/
+static void read_mts(const char *path);
static char *tailor_value (char *);
static void getuserinfo (void);
-static const char *get_mtsconf_pathname(void);
-static const char *get_mtsuserconf_pathname(void);
+static const char *get_optional_env_var(const char *name, const char *fallback);
static void mts_read_conf_file (FILE *fp);
/*
/*
* nmh mail transport interface customization file
*/
-static char *mtsconf = nmhetcdir(/mts.conf);
-
static char *localname = "";
static char *localdomain = "";
static char *systemname = "";
void
mts_init (void)
{
- const char *cp;
- FILE *fp;
- static int inited = 0;
+ static bool deja_vu;
+ const char *path;
- if (inited++ || (fp = fopen (get_mtsconf_pathname(), "r")) == NULL)
- return;
- mts_read_conf_file(fp);
- fclose (fp);
+ if (deja_vu)
+ return;
+ deja_vu = true;
- cp = get_mtsuserconf_pathname();
- if (cp != NULL &&
- ((fp = fopen (get_mtsuserconf_pathname(), "r")) != NULL)) {
- mts_read_conf_file(fp);
- fclose (fp);
- }
+ path = get_optional_env_var("MHMTSCONF", NMHETCDIR "/mts.conf");
+ read_mts(path);
+
+ path = get_optional_env_var("MHMTSUSERCONF", NULL);
+ if (path)
+ read_mts(path);
save_mts_method (mts_method);
}
+static void read_mts(const char *path)
+{
+ FILE *fp;
+
+ fp = fopen(path, "r");
+ if (!fp)
+ adios(path, "error opening mts.conf:");
+ mts_read_conf_file(fp);
+ if (ferror(fp))
+ adios(path, "error reading mts.conf:");
+ if (fclose(fp))
+ adios(path, "error closing mts.conf:");
+}
+
+
#define QUOTE '\\'
/*
escape_local_part(mboxname, sizeof(mboxname));
}
-static const char*
-get_mtsconf_pathname (void)
-{
- const char *cp = getenv ( "MHMTSCONF" );
- if (cp != NULL && *cp != '\0') {
- return cp;
- }
- return mtsconf;
-}
-static const char*
-get_mtsuserconf_pathname (void)
+static const char *
+get_optional_env_var(const char *name, const char *fallback)
{
- const char *cp = getenv ( "MHMTSUSERCONF" );
- if (cp != NULL && *cp != '\0') {
- return cp;
- }
- return NULL;
+ const char *v = getenv(name);
+ if (v)
+ return v;
+ return fallback;
}
+
static void
mts_read_conf_file (FILE *fp)
{
*/
#include "h/mh.h"
+#include "sbr/context_find.h"
#include "m_getfld.h"
#include "trimcpy.h"
#include "getcpy.h"
#include "error.h"
#include "h/utils.h"
+static void checkconfig();
+
struct procstr {
char *procname;
char **procnaddr;
}
if (opp == NULL) {
- /* Check for duplicated non-null profile entries. Except
- allow multiple profile entries named "#", because that's
- what mh-profile(5) suggests using for comments.
-
- Only do this check on the very first call from
- context_read(), when opp is NULL. That way, entries in
- mhn.defaults can be overridden without triggering
- warnings.
-
- Note that mhn.defaults, $MHN, $MHBUILD, $MHSHOW, and
- $MHSTORE all put their entries into just one list, m_defs,
- the same list that the profile uses. */
-
- struct node *np;
- for (np = m_defs; np; np = np->n_next) {
- /* Yes, this is O(N^2). The profile should be small enough so
- that's not a performance problem. */
- if (*np->n_name && strcmp("#", np->n_name)) {
- struct node *np2;
- for (np2 = np->n_next; np2; np2 = np2->n_next) {
- if (! strcasecmp (np->n_name, np2->n_name)) {
- inform("multiple \"%s\" profile components in %s, "
- "ignoring \"%s\", continuing...",
- np->n_name, defpath, np2->n_field);
- }
- }
- }
- }
+ checkconfig();
}
opp = npp;
newnode->n_next = m_defs;
m_defs = newnode;
}
+
+
+/* Check profile for issues to warn about. */
+void
+checkconfig() {
+ /* Check for duplicated non-null profile entries. Except
+ allow multiple profile entries named "#", because that's
+ what mh-profile(5) suggests using for comments.
+
+ Only do this check on the very first call from
+ context_read(), when opp is NULL. That way, entries in
+ mhn.defaults can be overridden without triggering
+ warnings.
+
+ Note that mhn.defaults, $MHN, $MHBUILD, $MHSHOW, and
+ $MHSTORE all put their entries into just one list, m_defs,
+ the same list that the profile uses. */
+ struct node *np;
+ bool has_post = false;
+ bool post_warning_disabled = false;
+ for (np = m_defs; np; np = np->n_next) {
+ if (*np->n_name) {
+ if (isatty(fileno(stderr))) {
+ /* Check for post component in profile. */
+ if (strcasecmp(np->n_name, "post") == 0) {
+ has_post = true;
+ } else if (strcasecmp(np->n_name, "postproc") == 0 &&
+ np->n_field != NULL) {
+ post_warning_disabled = true;
+ }
+ }
+
+ if (strcmp("#", np->n_name)) {
+ /* Yes, this is O(N^2). The profile should be small enough so
+ that's not a performance problem. */
+ struct node *np2;
+ for (np2 = np->n_next; np2; np2 = np2->n_next) {
+ if (! strcasecmp (np->n_name, np2->n_name)) {
+ inform("multiple \"%s\" profile components in %s, "
+ "ignoring \"%s\", continuing...",
+ np->n_name, defpath, np2->n_field);
+ }
+ }
+ }
+ }
+ }
+
+ if (has_post && ! post_warning_disabled) {
+ inform("post profile component will be ignored. To suppress "
+ "this warning,\n"
+ "either remove it, comment it with #:, or "
+ "add the following to %s:\npostproc: %s\n",
+ defpath, postproc);
+ }
+}
--- /dev/null
+#!/bin/sh
+######################################################
+#
+# Test profile parser warning messages.
+#
+######################################################
+
+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
+require_runpty_to_simulate_tty
+
+actual="${MH_TEST_DIR}/test-profile$$.actual"
+expected="$MH_TEST_DIR/test-profile$$.expected"
+
+start_test 'without post component in profile'
+set +e
+run_test 'mhparam post' ''
+set -e
+
+start_test 'disabled post warning'
+echo 'post: -snoop' >>"$MH"
+run_test 'mhparam post' '-snoop'
+
+start_test 'with no postproc component in profile'
+grep -v '^postproc: ' "$MH" >"$MH.new"
+cat >"$expected" <<EOF
+mhparam: post profile component will be ignored. To suppress this warning,\r
+either remove it, comment it with #:, or add the following to $MH.new:\r
+postproc: ${nmhlibexecdir}/post\r
+\r
+-snoop\r
+EOF
+MH="$MH.new" run_without_input "${actual}" mhparam post
+check "$expected" "$actual"
+rm -f "$MH.new"
+
+start_test 'multiple profile components'
+printf 'repeated-component: 1\nrepeated-component: 2\n' >>"$MH"
+run_test 'mhparam moreproc' \
+ "mhparam: multiple \"repeated-component\" profile components in $MH,"\
+" ignoring \"2\", continuing...
+cat"
+
+finish_test
+exit ${failed}