test/mhshow/test-subpart test/mhstore/test-mhstore \
test/new/test-basic \
test/pick/test-pick test/pick/test-stderr \
- test/post/test-post-basic test/post/test-post-multiple \
- test/post/test-post-bcc \
+ 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 \
test/post/test-post-multifrom test/post/test-post-envelope \
test/post/test-post-group test/post/test-mts test/post/test-messageid \
the mh-tailor(5) man page. The spost -noalias, -backup/-nobackup,
-push/-nopush, and -remove/-noremove switches are not supported by
post. Note that spost did not support -whom or Dcc, and neither
- does post when using sendmail/pipe. For backward compatibility,
- spost has been replaced by a simple shell script that exec's
- post -mts sendmail/pipe.
+ does post when using sendmail/pipe. And spost would expand blind
+ aliases and send them in the message; post with sendmail/pipe
+ refuses to do that. For backward compatibility, spost has been
+ replaced by a simple shell script that exec's post -mts
+ sendmail/pipe.
---------
BUG FIXES
- Removed obsolete BUGS section at end of rcvstore(1) man page [Bug #4361].
- Fixed -nocc me doesn't account for Alternate-Mailboxes [Bug #36635].
- Propagate Mail-Followup-To [Bug #5571].
+- "mark -sequence cur -delete all" now works for cur as well as any
+ other sequence, to allow clearing of the current message indication.
+- The first alias contained in a blind list is now expanded. The
+ mh-alias(5) man page was updated to show that blind lists must not
+ be terminated with, or contain, a trailing semicolon [Bug #15604].
struct home *h_next; /* next home in list */
};
-struct home *seek_home (char *);
-
/*
* prototypes
*/
not usually output, rather the address\-group that the alias maps to is
output instead. If \*(lqalias\*(rq is terminated with a `;' instead of
a `:', then both the \*(lqalias\*(rq and the address are output in the
-correct format. (This makes replies possible since
+correct format (with the alias quoted if necessary and the address
+wrapped in <>).
+
+This makes replies possible since
.B nmh
aliases
-and personal aliases are unknown to the mail transport system.)
+and personal aliases are unknown to the mail transport system.
.RE
.PP
Since the alias file is read line by line, forward references work, but
.nf
<%etcdir%/BBoardAliases
sgroup: fred, fear, freida
-b-people: Blind List: bill, betty;
+b-people: Blind List: bill, betty
fred: frated@UCI
UNIX\-committee: <unix.aliases
staff: =staff
is defined as an alias for the three names \*(lqfrated@UCI\*(rq,
\*(rqfear\*(rq, and \*(rqfreida\*(rq.
.PP
+
The alias \*(lqb-people\*(rq is a blind list which includes the addresses
\*(lqbill\*(rq and \*(lqbetty\*(rq; the message will be delivered to those
-addresses, but the message header will show only \*(lqBlind List: ;\*(rq
-(not the addresses).
+addresses, but the message header will show only \*(lqBlind List: ;\*(rq
+(not the addresses). The alias must not be terminated with, or contain,
+a semicolon; see
+.B Helpful Hints
+below. Note that blind lists are not supported with the
+.B sendmail/pipe
+mail transport method.
.PP
Next, the definition of \*(lqUNIX\-committee\*(rq is given by
reading the file
.RI \*(lq aliases \*(rq
file as appropriate.
.RE
+.PP
+Earlier versions of this man page showed a semicolon at the end of the
+blind list example. That caused the preceeding alias to not be
+expanded. There must not be a semicolon at the end of, or within, the
+address group of a blind list.
+.B post
+will append the semicolon to the blind list name.
.SH FILES
.fc ^ ~
Since the number of file descriptors is finite (and very limited), such
infinite recursion will terminate with a meaningless diagnostic when
all the fds are used up.
-.PP
-Forward references do not work correctly inside blind lists.
if (is_selected (mp, msgnum))
clear_sequence (mp, i, msgnum);
+ if (! strcmp (cp, current) &&
+ mp->lowsel <= mp->curmsg && mp->curmsg <= mp->hghsel) {
+ /* Removed current message indication, so reset curmsg. */
+ mp->curmsg = 0;
+ }
+
/*
* Set the public/private bit for this sequence.
*/
run_test 'ali' ''
# check with nonexistent alias file
-run_test 'ali -alias aliases' \
- "ali: aliasing error in aliases - unable to read 'aliases'"
+run_test 'ali -alias nonexistent' \
+ "ali: aliasing error in nonexistent - unable to read 'nonexistent'"
-cat >${MH_TEST_DIR}/Mail/aliases <<EOF
+cat >"${MH_TEST_DIR}/Mail/aliases" <<EOF
me: me@example.com
-rush: geddy@example.com, alex@example.com, neil@example.com
+rush: geddy, alex, neil
+geddy: geddy@example.com
+alex: alex@example.com
+neil: neil@example.com
EOF
# check -alias
run_test "ali -alias ${MH_TEST_DIR}/Mail/aliases" \
'me: me@example.com
-rush: geddy@example.com, alex@example.com, neil@example.com'
+rush: geddy@example.com, alex@example.com, neil@example.com
+geddy: geddy@example.com
+alex: alex@example.com
+neil: neil@example.com'
# check for a specific alias
run_test "ali -alias ${MH_TEST_DIR}/Mail/aliases rush" \
'me: me@example.com
rush: geddy@example.com
alex@example.com
- neil@example.com'
+ neil@example.com
+geddy: geddy@example.com
+alex: alex@example.com
+neil: neil@example.com'
# check -nolist, which is the default
run_test "ali -alias ${MH_TEST_DIR}/Mail/aliases -list -nolist" \
'me: me@example.com
-rush: geddy@example.com, alex@example.com, neil@example.com'
+rush: geddy@example.com, alex@example.com, neil@example.com
+geddy: geddy@example.com
+alex: alex@example.com
+neil: neil@example.com'
# check -user
run_test "ali -alias ${MH_TEST_DIR}/Mail/aliases -user geddy@example.com" \
- 'rush'
+ 'rush, geddy'
# check -nouser
run_test \
"ali -alias ${MH_TEST_DIR}/Mail/aliases -user -nouser geddy@example.com" \
'geddy@example.com'
+# check expansion of first address of blind list [Bug #15604]
+cat >"${MH_TEST_DIR}/Mail/aliases" <<EOF
+rush: Rush: geddy, alex, neil
+geddy: geddy@example.com
+alex: alex@example.com
+neil: neil@example.com
+EOF
+
+run_test "ali -alias ${MH_TEST_DIR}/Mail/aliases rush" \
+ 'Rush: geddy@example.com, alex@example.com, neil@example.com'
+
+# check that aliases followed by ; are not expanded [Bug #15604]
+cat >"${MH_TEST_DIR}/Mail/aliases" <<EOF
+rush: Rush: geddy, alex, neil;
+geddy: geddy@example.com
+alex: alex@example.com
+neil: neil@example.com
+EOF
+
+run_test "ali -alias ${MH_TEST_DIR}/Mail/aliases rush" \
+ 'Rush: geddy@example.com, alex@example.com, neil;'
+
exit $failed
--- /dev/null
+#!/bin/sh
+######################################################
+#
+# Test aliases all the way through post
+#
+######################################################
+
+set -e
+
+if test -z "${MH_OBJ_DIR}"; then
+ srcdir=`dirname "$0"`/../..
+ MH_OBJ_DIR=`cd "$srcdir" && pwd`; export MH_OBJ_DIR
+fi
+
+. "${srcdir}/test/post/test-post-common.sh"
+
+# Note that the last address in the blind list does not end with a
+# semicolon.
+cat >"${MH_TEST_DIR}/Mail/aliases" <<EOF
+blind_list: Blind List: one, two, three
+named.list; one@example.com, two@example.com
+one: one@example.com
+two: two@example.com
+three: three@example.com
+EOF
+
+#### Rely on sendmail/smtp or sendmail/pipe below to override default mts.
+mts_fakesendmail="${MHMTSCONF}-fakesendmail"
+cp "${MHMTSCONF}" "$mts_fakesendmail"
+printf "sendmail: ${srcdir}/test/fakesendmail\n" >>"$mts_fakesendmail"
+MHMTSCONF="$mts_fakesendmail"
+
+# $1: -mts switch selection
+# $2: expected output
+test_alias ()
+{
+ if [ "$1" = 'sendmail/smtp' ]; then
+ send -draft -alias "${MH_TEST_DIR}/Mail/aliases" -mts sendmail/smtp
+
+ # fakesendmail drops the message and any cc's into this mbox.
+ mbox="${MH_TEST_DIR}"/Mail/fakesendmail.mbox
+ inc -silent -file "$mbox"
+ rm -f "$mbox" "$mbox.map"
+
+ # It's hard to calculate the exact Date: header post is going to
+ # use, so we'll just use sed to remove the actual date so we can easily
+ # compare it against our "correct" output.
+ sed -e 's/^Date:.*/Date:/' "`mhpath cur`" >"${testname}.actual"
+
+ check "${testname}.actual" "$2"
+
+ if [ "`mhpath cur`" != "`mhpath last`" ]; then
+ folder next >/dev/null
+ arith_eval $n + 1; n=$arith_val
+ fi
+
+ elif [ "$1" = 'sendmail/pipe' ]; then
+ set +e
+ send -draft -alias "${MH_TEST_DIR}/Mail/aliases" -mts sendmail/pipe \
+ >"${testname}.actual" 2>&1
+ if [ $? -eq 0 ]; then
+ printf "$0: sendmail/pipe should have failed but didn't\n"
+ else
+ set -e
+ check "${testname}.actual" "$2"
+ fi
+
+ else
+ printf "$0: invalid -mts switch selection\n"
+ exit 1
+ fi
+}
+
+
+# check blind list
+cat >"${MH_TEST_DIR}/Mail/draft" <<EOF
+From: Mr Nobody <nobody@example.com>
+To: blind_list
+Subject: blind list test
+
+This is test of a blind list.
+EOF
+cp -p "${MH_TEST_DIR}/Mail/draft" "${MH_TEST_DIR}/Mail/draft2"
+
+cat >"${testname}.expected" <<EOF
+From: Mr Nobody <nobody@example.com>
+To: Blind List: ;
+Subject: blind list test
+Date:
+
+This is test of a blind list.
+EOF
+
+test_alias sendmail/smtp "${testname}.expected"
+
+# Make sure the addresses were expanded correctly.
+mv "${MH_TEST_DIR}/Mail/draft2" "${MH_TEST_DIR}/Mail/draft"
+
+cat > "${testname}.expected" <<EOF
+EHLO nosuchhost.example.com
+MAIL FROM:<nobody@example.com>
+RCPT TO:<one@example.com>
+RCPT TO:<two@example.com>
+RCPT TO:<three@example.com>
+DATA
+From: Mr Nobody <nobody@example.com>
+To: Blind List: ;
+Subject: blind list test
+Date:
+
+This is test of a blind list.
+.
+QUIT
+EOF
+
+test_post "${testname}.actual" "${testname}.expected" \
+ "-alias ${MH_TEST_DIR}/Mail/aliases"
+
+# check named list (alias followed by ;)
+cat >"${MH_TEST_DIR}/Mail/draft" <<EOF
+From: Mr Nobody <nobody@example.com>
+To: named.list
+Subject: named list test
+
+This is test of a named list.
+EOF
+
+cat >"${testname}.expected" <<EOF
+From: Mr Nobody <nobody@example.com>
+To: "named.list" <one@example.com>, "named.list" <two@example.com>
+Subject: named list test
+Date:
+
+This is test of a named list.
+EOF
+
+test_alias sendmail/smtp "${testname}.expected"
+
+# check blind list with -mts sendmail/pipe, which should fail
+cat >"${MH_TEST_DIR}/Mail/draft" <<EOF
+From: Mr Nobody <nobody@example.com>
+To: blind_list
+Subject: blind list test
+
+This is test of a blind list.
+EOF
+
+cat >"${testname}.expected" <<EOF
+post: blind lists not compatible with sendmail/pipe
+send: message not delivered to anyone
+EOF
+
+test_alias sendmail/pipe "${testname}.expected"
+
+
+exit ${failed:-0}
folder -create +other > /dev/null
run_test 'mark +other -sequence unseen all' 'mark: no messages in other'
+# Test removal of indication of cur message.
+mark +inbox -sequence cur -delete all
+run_test 'pick -nolist cur' 'pick: no cur message'
+
exit $failed
#include <h/mts.h>
#include <h/utils.h>
-/*
- * maximum number of names
- */
-#define NVEC 50
-
static struct swit switches[] = {
#define ALIASW 0
{ "alias aliasfile", 0 },
int i, vecp = 0, inverted = 0, list = 0;
int noalias = 0, normalize = AD_NHST;
char *cp, **ap, **argp, buf[BUFSIZ];
- char *vec[NVEC], **arguments;
+ /* Really only need to allocate for argc-1, but must allocate at least 1,
+ so go ahead and allocate for argc char pointers. */
+ char **vec = mh_xmalloc (argc * sizeof (char *)), **arguments;
struct aka *ak;
#ifdef LOCALE
continue;
}
}
- vec[vecp++] = cp;
+
+ if (vecp < argc) {
+ vec[vecp++] = cp;
+ } else {
+ /* Should never happen, but try to protect against code changes
+ that could allow it. */
+ adios (NULL, "too many arguments");
+ }
}
if (!noalias) {
for (i = 0; i < vecp; i++)
print_usr (vec[i], list, normalize);
-
- done (0);
- }
-
- if (vecp) {
- /* print specified aliases */
- for (i = 0; i < vecp; i++)
- print_aka (akvalue (vec[i]), list, 0);
} else {
- /* print them all */
- for (ak = akahead; ak; ak = ak->ak_next) {
- printf ("%s: ", ak->ak_name);
- pos += strlen (ak->ak_name) + 1;
- print_aka (akresult (ak), list, pos);
+ if (vecp) {
+ /* print specified aliases */
+ for (i = 0; i < vecp; i++)
+ print_aka (akvalue (vec[i]), list, 0);
+ } else {
+ /* print them all */
+ for (ak = akahead; ak; ak = ak->ak_next) {
+ printf ("%s: ", ak->ak_name);
+ pos += strlen (ak->ak_name) + 1;
+ print_aka (akresult (ak), list, pos);
+ }
}
}
+ free (vec);
done (0);
return 1;
}
#include <h/mh.h>
#include <h/aliasbr.h>
+#include <h/addrsbr.h>
#include <h/utils.h>
#include <grp.h>
#include <pwd.h>
/*
* prototypes
*/
-int alias (char *);
+int alias (char *);
int akvisible (void);
void init_pw (void);
char *akresult (struct aka *);
static void add_aka (struct aka *, char *);
static struct aka *akalloc (char *);
static struct home *hmalloc (struct passwd *);
-struct home *seek_home (char *);
/* Do mh alias substitution on 's' and return the results. */
if (!s)
return s; /* XXX */
- for (; ak; ak = ak->ak_next)
- if (aleq (s, ak->ak_name))
+ for (; ak; ak = ak->ak_next) {
+ if (aleq (s, ak->ak_name)) {
return akresult (ak);
+ } else if (strchr (s, ':')) {
+ /* The first address in a blind list will contain the
+ alias name, so try to match, but just with just the
+ address (not including the list name). If there's a
+ match, then replace the alias part with its
+ expansion. */
+
+ char *name = getname (s);
+ char *cp = NULL;
+
+ if (name) {
+ /* s is of the form "Blind list: address". If address
+ is an alias, expand it. */
+ struct mailname *mp = getm (name, NULL, 0, AD_NAME, NULL);
+
+ if (mp && mp->m_ingrp) {
+ char *gname = add (mp->m_gname, NULL);
+
+ if (gname && aleq (name, ak->ak_name)) {
+ /* Will leak cp. */
+ cp = concat (gname, akresult (ak), NULL);
+ free (gname);
+ }
+ }
+
+ mnfree (mp);
+ }
+
+ /* Need to flush getname after use. */
+ while (getname ("")) continue;
+
+ if (cp) {
+ return cp;
+ }
+ }
+ }
return getcpy (s);
}
if (*cp == 0)
return (cp = NULL);
+ /* Remove leading any space from the address. */
for (pp = cp; isspace (*pp); pp++)
continue;
if (*pp == 0)
return (cp = NULL);
+ /* Find the end of the address. */
for (qp = pp; *qp != 0 && *qp != ','; qp++)
continue;
+ /* Set cp to point to the remainder of the addresses. */
if (*qp == ',')
*qp++ = 0;
for (cp = qp, qp--; qp > pp; qp--)
return p;
}
-
-
-struct home *
-seek_home (char *name)
-{
- register struct home *hp;
- struct passwd *pw;
- char lname[32];
- unsigned char *c;
- char *c1;
-
- for (hp = homehead; hp; hp = hp->h_next)
- if (!mh_strcasecmp (name, hp->h_name))
- return hp;
-
- /*
- * The only place where there might be problems.
- * This assumes that ALL usernames are kept in lowercase.
- */
- for (c = name, c1 = lname;
- *c && (c1 - lname < (int) sizeof(lname) - 1);
- c++, c1++) {
- if (isalpha(*c) && isupper(*c))
- *c1 = tolower (*c);
- else
- *c1 = *c;
- }
- *c1 = '\0';
- if ((pw = getpwnam(lname)))
- return(hmalloc(pw));
-
- return NULL;
-}
else
if (mp->m_gname)
putgrp (namep, mp->m_gname, out, hdr->flags);
- if (mp->m_ingrp)
+ if (mp->m_ingrp) {
+ if (sm_mts == MTS_SENDMAIL_PIPE) {
+ /* Catch this before sendmail chokes with:
+ "553 List:; syntax illegal for recipient
+ addresses".
+ If we wanted to, we could expand out blind
+ aliases and put them in Bcc:, but then
+ they'd have the Blind-Carbon-Copy
+ indication. */
+ adios (NULL,
+ "blind lists not compatible with"
+ " sendmail/pipe");
+ }
+
grp++;
+ }
if (putadr (namep, qp, mp, out, hdr->flags))
msgflags |= (hdr->set & (MVIS | MINV));
else