Merge branch 'master' of ssh://git.sv.gnu.org/srv/git/nmh
authorLyndon Nerenberg <lyndon@orthanc.ca>
Mon, 15 Oct 2012 22:22:39 +0000 (15:22 -0700)
committerLyndon Nerenberg <lyndon@orthanc.ca>
Mon, 15 Oct 2012 22:22:39 +0000 (15:22 -0700)
Makefile.am
docs/pending-release-notes
h/aliasbr.h
man/mh-alias.man
sbr/seq_del.c
test/ali/test-ali
test/post/test-post-aliases [new file with mode: 0755]
test/sequences/test-mark
uip/ali.c
uip/aliasbr.c
uip/post.c

index 6d15d9f..8c571d2 100644 (file)
@@ -63,8 +63,8 @@ TESTS = test/ali/test-ali test/anno/test-anno \
        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 \
index 32080e7..c618aee 100644 (file)
@@ -56,9 +56,11 @@ OBSOLETE/DEPRECATED FEATURES
   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
@@ -69,3 +71,8 @@ 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].
index cc4da7f..f940026 100644 (file)
@@ -35,8 +35,6 @@ struct home {
     struct home *h_next;       /* next home in list                     */
 };
 
-struct home *seek_home (char *);
-
 /*
  * prototypes
  */
index e29db4a..926fb89 100644 (file)
@@ -146,10 +146,13 @@ the address list if it is not already on the list.  The alias itself is
 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
@@ -161,7 +164,7 @@ Example Alias File:
 .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
@@ -179,10 +182,16 @@ is defined as an alias for \*(lqfrated@UCI\*(rq, and \*(lqsgroup\*(rq
 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
@@ -251,6 +260,13 @@ Start adding aliases to your
 .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 ^ ~
@@ -282,5 +298,3 @@ command may defeat this.
 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.
index 8c353f3..97e3578 100644 (file)
@@ -83,6 +83,12 @@ seq_delsel (struct msgs *mp, char *cp, int public, int zero)
        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.
      */
index 7af25cc..4079790 100755 (executable)
@@ -54,18 +54,24 @@ run_test 'ali -nonexistent' 'ali: -nonexistent unknown'
 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" \
@@ -80,21 +86,49 @@ run_test "ali -alias ${MH_TEST_DIR}/Mail/aliases -list" \
          '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
diff --git a/test/post/test-post-aliases b/test/post/test-post-aliases
new file mode 100755 (executable)
index 0000000..6030ad1
--- /dev/null
@@ -0,0 +1,156 @@
+#!/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}
index 96a7e3d..cd3aedf 100755 (executable)
@@ -80,4 +80,8 @@ run_test 'mark -sequence privateseq -list -public' 'privateseq (private): 1-2'
 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
index 61ab6b2..e9a63fd 100644 (file)
--- a/uip/ali.c
+++ b/uip/ali.c
 #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 },
@@ -59,7 +54,9 @@ main (int argc, char **argv)
     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
@@ -124,7 +121,14 @@ main (int argc, char **argv)
                    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) {
@@ -151,23 +155,22 @@ main (int argc, char **argv)
 
        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;
 }
index b2e51f5..4937251 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <h/mh.h>
 #include <h/aliasbr.h>
+#include <h/addrsbr.h>
 #include <h/utils.h>
 #include <grp.h>
 #include <pwd.h>
@@ -25,7 +26,7 @@ struct home *hometail = NULL;
 /*
  * prototypes
  */
-int alias (char *); 
+int alias (char *);
 int akvisible (void);
 void init_pw (void);
 char *akresult (struct aka *);
@@ -45,7 +46,6 @@ static char *getalias (char *);
 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. */
@@ -104,9 +104,45 @@ akval (struct aka *ak, char *s)
     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);
 }
@@ -429,12 +465,15 @@ getalias (char *addrs)
        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--)
@@ -537,36 +576,3 @@ hmalloc (struct passwd *pw)
 
     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;
-}
index ff75197..6b07861 100644 (file)
@@ -854,8 +854,22 @@ putfmt (char *name, char *str, FILE *out)
                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