]> diplodocus.org Git - nmh/blobdiff - uip/post.c
Simplified m_strn() per Ralph's suggestions.
[nmh] / uip / post.c
index bf1c042db6276a058440936459f41e4138071c33..81bd7b4a6680f78aed187e8ee9ada401aa82f96a 100644 (file)
@@ -1,5 +1,4 @@
-/*
- * post.c -- enter messages into the mail transport system
+/* post.c -- enter messages into the mail transport system
  *
  * This code is Copyright (c) 2002, by the authors of nmh.  See the
  * COPYRIGHT file in the root directory of the nmh distribution for
@@ -16,6 +15,8 @@
 #include <h/utils.h>
 #include <h/tws.h>
 #include <h/mts.h>
+#include "../sbr/m_mktemp.h"
+#include "../sbr/message_id.h"
 
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
@@ -89,6 +90,8 @@
     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) \
@@ -118,7 +121,7 @@ DEFINE_SWITCH_ARRAY(POST, switches);
  * from 'send'.  We use a service name of 'post' internally.
  */
 
-static struct oauth_profile {
+static struct {
     const char *profname;
     int switchnum;
     const char *value;
@@ -168,7 +171,7 @@ struct headers {
 #define        MVIS  0x0008    /* we've seen sighted addrs  */
 #define        MINV  0x0010    /* we've seen blind addrs    */
 #define MSND  0x0020   /* we've seen a Sender:      */
-#define MRSN  0x0040   /* We've seen a Resent-Sendr:*/
+#define MRSN  0x0040   /* We've seen a Resent-Sender: */
 #define MEFM  0x0080   /* We've seen Envelope-From: */
 #define MMIM  0x0100    /* We've seen Mime-Version:  */
 
@@ -239,7 +242,7 @@ static int sasl=0;          /* Use SASL auth for SMTP                */
 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?        */
 
@@ -313,10 +316,11 @@ static int find_prefix (void);
 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;
+    char buf[NMH_BUFSIZ], name[NAMESZ], *auth_svc = NULL;
     FILE *in, *out;
     m_getfld_state_t gstate = 0;
 
@@ -530,6 +534,14 @@ main (int argc, char **argv)
                    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]);
@@ -612,7 +624,7 @@ main (int argc, char **argv)
            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);
@@ -692,6 +704,16 @@ main (int argc, char **argv)
 #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
@@ -775,7 +797,7 @@ putfmt (char *name, char *str, int *eai, FILE *out)
        str++;
 
     if (msgstate == NORMAL && uprf (name, "resent")) {
-       advise (NULL, "illegal header line -- %s:", name);
+       inform("illegal header line -- %s:", name);
        badmsg++;
        return;
     }
@@ -804,9 +826,9 @@ putfmt (char *name, char *str, int *eai, FILE *out)
               should never have reached this point.  Warn about any
               that are non-empty. */
            if (strcmp (str, "\n")) {
-                TrimSuffixC(str, '\n');
+                trim_suffix_c(str, '\n');
                if (! whomsw) {
-                   advise (NULL, "ignoring header line -- %s: %s", name, str);
+                   inform("ignoring header line -- %s: %s", name, str);
                }
            }
        }
@@ -819,7 +841,7 @@ putfmt (char *name, char *str, int *eai, FILE *out)
        return;
     }
     if (hdr->flags & HBAD) {
-       advise (NULL, "illegal header line -- %s:", name);
+       inform("illegal header line -- %s:", name);
        badmsg++;
        return;
     }
@@ -879,11 +901,11 @@ putfmt (char *name, char *str, int *eai, FILE *out)
             */
            if ((msgstate == RESENT) ? (hdr->set & MRSN)
                                        : (hdr->set & MSND)) {
-               advise (NULL, "%s: field requires one address", name);
+               inform("%s: field requires one address", name);
                badmsg++;
            }
 #ifdef notdef
-           advise (NULL, "%s: field requires at least one address", name);
+           inform("%s: field requires at least one address", name);
            badmsg++;
 #endif /* notdef */
        }
@@ -891,7 +913,7 @@ putfmt (char *name, char *str, int *eai, FILE *out)
     }
 
     if (count > 1 && (hdr->flags & HONE)) {
-       advise (NULL, "%s: field only permits one address", name);
+       inform("%s: field only permits one address", name);
        badmsg++;
        return;
     }
@@ -1047,7 +1069,7 @@ putfmt (char *name, char *str, int *eai, FILE *out)
     }
 
     if (grp > 0 && (hdr->flags & HNGR)) {
-       advise (NULL, "%s: field does not allow groups", name);
+       inform("%s: field does not allow groups", name);
        badmsg++;
     }
     if (linepos) {
@@ -1087,14 +1109,14 @@ finish_headers (FILE *out)
                /*
                 * A From: header is now required in the draft.
                 */
-               advise (NULL, "message has no From: header");
-               advise (NULL, "See default components files for examples");
+               inform("message has no From: header");
+               inform("See default components files for examples");
                badmsg++;
                break;
            }
 
            if (fromcount > 1 && (seensender == 0 && !(msgflags & MEFM))) {
-               advise (NULL, "A Sender: or Envelope-From: header is required "
+               inform("A Sender: or Envelope-From: header is required "
                        "with multiple\nFrom: addresses");
                badmsg++;
                break;
@@ -1114,7 +1136,7 @@ finish_headers (FILE *out)
 
            if (fromcount > 1 && seensender == 0) {
                if (efrom[0] == '\0') {
-                   advise (NULL, "Envelope-From cannot be blank when there "
+                   inform("Envelope-From cannot be blank when there "
                            "is multiple From: addresses\nand no Sender: "
                            "header");
                    badmsg++;
@@ -1129,21 +1151,21 @@ finish_headers (FILE *out)
 
        case RESENT: 
            if (!(msgflags & MDAT)) {
-               advise (NULL, "message has no Date: header");
+               inform("message has no Date: header");
                badmsg++;
            }
            if (!(msgflags & MFRM)) {
-               advise (NULL, "message has no From: header");
+               inform("message has no From: header");
                badmsg++;
            }
            if (!(msgflags & MRFM)) {
-               advise (NULL, "message has no Resent-From: header");
-               advise (NULL, "See default components files for examples");
+               inform("message has no Resent-From: header");
+               inform("See default components files for examples");
                badmsg++;
                break;
            }
            if (fromcount > 1 && (seensender == 0 && !(msgflags & MEFM))) {
-               advise (NULL, "A Resent-Sender: or Envelope-From: header is "
+               inform("A Resent-Sender: or Envelope-From: header is "
                        "required with multiple\nResent-From: addresses");
                badmsg++;
                break;
@@ -1164,7 +1186,7 @@ finish_headers (FILE *out)
 
            if (fromcount > 1 && seensender == 0) {
                if (efrom[0] == '\0') {
-                   advise (NULL, "Envelope-From cannot be blank when there "
+                   inform("Envelope-From cannot be blank when there "
                            "is multiple Resent-From: addresses and no "
                            "Resent-Sender: header");
                    badmsg++;
@@ -1191,7 +1213,7 @@ get_header (char *header, struct headers *table)
     struct headers *h;
 
     for (h = table; h->value; h++)
-       if (!strcasecmp (header ? header : "", h->value ? h->value : ""))
+       if (!strcasecmp (FENDNULL(header), FENDNULL(h->value)))
            return (h - table);
 
     return NOTOK;
@@ -1292,10 +1314,10 @@ insert (struct mailname *np)
            : &netaddrs;
            mp->m_next;
            mp = mp->m_next)
-       if (!strcasecmp (np->m_host ? np->m_host : "",
-                        mp->m_next->m_host ? mp->m_next->m_host : "") &&
-           !strcasecmp (np->m_mbox ? np->m_mbox : "",
-                        mp->m_next->m_mbox ? mp->m_next->m_mbox : "") &&
+       if (!strcasecmp (FENDNULL(np->m_host),
+                        FENDNULL(mp->m_next->m_host)) &&
+           !strcasecmp (FENDNULL(np->m_mbox),
+                        FENDNULL(mp->m_next->m_mbox)) &&
            np->m_bcc == mp->m_next->m_bcc)
            return 0;
 
@@ -1319,7 +1341,7 @@ pl (void)
 
     printf ("\nnet:\t");
     for (mp = netaddrs.m_next; mp; mp = mp->m_next)
-       printf ("%s%s@%s%s%s", mp->m_path ? mp->m_path : "",
+       printf ("%s%s@%s%s%s", FENDNULL(mp->m_path),
                mp->m_mbox, mp->m_host,
                mp->m_bcc ? "[BCC]" : "",
                mp->m_next ? ",\n\t" : "");
@@ -1527,7 +1549,7 @@ find_prefix (void)
     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;
 
@@ -1546,18 +1568,16 @@ find_prefix (void)
 }
 
 
-#define        plural(x) (x == 1 ? "" : "s")
-
 static void
 chkadr (void)
 {
     if (badadr && unkadr)
        die (NULL, "%d address%s unparsable, %d addressee%s undeliverable",
-               badadr, plural (badadr), unkadr, plural (badadr));
+               badadr, PLURALS(badadr), unkadr, PLURALS(badadr));
     if (badadr)
-       die (NULL, "%d address%s unparsable", badadr, plural (badadr));
+       die (NULL, "%d address%s unparsable", badadr, PLURALS(badadr));
     if (unkadr)
-       die (NULL, "%d addressee%s undeliverable", unkadr, plural (unkadr));
+       die (NULL, "%d addressee%s undeliverable", unkadr, PLURALS(unkadr));
 }
 
 
@@ -1680,7 +1700,7 @@ post (char *file, int bccque, int talk, int eai, char *envelope,
 
        if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch,
                                        verbose, snoop, sasl, saslmech, user,
-                                       oauth_flag ? auth_svc : NULL, tls))
+                                       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));
@@ -1724,7 +1744,7 @@ verify_all_addresses (int talk, int eai, char *envelope, int oauth_flag,
 
        if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch,
                                        verbose, snoop, sasl, saslmech, user,
-                                       oauth_flag ? auth_svc : NULL, tls))
+                                       oauth_flag ? auth_svc : NULL, tlsflag))
                || rp_isbad (retval = sm_winit (envelope, eai, eightbit))) {
            die (NULL, "problem initializing server; %s", rp_string (retval));
        }
@@ -1829,7 +1849,7 @@ do_text (char *file, int fd)
     int retval, state;
     char buf[BUFSIZ];
 
-    lseek (fd, (off_t) 0, SEEK_SET);
+    lseek(fd, 0, SEEK_SET);
 
     while ((state = read (fd, buf, sizeof(buf))) > 0) {
        if (rp_isbad (retval = sm_wtxt (buf, state)))
@@ -1846,6 +1866,7 @@ do_text (char *file, int fd)
        case RP_NO: 
        case RP_NDEL: 
            die (NULL, "posting failed; %s", rp_string (retval));
+           break;
 
        default: 
            die (NULL, "unexpected response; %s", rp_string (retval));
@@ -1967,7 +1988,7 @@ fcc (char *file, char *folder)
                if (!verbose)
                    fprintf (stderr, "  %sFcc %s: ",
                            msgstate == RESENT ? "Resent-" : "", folder);
-               pidstatus (status, verbose ? stdout : stderr, NULL);
+               pidstatus (status, verbose ? stdout : stderr, fileproc);
            } else {
                if (verbose)
                    puts("folder ok");
@@ -1984,8 +2005,11 @@ fcc (char *file, char *folder)
 static void
 die (char *what, char *fmt, ...)
 {
+    int err;
     va_list ap;
 
+    err = errno;
+
     (void) m_unlink (tmpfil);
     if (msgflags & MINV)
        (void) m_unlink (bccfil);
@@ -1994,6 +2018,7 @@ die (char *what, char *fmt, ...)
        sm_end (NOTOK);
 
     va_start(ap, fmt);
+    errno = err;
     advertise (what, NULL, fmt, ap);
     va_end(ap);
     done (1);