Download raw body.
mail(1) add any header from command line (diff adapted from Debian)
mail(1) add any header from command line (working version)
What I discovered here:
https://marc.info/?l=openbsd-tech&m=172596284520414&w=2
Cleared up one of my doubts about this new proposal for mail(1).
Furthermore, while I add at least one header recognized by smtpd(8), it
allows me to add even headers invented by myself.
$ printf "Subject: hello\nPocahontas: invented by myself\n\nBody.\n" |\
sendmail $(logname)
I mean, if smtpd(8) allows me to do that why not mail(1).
Here is a new version of the diff where I cleaned a bit the conditionals
in puthead() by adding a small function bellow.
Index: cmd3.c
===================================================================
RCS file: /cvs/src/usr.bin/mail/cmd3.c,v
diff -u -p -r1.30 cmd3.c
--- cmd3.c 8 Mar 2023 04:43:11 -0000 1.30
+++ cmd3.c 7 Sep 2024 07:49:29 -0000
@@ -193,6 +193,8 @@ _respond(int *msgvec)
struct name *np;
struct header head;
+ memset(&head, 0, sizeof(head));
+
if (msgvec[1] != 0) {
puts("Sorry, can't reply to multiple messages at once");
return(1);
@@ -601,6 +603,8 @@ _Respond(int *msgvec)
struct message *mp;
int *ap;
char *cp;
+
+ memset(&head, 0, sizeof(head));
head.h_to = NULL;
for (ap = msgvec; *ap != 0; ap++) {
Index: def.h
===================================================================
RCS file: /cvs/src/usr.bin/mail/def.h,v
diff -u -p -r1.17 def.h
--- def.h 28 Jan 2022 06:18:41 -0000 1.17
+++ def.h 7 Sep 2024 07:49:29 -0000
@@ -173,6 +173,7 @@ struct header {
struct name *h_to; /* Dynamic "To:" string */
char *h_from; /* User-specified "From:" string */
char *h_subject; /* Subject string */
+ char *h_header; /* Additional header string */
struct name *h_cc; /* Carbon copies string */
struct name *h_bcc; /* Blind carbon copies */
struct name *h_smopts; /* Sendmail options */
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.bin/mail/extern.h,v
diff -u -p -r1.30 extern.h
--- extern.h 21 May 2024 05:00:48 -0000 1.30
+++ extern.h 7 Sep 2024 07:49:29 -0000
@@ -153,6 +153,7 @@ int isdate(char *);
int isdir(char *);
int isfileaddr(char *);
int ishead(char *);
+int ishead_set(struct header *hp, char *head);
int isign(char *, struct ignoretab *);
int isprefix(char *, char *);
size_t istrlcpy(char *, const char *, size_t);
@@ -162,7 +163,7 @@ void load(char *);
struct var *
lookup(char *);
int mail(struct name *, struct name *, struct name *, struct name *,
- char *, char *);
+ char *, char *, char *);
void mail1(struct header *, int);
void makemessage(FILE *, int);
void mark(int);
Index: mail.1
===================================================================
RCS file: /cvs/src/usr.bin/mail/mail.1,v
diff -u -p -r1.83 mail.1
--- mail.1 31 Mar 2022 17:27:25 -0000 1.83
+++ mail.1 7 Sep 2024 07:49:29 -0000
@@ -63,6 +63,12 @@ with lines replaced by messages.
.Pp
The options are as follows:
.Bl -tag -width Ds
+.It Fl a
+Specify additional header fields on the command line such as "X-Loop:
+foo@bar" etc.
+You have to use quotes if the string contains spaces.
+This argument may be specified more than once, the headers will then
+be concatenated.
.It Fl b Ar list
Send blind carbon copies to
.Ar list .
@@ -1254,7 +1260,7 @@ and are not supported by this implementa
.Nm mailx .
.Pp
The flags
-.Op Fl bcdEIrv
+.Op Fl abcdEIrv
are extensions to the specification.
.Sh HISTORY
A
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/mail/main.c,v
diff -u -p -r1.35 main.c
--- main.c 26 Jan 2021 18:21:47 -0000 1.35
+++ main.c 7 Sep 2024 07:49:29 -0000
@@ -103,6 +103,9 @@ main(int argc, char **argv)
struct name *to, *cc, *bcc, *smopts;
char *fromaddr;
char *subject;
+ char *header;
+ char *htmp;
+ size_t hlen = 0;
char *ef;
char nosrc = 0;
char *rc;
@@ -136,7 +139,9 @@ main(int argc, char **argv)
smopts = NULL;
fromaddr = NULL;
subject = NULL;
- while ((i = getopt(argc, argv, "EINb:c:dfinr:s:u:v")) != -1) {
+ header = NULL;
+ htmp = NULL;
+ while ((i = getopt(argc, argv, "EINa:b:c:dfinr:s:u:v")) != -1) {
switch (i) {
case 'u':
/*
@@ -171,6 +176,24 @@ main(int argc, char **argv)
*/
subject = optarg;
break;
+
+ case 'a':
+ /*
+ * Give additional header fields for sending from
+ * non terminal
+ */
+ if (header == NULL) {
+ header = strdup(optarg);
+ if (header == NULL)
+ err(1, NULL);
+ } else {
+ if (asprintf(&htmp, "%s\n%s", header,
+ optarg) == -1)
+ err(1, NULL);
+ free(header);
+ header = htmp;
+ }
+ break;
case 'f':
/*
* User is specifying file to "edit" with Mail,
@@ -269,7 +292,7 @@ main(int argc, char **argv)
rc = "~/.mailrc";
load(expand(rc));
if (!rcvmode) {
- mail(to, cc, bcc, smopts, fromaddr, subject);
+ mail(to, cc, bcc, smopts, fromaddr, subject, header);
/*
* why wait?
*/
Index: send.c
===================================================================
RCS file: /cvs/src/usr.bin/mail/send.c,v
diff -u -p -r1.26 send.c
--- send.c 8 Mar 2023 04:43:11 -0000 1.26
+++ send.c 7 Sep 2024 07:49:29 -0000
@@ -279,13 +279,14 @@ statusput(struct message *mp, FILE *obuf
*/
int
mail(struct name *to, struct name *cc, struct name *bcc, struct name *smopts,
- char *fromaddr, char *subject)
+ char *fromaddr, char *subject, char *header)
{
struct header head;
head.h_to = to;
head.h_from = fromaddr;
head.h_subject = subject;
+ head.h_header = header;
head.h_cc = cc;
head.h_bcc = bcc;
head.h_smopts = smopts;
@@ -306,6 +307,7 @@ sendmail(void *v)
head.h_to = extract(str, GTO);
head.h_from = NULL;
head.h_subject = NULL;
+ head.h_header = NULL;
head.h_cc = NULL;
head.h_bcc = NULL;
head.h_smopts = NULL;
@@ -519,19 +521,34 @@ puthead(struct header *hp, FILE *fo, int
gotcha = 0;
from = hp->h_from ? hp->h_from : value("from");
- if (from != NULL)
+ if (from != NULL && !ishead_set(hp, "From:"))
fprintf(fo, "From: %s\n", from), gotcha++;
- if (hp->h_to != NULL && w & GTO)
+ if (hp->h_to != NULL && w & GTO && !ishead_set(hp, "To:"))
fmt("To:", hp->h_to, fo, w&GCOMMA), gotcha++;
- if (hp->h_subject != NULL && w & GSUBJECT)
+ if (hp->h_subject != NULL && w & GSUBJECT &&
+ !ishead_set(hp, "Subject:"))
fprintf(fo, "Subject: %s\n", hp->h_subject), gotcha++;
- if (hp->h_cc != NULL && w & GCC)
+ if (hp->h_cc != NULL && w & GCC && !ishead_set(hp, "Cc:"))
fmt("Cc:", hp->h_cc, fo, w&GCOMMA), gotcha++;
- if (hp->h_bcc != NULL && w & GBCC)
+ if (hp->h_bcc != NULL && w & GBCC && !ishead_set(hp, "Bcc:"))
fmt("Bcc:", hp->h_bcc, fo, w&GCOMMA), gotcha++;
+ if (hp->h_header != NULL && w)
+ fprintf(fo, "%s\n", hp->h_header), gotcha++;
if (gotcha && w & GNL)
(void)putc('\n', fo);
return(0);
+}
+
+/*
+ * Check if header is already set with option '-a'.
+ */
+int
+ishead_set(struct header *hp, char *head)
+{
+ if (hp->h_header != NULL && strstr(hp->h_header, head) != NULL)
+ return 1;
+
+ return 0;
}
/*
--
Walter
mail(1) add any header from command line (diff adapted from Debian)
mail(1) add any header from command line (working version)