X("tls", TLSminc(-3), TLSSW) \
X("initialtls", TLSminc(-10), INITTLSSW) \
X("notls", TLSminc(-5), NTLSSW) \
+ X("certverify", TLSminc(-10), CERTVERSW) \
+ X("nocertverify", TLSminc(-12), NOCERTVERSW) \
X("fileproc", -4, FILEPROCSW) \
X("mhlproc", -3, MHLPROCSW) \
X("sendmail program", 0, MTSSM) \
#define HDCC 0x0400 /* another undocumented feature */
#define HONE 0x0800 /* Only (zero or) one address allowed */
#define HEFM 0x1000 /* Envelope-From: header */
+#define HMIM 0x2000 /* MIME-Version: header */
+#define HCTE 0x4000 /* Content-Transfer-Encoding: header */
/*
* flags for headers->set
#define MSND 0x0020 /* we've seen a Sender: */
#define MRSN 0x0040 /* We've seen a Resent-Sendr:*/
#define MEFM 0x0080 /* We've seen Envelope-From: */
-
+#define MMIM 0x0100 /* We've seen Mime-Version: */
static struct headers NHeaders[] = {
{ "Return-Path", HBAD, 0 },
{ "Message-ID", HBAD, 0 },
{ "Fcc", HFCC, 0 },
{ "Envelope-From", HADR|HONE|HEFM, MEFM },
+ { "MIME-Version", HMIM, MMIM },
+ { "Content-Transfer-Encoding", HCTE, 0 },
{ NULL, 0, 0 }
};
{ "Bcc", HADR|HTRY|HBCC|HNIL, 0 },
{ "Fcc", HIGN, 0 },
{ "Envelope-From", HADR|HONE|HEFM, MEFM },
+ { "MIME-Version", HMIM, MMIM },
+ { "Content-Transfer-Encoding", HCTE, 0 },
{ NULL, 0, 0 }
};
static char *saslmech=NULL; /* Force use of particular SASL mech */
static char *user=NULL; /* Authenticate as this user */
static char *port="submission"; /* Name of server port for SMTP submission */
-static int tls=-1; /* Use TLS for encryption */
+static int tlsflag=0; /* Flags to control TLS settings */
static int fromcount=0; /* Count of addresses on From: header */
static int seensender=0; /* Have we seen a Sender: header? */
static char *filter = NULL; /* the filter for BCC'ing */
static char *subject = NULL; /* the subject field for BCC'ing */
static char *fccfold[FCCS]; /* foldernames for FCC'ing */
+enum encoding { UNKNOWN = 0, BINARY = 1, SEVENBIT = 7, EIGHTBIT = 8 };
+static enum encoding cte = UNKNOWN;
static struct headers *hdrtab; /* table for the message we're doing */
int
main (int argc, char **argv)
{
- int state, compnum, dashstuff = 0, swnum, oauth_flag = 0;
+ int state, compnum, dashstuff = 0, swnum, oauth_flag = 0, tls = -1;
+ int noverify = 0;
int eai = 0; /* use Email Address Internationalization (EAI) (SMTPUTF8) */
char *cp, *msg = NULL, **argp, **arguments, *envelope;
char buf[BUFSIZ], name[NAMESZ], *auth_svc = NULL;
tls = 0;
continue;
+ case CERTVERSW:
+ noverify = 0;
+ continue;
+
+ case NOCERTVERSW:
+ noverify++;
+ continue;
+
case FILEPROCSW:
if (!(cp = *argp++) || *cp == '-')
adios (NULL, "missing argument to %s", argp[-2]);
case FLD:
case FLDPLUS:
compnum++;
- cp = add (buf, NULL);
+ cp = mh_xstrdup(buf);
while (state == FLDPLUS) {
bufsz = sizeof buf;
state = m_getfld (&gstate, name, buf, &bufsz, in);
#endif /* ! TLS_SUPPORT */
}
+ if (tls == 1)
+ tlsflag = S_STARTTLS;
+ else if (tls == 2)
+ tlsflag = S_INITTLS;
+ else
+ tlsflag = 0;
+
+ if (noverify)
+ tlsflag |= S_NOVERIFY;
+
/*
* If we were given any oauth flags, store the appropriate profile
* entries and make sure an authservice was given (we have to do this
if (partno)
printf ("Partial Message #%s Processed\n", partno);
else
- printf ("Message Processed\n");
+ puts("Message Processed");
}
done (0);
If it does, enable EAI support. */
if (contains8bit(str, NULL)) {
if (verbose) {
- printf ("EAI/SMTPUTF8 enabled\n");
+ puts("EAI/SMTPUTF8 enabled");
}
/* Enable SMTPUTF8. */
should never have reached this point. Warn about any
that are non-empty. */
if (strcmp (str, "\n")) {
- char *newline = strchr (str, '\n');
- if (newline) *newline = '\0';
+ trim_suffix_c(str, '\n');
if (! whomsw) {
advise (NULL, "ignoring header line -- %s: %s", name, str);
}
msgflags |= (hdr->set & ~(MVIS | MINV));
if (hdr->flags & HSUB)
- subject = subject ? add (str, add ("\t", subject)) : getcpy (str);
+ subject = subject ? add (str, add ("\t", subject)) : mh_xstrdup(str);
if (hdr->flags & HFCC) {
if ((cp = strrchr(str, '\n')))
*cp = 0;
insert_fcc (hdr, pp);
return;
}
-
+ if (hdr->flags & HCTE) {
+ if (strncasecmp (str, "7bit", 4) == 0) {
+ cte = SEVENBIT;
+ } else if (strncasecmp (str, "8bit", 4) == 0) {
+ cte = EIGHTBIT;
+ } else if (strncasecmp (str, "binary", 6) == 0) {
+ cte = BINARY;
+ }
+ }
if (!(hdr->flags & HADR)) {
fprintf (out, "%s: %s", name, str);
return;
* Strip off any trailing newlines
*/
- while (strlen(fullfrom) > 0 && fullfrom[strlen(fullfrom) - 1] == '\n') {
+ while (*fullfrom && fullfrom[strlen(fullfrom) - 1] == '\n') {
fullfrom[strlen(fullfrom) - 1] = '\0';
}
}
}
if (*aka && mp->m_type != UUCPHOST && !mp->m_pers)
- mp->m_pers = getcpy (aka);
+ mp->m_pers = mh_xstrdup(aka);
if (format) {
if (mp->m_gname) {
snprintf (buffer, sizeof(buffer), "%s;", mp->m_gname);
printf ("\n\t-- Folder Copies --\nfcc:\t");
for (i = 0; i < fccind; i++)
printf ("%s%s", fccfold[i], i + 1 < fccind ? ",\n\t" : "");
- printf ("\n");
+ putchar('\n');
}
if (fccind >= FCCS)
adios (NULL, "too many %ss", hdr->value);
- fccfold[fccind++] = getcpy (cp);
+ fccfold[fccind++] = mh_xstrdup(cp);
}
/*
if ((in = fopen (tmpfil, "r")) == NULL)
adios (tmpfil, "unable to re-open");
- while (fgets (buffer, sizeof(buffer) - 1, in))
+ while (fgets (buffer, sizeof buffer, in))
if (buffer[0] == '-' && buffer[1] == '-') {
char *cp;
for (lp = localaddrs.m_next; lp; lp = lp->m_next)
if (lp->m_bcc ? bccque : !bccque) {
if (talk && !state)
- printf (" -- Local Recipients --\n");
+ puts(" -- Local Recipients --");
do_an_address (lp, talk);
state++;
}
for (lp = uuaddrs.m_next; lp; lp = lp->m_next)
if (lp->m_bcc ? bccque : !bccque) {
if (talk && !state)
- printf (" -- UUCP Recipients --\n");
+ puts(" -- UUCP Recipients --");
do_an_address (lp, talk);
state++;
}
for (lp = netaddrs.m_next; lp; lp = lp->m_next)
if (lp->m_bcc ? bccque : !bccque) {
if (talk && !state)
- printf (" -- Network Recipients --\n");
+ puts(" -- Network Recipients --");
do_an_address (lp, talk);
state++;
}
post (char *file, int bccque, int talk, int eai, char *envelope,
int oauth_flag, char *auth_svc)
{
- int fd;
int retval, i;
pid_t child_id;
printf (" -- Posting for %s Recipients --\n",
bccque ? "Blind" : "Sighted");
else
- printf (" -- Posting for All Recipients --\n");
+ puts(" -- Posting for All Recipients --");
}
sigon ();
break;
}
} else {
+ const int fd = open (file, O_RDONLY);
+ int eightbit = 0;
+
+ if (fd == NOTOK) {
+ die (file, "unable to re-open");
+ }
+
+ if (msgflags & MMIM && cte != UNKNOWN) {
+ /* MIME message with C-T-E header. (BINARYMIME isn't
+ supported, use 8BITMIME instead for binary.) */
+ eightbit = cte != SEVENBIT;
+ } else {
+ if (scan_input (fd, &eightbit) == NOTOK) {
+ close (fd);
+ die (file, "problem reading from");
+ }
+ }
+
if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch,
verbose, snoop, sasl, saslmech, user,
- oauth_flag ? auth_svc : NULL, tls))
- || rp_isbad (retval = sm_winit (envelope, eai))) {
+ oauth_flag ? auth_svc : NULL, tlsflag))
+ || rp_isbad (retval = sm_winit (envelope, eai, eightbit))) {
+ close (fd);
die (NULL, "problem initializing server; %s", rp_string (retval));
}
do_addresses (bccque, talk && verbose);
- if ((fd = open (file, O_RDONLY)) == NOTOK)
- die (file, "unable to re-open");
do_text (file, fd);
close (fd);
fflush (stdout);
printf (" -- %s Recipient Copies Posted --\n",
bccque ? "Blind" : "Sighted");
else
- printf (" -- Recipient Copies Posted --\n");
+ puts(" -- Recipient Copies Posted --");
}
fflush (stdout);
sigon ();
if (!whomsw || checksw) {
+ /* Not sending message body, so don't need to use 8BITMIME. */
+ const int eightbit = 0;
+
if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch,
verbose, snoop, sasl, saslmech, user,
- oauth_flag ? auth_svc : NULL, tls))
- || rp_isbad (retval = sm_winit (envelope, eai))) {
+ oauth_flag ? auth_svc : NULL, tlsflag))
+ || rp_isbad (retval = sm_winit (envelope, eai, eightbit))) {
die (NULL, "problem initializing server; %s", rp_string (retval));
}
}
if (talk && !whomsw)
- printf (" -- Address Verification --\n");
+ puts(" -- Address Verification --");
if (talk && localaddrs.m_next)
- printf (" -- Local Recipients --\n");
+ puts(" -- Local Recipients --");
for (lp = localaddrs.m_next; lp; lp = lp->m_next)
do_an_address (lp, talk);
if (talk && uuaddrs.m_next)
- printf (" -- UUCP Recipients --\n");
+ puts(" -- UUCP Recipients --");
for (lp = uuaddrs.m_next; lp; lp = lp->m_next)
do_an_address (lp, talk);
if (talk && netaddrs.m_next)
- printf (" -- Network Recipients --\n");
+ puts(" -- Network Recipients --");
for (lp = netaddrs.m_next; lp; lp = lp->m_next)
do_an_address (lp, talk);
chkadr ();
if (talk && !whomsw)
- printf (" -- Address Verification Successful --\n");
+ puts(" -- Address Verification Successful --");
if (!whomsw || checksw)
sm_end (DONE);
lp->m_type != UUCPHOST ? lp->m_path : NULL)) {
case RP_OK:
if (talk)
- printf ("address ok\n");
+ puts("address ok");
break;
case RP_NO:
case RP_NO:
case RP_NDEL:
die (NULL, "posting failed; %s", rp_string (retval));
+ /* FALLTHRU */
default:
die (NULL, "unexpected response; %s", rp_string (retval));
return;
if (verbose)
- printf (" -- Filing Folder Copies --\n");
+ puts(" -- Filing Folder Copies --");
for (i = 0; i < fccind; i++)
fcc (file, fccfold[i]);
if (verbose)
- printf (" -- Folder Copies Filed --\n");
+ puts(" -- Folder Copies Filed --");
}
pidstatus (status, verbose ? stdout : stderr, NULL);
} else {
if (verbose)
- printf ("folder ok\n");
+ puts("folder ok");
}
}