On Sun, 04 Jan 2015 05:57:38 +0000, Martin Brandenburg wrote:
> Since the ability to pass arbitrary arguments to sendmail has been
> removed from mail(1), I have added a variable and flag to pass a from
> address to sendmail.
>
> I considered making mail take the same arguments for this as it would
> have when it was just passing onto sendmail but decided against that
> because the code would be more complicated than necessary. But maybe
> somebody wants the compatibility?
>
> Thoughts?
>
> -- Martin Brandenburg
>
> Index: mail.1
> ===================================================================
> RCS file: /cvs/src/usr.bin/mail/mail.1,v
> retrieving revision 1.70
> diff -u -p -r1.70 mail.1
> --- mail.1 16 Dec 2014 18:37:17 -0000 1.70
> +++ mail.1 4 Jan 2015 05:42:08 -0000
> @@ -41,6 +41,7 @@
> .Nm mail
> .Bk -words
> .Op Fl dEIinv
> +.Op Fl a Ar from
> .Op Fl b Ar list
> .Op Fl c Ar list
> .Op Fl s Ar subject
> @@ -62,6 +63,11 @@ with lines replaced by messages.
> .Pp
> The options are as follows:
> .Bl -tag -width Ds
> +.It Fl a Ar from
> +Pass
> +.Ar from
> +to the mail delivery system as the from address.
> +Overrides the from option below.
> .It Fl b Ar list
> Send blind carbon copies to
> .Ar list .
> @@ -965,6 +971,14 @@ Causes
> .Nm mail
> to expand message recipient addresses, as explained in the section
> .Sx Recipient address specifications .
> +.It Ar from
> +Causes
> +.Nm mail
> +to pass a from address to the mail delivery system. If unset, no from
> +address will be passed and the mail delivery system will use its default
> +of user@host. This will be overriden if the
> +.Fl a
> +flag is set.
> .It Ar hold
> This option is used to hold messages in the system mailbox
> by default.
> Index: main.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/mail/main.c,v
> retrieving revision 1.26
> diff -u -p -r1.26 main.c
> --- main.c 16 Dec 2014 18:37:17 -0000 1.26
> +++ main.c 4 Jan 2015 05:42:08 -0000
> @@ -49,6 +49,7 @@ main(int argc, char **argv)
> {
> int i;
> struct name *to, *cc, *bcc, *smopts;
> + char *from = NULL;
> char *subject;
> char *ef;
> char nosrc = 0;
> @@ -78,7 +79,7 @@ main(int argc, char **argv)
> bcc = NULL;
> smopts = NULL;
> subject = NULL;
> - while ((i = getopt(argc, argv, "EIN:b:c:dfins:u:v")) != -1) {
> + while ((i = getopt(argc, argv, "EIN:a:b:c:dfins:u:v")) != -1) {
> switch (i) {
> case 'u':
> /*
> @@ -158,6 +159,9 @@ main(int argc, char **argv)
> */
> assign("skipempty", "");
> break;
> + case 'a':
> + from = optarg;
> + break;
> default:
> usage();
> /*NOTREACHED*/
> @@ -202,6 +206,8 @@ main(int argc, char **argv)
> if ((rc = getenv("MAILRC")) == 0)
> rc = "~/.mailrc";
> load(expand(rc));
> + if (from)
> + assign("from", from);
> if (!rcvmode) {
> mail(to, cc, bcc, smopts, subject);
> /*
> @@ -271,7 +277,7 @@ __dead void
> usage(void)
> {
>
> - fprintf(stderr, "usage: %s [-dEIinv] [-b list] [-c list] "
> + fprintf(stderr, "usage: %s [-dEIinv] [-a from] [-b list] [-c list] "
> "[-s subject] to-addr ...\n", __progname);
> fprintf(stderr, " %s [-dEIiNnv] -f [file]\n", __progname);
> fprintf(stderr, " %s [-dEIiNnv] [-u user]\n", __progname);
> Index: send.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/mail/send.c,v
> retrieving revision 1.23
> diff -u -p -r1.23 send.c
> --- send.c 17 Jan 2014 18:42:30 -0000 1.23
> +++ send.c 4 Jan 2015 05:42:08 -0000
> @@ -287,7 +287,11 @@ mail(struct name *to, struct name *cc, s
> head.h_subject = subject;
> head.h_cc = cc;
> head.h_bcc = bcc;
> - head.h_smopts = smopts;
> + if (value("from")) {
> + head.h_smopts = cat(smopts, nalloc("-f", 0));
> + head.h_smopts = cat(head.h_smopts, nalloc(value("from"), 0));
> + } else
> + head.h_smopts = smopts;
> mail1(&head, 0);
> return(0);
> }
> @@ -307,7 +311,11 @@ sendmail(void *v)
> head.h_subject = NULL;
> head.h_cc = NULL;
> head.h_bcc = NULL;
> - head.h_smopts = NULL;
> + if (value("from")) {
> + head.h_smopts = nalloc("-f", 0);
> + head.h_smopts = cat(head.h_smopts, nalloc(value("from"), 0));
> + } else
> + head.h_smopts = NULL;
> mail1(&head, 0);
> return(0);
> }
>
I like to be able to specify both the sender name and address.
I've been using the following approach which allows me to specify both name
and address for recipients as well as sender.
mail -s "Lunch?" -F "Batman <[email protected]>" -c "Robin <[email protected]>"
-b "Al <[email protected]>" "Jim <[email protected]>"
I like the symmetry of treating all these headers in the same way, and it
can simplify mail(1) slightly since namelist / unpack() is no longer needed.
It relies on smtpd specific behaviour though so probably not a realistic
option since it won't work for people who choose to not use smtpd (from
usr.sbin/smtpd/enqueue.c):
/*
* using From: as envelope sender is not sendmail compatible,
* but I really want it that way - maybe needs a knob
*/
Index: def.h
===================================================================
RCS file: /cvs/src/usr.bin/mail/def.h,v
retrieving revision 1.13
diff -u -p -r1.13 def.h
--- def.h 25 Jun 2003 15:13:32 -0000 1.13
+++ def.h 4 Jan 2015 16:32:51 -0000
@@ -175,6 +175,7 @@ struct header {
char *h_subject; /* Subject string */
struct name *h_cc; /* Carbon copies string */
struct name *h_bcc; /* Blind carbon copies */
+ char *h_from; /* Sender */
struct name *h_smopts; /* Sendmail options */
};
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.bin/mail/extern.h,v
retrieving revision 1.27
diff -u -p -r1.27 extern.h
--- extern.h 28 Jul 2009 16:05:04 -0000 1.27
+++ extern.h 4 Jan 2015 16:32:51 -0000
@@ -164,7 +164,7 @@ void load(char *);
struct var *
lookup(char *);
int mail (struct name *, struct name *, struct name *, struct name *,
- char *);
+ char *, char *);
void mail1(struct header *, int);
void makemessage(FILE *, int);
void mark(int);
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/mail/main.c,v
retrieving revision 1.26
diff -u -p -r1.26 main.c
--- main.c 16 Dec 2014 18:37:17 -0000 1.26
+++ main.c 4 Jan 2015 16:32:51 -0000
@@ -49,6 +49,7 @@ main(int argc, char **argv)
{
int i;
struct name *to, *cc, *bcc, *smopts;
+ char *from;
char *subject;
char *ef;
char nosrc = 0;
@@ -78,7 +79,8 @@ main(int argc, char **argv)
bcc = NULL;
smopts = NULL;
subject = NULL;
- while ((i = getopt(argc, argv, "EIN:b:c:dfins:u:v")) != -1) {
+ from = NULL;
+ while ((i = getopt(argc, argv, "EF:IN:b:c:dfins:u:v")) != -1) {
switch (i) {
case 'u':
/*
@@ -100,6 +102,9 @@ main(int argc, char **argv)
case 'd':
debug++;
break;
+ case 'F':
+ from = optarg;
+ break;
case 's':
/*
* Give a subject field for sending from
@@ -203,7 +208,7 @@ main(int argc, char **argv)
rc = "~/.mailrc";
load(expand(rc));
if (!rcvmode) {
- mail(to, cc, bcc, smopts, subject);
+ mail(to, cc, bcc, smopts, subject, from);
/*
* why wait?
*/
Index: send.c
===================================================================
RCS file: /cvs/src/usr.bin/mail/send.c,v
retrieving revision 1.23
diff -u -p -r1.23 send.c
--- send.c 17 Jan 2014 18:42:30 -0000 1.23
+++ send.c 4 Jan 2015 16:32:51 -0000
@@ -279,7 +279,7 @@ statusput(struct message *mp, FILE *obuf
*/
int
mail(struct name *to, struct name *cc, struct name *bcc, struct name *smopts,
- char *subject)
+ char *subject, char *from)
{
struct header head;
@@ -288,6 +288,7 @@ mail(struct name *to, struct name *cc, s
head.h_cc = cc;
head.h_bcc = bcc;
head.h_smopts = smopts;
+ head.h_from = from;
mail1(&head, 0);
return(0);
}
@@ -403,7 +404,7 @@ mail1(struct header *hp, int printheader
cp = expand(cp);
else
cp = _PATH_SENDMAIL;
- execv(cp, namelist);
+ execl(cp, "sendmail", "-t", NULL);
warn("%s", cp);
_exit(1);
}
@@ -499,6 +500,8 @@ puthead(struct header *hp, FILE *fo, int
int gotcha;
gotcha = 0;
+ if (hp->h_from != NULL)
+ fprintf(fo, "From: %s\n", hp->h_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)
Nathanael