make rewriting of addresses in headers really work. This adds the $q
authorEric Allman <eric@ucbvax.Berkeley.EDU>
Sun, 21 Feb 1982 11:16:34 +0000 (03:16 -0800)
committerEric Allman <eric@ucbvax.Berkeley.EDU>
Sun, 21 Feb 1982 11:16:34 +0000 (03:16 -0800)
macro.  The rewriting of the From: address is still ad hoc and should
be integrated into this format.
Note:  old .cf files will not work with this version.

SCCS-vsn: usr.sbin/sendmail/src/conf.c 3.43
SCCS-vsn: usr.sbin/sendmail/src/deliver.c 3.67
SCCS-vsn: usr.sbin/sendmail/src/collect.c 3.33
SCCS-vsn: usr.sbin/sendmail/src/sendmail.h 3.60
SCCS-vsn: usr.sbin/sendmail/src/macro.c 3.10
SCCS-vsn: usr.sbin/sendmail/src/headers.c 3.15
SCCS-vsn: usr.sbin/sendmail/doc/intro/intro.me 3.16

usr/src/usr.sbin/sendmail/doc/intro/intro.me
usr/src/usr.sbin/sendmail/src/collect.c
usr/src/usr.sbin/sendmail/src/conf.c
usr/src/usr.sbin/sendmail/src/deliver.c
usr/src/usr.sbin/sendmail/src/headers.c
usr/src/usr.sbin/sendmail/src/macro.c
usr/src/usr.sbin/sendmail/src/sendmail.h

index 782d509..f280eef 100644 (file)
@@ -21,7 +21,7 @@ Berkeley, California  94720
 .(f
 This is
 .if \n(DR draft
 .(f
 This is
 .if \n(DR draft
-version 3.15,
+version 3.16,
 last modified on %G%.
 .if \n(DR Please do not distribute this version without permission
 .if \n(DR of the author.
 last modified on %G%.
 .if \n(DR Please do not distribute this version without permission
 .if \n(DR of the author.
@@ -939,6 +939,8 @@ D\&n\&MAILER-DAEMON
 D\&l\&From $g  $d
 # delimiter (operator) characters
 D\&o\&.:@!^
 D\&l\&From $g  $d
 # delimiter (operator) characters
 D\&o\&.:@!^
+# address writing style
+D\&q\&$g$?x ($x)$.
 .sp \n(psu
 ### format of headers:
 H\&Date: $a
 .sp \n(psu
 ### format of headers:
 H\&Date: $a
@@ -959,16 +961,12 @@ C\&U\&ucbvax ernie
 .sp \n(psu
 .ta \w'M\&local  'u +\w'/usr/net/bin/sendberkmail  'u +\w'rlsAmn  'u +\w'$f@$A  'u
 ###  mailers
 .sp \n(psu
 .ta \w'M\&local  'u +\w'/usr/net/bin/sendberkmail  'u +\w'rlsAmn  'u +\w'$f@$A  'u
 ###  mailers
-# local mail -- must be zero
 M\&local       /bin/mail       rlsAmn  $f      ...local\&mail -d $u
 M\&local       /bin/mail       rlsAmn  $f      ...local\&mail -d $u
-# program mail -- must be one
 M\&prog        /bin/csh        lA      $f      ...prog\&mail -fc $u
 M\&prog        /bin/csh        lA      $f      ...prog\&mail -fc $u
-# berkeley net mail
 M\&berk        /usr/net/bin/sendberkmail       fxs     $B:$f   ...berk\&mail -m $h -h $c -t $u
 M\&berk        /usr/net/bin/sendberkmail       fxs     $B:$f   ...berk\&mail -m $h -h $c -t $u
-# arpanet mail
 M\&arpa        /usr/lib/mailers/arpa   sAu     $f@$A   ...arpa\&mail $f $h $u
 M\&arpa        /usr/lib/mailers/arpa   sAu     $f@$A   ...arpa\&mail $f $h $u
-# uucp mail
 M\&uucp        /usr/bin/uux    rsDxmU  $U!$f   ...uucp\&mail - $h!rmail ($u)
 M\&uucp        /usr/bin/uux    rsDxmU  $U!$f   ...uucp\&mail - $h!rmail ($u)
+M\&xlate       /       A       $f      /
 .sp \n(psu
 ### rewriting rules
 .ta \w'R\&CSVAX:$-h!$+u  'u +\w'$#berk$@ing70$:$+u@$+h  'u
 .sp \n(psu
 ### rewriting rules
 .ta \w'R\&CSVAX:$-h!$+u  'u +\w'$#berk$@ing70$:$+u@$+h  'u
@@ -1030,6 +1028,7 @@ These are:
 $l     UNIX-style \*(lqFrom\*(rq line.
 $n     My address in error messages.
 $o     \*(lqOperators\*(rq in addresses.
 $l     UNIX-style \*(lqFrom\*(rq line.
 $n     My address in error messages.
 $o     \*(lqOperators\*(rq in addresses.
+$q     How to write addresses in headers.
 .)b
 The
 .b $l
 .)b
 The
 .b $l
@@ -1067,6 +1066,16 @@ Ing70, :, ZRM, @, MIT-MC, SRI-KL
 .)b
 assuming that colon and at-sign are operators
 (but hyphen is not).
 .)b
 assuming that colon and at-sign are operators
 (but hyphen is not).
+The
+.b $q
+macro gives the format for addresses
+as they should appear in headers.
+This will normally be something like:
+.(b
+$g$?x ($x)$.
+.)b
+Which will give the translated from address
+followed by the full name if known.
 .pp
 A number of macros are defined by
 .i sendmail
 .pp
 A number of macros are defined by
 .i sendmail
@@ -1364,6 +1373,9 @@ header line.
 Upper case should be preserved in user names.
 .ip h
 Upper case should be preserved in host names.
 Upper case should be preserved in user names.
 .ip h
 Upper case should be preserved in host names.
+.ip e
+This mailer is expensive,
+and it may be desirable to limit usage.
 .ip A
 This mailer wants an ARPANET standard header
 (equivalent to the
 .ip A
 This mailer wants an ARPANET standard header
 (equivalent to the
@@ -1570,6 +1582,7 @@ DUucbvax
 DnMAILER-DAEMON
 DlFrom $g  $d
 Do.:@!^
 DnMAILER-DAEMON
 DlFrom $g  $d
 Do.:@!^
+Dq$g$?x ($x)$.
 .)b
 The first three macros are for convenience only,
 and are used to define the local host names
 .)b
 The first three macros are for convenience only,
 and are used to define the local host names
@@ -1688,10 +1701,11 @@ M\&prog /bin/csh        lA      $f      ...progmail -fc $u
 M\&berk        /usr/net/bin/sendberkmail       fxs     $B:$f   ...berkmail -m $h -h $c -t $u
 M\&arpa        /usr/lib/mailers/arpa   sAu     $f@$A   ...arpamail $f $h $u
 M\&uucp        /usr/bin/uux    rsDxmU  $U!$f   ...uucpmail - $h!rmail ($u)
 M\&berk        /usr/net/bin/sendberkmail       fxs     $B:$f   ...berkmail -m $h -h $c -t $u
 M\&arpa        /usr/lib/mailers/arpa   sAu     $f@$A   ...arpamail $f $h $u
 M\&uucp        /usr/bin/uux    rsDxmU  $U!$f   ...uucpmail - $h!rmail ($u)
+M\&xlate       /       A       $f      /
 .if n .in
 .if t .sz
 .)b
 .if n .in
 .if t .sz
 .)b
-Five mailers are known in the configuration file.
+Six mailers are known in the configuration file.
 There
 .i must
 be entries for local and program mail.
 There
 .i must
 be entries for local and program mail.
@@ -1790,6 +1804,16 @@ and with multiple users listed.
 Since UUCP is a relic of the (not so) distant past,
 it requires ugly header lines.
 .pp
 Since UUCP is a relic of the (not so) distant past,
 it requires ugly header lines.
 .pp
+The final entry is a dummy entry to declare the pseudo-mailer
+.i xlate .
+When this mailer is found
+it causes a table lookup to be done in the alias file
+using the host name as a key.
+A
+.q %s
+in the value part is replaced by the user name.
+The entire parsing mechanism is restarted when this is encountered.
+.pp
 If
 .q $u
 were to be missing from the argument vector for a mailer,
 If
 .q $u
 were to be missing from the argument vector for a mailer,
@@ -2458,6 +2482,11 @@ Normally
 .i sendmail
 suppresses the sender
 if in a group being sent to.
 .i sendmail
 suppresses the sender
 if in a group being sent to.
+.ip \-o
+Assume that header lines containing recepient names in the message
+will have addresses separated by spaces
+rather than by commas.
+Headers are always output with commas between the names.
 .ip \-i
 Don't take a dot to end a message.
 .ip \-t
 .ip \-i
 Don't take a dot to end a message.
 .ip \-t
@@ -2485,7 +2514,7 @@ style messages
 the FTP protocol
 [Neigus73, Postel74, Postel77]),
 and ending lines of error messages with <CRLF>.
 the FTP protocol
 [Neigus73, Postel74, Postel77]),
 and ending lines of error messages with <CRLF>.
-.ip \-a\&p
+.ip \-a\&s
 Take input over an SMTP connection on standard input and output.
 This does everything the \-a flag does also.
 .ip \-s
 Take input over an SMTP connection on standard input and output.
 This does everything the \-a flag does also.
 .ip \-s
@@ -2503,6 +2532,12 @@ maintainer;
 for example,
 aliases are printed as expanded
 and mailer functions are printed as they run.
 for example,
 aliases are printed as expanded
 and mailer functions are printed as they run.
+.ip \-c
+If this mailer is marked as being expensive,
+don't connect immediately.
+This requires that queueing be compiled in,
+since it will depend on a sender process to
+actually send the mail.
 .ip \-q
 Try to execute the queued up mail.
 .ip \-p
 .ip \-q
 Try to execute the queued up mail.
 .ip \-p
@@ -2680,13 +2715,17 @@ will not add another header line if a header line
 of this name already existed.
 This would normally be used to stamp the message
 by everyone who handled it.
 of this name already existed.
 This would normally be used to stamp the message
 by everyone who handled it.
-.ip H_ADDR
+.ip H_RCPT
 If set,
 this field contains recipient addresses.
 This is used by the
 .b \-t
 flag to determine who to send to
 when it is collecting recipients from the message.
 If set,
 this field contains recipient addresses.
 This is used by the
 .b \-t
 flag to determine who to send to
 when it is collecting recipients from the message.
+.ip H_ADDR
+This flag indicates that this field
+contains addresses that should be rewritten
+to include commas, etc.
 .nr ii 5n
 .lp
 Let's look at a sample
 .nr ii 5n
 .lp
 Let's look at a sample
index a93d813..dfcbe0b 100644 (file)
@@ -1,7 +1,7 @@
 # include <errno.h>
 # include "sendmail.h"
 
 # include <errno.h>
 # include "sendmail.h"
 
-SCCSID(@(#)collect.c   3.32            %G%);
+SCCSID(@(#)collect.c   3.33            %G%);
 
 /*
 **  COLLECT -- read & parse message header & make temp file.
 
 /*
 **  COLLECT -- read & parse message header & make temp file.
@@ -234,7 +234,7 @@ maketemp(from)
                define('x', p);
        else
        {
                define('x', p);
        else
        {
-               register char *q;
+               extern char *getxpart();
 
                /*
                **  Try to extract the full name from a general From:
 
                /*
                **  Try to extract the full name from a general From:
@@ -249,40 +249,9 @@ maketemp(from)
                p = hvalue("original-from");
                if (p == NULL)
                        p = OrigFrom;
                p = hvalue("original-from");
                if (p == NULL)
                        p = OrigFrom;
-               q = index(p, '(');
-               if (q != NULL)
-               {
-                       int parenlev = 0;
-
-                       for (p = q; *p != '\0'; p++)
-                       {
-                               if (*p == '(')
-                                       parenlev++;
-                               else if (*p == ')' && --parenlev <= 0)
-                                       break;
-                       }
-                       if (*p == ')')
-                       {
-                               *p = '\0';
-                               if (*++q != '\0')
-                                       define('x', newstr(q));
-                               *p = ')';
-                       }
-               }
-               else if ((q = index(p, '<')) != NULL)
-               {
-                       char savec;
-
-                       while (*--q == ' ')
-                               continue;
-                       while (isspace(*p))
-                               p++;
-                       savec = *++q;
-                       *q = '\0';
-                       if (*p != '\0')
-                               define('x', newstr(p));
-                       *q = savec;
-               }
+               p = getxpart(p);
+               if (p != NULL)
+                       define('x', newstr(p));
        }
 
        /* date message originated */
        }
 
        /* date message originated */
index 1d87165..e080fb3 100644 (file)
@@ -36,7 +36,7 @@
 
 
 
 
 
 
-SCCSID(@(#)conf.c      3.42            %G%);
+SCCSID(@(#)conf.c      3.43            %G%);
 \f/*
 **  Header info table
 **     Final (null) entry contains the flags used for any other field.
 \f/*
 **  Header info table
 **     Final (null) entry contains the flags used for any other field.
@@ -50,13 +50,13 @@ SCCSID(@(#)conf.c   3.42            %G%);
 struct hdrinfo HdrInfo[] =
 {
        "date",                 H_CHECK,                M_NEEDDATE,
 struct hdrinfo HdrInfo[] =
 {
        "date",                 H_CHECK,                M_NEEDDATE,
-       "from",                 H_CHECK,                M_NEEDFROM,
+       "from",                 H_ADDR|H_CHECK,         M_NEEDFROM,
        "original-from",        0,                      0,
        "original-from",        0,                      0,
-       "sender",               0,                      0,
+       "sender",               H_ADDR,                 0,
        "full-name",            H_ACHECK,               M_FULLNAME,
        "full-name",            H_ACHECK,               M_FULLNAME,
-       "to",                   H_ADDR,                 0,
-       "cc",                   H_ADDR,                 0,
-       "bcc",                  H_ADDR|H_ACHECK,        0,
+       "to",                   H_ADDR|H_RCPT,          0,
+       "cc",                   H_ADDR|H_RCPT,          0,
+       "bcc",                  H_ADDR|H_ACHECK|H_RCPT, 0,
        "message-id",           H_CHECK,                M_MSGID,
        "message",              H_EOH,                  0,
        "text",                 H_EOH,                  0,
        "message-id",           H_CHECK,                M_MSGID,
        "message",              H_EOH,                  0,
        "text",                 H_EOH,                  0,
index b4859c8..8fd3c83 100644 (file)
@@ -6,7 +6,7 @@
 # include <syslog.h>
 # endif LOG
 
 # include <syslog.h>
 # endif LOG
 
-SCCSID(@(#)deliver.c   3.66            %G%);
+SCCSID(@(#)deliver.c   3.67            %G%);
 
 /*
 **  DELIVER -- Deliver a message to a list of addresses.
 
 /*
 **  DELIVER -- Deliver a message to a list of addresses.
@@ -941,7 +941,7 @@ putmessage(fp, m, xdot)
                                *p = '\0';
 
                                /* translate the name to be relative */
                                *p = '\0';
 
                                /* translate the name to be relative */
-                               name = remotename(name);
+                               name = remotename(name, m);
                                if (*name == '\0')
                                        continue;
 
                                if (*name == '\0')
                                        continue;
 
@@ -952,7 +952,7 @@ putmessage(fp, m, xdot)
                                if (opos > 78 && !firstone)
                                {
                                        fprintf(fp, ",\n        ");
                                if (opos > 78 && !firstone)
                                {
                                        fprintf(fp, ",\n        ");
-                                       opos = 8;
+                                       opos = 8 + strlen(name);
                                }
                                else if (!firstone)
                                        fprintf(fp, ", ");
                                }
                                else if (!firstone)
                                        fprintf(fp, ", ");
@@ -1046,21 +1046,26 @@ putmessage(fp, m, xdot)
 */
 
 char *
 */
 
 char *
-remotename(name)
+remotename(name, m)
        char *name;
        char *name;
+       struct mailer *m;
 {
        static char buf[MAXNAME];
        char lbuf[MAXNAME];
        extern char *macvalue();
        char *oldf = macvalue('f');
 {
        static char buf[MAXNAME];
        char lbuf[MAXNAME];
        extern char *macvalue();
        char *oldf = macvalue('f');
+       char *oldx = macvalue('x');
+       char *oldg = macvalue('g');
        extern char **prescan();
        register char **pvp;
        extern char **prescan();
        register char **pvp;
+       extern char *getxpart();
 
        /*
        **  Do general rewriting of name.
        **      This will also take care of doing global name translation.
        */
 
 
        /*
        **  Do general rewriting of name.
        **      This will also take care of doing global name translation.
        */
 
+       define('x', getxpart(name));
        pvp = prescan(name, '\0');
        for (;;)
        {
        pvp = prescan(name, '\0');
        for (;;)
        {
@@ -1089,14 +1094,20 @@ remotename(name)
 
        /* make the name relative to the receiving mailer */
        define('f', lbuf);
 
        /* make the name relative to the receiving mailer */
        define('f', lbuf);
-       (void) expand(From.q_mailer->m_from, buf, &buf[sizeof buf - 1]);
+       (void) expand(m->m_from, buf, &buf[sizeof buf - 1]);
 
        /* rewrite to get rid of garbage we added in the expand above */
        pvp = prescan(buf, '\0');
        rewrite(pvp, 2);
 
        /* rewrite to get rid of garbage we added in the expand above */
        pvp = prescan(buf, '\0');
        rewrite(pvp, 2);
-       cataddr(pvp, buf, sizeof buf);
+       cataddr(pvp, lbuf, sizeof lbuf);
+
+       /* now add any comment info we had before back */
+       define('g', lbuf);
+       (void) expand("$q", buf, &buf[sizeof buf - 1]);
 
        define('f', oldf);
 
        define('f', oldf);
+       define('g', oldg);
+       define('x', oldx);
 
 # ifdef DEBUG
        if (Debug > 0)
 
 # ifdef DEBUG
        if (Debug > 0)
index 4400db2..490b14c 100644 (file)
@@ -1,7 +1,7 @@
 # include <errno.h>
 # include "sendmail.h"
 
 # include <errno.h>
 # include "sendmail.h"
 
-SCCSID(@(#)headers.c   3.14.1.1                %G%);
+SCCSID(@(#)headers.c   3.15            %G%);
 
 /*
 **  CHOMPHEADER -- process and save a header line.
 
 /*
 **  CHOMPHEADER -- process and save a header line.
@@ -190,3 +190,69 @@ isheader(s)
                s++;
        return (*s == ':');
 }
                s++;
        return (*s == ':');
 }
+\f/*
+**  GETXPART -- extract the "signature" part of an address line.
+**
+**     Try to extract the full name from a general address
+**     field.  We take anything which is a comment as a
+**     first choice.  Failing in that, we see if there is
+**     a "machine readable" name (in <angle brackets>); if
+**     so we take anything preceeding that clause.
+**
+**     If we blow it here it's not all that serious.
+**
+**     Parameters:
+**             p -- line to crack.
+**
+**     Returns:
+**             signature part.
+**             NULL if no signature part.
+**
+**     Side Effects:
+**             none.
+*/
+
+char *
+getxpart(p)
+       register char *p;
+{
+       register char *q;
+       register char *rval = NULL;
+
+       q = index(p, '(');
+       if (q != NULL)
+       {
+               int parenlev = 0;
+
+               for (p = q; *p != '\0'; p++)
+               {
+                       if (*p == '(')
+                               parenlev++;
+                       else if (*p == ')' && --parenlev <= 0)
+                               break;
+               }
+               if (*p == ')')
+               {
+                       *p = '\0';
+                       if (*++q != '\0')
+                               rval = newstr(q);
+                       *p = ')';
+               }
+       }
+       else if ((q = index(p, '<')) != NULL)
+       {
+               char savec;
+
+               while (*--q == ' ')
+                       continue;
+               while (isspace(*p))
+                       p++;
+               savec = *++q;
+               *q = '\0';
+               if (*p != '\0')
+                       rval = newstr(p);
+               *q = savec;
+       }
+
+       return (rval);
+}
index 3199818..996248d 100644 (file)
@@ -1,7 +1,7 @@
 # include "useful.h"
 # include "conf.h"
 
 # include "useful.h"
 # include "conf.h"
 
-SCCSID(@(#)macro.c     3.            %G%);
+SCCSID(@(#)macro.c     3.10            %G%);
 
 char   *Macro[128];
 extern int     Debug;
 
 char   *Macro[128];
 extern int     Debug;
@@ -131,6 +131,8 @@ expand(s, buf, buflim)
 **                  net typically)+
 **             $o   delimiters ("operators") for address tokens+
 **             $p   my process id in decimal
 **                  net typically)+
 **             $o   delimiters ("operators") for address tokens+
 **             $p   my process id in decimal
+**             $q   the string that becomes an address -- this is
+**                  normally used to combine $g & $x.
 **             $r   protocol used to talk to sender
 **             $s   sender's host name
 **             $t   the current time in seconds since 1/1/1970
 **             $r   protocol used to talk to sender
 **             $s   sender's host name
 **             $t   the current time in seconds since 1/1/1970
index 04e277e..4d43b58 100644 (file)
@@ -7,7 +7,7 @@
 # ifdef _DEFINE
 # define EXTERN
 # ifndef lint
 # ifdef _DEFINE
 # define EXTERN
 # ifndef lint
-static char SmailSccsId[] =    "@(#)sendmail.h 3.59            %G%";
+static char SmailSccsId[] =    "@(#)sendmail.h 3.60            %G%";
 # endif lint
 # else  _DEFINE
 # define EXTERN extern
 # endif lint
 # else  _DEFINE
 # define EXTERN extern
@@ -174,6 +174,7 @@ extern struct hdrinfo       HdrInfo[];
 
 /* bits for h_flags and hi_flags */
 # define H_EOH         00001   /* this field terminates header */
 
 /* bits for h_flags and hi_flags */
 # define H_EOH         00001   /* this field terminates header */
+# define H_RCPT                00002   /* contains recipient addresses */
 # define H_DEFAULT     00004   /* if another value is found, drop this */
 # define H_USED                00010   /* indicates that this has been output */
 # define H_CHECK       00020   /* check h_mflags against m_flags */
 # define H_DEFAULT     00004   /* if another value is found, drop this */
 # define H_USED                00010   /* indicates that this has been output */
 # define H_CHECK       00020   /* check h_mflags against m_flags */