#include <h/dropsbr.h>
#include <h/tws.h>
#include <h/utils.h>
+#include <unistd.h>
+#include <locale.h>
+#include <sysexits.h>
#define MAX_SM_FIELD 1476 /* < largest hdr field sendmail will accept */
#define MVIS 0x0008 /* we've seen sighted addrs */
#define MINV 0x0010 /* we've seen blind addrs */
#define MRDT 0x0020 /* we've seen a Resent-Date: */
+#define MFMM 0x0040 /* The Mail is From a Alternative-Mailbox Addresse */
struct headers {
char *value;
static char *subject = NULL; /* the subject field for BCC'ing */
static char fccs[BUFSIZ] = "";
struct mailname *bccs = NULL; /* list of the bcc recipients */
+struct mailname *sender = NULL;
static struct headers *hdrtab; /* table for the message we're doing */
static FILE *out; /* output (temp) file */
switch (smatch(++cp, switches)) {
case AMBIGSW:
ambigsw(cp, switches);
- done(1);
+ exit(EX_USAGE);
case UNKWNSW:
- adios(NULL, "-%s unknown", cp);
+ adios(EX_USAGE, NULL, "-%s unknown", cp);
case HELPSW:
snprintf(buf, sizeof(buf),
"%s [switches] file",
invo_name);
print_help(buf, switches, 1);
- done(1);
+ exit(argc == 2 ? EX_OK : EX_USAGE);
case VERSIONSW:
print_version(invo_name);
- done(1);
+ exit(argc == 2 ? EX_OK : EX_USAGE);
case DEBUGSW:
debug++;
continue;
}
}
- if (msg)
- adios(NULL, "only one message at a time!");
- else
+ if (msg) {
+ adios(EX_USAGE, NULL, "only one message at a time!");
+ } else {
msg = cp;
+ }
}
- if (!msg)
- adios(NULL, "usage: %s [switches] file", invo_name);
+ if (!msg) {
+ adios(EX_USAGE, NULL, "usage: %s [switches] file", invo_name);
+ }
- if ((in = fopen(msg, "r")) == NULL)
- adios(msg, "unable to open");
+ if ((in = fopen(msg, "r")) == NULL) {
+ adios(EX_IOERR, msg, "unable to open");
+ }
if (debug) {
verbose++;
for (ap=brkstring(dp=getcpy(cp), " ", "\n"); ap && *ap;
ap++) {
if ((state = alias(etcpath(*ap))) != AK_OK) {
- adios(NULL, "aliasing error in file %s: %s",
+ adios(EX_IOERR, NULL, "aliasing error in file %s: %s",
*ap, akerror(state));
}
}
for (compnum = 1, state = FLD;;) {
switch (state = m_getfld(state, name, buf, sizeof(buf), in)) {
case FLD:
- compnum++;
- putfmt(name, buf, out);
- continue;
-
case FLDPLUS:
compnum++;
- cp = add(buf, cp);
+ cp = getcpy(buf);
while (state == FLDPLUS) {
state = m_getfld(state, name, buf,
sizeof(buf), in);
case LENERR:
case FMTERR:
- adios(NULL, "message format error in component #%d",
+ adios(EX_DATAERR, NULL, "message format error in component #%d",
compnum);
default:
- adios(NULL, "getfld() returned %d", state);
+ adios(EX_SOFTWARE, NULL, "getfld() returned %d", state);
}
break;
}
if (debug) {
/* stop here */
- done(0);
+ exit(EX_OK);
}
fclose(out);
if (!(msgflags & MVIS)) {
/* only Bcc rcpts: we're finished here */
unlink(tmpfil);
- exit(0);
+ exit(EX_OK);
}
}
** the msg temp file as std in.
*/
if (!freopen(tmpfil, "r", stdin)) {
- adios(tmpfil, "can't reopen for sendmail");
+ adios(EX_IOERR, tmpfil, "can't reopen for sendmail");
}
unlink(tmpfil);
}
*argp = NULL;
execv(sendmail, sargv);
- adios(sendmail, "can't exec");
+ adios(EX_OSERR, sendmail, "can't exec");
return -1;
}
if ((i = get_header(name, hdrtab)) == NOTOK) {
/* no header we would care for */
- if (mh_strcasecmp(name, attach_hdr)!=0 &&
- mh_strcasecmp(name, sign_hdr)!=0 &&
- mh_strcasecmp(name, enc_hdr)!=0) {
- /* push it through */
- fprintf(out, "%s: %s", name, str);
+ if (mh_strcasecmp(name, attach_hdr)==0) {
+ return;
}
+ if (mh_strcasecmp(name, sign_hdr)==0) {
+ return;
+ }
+ if (mh_strcasecmp(name, enc_hdr)==0) {
+ return;
+ }
+ /* push it through */
+ fprintf(out, "%s: %s", name, str);
return;
}
/* it's one of the interesting headers */
** -- meillo@marmaro.de 2012-02
*/
+ if (hdr->set & MFRM) {
+ struct mailname *mp = NULL;
+ struct mailname *my = NULL;
+ unsigned int fromcnt = 0;
+
+ /* needed because the address parser holds global state */
+ ismymbox(NULL);
+
+ while ((cp = getname(str)) != NULL) {
+ fromcnt++;
+ mp = getm(cp, NULL, 0, AD_NAME, NULL);
+ if (ismymbox(mp)) {
+ msgflags |= MFMM;
+ if (my == NULL) {
+ my = mp;
+ } else {
+ mnfree(mp);
+ mp = NULL;
+ }
+ } else {
+ mnfree(mp);
+ mp = NULL;
+ }
+ }
+
+ if (fromcnt > 1) {
+ sender = my;
+ } else {
+ mnfree(my);
+ }
+
+ free(cp);
+ cp = NULL;
+
+ }
+
if (hdr->flags & HSUB) {
subject = getcpy(str);
}
fprintf(out, "%sDate: %s\n", resentstr, dtimenow());
}
- snprintf(from, sizeof(from), "%s@%s", getusername(), LocalName());
- if ((cp = getfullname()) && *cp) {
- snprintf(signature, sizeof(signature), "%s <%s>", cp, from);
+ if (sender != NULL) {
+ snprintf(signature, sizeof(signature), "%s", sender->m_text);
+ } else if ((cp = context_find("Default-From")) != NULL) {
+ snprintf(signature, sizeof(signature), "%s", cp);
} else {
- snprintf(signature, sizeof(signature), "%s", from);
+ snprintf(from, sizeof(from), "%s@%s", getusername(), LocalName());
+ if ((cp = getfullname()) && *cp) {
+ snprintf(signature, sizeof(signature), "%s <%s>", cp, from);
+ } else {
+ snprintf(signature, sizeof(signature), "%s", from);
+ }
}
if (!(msgflags & MFRM)) {
fprintf(out, "%sFrom: %s\n", resentstr, signature);
** Add a Sender: header because the From: header could
** be fake or contain multiple addresses.
*/
- fprintf(out, "%sSender: %s\n", resentstr, from);
+ if (!(msgflags & MFMM) || sender != NULL) {
+ fprintf(out, "%sSender: %s\n", resentstr, signature);
+ }
}
if (!(msgflags & MVIS)) {
fprintf(out, "%sBcc: undisclosed-recipients:;\n", resentstr);
}
if (badmsg) {
unlink(tmpfil);
- adios(NULL, "re-format message and try again");
+ adios(EX_DATAERR, NULL, "re-format message and try again");
}
}
return (h - table);
}
}
-
return NOTOK;
}
/* a local name - see if it's an alias */
cp = akvalue(mp->m_mbox);
if (cp == mp->m_mbox) {
- /* wasn't an alias - use what the user typed */
+ /* wasn't an alias - use it unchanged */
linepos = putone(mp->m_text, linepos, namelen);
} else {
/* an alias - expand it */
}
}
} else {
- /* not a local name - use what the user typed */
+ /* not a local name - use it unchanged */
linepos = putone(mp->m_text, linepos, namelen);
}
mp2 = mp;
static int
putone(char *adr, int pos, int indent)
{
- register int len;
+ int len;
static int linepos;
len = strlen(adr);
- if (pos == indent)
+ if (pos == indent) {
linepos = pos;
- else if (linepos+len > OUTPUTLINELEN) {
+ } else if (linepos+len > OUTPUTLINELEN) {
fprintf(out, ",\n%*s", indent, "");
linepos = indent;
pos += indent + 2;
int state = 0;
if (strlen(str)+strlen(fccs) > sizeof fccs /2) {
- adios(NULL, "Too much Fcc data");
+ adios(EX_DATAERR, NULL, "Too much Fcc data");
}
/* todo: better have three states: SEPARATOR, PLUS, WORD */
for (cp=pp=str; *cp; cp++) {
fflush(stdout);
}
if (100+strlen(file)+strlen(folders) > sizeof cmd) {
- adios(NULL, "Too much Fcc data");
+ adios(EX_DATAERR, NULL, "Too much Fcc data");
}
/* hack: read from /dev/null and refile(1) won't question us */
snprintf(cmd, sizeof cmd, "</dev/null refile -link -file '%s' %s",