Added a new "boolean" type to mh.h and TRUE and FALSE constants.
authorDan Harkless <dan@harkless.org>
Fri, 3 Mar 2000 07:24:41 +0000 (07:24 +0000)
committerDan Harkless <dan@harkless.org>
Fri, 3 Mar 2000 07:24:41 +0000 (07:24 +0000)
Added a note to DIFFERENCES stating that it's out-of-date (Richard was the last
one to update it) and that we should consider only documenting incompatibilities
with MH there.

Implemented (and documented) a third kind of username masquerading: "plussed
user" masquerading.  This one was suggested by Neil Rickert
<rickert@cs.niu.edu>.  It's based on sendmail's "plussed user" feature, where
mail sent to <user>+<string> will be delivered to <user>.  When it's enabled,
it's controlled by the $USERPLUS environment variable.  How is it enabled?
Well, that leads me to:

Renamed the "mmailid:" setting in mts.conf to "masquerade:", and changed it so
that rather than being a boolean, it can be set to any combination of the three
values "draft_from", "mmailid", and "plussed_user".  Thus it is now possible to
enable the three types of masquerading individually.

Fixed a bug with "mmailid" masquerading (dating back to MH?)  where if it was
turned on, ','s would no longer be considered GECOS field delimiters.

ChangeLog
DIFFERENCES
INSTALL
etc/mts.conf.in
h/mh.h
man/mh-tailor.man
man/post.man
uip/post.c
zotnet/mts/mts.c

index d96f7c1..bbe8092 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+Thu Mar 02 23:04:30 2000 Dan Harkless <dan-nmh@dilvish.speed.net>
+
+       * Added a new "boolean" type to mh.h and TRUE and FALSE constants.
+               
+       * Added a note to DIFFERENCES stating that it's out-of-date
+       (Richard was the last one to update it) and that we should
+       consider only documenting incompatibilities with MH there.
+
+       * Implemented (and documented) a third kind of username
+       masquerading: "plussed user" masquerading.  This one was suggested
+       by Neil Rickert <rickert@cs.niu.edu>.  It's based on sendmail's
+       "plussed user" feature, where mail sent to <user>+<string> will be
+       delivered to <user>.  When it's enabled, it's controlled by the
+       $USERPLUS environment variable.  How is it enabled?  Well, that
+       leads me to:
+
+       * Renamed the "mmailid:" setting in mts.conf to "masquerade:", and
+       changed it so that rather than being a boolean, it can be set to
+       any combination of the three values "draft_from", "mmailid", and
+       "plussed_user".  Thus it is now possible to enable the three types
+       of masquerading individually.
+
+       * Fixed a bug with "mmailid" masquerading (dating back to MH?)
+       where if it was turned on, ','s would no longer be considered
+       GECOS field delimiters.
+       
 Wed Mar 01 23:30:50 2000 Dan Harkless <dan-nmh@dilvish.speed.net>
 
        * Changed the GECOS-field '&' translation behavior to be
index 1a24037..b664639 100644 (file)
@@ -1,3 +1,6 @@
+[NOTE: This file is out-of-date.  Updating it every time new features are added
+       to nmh forevermore is a pain.  Perhaps we should limit it to
+       documentation of _incompatibilities_ with MH (which should be rare).]
 
 The following are the differences between nmh and MH-6.8.3.  UCI has
 since released MH-6.8.4.  Most of the new features it adds have
diff --git a/INSTALL b/INSTALL
index 63dcbbe..7eae1db 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -45,62 +45,33 @@ need an ANSI C compiler such as gcc.
    injecting the message to a mail transfer agent (such as sendmail)
    on the local machine via SMTP.
 
-   If you have enabled POP support and you want this to be the
-   default method of accessing new mail, you will need to change
-   the values of the variables "servers", "pophost", "localname",
-   and possibly "mmailid".
-
-   a) "servers" defines the server to which you send outgoing SMTP
-      traffic.
-
-   b) "pophost" defines the server that runs the POP daemon, and to
-      which `inc' and `msgchk' will query for new mail.
-
-   c) "localname" defines the hostname that nmh considers local.
-      If not set, then nmh queries your OS for this value.  You may
-      want to change this if you wish your e-mail to appear as if it
-      originated on the POP server.
-
-   d) "mmailid" allows two different types of email address masquerading
-      when it's set to be non-zero.  The first type is GECOS-based
-      masquerading.  nmh will check if the user's pw_gecos field in the passwd
-      is of the form:
-
-          Full Name <fakeusername>
-
-      If it is, the internal nmh routines that find the username and full
-      name of that user will return "fakeusername" and "Full Name"
-      respectively.  This is useful if you want the messages you send to
-      always appear to come from the name of an MTA alias rather than your
-      actual account name.  For instance, many organizations set up
-      "First.Last" sendmail aliases for all users.  If this is the case,
-      the GECOS field for each user should look like:
-
-          First [Middle] Last <First.Last>
-
-      The other type of masquerading that mmailid turns on is envelope
-      "From:" masquerading based on draft contents.  When a user explicitly
-      specifies a "From:" header in a message, nmh uses it rather than
-      constructing its own.  However, the SMTP envelope "From:" and the
-      "Sender:" header are set to the user's real address.  Turning on
-      mmailid prevents this latter behavior.  This is useful when the user
-      wants to pretend to be sending mail "directly" from a remote POP3
-      account, or when remote mail robots incorrectly use the envelope
-      "From:" in preference to the body "From:" (or refuse to take action
-      when the two don't match).
+   If, instead, all your mail sending and receiving occurs on a 
+   remote POP/SMTP server, you will need to look at the values of the 
+   variables "localname", "pophost", and "servers":
+
+    a) "localname" defines the hostname that nmh considers local.
+       If not set, then nmh queries your OS for this value.  You will
+       want to change this if you wish your e-mail to appear as if it
+       originated on the POP server.
+
+    b) "pophost" defines the server that runs the POP daemon, and to
+       which `inc' and `msgchk' will always query for new mail.
+
+    c) "servers" defines the server to which you send outgoing SMTP
+       traffic.
 
    If you compile with POP support, but don't want to use it exclusively,
    you can use the `-host' and `-user' options to `inc' and `msgchk'
-   rather than hardcoding values in `mts.conf'.
+   rather than hardcoding pophost in `mts.conf'.
 
    Check the `mh-tailor' man page for a list of all the available options
-   for this file.
+   for this file ("masquerade" may be of particular interest).
 
 6) If you have enabled POP support, make sure that `pop3' (or more
    precisely the value of the define POPSERVICE in config.h) is defined
    in the /etc/services file (or its NIS/NIS+ equivalent) on the client
    machine.  It should be something equivalent to "110/tcp".  This might
-   have already been done when the pop daemon was installed.
+   have already been done when the POP daemon was installed.
 
 7) Edit the file `mhn.defaults' (installed in the nmh `etc' directory).
    This file contains the default profile entries for the nmh command
@@ -111,8 +82,8 @@ need an ANSI C compiler such as gcc.
    want to re-run this script later if you install new programs to
    display content.  An example of this is:
 
-   cd support/general
-   ./mhn.defaults.sh /usr/local/bin:/usr/X11/bin:/usr/ucb > mhn.defaults
+    % cd support/general
+    % ./mhn.defaults.sh /usr/local/bin:/usr/X11/bin:/usr/ucb > mhn.defaults
 
    and then move `mhn.defaults' into the nmh `etc' directory.
 
index b8a61b8..6f1af4f 100644 (file)
@@ -5,6 +5,18 @@
 # all the available options for this file.
 #
 
+# The exceptions file for /etc/hosts used by
+# `post' to try to find official names.
+hostable: %etcdir%/hosts
+
+# Name that nmh considers `local'.  If not set, nmh will
+# query the system for this value (gethostname, etc...).
+#localname: foo.bar.com
+
+# Uncomment the following line to allow username masquerading.  Any or all of
+# the three types of masquerading may be used (see mh-tailor(5) for details).
+#masquerade: draft_from mmailid plussed_user
+
 # Default location of mail drops.  If this option is
 # set, but empty, the user's home directory is used.
 mmdfldir: %mailspool%
@@ -13,19 +25,8 @@ mmdfldir: %mailspool%
 # are kept.  If this is empty, the user's login name is used.
 mmdflfil:
 
-# The exceptions file for /etc/hosts used by
-# `post' to try to find official names.
-hostable: %etcdir%/hosts
+# Hardcoded POP server name (prevents inc'ing from local mail spool).
+#pophost: localhost
 
 # List of smtp servers to try if using smtp support
 servers: localhost
-
-# Name of POP server
-# pophost: localhost
-
-# Name that nmh considers `local'.  If not set, nmh will
-# query the system for this value (gethostname, etc...).
-# localname: foo.bar.com
-
-# Uncomment this to allow the two types of username masquerading.
-# mmailid: 1
diff --git a/h/mh.h b/h/mh.h
index a59b0a0..81a6021 100644 (file)
--- a/h/mh.h
+++ b/h/mh.h
 #define DMAXFOLDER     4       /* typical number of digits             */
 #define MAXFOLDER   1000       /* message increment                    */
 
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+typedef unsigned char  boolean;  /* not int so we can pack in a structure */
+
 /*
  * user context/profile structure
  */
index ea95045..ff767b0 100644 (file)
@@ -99,12 +99,17 @@ mmdelim2: \\001\\001\\001\\001\\n
 The end-of-message delimiter for maildrops.
 
 .ti -.5i
-mmailid: 0
+masquerade:
 .br
-If this is non-zero, two different types of email address masquerading are
-allowed ("mmailid" = "masquerade mail ID").  The first type is GECOS-based
-masquerading.  \fInmh\fR will check if the user's pw_gecos field in the passwd
-file is of the form:
+This directive controls three different types of email address masquerading.
+The three possible values, which may be specified in any combination on the
+line, are "draft_from", "mmailid", and "plussed_user".
+
+"mmailid" was the only type of masquerading in the original MH package, and
+apparently stands for "masquerade mail identification".  This type of
+masquerading keys off of the GECOS field of the passwd file.  When enabled,
+\fInmh\fR will check if the user's pw_gecos field in the passwd file is of the
+form:
 
 .ti +.5i
 Full Name <fakeusername>
@@ -119,15 +124,28 @@ the case, the GECOS field for each user should look like:
 .ti +.5i
 First [Middle] Last <First.Last>
 
-The other type of masquerading that mmailid turns on is envelope "From:"
-masquerading based on draft contents.  When a user explicitly specifies a
-"From:" header in a message, \fInmh\fR uses it rather than constructing its own.
-However, the SMTP envelope "From:" and the "Sender:" header are set to the
-user's real address.  Turning on mmailid prevents this latter behavior.  This is
-useful when the user wants to pretend to be sending mail "directly" from a
-remote POP3 account, or when remote mail robots incorrectly use the envelope
-"From:" in preference to the body "From:" (or refuse to take action when the two
-don't match).
+"plussed_user", when specified on the "masquerade:" line, allows a second type
+of username masquerading.  If the user sets the \fB$USERPLUS\fR environment
+variable, its value will be tacked onto the actual login name, following a '+'
+sign.  For instance, if I am dan@company.com, and I set \fB$USERPLUS\fR to
+"www", my mail will appear to come from "dan+www@company.com".  This feature is
+meant to interact with MTA features like the one in sendmail that automatically
+delivers all mail sent to \fIuser\fR+\fIstring\fR to \fIuser\fR.  One can use
+different email addresses in different situations (to aid in automatic mail
+filtering or in determining where spammers got your address) while only actually
+having a single account.
+
+"draft_from" controls the most powerful type of address masquerading.  Normally,
+when a user explicitly specifies a "From:" header in a draft, \fInmh\fR uses it
+rather than constructing its own.  However, to discourage email forgery, the
+SMTP envelope "From:" and a "Sender:" header are set to the user's real address.
+When "draft_from" is turned on, though, the envelope "From:" will use the
+address specified in the draft, and there will be no "Sender:" header.  This is
+useful when a user wants to pretend to be sending mail "directly" from a remote
+POP3 account, or when remote mail robots incorrectly use the envelope "From:" in
+preference to the body "From:" (or refuse to take action when the two don't
+match).  Note that your MTA may still reveal the user's real identity (e.g.
+sendmail's "X-Authentication-Warning:" header).
 
 .ti -.5i
 maildelivery: %libdir%/maildelivery
@@ -290,7 +308,7 @@ your site, and set the appropriate values.
 .Pr
 None
 .Sa
-mh\-mts(8)
+mh\-mts(8), post(8)
 .De
 As listed above
 .Co
index d5b9e4e..c344043 100644 (file)
@@ -74,36 +74,45 @@ transport system's handling of the message (e.g., local and \*(lqfast\*(rq
 delivery).
 
 Under normal circumstances, \fIpost\fR constructs the "From:" line of the
-message from the user's UNIX username, the full name from the GECOS field of the
-passwd file, and the fully-qualified name of the local machine (e.g. `From: "Dan
-Harkless" <dan@machine.company.com>').  However, there are three ways to
-override these values.  Note that they apply equally to "Resent-From:" lines in
-messages sent with \fIdist\fR.
+message from the user's login name, the full name from the GECOS field of the
+passwd file, and the fully-qualified name of the local machine (or the value of
+"localname" in mts.conf, if set).  An example is "From: Dan Harkless
+<dan@machine.company.com>".  There are four ways to override these values,
+however.  Note that they apply equally to "Resent-From:" lines in messages sent
+with \fIdist\fR.
 
-The first way is GECOS-based username masquerading.  If "mmailid" in the
-mts.conf file has been set to non-zero, this processing is activated.  If a
-user's GECOS field in the passwd file is of the form "Full Name <fakename>" then
-"fakename" will be used in place of the real username.  For instance, a GECOS
-field of "Dan Harkless <Dan.Harkless>" would result in `From: "Dan Harkless"
-<Dan.Harkless@machine.company.com>'.  Naturally if you were doing something like
+The first way is GECOS-based username masquerading.  If the "masquerade:" line
+in mts.conf contains "mmailid", this processing is activated.  If a user's GECOS
+field in the passwd file is of the form "Full Name <fakename>" then "fakename"
+will be used in place of the real username.  For instance, a GECOS field of "Dan
+Harkless <Dan.Harkless>" would result in "From: Dan Harkless
+<Dan.Harkless@machine.company.com>".  Naturally if you were doing something like
 this you'd want to set up an MTA alias (e.g. in /etc/aliases) from, for
 instance, "Dan.Harkless" to "dan".
 
 The second way to override default construction of "From:" is to set the
 \fB$SIGNATURE\fR environment variable.  This variable overrides the full name
-from the GECOS field, even if GECOS-based masquerading is being done.
+from the GECOS field, even if GECOS-based masquerading is being done.  This
+processing is always active, and does not need to be enabled from mts.conf.
 
-The third way, which will override either of the previous two, is to specify a
-"From:" line manually in the message draft.  It will be used as provided (after
-alias substitution), but to discourage email forgery, the user's real address
-will be used in the SMTP envelope "From:" and in the "Sender:" line.  However,
-if the system administrator has allowed address masquerading by setting
-"mmailid" to non-zero in mts.conf, the SMTP envelope "From:" will use the
-address given in the draft "From:", and there will be no "Sender:" header.  This
-is useful in pretending to send mail "directly" from a remote POP3 account, or
-when remote email robots give improper precedence to the envelope "From:".  Note
-that your MTA may still reveal your real identity (e.g. sendmail's
-"X-Authentication-Warning:" header).
+The third way is controlled by the "plussed_user" value of "masquerade:" line of
+mts.conf.  When that's turned on, setting the $USERPLUS environment variable
+will result in its value being tacked onto the user's login name, following 
+a '+' sign.  For instance, if I set $USERPLUS to "www", my "From:" line will
+contain "Dan Harkless <dan+www@machine.company.com>" (or "Dan.Harkless+www" if
+I'm using mmailid masquerading as well).  Recent versions of sendmail
+automatically deliver all mail sent to \fIuser\fR+\fIstring\fR to \fIuser\fR.
+
+The fourth method of address masquerading is to specify a "From:" line manually
+in the message draft.  It will be used as provided (after alias substitution),
+but normally, to discourage email forgery, the user's \fIreal\fR address will be
+used in the SMTP envelope "From:" and in a "Sender:" header.  However, if the
+"masquerade:" line of mts.conf contains "draft_from", the SMTP envelope "From:"
+will use the address given in the draft "From:", and there will be no "Sender:"
+header.  This is useful in pretending to send mail "directly" from a remote POP3
+account, or when remote email robots give improper precedence to the envelope
+"From:".  Note that your MTA may still reveal your real identity (e.g.
+sendmail's "X-Authentication-Warning:" header). 
 
 .Fi
 ^%etcdir%/mts.conf~^nmh mts configuration file
index 66d978c..abc2285 100644 (file)
@@ -283,7 +283,7 @@ static char *fill_in = NULL;
 static char *partno = NULL;
 static int queued = 0;
 
-extern int  MMailids;
+extern boolean  draft_from_masquerading;  /* defined in mts.c */
 
 /*
  * static prototypes
@@ -768,15 +768,16 @@ putfmt (char *name, char *str, FILE *out)
                    continue;
                }
 
-               if (MMailids && ((msgstate == RESENT)
-                                ? (hdr->set & MRFM)
-                                : (hdr->set & MFRM)))
+               if (draft_from_masquerading && ((msgstate == RESENT)
+                                               ? (hdr->set & MRFM)
+                                               : (hdr->set & MFRM)))
                    /* The user manually specified a [Resent-]From: address in
-                      their draft and mts.conf turned on "mmailid", so we'll
-                      set things up to use the actual email address embedded in
-                      the draft [Resent-]From: (after alias substitution, and
-                      without the GECOS full name or angle brackets) as the
-                      envelope From:. */
+                      their draft and the "masquerade:" line in mts.conf
+                      doesn't contain "draft_from", so we'll set things up to
+                      use the actual email address embedded in the draft
+                      [Resent-]From: (after alias substitution, and without the
+                      GECOS full name or angle brackets) as the envelope
+                      From:. */
                    strncpy(from, auxformat(mp, 0), sizeof(from) - 1);
 
                if (hdr->flags & HBCC)
@@ -799,14 +800,16 @@ putfmt (char *name, char *str, FILE *out)
        }
        else {
            /* Address includes a host, so no alias substitution is needed. */
-           if (MMailids && ((msgstate == RESENT)
-                            ? (hdr->set & MRFM)
-                            : (hdr->set & MFRM)))
-               /* The user manually specified a [Resent-]From: address in their
-                  draft and mts.conf turned on "mmailid", so we'll set things
-                  up to use the actual email address embedded in the draft
-                  [Resent-]From: (without the GECOS full name or angle
-                  brackets) as the envelope From:. */
+           if (draft_from_masquerading && ((msgstate == RESENT)
+                                           ? (hdr->set & MRFM)
+                                           : (hdr->set & MFRM)))
+               /* The user manually specified a [Resent-]From: address in
+                  their draft and the "masquerade:" line in mts.conf
+                  doesn't contain "draft_from", so we'll set things up to
+                  use the actual email address embedded in the draft
+                  [Resent-]From: (after alias substitution, and without the
+                  GECOS full name or angle brackets) as the envelope
+                  From:. */
                strncpy(from, auxformat(mp, 0), sizeof(from) - 1);
 
            if (hdr->flags & HBCC)
@@ -891,10 +894,11 @@ finish_headers (FILE *out)
                        (int) getpid (), (long) tclock, LocalName ());
            if (msgflags & MFRM) {
                /* There was already a From: in the draft.  Don't add one. */
-               if (!MMailids)
-                   /* mts.conf didn't turn on mmailid, so we'll reveal the
-                      user's actual account@thismachine address in a Sender:
-                      header (and use it as the envelope From: later). */
+               if (!draft_from_masquerading)
+                   /* mts.conf didn't contain "masquerade:[...]draft_from[...]"
+                      so we'll reveal the user's actual account@thismachine
+                      address in a Sender: header (and use it as the envelope
+                      From: later). */
                    fprintf (out, "Sender: %s\n", from);
            }
            else
@@ -929,11 +933,11 @@ finish_headers (FILE *out)
                        (int) getpid (), (long) tclock, LocalName ());
            if (msgflags & MRFM) {
                /* There was already a Resent-From: in draft.  Don't add one. */
-               if (!MMailids)
-                   /* mts.conf didn't turn on mmailid, so we'll reveal the
-                      user's actual account@thismachine address in a
-                      Resent-Sender: header (and use it as the envelope From:
-                      later). */
+               if (!draft_from_masquerading)
+                   /* mts.conf didn't contain "masquerade:[...]draft_from[...]"
+                      so we'll reveal the user's actual account@thismachine
+                      address in a Sender: header (and use it as the envelope
+                      From: later). */
                    fprintf (out, "Resent-Sender: %s\n", from);
            }
            else
index 26e4807..0951c4c 100644 (file)
@@ -60,9 +60,11 @@ char *mmdlm2 = "\001\001\001\001\n";
 static char username[BUFSIZ];
 static char fullname[BUFSIZ];
 
-/* variables for username masquerading */
-int MMailids = 0;  /* used from post.c as well as here */
-static char *mmailid = "0";
+/* Variables for username masquerading: */
+       boolean  draft_from_masquerading = FALSE;  /* also used from post.c */
+static boolean  mmailid_masquerading = FALSE;
+static boolean  plussed_user_masquerading = FALSE;
+static char*    masquerade = "";
 
 
 /*
@@ -128,7 +130,7 @@ static struct bind binds[] = {
     { "uucplfil", &uucplfil },
     { "mmdelim1", &mmdlm1 },
     { "mmdelim2", &mmdlm2 },
-    { "mmailid", &mmailid },
+    { "masquerade", &masquerade },
 
 #if defined(SENDMTS) || defined(SMTPMTS)
     { "hostable", &hostable },
@@ -196,8 +198,17 @@ mts_init (char *name)
     }
 
     fclose (fp);
-    MMailids = atoi (mmailid);
+
     Everyone = atoi (everyone);
+
+    if (strstr(masquerade, "draft_from") != NULL)
+       draft_from_masquerading = TRUE;
+
+    if (strstr(masquerade, "mmailid") != NULL)
+       mmailid_masquerading = TRUE;
+
+    if (strstr(masquerade, "plussed_user") != NULL)
+       plussed_user_masquerading = TRUE;
 }
 
 
@@ -400,7 +411,6 @@ getuserinfo (void)
            || pw->pw_name == NULL
            || *pw->pw_name == '\0') {
 #endif /* KPOP */
-
        strncpy (username, "unknown", sizeof(username));
        snprintf (fullname, sizeof(fullname), "The Unknown User-ID (%d)",
                (int) getuid ());
@@ -409,15 +419,26 @@ getuserinfo (void)
 
     np = pw->pw_gecos;
 
-    /*
-     * Do mmailid (username masquerading) processing.  The GECOS
-     * field should have the form "Full Name <fakeusername>".  For instance,
-     * "Dan Harkless <Dan.Harkless>".  Naturally, you'll want your MTA to have
-     * an alias (e.g. in /etc/aliases) from "fakeusername" to your account name.
-     */
+    /* Get the user's real name from the GECOS field.  Stop once we hit a ',',
+       which some OSes use to separate other 'finger' information in the GECOS
+       field, like phone number.  Also, if mmailid masquerading is turned on due
+       to "mmailid" appearing on the "masquerade:" line of mts.conf, stop if we
+       hit a '<' (which should precede any ','s). */
 #ifndef BSD42
-    for (cp = fullname; *np && *np != (MMailids ? '<' : ','); *cp++ = *np++)
-       continue;
+    if (mmailid_masquerading)
+       /* Stop at ',' or '<'. */
+       for (cp = fullname; *np != '\0' && *np != ',' && *np != '<';
+            *cp++ = *np++)
+           continue;
+    else
+       /* Allow '<' as a legal character of the user's name.  This code is
+          basically a duplicate of the code above the "else" -- we don't
+          collapse it down to one copy and put the mmailid_masquerading check
+          inside the loop with "(x ? y : z)" because that's inefficient and the
+          value'll never change while it's in there. */
+       for (cp = fullname; *np != '\0' && *np != ',';
+            *cp++ = *np++)
+           continue;
 #else /* BSD42 */
     /* On BSD(-derived) systems, the system utilities that deal with the GECOS
        field (finger, mail, sendmail, etc.) translate any '&' character in it to
@@ -425,30 +446,69 @@ getuserinfo (void)
        fingering a user "bob" with the GECOS field "& Jones" would reveal him to
        be "In real life: Bob Jones".  Surprisingly, though, the OS doesn't do
        the translation for you, so we have to do it manually here. */
-    for (cp = fullname; *np && *np != (MMailids ? '<' : ','); ) {
-       if (*np == '&') {       /* blech! */
-           strcpy (cp, pw->pw_name);
-           *cp = toupper(*cp);
-           while (*cp)
-               cp++;
-           np++;
-       } else {
-           *cp++ = *np++;
+    if (mmailid_masquerading)
+       /* Stop at ',' or '<'. */
+       for (cp = fullname;
+            *np != '\0' && *np != ',' && *np != '<';) {
+           if (*np == '&')     {       /* blech! */
+               strcpy (cp, pw->pw_name);
+               *cp = toupper(*cp);
+               while (*cp)
+                   cp++;
+               np++;
+           } else {
+               *cp++ = *np++;
+           }
+       }
+    else
+       /* Allow '<' as a legal character of the user's name.  This code is
+          basically a duplicate of the code above the "else" -- we don't
+          collapse it down to one copy and put the mmailid_masquerading check
+          inside the loop with "(x ? y : z)" because that's inefficient and the
+          value'll never change while it's in there. */
+       for (cp = fullname;
+            *np != '\0' && *np != ',';) {
+           if (*np == '&')     {       /* blech! */
+               strcpy (cp, pw->pw_name);
+               *cp = toupper(*cp);
+               while (*cp)
+                   cp++;
+               np++;
+           } else {
+               *cp++ = *np++;
+           }
        }
-    }
 #endif /* BSD42 */
-
     *cp = '\0';
-    if (MMailids) {
+
+    if (mmailid_masquerading) {
+       /* Do mmailid processing.  The GECOS field should have the form
+          "Full Name <fakeusername>".  For instance,
+          "Dan Harkless <Dan.Harkless>".  Naturally, you'll want your MTA to
+          have an alias (e.g. in /etc/aliases) from "fakeusername" to your
+          account name.  */ 
        if (*np)
            np++;
        for (cp = username; *np && *np != '>'; *cp++ = *np++)
            continue;
        *cp = '\0';
     }
-    if (MMailids == 0 || *np == '\0')
+    if (!mmailid_masquerading || *np == '\0')
        strncpy (username, pw->pw_name, sizeof(username));
 
+    if (plussed_user_masquerading) {
+       /* Tack on '+' and $USERPLUS environment variable to actual username.
+          Presumably the local MTA (e.g. sendmail) has been set up to deliver
+          all mail sent to <user>+<string> to <user>. */
+       char*  plussed_user_addon = getenv("USERPLUS");
+
+       if (plussed_user_addon != NULL && *plussed_user_addon != '\0') 
+           snprintf(username, sizeof(username), "%s+%s",
+                    username, plussed_user_addon);
+    }
+
+    /* The $SIGNATURE environment variable overrides the GECOS field's idea of
+       your real name. */
     if ((cp = getenv ("SIGNATURE")) && *cp)
        strncpy (fullname, cp, sizeof(fullname));