check for "<<>>" etc as equivalent to "<>"
[unix-history] / usr / src / usr.sbin / sendmail / src / envelope.c
index f7de4d0..f8e09e7 100644 (file)
@@ -7,11 +7,10 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)envelope.c 8.13 (Berkeley) %G%";
+static char sccsid[] = "@(#)envelope.c 8.43 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "sendmail.h"
 #endif /* not lint */
 
 #include "sendmail.h"
-#include <sys/time.h>
 #include <pwd.h>
 
 /*
 #include <pwd.h>
 
 /*
@@ -75,16 +74,18 @@ dropenvelope(e)
        register ENVELOPE *e;
 {
        bool queueit = FALSE;
        register ENVELOPE *e;
 {
        bool queueit = FALSE;
-       bool saveit = bitset(EF_FATALERRS, e->e_flags);
+       bool failure_return = FALSE;
+       bool success_return = FALSE;
        register ADDRESS *q;
        char *id = e->e_id;
        register ADDRESS *q;
        char *id = e->e_id;
+       bool return_no, return_yes;
        char buf[MAXLINE];
 
        if (tTd(50, 1))
        {
                printf("dropenvelope %x: id=", e);
                xputs(e->e_id);
        char buf[MAXLINE];
 
        if (tTd(50, 1))
        {
                printf("dropenvelope %x: id=", e);
                xputs(e->e_id);
-               printf(", flags=%o\n", e->e_flags);
+               printf(", flags=0x%x\n", e->e_flags);
                if (tTd(50, 10))
                {
                        printf("sendq=");
                if (tTd(50, 10))
                {
                        printf("sendq=");
@@ -97,10 +98,13 @@ dropenvelope(e)
                return;
 
 #ifdef LOG
                return;
 
 #ifdef LOG
+       if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
+               logsender(e, NULL);
        if (LogLevel > 84)
        if (LogLevel > 84)
-               syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=%o, pid=%d",
+               syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=0x%x, pid=%d",
                                  id, e->e_flags, getpid());
 #endif /* LOG */
                                  id, e->e_flags, getpid());
 #endif /* LOG */
+       e->e_flags &= ~EF_LOGSENDER;
 
        /* post statistics */
        poststats(StatFile);
 
        /* post statistics */
        poststats(StatFile);
@@ -110,19 +114,45 @@ dropenvelope(e)
        */
 
        e->e_flags &= ~EF_QUEUERUN;
        */
 
        e->e_flags &= ~EF_QUEUERUN;
+       return_no = return_yes = FALSE;
        for (q = e->e_sendqueue; q != NULL; q = q->q_next)
        {
                if (bitset(QQUEUEUP, q->q_flags))
                        queueit = TRUE;
        for (q = e->e_sendqueue; q != NULL; q = q->q_next)
        {
                if (bitset(QQUEUEUP, q->q_flags))
                        queueit = TRUE;
-               if (!bitset(QDONTSEND, q->q_flags) &&
-                   bitset(QBADADDR, q->q_flags))
+
+               /* see if a notification is needed */
+               if (bitset(QBADADDR, q->q_flags) &&
+                   bitset(QPINGONFAILURE, q->q_flags))
                {
                {
-                       if (q->q_owner == NULL &&
-                           strcmp(e->e_from.q_paddr, "<>") != 0)
+                       failure_return = TRUE;
+                       if (q->q_owner == NULL && !emptyaddr(&e->e_from))
                                (void) sendtolist(e->e_from.q_paddr, NULL,
                                                  &e->e_errorqueue, e);
                }
                                (void) sendtolist(e->e_from.q_paddr, NULL,
                                                  &e->e_errorqueue, e);
                }
+               else if (bitset(QSENT, q->q_flags) &&
+                   bitnset(M_LOCALMAILER, q->q_mailer->m_flags) &&
+                   bitset(QPINGONSUCCESS, q->q_flags))
+               {
+                       success_return = TRUE;
+               }
+               else
+                       continue;
+
+               /* common code for error returns and return receipts */
+
+               /* test for returning the body */
+               if (!bitset(QHASRETPARAM, q->q_flags))
+               {
+                       if (!bitset(EF_NORETURN, e->e_flags))
+                               return_yes = TRUE;
+               }
+               else if (bitset(QNOBODYRETURN, q->q_flags))
+                       return_no = TRUE;
+               else
+                       return_yes = TRUE;
        }
        }
+       if (return_no && !return_yes)
+               e->e_flags |= EF_NORETURN;
 
        /*
        **  See if the message timed out.
 
        /*
        **  See if the message timed out.
@@ -130,18 +160,18 @@ dropenvelope(e)
 
        if (!queueit)
                /* nothing to do */ ;
 
        if (!queueit)
                /* nothing to do */ ;
-       else if (curtime() > e->e_ctime + TimeOuts.to_q_return)
+       else if (curtime() > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass])
        {
                (void) sprintf(buf, "Cannot send message for %s",
        {
                (void) sprintf(buf, "Cannot send message for %s",
-                       pintvl(TimeOuts.to_q_return, FALSE));
+                       pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
                if (e->e_message != NULL)
                        free(e->e_message);
                e->e_message = newstr(buf);
                message(buf);
                e->e_flags |= EF_CLRQUEUE;
                if (e->e_message != NULL)
                        free(e->e_message);
                e->e_message = newstr(buf);
                message(buf);
                e->e_flags |= EF_CLRQUEUE;
-               saveit = TRUE;
+               failure_return = TRUE;
                fprintf(e->e_xfp, "Message could not be delivered for %s\n",
                fprintf(e->e_xfp, "Message could not be delivered for %s\n",
-                       pintvl(TimeOuts.to_q_return, FALSE));
+                       pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
                fprintf(e->e_xfp, "Message will be deleted from queue\n");
                for (q = e->e_sendqueue; q != NULL; q = q->q_next)
                {
                fprintf(e->e_xfp, "Message will be deleted from queue\n");
                for (q = e->e_sendqueue; q != NULL; q = q->q_next)
                {
@@ -149,28 +179,31 @@ dropenvelope(e)
                                q->q_flags |= QBADADDR;
                }
        }
                                q->q_flags |= QBADADDR;
                }
        }
-       else if (TimeOuts.to_q_warning > 0 &&
-           curtime() > e->e_ctime + TimeOuts.to_q_warning)
+       else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 &&
+           curtime() > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass])
        {
                if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) &&
                    e->e_class >= 0 &&
        {
                if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) &&
                    e->e_class >= 0 &&
-                   strcmp(e->e_from.q_paddr, "<>") != 0)
+                   strcmp(e->e_from.q_paddr, "<>") != 0 &&
+                   strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 &&
+                   (strlen(e->e_from.q_paddr) <= 8 ||
+                    strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], "-request") != 0))
                {
                        (void) sprintf(buf,
                {
                        (void) sprintf(buf,
-                               "warning: cannot send message for %s",
-                               pintvl(TimeOuts.to_q_warning, FALSE));
+                               "Warning: cannot send message for %s",
+                               pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE));
                        if (e->e_message != NULL)
                                free(e->e_message);
                        e->e_message = newstr(buf);
                        message(buf);
                        e->e_flags |= EF_WARNING;
                        if (e->e_message != NULL)
                                free(e->e_message);
                        e->e_message = newstr(buf);
                        message(buf);
                        e->e_flags |= EF_WARNING;
-                       saveit = TRUE;
+                       failure_return = TRUE;
                }
                fprintf(e->e_xfp,
                        "Warning: message still undelivered after %s\n",
                }
                fprintf(e->e_xfp,
                        "Warning: message still undelivered after %s\n",
-                       pintvl(TimeOuts.to_q_warning, FALSE));
+                       pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE));
                fprintf(e->e_xfp, "Will keep trying until message is %s old\n",
                fprintf(e->e_xfp, "Will keep trying until message is %s old\n",
-                       pintvl(TimeOuts.to_q_return, FALSE));
+                       pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
                for (q = e->e_sendqueue; q != NULL; q = q->q_next)
                {
                        if (bitset(QQUEUEUP, q->q_flags))
                for (q = e->e_sendqueue; q != NULL; q = q->q_next)
                {
                        if (bitset(QQUEUEUP, q->q_flags))
@@ -178,23 +211,35 @@ dropenvelope(e)
                }
        }
 
                }
        }
 
+       if (tTd(50, 2))
+               printf("failure_return=%d success_return=%d queueit=%d\n",
+                       failure_return, success_return, queueit);
+
        /*
        **  Send back return receipts as requested.
        */
 
        /*
        **  Send back return receipts as requested.
        */
 
-       if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags))
+/*
+       if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags)
+           && !bitset(PRIV_NORECEIPTS, PrivacyFlags))
+*/
+       if (e->e_receiptto == NULL)
+               e->e_receiptto = e->e_from.q_paddr;
+       if (success_return && strcmp(e->e_receiptto, "<>") != 0)
        {
                auto ADDRESS *rlist = NULL;
 
        {
                auto ADDRESS *rlist = NULL;
 
+               e->e_flags |= EF_SENDRECEIPT;
                (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, e);
                (void) returntosender("Return receipt", rlist, FALSE, e);
        }
                (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, e);
                (void) returntosender("Return receipt", rlist, FALSE, e);
        }
+       e->e_flags &= ~EF_SENDRECEIPT;
 
        /*
        **  Arrange to send error messages if there are fatal errors.
        */
 
 
        /*
        **  Arrange to send error messages if there are fatal errors.
        */
 
-       if (saveit && e->e_errormode != EM_QUIET)
+       if (failure_return && e->e_errormode != EM_QUIET)
                savemail(e);
 
        /*
                savemail(e);
 
        /*
@@ -218,7 +263,8 @@ dropenvelope(e)
            bitset(EF_CLRQUEUE, e->e_flags))
        {
                if (tTd(50, 1))
            bitset(EF_CLRQUEUE, e->e_flags))
        {
                if (tTd(50, 1))
-                       printf("\n===== Dropping [dq]f%s =====\n\n", e->e_id);
+                       printf("\n===== Dropping [dq]f%s (queueit=%d, e_flags=%x) =====\n\n",
+                               e->e_id, queueit, e->e_flags);
                if (e->e_df != NULL)
                        xunlink(e->e_df);
                xunlink(queuename(e, 'q'));
                if (e->e_df != NULL)
                        xunlink(e->e_df);
                xunlink(queuename(e, 'q'));
@@ -246,9 +292,6 @@ dropenvelope(e)
                (void) xfclose(e->e_dfp, "dropenvelope", e->e_df);
        e->e_dfp = NULL;
        e->e_id = e->e_df = NULL;
                (void) xfclose(e->e_dfp, "dropenvelope", e->e_df);
        e->e_dfp = NULL;
        e->e_id = e->e_df = NULL;
-#ifdef XDEBUG
-       checkfd012("dropenvelope");
-#endif
 }
 \f/*
 **  CLEARENVELOPE -- clear an envelope without unlocking
 }
 \f/*
 **  CLEARENVELOPE -- clear an envelope without unlocking
@@ -324,8 +367,8 @@ void
 initsys(e)
        register ENVELOPE *e;
 {
 initsys(e)
        register ENVELOPE *e;
 {
-       static char cbuf[5];                    /* holds hop count */
-       static char pbuf[10];                   /* holds pid */
+       char cbuf[5];                           /* holds hop count */
+       char pbuf[10];                          /* holds pid */
 #ifdef TTYNAME
        static char ybuf[60];                   /* holds tty id */
        register char *p;
 #ifdef TTYNAME
        static char ybuf[60];                   /* holds tty id */
        register char *p;
@@ -349,7 +392,7 @@ initsys(e)
        **      tucked away in the transcript).
        */
 
        **      tucked away in the transcript).
        */
 
-       if (OpMode == MD_DAEMON && !bitset(EF_QUEUERUN, e->e_flags) &&
+       if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) &&
            e->e_xfp != NULL)
                OutChannel = e->e_xfp;
 
            e->e_xfp != NULL)
                OutChannel = e->e_xfp;
 
@@ -359,11 +402,11 @@ initsys(e)
 
        /* process id */
        (void) sprintf(pbuf, "%d", getpid());
 
        /* process id */
        (void) sprintf(pbuf, "%d", getpid());
-       define('p', pbuf, e);
+       define('p', newstr(pbuf), e);
 
        /* hop count */
        (void) sprintf(cbuf, "%d", e->e_hopcount);
 
        /* hop count */
        (void) sprintf(cbuf, "%d", e->e_hopcount);
-       define('c', cbuf, e);
+       define('c', newstr(cbuf), e);
 
        /* time as integer, unix time, arpa time */
        settime(e);
 
        /* time as integer, unix time, arpa time */
        settime(e);
@@ -402,8 +445,8 @@ settime(e)
 {
        register char *p;
        auto time_t now;
 {
        register char *p;
        auto time_t now;
-       static char tbuf[20];                   /* holds "current" time */
-       static char dbuf[30];                   /* holds ctime(tbuf) */
+       char tbuf[20];                          /* holds "current" time */
+       char dbuf[30];                          /* holds ctime(tbuf) */
        register struct tm *tm;
        extern char *arpadate();
        extern struct tm *gmtime();
        register struct tm *tm;
        extern char *arpadate();
        extern struct tm *gmtime();
@@ -412,12 +455,12 @@ settime(e)
        tm = gmtime(&now);
        (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900,
                        tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
        tm = gmtime(&now);
        (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900,
                        tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
-       define('t', tbuf, e);
+       define('t', newstr(tbuf), e);
        (void) strcpy(dbuf, ctime(&now));
        p = strchr(dbuf, '\n');
        if (p != NULL)
                *p = '\0';
        (void) strcpy(dbuf, ctime(&now));
        p = strchr(dbuf, '\n');
        if (p != NULL)
                *p = '\0';
-       define('d', dbuf, e);
+       define('d', newstr(dbuf), e);
        p = arpadate(dbuf);
        p = newstr(p);
        if (macvalue('a', e) == NULL)
        p = arpadate(dbuf);
        p = newstr(p);
        if (macvalue('a', e) == NULL)
@@ -557,7 +600,8 @@ setsender(from, e, delimptr, internal)
        **      Username can return errno != 0 on non-errors.
        */
 
        **      Username can return errno != 0 on non-errors.
        */
 
-       if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP)
+       if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP ||
+           OpMode == MD_ARPAFTP || OpMode == MD_DAEMON)
                realname = from;
        if (realname == NULL || realname[0] == '\0')
                realname = username();
                realname = from;
        if (realname == NULL || realname[0] == '\0')
                realname = username();
@@ -566,9 +610,14 @@ setsender(from, e, delimptr, internal)
                SuprErrs = TRUE;
 
        delimchar = internal ? '\0' : ' ';
                SuprErrs = TRUE;
 
        delimchar = internal ? '\0' : ' ';
+       e->e_from.q_flags = QBADADDR;
        if (from == NULL ||
            parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR,
        if (from == NULL ||
            parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR,
-                     delimchar, delimptr, e) == NULL)
+                     delimchar, delimptr, e) == NULL ||
+           bitset(QBADADDR, e->e_from.q_flags) ||
+           e->e_from.q_mailer == ProgMailer ||
+           e->e_from.q_mailer == FileMailer ||
+           e->e_from.q_mailer == InclMailer)
        {
                /* log garbage addresses for traceback */
 # ifdef LOG
        {
                /* log garbage addresses for traceback */
 # ifdef LOG
@@ -587,19 +636,31 @@ setsender(from, e, delimptr, internal)
                                p = ebuf;
                        }
                        syslog(LOG_NOTICE,
                                p = ebuf;
                        }
                        syslog(LOG_NOTICE,
-                               "from=%s unparseable, received from %s",
-                               from, p);
+                               "setsender: %s: invalid or unparseable, received from %s",
+                               shortenstring(from, 83), p);
                }
 # endif /* LOG */
                if (from != NULL)
                }
 # endif /* LOG */
                if (from != NULL)
+               {
+                       if (!bitset(QBADADDR, e->e_from.q_flags))
+                       {
+                               /* it was a bogus mailer in the from addr */
+                               usrerr("553 Invalid sender address");
+                       }
                        SuprErrs = TRUE;
                        SuprErrs = TRUE;
+               }
                if (from == realname ||
                    parseaddr(from = newstr(realname), &e->e_from,
                              RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL)
                {
                if (from == realname ||
                    parseaddr(from = newstr(realname), &e->e_from,
                              RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL)
                {
+                       char nbuf[100];
+
                        SuprErrs = TRUE;
                        SuprErrs = TRUE;
-                       if (parseaddr("postmaster", &e->e_from, RF_COPYALL,
-                                     ' ', NULL, e) == NULL)
+                       expand("\201n", nbuf, &nbuf[sizeof nbuf], e);
+                       if (parseaddr(from = newstr(nbuf), &e->e_from,
+                                     RF_COPYALL, ' ', NULL, e) == NULL &&
+                           parseaddr(from = "postmaster", &e->e_from,
+                                     RF_COPYALL, ' ', NULL, e) == NULL)
                                syserr("553 setsender: can't even parse postmaster!");
                }
        }
                                syserr("553 setsender: can't even parse postmaster!");
                }
        }
@@ -613,34 +674,27 @@ setsender(from, e, delimptr, internal)
        }
        SuprErrs = FALSE;
 
        }
        SuprErrs = FALSE;
 
-       pvp = NULL;
-       if (e->e_from.q_mailer == LocalMailer)
-       {
 # ifdef USERDB
 # ifdef USERDB
+       if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags))
+       {
                register char *p;
                extern char *udbsender();
                register char *p;
                extern char *udbsender();
-# endif
 
 
+               p = udbsender(e->e_from.q_user);
+               if (p != NULL)
+                       from = p;
+       }
+# endif /* USERDB */
+
+       if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags))
+       {
                if (!internal)
                {
                if (!internal)
                {
-                       /* if the user has given fullname already, don't redefine */
+                       /* if the user already given fullname don't redefine */
                        if (FullName == NULL)
                                FullName = macvalue('x', e);
                        if (FullName != NULL && FullName[0] == '\0')
                                FullName = NULL;
                        if (FullName == NULL)
                                FullName = macvalue('x', e);
                        if (FullName != NULL && FullName[0] == '\0')
                                FullName = NULL;
-
-# ifdef USERDB
-                       p = udbsender(e->e_from.q_user);
-
-                       if (p != NULL)
-                       {
-                               /*
-                               **  We have an alternate address for the sender
-                               */
-
-                               pvp = prescan(p, '\0', pvpbuf, NULL);
-                       }
-# endif /* USERDB */
                }
 
                if ((pw = getpwnam(e->e_from.q_user)) != NULL)
                }
 
                if ((pw = getpwnam(e->e_from.q_user)) != NULL)
@@ -649,21 +703,26 @@ setsender(from, e, delimptr, internal)
                        **  Process passwd file entry.
                        */
 
                        **  Process passwd file entry.
                        */
 
-
                        /* extract home directory */
                        /* extract home directory */
-                       e->e_from.q_home = newstr(pw->pw_dir);
+                       if (strcmp(pw->pw_dir, "/") == 0)
+                               e->e_from.q_home = newstr("");
+                       else
+                               e->e_from.q_home = newstr(pw->pw_dir);
                        define('z', e->e_from.q_home, e);
 
                        /* extract user and group id */
                        e->e_from.q_uid = pw->pw_uid;
                        e->e_from.q_gid = pw->pw_gid;
                        define('z', e->e_from.q_home, e);
 
                        /* extract user and group id */
                        e->e_from.q_uid = pw->pw_uid;
                        e->e_from.q_gid = pw->pw_gid;
+                       e->e_from.q_flags |= QGOODUID;
 
                        /* extract full name from passwd file */
                        if (FullName == NULL && pw->pw_gecos != NULL &&
                            strcmp(pw->pw_name, e->e_from.q_user) == 0 &&
                            !internal)
                        {
 
                        /* extract full name from passwd file */
                        if (FullName == NULL && pw->pw_gecos != NULL &&
                            strcmp(pw->pw_name, e->e_from.q_user) == 0 &&
                            !internal)
                        {
-                               buildfname(pw->pw_gecos, e->e_from.q_user, buf);
+                               if (buildfname(pw->pw_gecos, e->e_from.q_user, buf) &&
+                                       hvalue("MIME-Version", e) == NULL)
+                                               addheader("MIME-Version", "1.0", e);
                                if (buf[0] != '\0')
                                        FullName = newstr(buf);
                        }
                                if (buf[0] != '\0')
                                        FullName = newstr(buf);
                        }
@@ -671,12 +730,18 @@ setsender(from, e, delimptr, internal)
                if (FullName != NULL && !internal)
                        define('x', FullName, e);
        }
                if (FullName != NULL && !internal)
                        define('x', FullName, e);
        }
-       else if (!internal)
+       else if (!internal && OpMode != MD_DAEMON)
        {
                if (e->e_from.q_home == NULL)
        {
                if (e->e_from.q_home == NULL)
+               {
                        e->e_from.q_home = getenv("HOME");
                        e->e_from.q_home = getenv("HOME");
+                       if (e->e_from.q_home != NULL &&
+                           strcmp(e->e_from.q_home, "/") == 0)
+                               e->e_from.q_home++;
+               }
                e->e_from.q_uid = RealUid;
                e->e_from.q_gid = RealGid;
                e->e_from.q_uid = RealUid;
                e->e_from.q_gid = RealGid;
+               e->e_from.q_flags |= QGOODUID;
        }
 
        /*
        }
 
        /*
@@ -684,8 +749,7 @@ setsender(from, e, delimptr, internal)
        **      links in the net.
        */
 
        **      links in the net.
        */
 
-       if (pvp == NULL)
-               pvp = prescan(from, '\0', pvpbuf, NULL);
+       pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL);
        if (pvp == NULL)
        {
                /* don't need to give error -- prescan did that already */
        if (pvp == NULL)
        {
                /* don't need to give error -- prescan did that already */
@@ -695,12 +759,14 @@ setsender(from, e, delimptr, internal)
 # endif
                finis();
        }
 # endif
                finis();
        }
-       (void) rewrite(pvp, 3, e);
-       (void) rewrite(pvp, 1, e);
-       (void) rewrite(pvp, 4, e);
+/*
+       (void) rewrite(pvp, 3, 0, e);
+       (void) rewrite(pvp, 1, 0, e);
+       (void) rewrite(pvp, 4, 0, e);
+*/
        bp = buf + 1;
        cataddr(pvp, NULL, bp, sizeof buf - 2, '\0');
        bp = buf + 1;
        cataddr(pvp, NULL, bp, sizeof buf - 2, '\0');
-       if (*bp == '@')
+       if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags))
        {
                /* heuristic: route-addr: add angle brackets */
                strcat(bp, ">");
        {
                /* heuristic: route-addr: add angle brackets */
                strcat(bp, ">");
@@ -710,7 +776,7 @@ setsender(from, e, delimptr, internal)
        define('f', e->e_sender, e);
 
        /* save the domain spec if this mailer wants it */
        define('f', e->e_sender, e);
 
        /* save the domain spec if this mailer wants it */
-       if (!internal && e->e_from.q_mailer != NULL &&
+       if (e->e_from.q_mailer != NULL &&
            bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags))
        {
                extern char **copyplist();
            bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags))
        {
                extern char **copyplist();