# 'mtaopts patch' for Heirloom mailx 12.5 7/5/10
#
# Copyright (C) Dario Niedermann, 2012-2018
#
# Implements 'mtaopts' user-settable mailx config variable, by which
# arbitrary options can be passed to the MTA (e.g.: sendmail).
# 'mtaopts' can also be set within account{} blocks in config files.
# Example usage case: passing sendmail the '-f my.mbox@example.com'
# option via 'mtaopts' prevents sendmail from exposing $USER@$HOSTNAME
#
# This file is released with NO WARRANTY under the terms of the GPLv3
# license. All files modified by this patch retain their original licenses.
#
# Official web page for this patch:
# <http://www.darioniedermann.it/sw/mtaopts.html>
========================================================================
--- mailx-12.5/extern.h 2016-09-17 17:44:43.515548337 +0200
+++ mailx-12.5+mtao/extern.h 2016-09-16 20:23:45.362661232 +0200
@@ -391,6 +391,7 @@
struct name *nalloc(char *str, enum gfield ntype);
struct name *extract(char *line, enum gfield ntype);
struct name *sextract(char *line, enum gfield ntype);
+struct name *catWords(struct name *optList, char *line, char *varName);
char *detract(struct name *np, enum gfield ntype);
struct name *outof(struct name *names, FILE *fo, struct header *hp);
int is_fileaddr(char *name);
========================================================================
--- mailx-12.5/names.c 2016-09-17 17:44:43.529549966 +0200
+++ mailx-12.5+mtao/names.c 2016-09-16 20:23:45.364661464 +0200
@@ -544,6 +544,68 @@
return(n1);
}
+/* extract all words from a line and append them one by one to the passed-in
+ * name-struct optList. Space is a separator only if it is not
+ * backslash-escaped and it is not between single quotes. 'varName' is the name
+ * of the variable that holds 'line' as its value. 'varName' is used only to
+ * warn the user in case too many words (>256) have been put into it. */
+struct name *
+catWords(struct name *optList, char *line, char *varName)
+{
+#define NONE 0
+#define COPY 1
+#define WORDDONE 2
+ char * lineCopy, * word[256];
+ char prevCharWasEsc, betweenQuotes, action;
+ int i, j, w;
+ struct name * optName[256];
+
+ lineCopy = calloc(strlen(line)+1, sizeof(char));
+
+ /* copy line to lineCopy, a word at a time; when a word is done, copy
+ * it to word[w] and make a name-struct member to hold it. Link this
+ * struct member to optList. Rewind lineCopy & cp another word into it... */
+ prevCharWasEsc = 0; betweenQuotes = 0;
+ for (i=0, j=0, w=0, action=NONE ; ; i++, action=NONE) {
+ if (line[i] == '\\' && !prevCharWasEsc)
+ { prevCharWasEsc = 1; continue; }
+ // else...
+ if (line[i] == '\'' && !prevCharWasEsc)
+ { betweenQuotes = 1-betweenQuotes; continue; }
+ // else...
+ if (line[i] == '\0')
+ action = WORDDONE;
+ else if (line[i] != ' ' && line[i] != '\t') // char's not whitespace
+ action = COPY; // copy it
+ else if (prevCharWasEsc || betweenQuotes) // char IS space, but escaped
+ action = COPY; // copy it
+ else
+ action = WORDDONE; // an unesc'd space NOT between quotes
+ // means we're done reading a word
+ if (action == COPY) {
+ lineCopy[j++] = line[i];
+ prevCharWasEsc = 0;
+ }
+ else if (action == WORDDONE) {
+ lineCopy[j] = '\0';
+ word[w] = calloc(strlen(lineCopy)+1, sizeof(char));
+ strcpy(word[w], lineCopy);
+ optName[w] = nalloc(word[w], 0);
+ optList = cat(optList, optName[w]);
+ if (line[i] == '\0') break; // finished reading line
+ // else...
+ w++; j = 0;
+ if (w > 255) {
+ fprintf(stderr,"Warning: too many words in variable '%s'\n", varName);
+ fprintf(stderr," ignoring after the 256th word '%s'\n", word[255]);
+ break;
+ }
+ }
+ }
+ free(lineCopy);
+ return optList;
+}
+
/*
* Unpack the name list onto a vector of strings.
* Return an error if the name list won't fit.
========================================================================
--- mailx-12.5/sendout.c 2016-09-17 17:44:43.543551595 +0200
+++ mailx-12.5+mtao/sendout.c 2016-09-16 20:23:45.366661696 +0200
@@ -971,6 +971,8 @@
if ((cp = value("autobcc")) != NULL && *cp)
hp->h_bcc = cat(hp->h_bcc,
checkaddrs(sextract(cp, GBCC|GFULL)));
+ if ((cp = value("mtaopts")) != NULL && *cp) // user set var "mtaopts"
+ hp->h_smopts = catWords(hp->h_smopts, cp, "mtaopts");
/*
* Collect user's mail from standard input.
* Get the result as mtf.
========================================================================
--- mailx-12.5/version.c 2010-07-05 01:07:59.000000000 +0200
+++ mailx-12.5+mtao/version.c 2016-09-17 17:36:50.302626899 +0200
@@ -1,4 +1,4 @@
-#define V "12.5"
+#define V "12.5+mtao"
/*
* Heirloom mailx - a mail user agent derived from Berkeley Mail.
*
“MTAopts for mailx” is Copyright © Dario Niedermann —
Released with no warranty under the terms of the
GPLv3 license. Written and tested on Linux using GNU tools.