On Wed, 07 Jan 2015 14:31:13 -0700, Todd C. Miller wrote:

> Here's a version that does not rely on non-standard "sendmail -t"
> behavior.
> 
>  - todd

Much better. Works well for me, thanks.

Nathanael

> Index: usr.bin/mail/cmd3.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/mail/cmd3.c,v
> retrieving revision 1.25
> diff -u -r1.25 cmd3.c
> --- usr.bin/mail/cmd3.c       6 Apr 2011 11:36:26 -0000       1.25
> +++ usr.bin/mail/cmd3.c       7 Jan 2015 18:07:06 -0000
> @@ -227,6 +227,7 @@
>       }
>       np = elide(np);
>       head.h_to = np;
> +     head.h_from = NULL;
>       if ((head.h_subject = hfield("subject", mp)) == NULL)
>               head.h_subject = hfield("subj", mp);
>       head.h_subject = reedit(head.h_subject);
> @@ -619,6 +620,7 @@
>       if ((head.h_subject = hfield("subject", mp)) == NULL)
>               head.h_subject = hfield("subj", mp);
>       head.h_subject = reedit(head.h_subject);
> +     head.h_from = NULL;
>       head.h_cc = NULL;
>       head.h_bcc = NULL;
>       head.h_smopts = NULL;
> Index: usr.bin/mail/def.h
> ===================================================================
> RCS file: /cvs/src/usr.bin/mail/def.h,v
> retrieving revision 1.13
> diff -u -r1.13 def.h
> --- usr.bin/mail/def.h        25 Jun 2003 15:13:32 -0000      1.13
> +++ usr.bin/mail/def.h        7 Jan 2015 21:08:11 -0000
> @@ -172,6 +172,7 @@
>   */
>  struct header {
>       struct name *h_to;              /* Dynamic "To:" string */
> +     char *h_from;                   /* User-specified "From:" string */
>       char *h_subject;                /* Subject string */
>       struct name *h_cc;              /* Carbon copies string */
>       struct name *h_bcc;             /* Blind carbon copies */
> Index: usr.bin/mail/extern.h
> ===================================================================
> RCS file: /cvs/src/usr.bin/mail/extern.h,v
> retrieving revision 1.27
> diff -u -r1.27 extern.h
> --- usr.bin/mail/extern.h     28 Jul 2009 16:05:04 -0000      1.27
> +++ usr.bin/mail/extern.h     7 Jan 2015 17:59:52 -0000
> @@ -163,8 +163,8 @@
>  void  load(char *);
>  struct var *
>        lookup(char *);
> -int   mail (struct name *, struct name *, struct name *, struct name *,
> -            char *);
> +int   mail(struct name *, struct name *, struct name *, struct name *,
> +            char *, char *);
>  void  mail1(struct header *, int);
>  void  makemessage(FILE *, int);
>  void  mark(int);
> Index: usr.bin/mail/mail.1
> ===================================================================
> RCS file: /cvs/src/usr.bin/mail/mail.1,v
> retrieving revision 1.72
> diff -u -r1.72 mail.1
> --- usr.bin/mail/mail.1       7 Jan 2015 17:08:21 -0000       1.72
> +++ usr.bin/mail/mail.1       7 Jan 2015 21:25:55 -0000
> @@ -43,6 +43,7 @@
>  .Op Fl dEIinv
>  .Op Fl b Ar list
>  .Op Fl c Ar list
> +.Op Fl r Ar from-addr
>  .Op Fl s Ar subject
>  .Ar to-addr ...
>  .Ek
> @@ -109,6 +110,13 @@
>  Inhibits reading
>  .Pa /etc/mail.rc
>  upon startup.
> +.It Fl r Ar from-addr
> +Use
> +.Ar from-addr
> +as the from address in the message and envelope.
> +Overrides any
> +.Em from
> +options in the startup files.
>  .It Fl s Ar subject
>  Specify subject on command line
>  (only the first argument after the
> @@ -969,6 +977,19 @@
>  .Nm mail
>  to expand message recipient addresses, as explained in the section
>  .Sx Recipient address specifications .
> +.It Ar from
> +Causes
> +.Nm mail
> +to use the specified sender address in the
> +.Dq From:
> +field of the message header.
> +A stripped down version of the address is also used in the message envelope.
> +If unset, the message will not include an explicit sender address and
> +a default value will be added by the MTA, typically
> +.Dq user@host .
> +This value can be overridden by specifying the
> +.Fl r
> +flag on the command line.
>  .It Ar hold
>  This option is used to hold messages in the system mailbox
>  by default.
> Index: usr.bin/mail/main.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/mail/main.c,v
> retrieving revision 1.26
> diff -u -r1.26 main.c
> --- usr.bin/mail/main.c       16 Dec 2014 18:37:17 -0000      1.26
> +++ usr.bin/mail/main.c       7 Jan 2015 21:27:04 -0000
> @@ -49,6 +49,7 @@
>  {
>       int i;
>       struct name *to, *cc, *bcc, *smopts;
> +     char *fromaddr;
>       char *subject;
>       char *ef;
>       char nosrc = 0;
> @@ -77,8 +78,9 @@
>       cc = NULL;
>       bcc = NULL;
>       smopts = NULL;
> +     fromaddr = NULL;
>       subject = NULL;
> -     while ((i = getopt(argc, argv, "EIN:b:c:dfins:u:v")) != -1) {
> +     while ((i = getopt(argc, argv, "EIN:b:c:dfinr:s:u:v")) != -1) {
>               switch (i) {
>               case 'u':
>                       /*
> @@ -100,6 +102,12 @@
>               case 'd':
>                       debug++;
>                       break;
> +             case 'r':
> +                     /*
> +                      * Set From: address
> +                      */
> +                     fromaddr = optarg;
> +                     break;
>               case 's':
>                       /*
>                        * Give a subject field for sending from
> @@ -203,7 +211,7 @@
>               rc = "~/.mailrc";
>       load(expand(rc));
>       if (!rcvmode) {
> -             mail(to, cc, bcc, smopts, subject);
> +             mail(to, cc, bcc, smopts, fromaddr, subject);
>               /*
>                * why wait?
>                */
> @@ -272,7 +280,7 @@
>  {
>  
>       fprintf(stderr, "usage: %s [-dEIinv] [-b list] [-c list] "
> -         "[-s subject] to-addr ...\n", __progname);
> +         "[-r from-addr] [-s subject] to-addr ...\n", __progname);
>       fprintf(stderr, "       %s [-dEIiNnv] -f [file]\n", __progname);
>       fprintf(stderr, "       %s [-dEIiNnv] [-u user]\n", __progname);
>       exit(1);
> Index: usr.bin/mail/names.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/mail/names.c,v
> retrieving revision 1.21
> diff -u -r1.21 names.c
> --- usr.bin/mail/names.c      16 Dec 2014 18:36:46 -0000      1.21
> +++ usr.bin/mail/names.c      7 Jan 2015 17:54:59 -0000
> @@ -456,52 +456,6 @@
>  }
>  
>  /*
> - * Unpack the name list onto a vector of strings.
> - * Return an error if the name list won't fit.
> - */
> -char **
> -unpack(struct name *sm, struct name *np)
> -{
> -     char **ap, **top;
> -     int t, extra, metoo, verbose;
> -
> -     if ((t = count(np)) == 0)
> -             errx(1, "No names to unpack");
> -     t += count(sm);
> -
> -     /*
> -      * Compute the number of extra arguments we will need.
> -      * We need at least four extra -- one for "send-mail", one for the
> -      * "-i" flag, one for the "--" to signal end of command line
> -      * arguments, and one for the terminating 0 pointer.
> -      */
> -     extra = 4;
> -     metoo = value("metoo") != NULL;
> -     if (metoo)
> -             extra++;
> -     verbose = value("verbose") != NULL;
> -     if (verbose)
> -             extra++;
> -     top = (char **)salloc((t + extra) * sizeof(*top));
> -     ap = top;
> -     *ap++ = "send-mail";
> -     *ap++ = "-i";
> -     if (metoo)
> -             *ap++ = "-m";
> -     if (verbose)
> -             *ap++ = "-v";
> -     for (; sm != NULL; sm = sm->n_flink)
> -             if ((sm->n_type & GDEL) == 0)
> -                     *ap++ = sm->n_name;
> -     *ap++ = "--";
> -     for (; np != NULL; np = np->n_flink)
> -             if ((np->n_type & GDEL) == 0)
> -                     *ap++ = np->n_name;
> -     *ap = NULL;
> -     return(top);
> -}
> -
> -/*
>   * Remove all of the duplicates from the passed name list by
>   * insertion sorting them, then checking for dups.
>   * Return the head of the new list.
> Index: usr.bin/mail/send.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/mail/send.c,v
> retrieving revision 1.23
> diff -u -r1.23 send.c
> --- usr.bin/mail/send.c       17 Jan 2014 18:42:30 -0000      1.23
> +++ usr.bin/mail/send.c       7 Jan 2015 21:08:37 -0000
> @@ -279,11 +279,12 @@
>   */
>  int
>  mail(struct name *to, struct name *cc, struct name *bcc, struct name *smopts,
> -     char *subject)
> +     char *fromaddr, char *subject)
>  {
>       struct header head;
>  
>       head.h_to = to;
> +     head.h_from = fromaddr;
>       head.h_subject = subject;
>       head.h_cc = cc;
>       head.h_bcc = bcc;
> @@ -292,7 +293,6 @@
>       return(0);
>  }
>  
> -
>  /*
>   * Send mail to a bunch of user names.  The interface is through
>   * the mail routine below.
> @@ -304,6 +304,7 @@
>       struct header head;
>  
>       head.h_to = extract(str, GTO);
> +     head.h_from = NULL;
>       head.h_subject = NULL;
>       head.h_cc = NULL;
>       head.h_bcc = NULL;
> @@ -319,9 +320,10 @@
>  void
>  mail1(struct header *hp, int printheaders)
>  {
> -     char *cp;
> +     char *cp, *envfrom = NULL;
> +     char *argv[8];
> +     char **ap = argv;
>       pid_t pid;
> -     char **namelist;
>       struct name *to;
>       FILE *mtf;
>  
> @@ -365,18 +367,33 @@
>               fputs(". . . message lost, sorry.\n", stderr);
>               return;
>       }
> -     namelist = unpack(hp->h_smopts, to);
> +     if ((cp = value("record")) != NULL)
> +             (void)savemail(expand(cp), mtf);
> +     
> +     /* Setup sendmail arguments. */
> +        *ap++ = "send-mail";
> +        *ap++ = "-i";
> +        *ap++ = "-t";
> +     cp = hp->h_from ? hp->h_from : value("from");
> +     if (cp != NULL) {
> +             envfrom = skin(cp);
> +             *ap++ = "-f";
> +             *ap++ = envfrom;
> +             if (envfrom == cp)
> +                     envfrom = NULL;
> +     }
> +     if (value("metoo") != NULL)
> +                *ap++ = "-m";
> +     if (value("verbose") != NULL)
> +                *ap++ = "-v";
> +     *ap = NULL;
>       if (debug) {
> -             char **t;
> -
>               fputs("Sendmail arguments:", stdout);
> -             for (t = namelist; *t != NULL; t++)
> -                     printf(" \"%s\"", *t);
> +             for (ap = argv; *ap != NULL; ap++)
> +                     printf(" \"%s\"", *ap);
>               putchar('\n');
>               goto out;
>       }
> -     if ((cp = value("record")) != NULL)
> -             (void)savemail(expand(cp), mtf);
>       /*
>        * Fork, set up the temporary mail file as standard
>        * input for "mail", and exec with the user list we generated
> @@ -403,10 +420,11 @@
>                       cp = expand(cp);
>               else
>                       cp = _PATH_SENDMAIL;
> -             execv(cp, namelist);
> +             execv(cp, argv);
>               warn("%s", cp);
>               _exit(1);
>       }
> +     free(envfrom);
>       if (value("verbose") != NULL)
>               (void)wait_child(pid);
>       else
> @@ -497,8 +515,12 @@
>  puthead(struct header *hp, FILE *fo, int w)
>  {
>       int gotcha;
> +     char *from;
>  
>       gotcha = 0;
> +     from = hp->h_from ? hp->h_from : value("from");
> +     if (from != NULL)
> +             fprintf(fo, "From: %s\n", from), gotcha++;
>       if (hp->h_to != NULL && w & GTO)
>               fmt("To:", hp->h_to, fo, w&GCOMMA), gotcha++;
>       if (hp->h_subject != NULL && w & GSUBJECT)

Reply via email to