]> diplodocus.org Git - nmh/blobdiff - uip/post.c
Reworked attach to add charset to Content-Type string for
[nmh] / uip / post.c
index ffc9de803fe63ff8dee4067f83d3f31153413e44..858946354ba2e55a5ec7e0c2242cf1720e3e519e 100644 (file)
 #include <h/dropsbr.h>
 #include <h/mime.h>
 #include <h/utils.h>
-
 #include <h/tws.h>
 #include <h/mts.h>
 
-#include <errno.h>
-#include <signal.h>
-
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
 #endif
    0  : Switch can't be abbreviated;               switch shown in -help.
    #  : Switch can be abbreviated to # characters; switch shown in -help. */
 
-static struct swit switches[] = {
-#define        ALIASW                    0
-    { "alias aliasfile", 0 },
-#define        CHKSW                     1
-    { "check", -5 },                   /* interface from whom */
-#define        NCHKSW                    2
-    { "nocheck", -7 },                 /* interface from whom */
-#define        DEBUGSW                   3
-    { "debug", -5 },
-#define        DISTSW                    4
-    { "dist", -4 },                    /* interface from dist */
-#define        FILTSW                    5
-    { "filter filterfile", 0 },
-#define        NFILTSW                   6
-    { "nofilter", 0 },
-#define        FRMTSW                    7
-    { "format", 0 },
-#define        NFRMTSW                   8
-    { "noformat", 0 },
-#define        LIBSW                     9
-    { "library directory", -7 },       /* interface from send, whom */
-#define        MIMESW                   10
-    { "mime", 0 },
-#define        NMIMESW                  11
-    { "nomime", 0 },
-#define        MSGDSW                   12
-    { "msgid", 0 },
-#define        NMSGDSW                  13
-    { "nomsgid", 0 },
-#define        VERBSW                   14
-    { "verbose", 0 },
-#define        NVERBSW                  15
-    { "noverbose", 0 },
-#define        WATCSW                   16
-    { "watch", 0 },
-#define        NWATCSW                  17
-    { "nowatch", 0 },
-#define        WHOMSW                   18
-    { "whom", -4 },                    /* interface from whom */
-#define        WIDTHSW                  19
-    { "width columns", 0 },
-#define VERSIONSW                20
-    { "version", 0 },
-#define        HELPSW                   21
-    { "help", 0 },
-#define BITSTUFFSW               22
-    { "dashstuffing", -12 },           /* should we dashstuff BCC messages? */
-#define NBITSTUFFSW              23
-    { "nodashstuffing", -14 },
-#define        ANNOSW                   24
-    { "idanno number", -6 },           /* interface from send    */
-#define        CLIESW                   25
-    { "client host", -6 },
-#define        SERVSW                   26
-    { "server host", 6 },              /* specify alternate SMTP server */
-#define        SNOOPSW                  27
-    { "snoop", -5 },                   /* snoop the SMTP transaction */
-#define        PARTSW                   28
-    { "partno", -6 },
-#define        QUEUESW                  29
-    { "queued", -6 },
-#define SASLSW                   30
-    { "sasl", SASLminc(-4) },
-#define NOSASLSW                 31
-    { "nosasl", SASLminc(-6) },
-#define SASLMXSSFSW              32
-    { "saslmaxssf", SASLminc(-10) },
-#define SASLMECHSW               33
-    { "saslmech", SASLminc(-5) },
-#define USERSW                   34
-    { "user", SASLminc(-4) },
-#define PORTSW                  35
-    { "port server port name/number", 4 },
-#define TLSSW                   36
-    { "tls", TLSminc(-3) },
-#define NTLSSW                   37
-    { "notls", TLSminc(-5) },
-#define FILEPROCSW              38
-    { "fileproc", -4 },
-#define MHLPROCSW               39
-    { "mhlproc", -3 },
-#define MTSSW                   40
-    { "mts smtp|sendmail/smtp|sendmail/pipe", 2 },
-#define MESSAGEIDSW             41
-    { "messageid localname|random", 2 },
-    { NULL, 0 }
-};
+#define POST_SWITCHES \
+    X("alias aliasfile", 0, ALIASW) \
+    X("check", -5, CHKSW) /* interface from whom */ \
+    X("nocheck", -7, NCHKSW) /* interface from whom */ \
+    X("debug", -5, DEBUGSW) \
+    X("dist", -4, DISTSW) /* interface from dist */ \
+    X("filter filterfile", 0, FILTSW) \
+    X("nofilter", 0, NFILTSW) \
+    X("format", 0, FRMTSW) \
+    X("noformat", 0, NFRMTSW) \
+    X("library directory", -7, LIBSW) /* interface from send, whom */ \
+    X("mime", 0, MIMESW) \
+    X("nomime", 0, NMIMESW) \
+    X("msgid", 0, MSGDSW) \
+    X("nomsgid", 0, NMSGDSW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("watch", 0, WATCSW) \
+    X("nowatch", 0, NWATCSW) \
+    X("whom", -4, WHOMSW) /* interface from whom */ \
+    X("width columns", 0, WIDTHSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("dashstuffing", -12, BITSTUFFSW) /* should we dashstuff BCC messages? */ \
+    X("nodashstuffing", -14, NBITSTUFFSW) \
+    X("idanno number", -6, ANNOSW) /* interface from send    */ \
+    X("client host", -6, CLIESW) \
+    X("server host", 6, SERVSW) /* specify alternate SMTP server */ \
+    X("snoop", -5, SNOOPSW) /* snoop the SMTP transaction */ \
+    X("partno", -6, PARTSW) \
+    X("queued", -6, QUEUESW) \
+    X("sasl", SASLminc(-4), SASLSW) \
+    X("nosasl", SASLminc(-6), NOSASLSW) \
+    X("saslmaxssf", SASLminc(-10), SASLMXSSFSW) \
+    X("saslmech", SASLminc(-5), SASLMECHSW) \
+    X("user", SASLminc(-4), USERSW) \
+    X("port server port name/number", 4, PORTSW) \
+    X("tls", TLSminc(-3), TLSSW) \
+    X("initialtls", TLSminc(-10), INITTLSSW) \
+    X("notls", TLSminc(-5), NTLSSW) \
+    X("fileproc", -4, FILEPROCSW) \
+    X("mhlproc", -3, MHLPROCSW) \
+    X("mts smtp|sendmail/smtp|sendmail/pipe", 2, MTSSW) \
+    X("credentials legacy|file:filename", 0, CREDENTIALSSW) \
+    X("messageid localname|random", 2, MESSAGEIDSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(POST);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(POST, switches);
+#undef X
 
 
 struct headers {
@@ -221,8 +183,6 @@ static short fccind = 0;    /* index into fccfold[] */
 static short outputlinelen = OUTPUTLINELEN;
 
 static int pfd = NOTOK;                /* fd to write annotation list to        */
-static uid_t myuid= -1;                /* my user id                            */
-static gid_t mygid= -1;                /* my group id                           */
 static int recipients = 0;     /* how many people will get a copy       */
 static int unkadr = 0;         /* how many of those were unknown        */
 static int badadr = 0;         /* number of bad addrs                   */
@@ -263,7 +223,6 @@ static char from[BUFSIZ];   /* my network address            */
 static char sender[BUFSIZ];    /* my Sender: header             */
 static char efrom[BUFSIZ];     /* my Envelope-From: header      */
 static char fullfrom[BUFSIZ];  /* full contents of From header  */
-static char signature[BUFSIZ]; /* my signature                  */
 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       */
@@ -299,7 +258,7 @@ static int insert (struct mailname *);
 static void pl (void);
 static void anno (void);
 static int annoaux (struct mailname *);
-static void insert_fcc (struct headers *, unsigned char *);
+static void insert_fcc (struct headers *, char *);
 static void make_bcc_file (int);
 static void verify_all_addresses (int, char *);
 static void chkadr (void);
@@ -322,6 +281,7 @@ main (int argc, char **argv)
     char *cp, *msg = NULL, **argp, **arguments, *envelope;
     char buf[BUFSIZ], name[NAMESZ];
     FILE *in, *out;
+    m_getfld_state_t gstate = 0;
 
 #ifdef LOCALE
     setlocale(LC_ALL, "");
@@ -505,7 +465,11 @@ main (int argc, char **argv)
                    continue;
 
                case TLSSW:
-                   tls++;
+                   tls = 1;
+                   continue;
+
+               case INITTLSSW:
+                   tls = 2;
                    continue;
 
                case NTLSSW:
@@ -530,6 +494,13 @@ main (int argc, char **argv)
                     save_mts_method (cp);
                    continue;
 
+               case CREDENTIALSSW: {
+                   if (!(cp = *argp++) || *cp == '-')
+                       adios (NULL, "missing argument to %s", argp[-2]);
+                   add_profile_entry ("credentials", cp);
+                   continue;
+               }
+
                case MESSAGEIDSW:
                    if (!(cp = *argp++) || *cp == '-')
                        adios (NULL, "missing argument to %s", argp[-2]);
@@ -558,7 +529,7 @@ main (int argc, char **argv)
     start_headers ();
     if (debug) {
        verbose++;
-       discard (out = stdout); /* XXX: reference discard() to help loader */
+       out = stdout;
     } else {
        if (whomsw) {
            if ((out = fopen ("/dev/null", "w")) == NULL)
@@ -578,35 +549,30 @@ main (int argc, char **argv)
 
     hdrtab = msgstate == NORMAL ? NHeaders : RHeaders;
 
-    for (compnum = 1, state = FLD;;) {
+    for (compnum = 1;;) {
        int bufsz = sizeof buf;
-       switch (state = m_getfld (state, name, buf, &bufsz, in)) {
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, in)) {
            case FLD: 
-           case FLDEOF: 
            case FLDPLUS: 
                compnum++;
                cp = add (buf, NULL);
                while (state == FLDPLUS) {
                    bufsz = sizeof buf;
-                   state = m_getfld (state, name, buf, &bufsz, in);
+                   state = m_getfld (&gstate, name, buf, &bufsz, in);
                    cp = add (buf, cp);
                }
                putfmt (name, cp, out);
                free (cp);
-               if (state != FLDEOF)
-                   continue;
-               finish_headers (out);
-               break;
+               continue;
 
            case BODY: 
-           case BODYEOF: 
                finish_headers (out);
                if (whomsw)
                    break;
                fprintf (out, "\n%s", buf);
                while (state == BODY) {
                    bufsz = sizeof buf;
-                   state = m_getfld (state, name, buf, &bufsz, in);
+                   state = m_getfld (&gstate, name, buf, &bufsz, in);
                    fputs (buf, out);
                }
                break;
@@ -624,6 +590,7 @@ main (int argc, char **argv)
        }
        break;
     }
+    m_getfld_state_destroy (&gstate);
 
     if (pfd != NOTOK)
        anno ();
@@ -681,9 +648,13 @@ main (int argc, char **argv)
     p_refile (tmpfil);
     unlink (tmpfil);
 
-    if (verbose)
-       printf (partno ? "Partial Message #%s Processed\n" : "Message Processed\n",
-               partno);
+    if (verbose) {
+       if (partno)
+           printf ("Partial Message #%s Processed\n", partno);
+       else
+           printf ("Message Processed\n");
+    }
+
     done (0);
     return 1;
 }
@@ -698,7 +669,7 @@ putfmt (char *name, char *str, FILE *out)
 {
     int count, grp, i, keep;
     char *cp, *pp, *qp;
-    char namep[BUFSIZ];
+    char namep[BUFSIZ], error[BUFSIZ];
     struct mailname *mp = NULL, *np = NULL;
     struct headers *hdr;
 
@@ -761,18 +732,20 @@ putfmt (char *name, char *str, FILE *out)
 
     tmpaddrs.m_next = NULL;
     for (count = 0; (cp = getname (str)); count++)
-       if ((mp = getm (cp, NULL, 0, AD_HOST, NULL))) {
+       if ((mp = getm (cp, NULL, 0, error, sizeof(error)))) {
            if (tmpaddrs.m_next)
                np->m_next = mp;
            else
                tmpaddrs.m_next = mp;
            np = mp;
        }
-       else
+       else {
+           admonish(cp, "%s", error);
            if (hdr->flags & HTRY)
                badadr++;
            else
                badmsg++;
+       }
 
     if (count < 1) {
        if (hdr->flags & HNIL)
@@ -813,7 +786,8 @@ putfmt (char *name, char *str, FILE *out)
            if (np->m_gname)
                putgrp (namep, np->m_gname, out, hdr->flags);
            while ((cp = getname (pp))) {
-               if (!(mp = getm (cp, NULL, 0, AD_HOST, NULL))) {
+               if (!(mp = getm (cp, NULL, 0, error, sizeof(error)))) {
+                   admonish(cp, "%s", error);
                    badadr++;
                    continue;
                }
@@ -962,12 +936,6 @@ putfmt (char *name, char *str, FILE *out)
 static void
 start_headers (void)
 {
-    unsigned char  *cp;
-    char sigbuf[BUFSIZ];
-    struct mailname *mp;
-
-    myuid = getuid ();
-    mygid = getgid ();
     time (&tclock);
 
     /*
@@ -978,21 +946,6 @@ start_headers (void)
     efrom[0] = '\0';
     sender[0] = '\0';
     fullfrom[0] = '\0';
-
-    if ((cp = getfullname ()) && *cp) {
-       strncpy (sigbuf, cp, sizeof(sigbuf));
-       snprintf (signature, sizeof(signature), "%s <%s>",
-               sigbuf, getlocaladdr());
-       if ((cp = getname (signature)) == NULL)
-           adios (NULL, "getname () failed -- you lose extraordinarily big");
-       if ((mp = getm (cp, NULL, 0, AD_HOST, NULL)) == NULL)
-           adios (NULL, "bad signature '%s'", sigbuf);
-       mnfree (mp);
-       while (getname (""))
-           continue;
-    } else {
-       strncpy (signature, getlocaladdr(), sizeof(signature));
-    }
 }
 
 
@@ -1115,7 +1068,7 @@ get_header (char *header, struct headers *table)
     struct headers *h;
 
     for (h = table; h->value; h++)
-       if (!mh_strcasecmp (header, h->value))
+       if (!strcasecmp (header ? header : "", h->value ? h->value : ""))
            return (h - table);
 
     return NOTOK;
@@ -1216,9 +1169,11 @@ insert (struct mailname *np)
            : &netaddrs;
            mp->m_next;
            mp = mp->m_next)
-       if (!mh_strcasecmp (np->m_host, mp->m_next->m_host)
-               && !mh_strcasecmp (np->m_mbox, mp->m_next->m_mbox)
-               && np->m_bcc == mp->m_next->m_bcc)
+       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 : "") &&
+           np->m_bcc == mp->m_next->m_bcc)
            return 0;
 
     mp->m_next = np;
@@ -1296,13 +1251,13 @@ annoaux (struct mailname *mp)
 
 
 static void
-insert_fcc (struct headers *hdr, unsigned char *pp)
+insert_fcc (struct headers *hdr, char *pp)
 {
-    unsigned char *cp;
+    char *cp;
 
-    for (cp = pp; isspace (*cp); cp++)
+    for (cp = pp; isspace ((unsigned char) *cp); cp++)
        continue;
-    for (pp += strlen (pp) - 1; pp > cp && isspace (*pp); pp--)
+    for (pp += strlen (pp) - 1; pp > cp && isspace ((unsigned char) *pp); pp--)
        continue;
     if (pp >= cp)
        *++pp = 0;
@@ -1323,9 +1278,9 @@ make_bcc_file (int dashstuff)
 {
     int fd, i;
     pid_t child_id;
-    char *vec[6];
+    char **vec;
     FILE *out;
-    char *tfile = NULL;
+    char *tfile = NULL, *program;
 
     tfile = m_mktemp2(NULL, "bccs", NULL, &out);
     if (tfile == NULL) adios("bcc", "unable to create temporary file");
@@ -1377,8 +1332,6 @@ make_bcc_file (int dashstuff)
      * of MIME encapsulation.
      */
     if (filter != NULL) {
-       vec[0] = r1bindex (mhlproc, '/');
-
        for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
            sleep (5);
        switch (child_id) {
@@ -1388,7 +1341,7 @@ make_bcc_file (int dashstuff)
            case OK: 
                dup2 (fileno (out), 1);
 
-               i = 1;
+               vec = argsplit(mhlproc, &program, &i);
                vec[i++] = "-forward";
                vec[i++] = "-form";
                vec[i++] = filter;
@@ -1401,7 +1354,7 @@ make_bcc_file (int dashstuff)
                    vec[i++] = "-nodashstuffing";
                vec[i] = NULL;
 
-               execvp (mhlproc, vec);
+               execvp (program, vec);
                fprintf (stderr, "unable to exec ");
                perror (mhlproc);
                _exit (-1);
@@ -1444,7 +1397,7 @@ static int
 find_prefix (void)
 {
     int        result = OK;
-    unsigned char buffer[BUFSIZ];
+    char buffer[BUFSIZ];
     FILE *in;
 
     if ((in = fopen (tmpfil, "r")) == NULL)
@@ -1452,10 +1405,10 @@ find_prefix (void)
 
     while (fgets (buffer, sizeof(buffer) - 1, in))
        if (buffer[0] == '-' && buffer[1] == '-') {
-           unsigned char *cp;
+           char *cp;
 
            for (cp = buffer + strlen (buffer) - 1; cp >= buffer; cp--)
-               if (!isspace (*cp))
+               if (!isspace ((unsigned char) *cp))
                    break;
            *++cp = '\0';
            if (strcmp (buffer + 2, prefix) == 0) {
@@ -1552,7 +1505,8 @@ post (char *file, int bccque, int talk, char *envelope)
     sigon ();
 
     if (sm_mts == MTS_SENDMAIL_PIPE) {
-       char *sargv[16], **argp;
+       char **argp, *program;
+       int argc;
 
        for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
            sleep (5);
@@ -1565,17 +1519,16 @@ post (char *file, int bccque, int talk, char *envelope)
                    adios (file, "can't reopen for sendmail");
                }
 
-               argp = sargv;
-               *argp++ = "sendmail";
-               *argp++ = "-t"; /* read msg for recipients */
-               *argp++ = "-i"; /* don't stop on "." */
+               argp = argsplit(sendmail, &program, &argc);
+               argp[argc++] = "-t"; /* read msg for recipients */
+               argp[argc++] = "-i"; /* don't stop on "." */
                if (whomsw)
-                   *argp++ = "-bv";
+                   argp[argc++] = "-bv";
                if (snoop)
-                   *argp++ = "-v";
-               *argp = NULL;
+                   argp[argc++] = "-v";
+               argp[argc] = NULL;
 
-               execv (sendmail, sargv);
+               execv (program, argp);
                adios (sendmail, "can't exec");
 
            default: 
@@ -1826,8 +1779,9 @@ static void
 fcc (char *file, char *folder)
 {
     pid_t child_id;
-    int i, status;
+    int i, status, argp;
     char fold[BUFSIZ];
+    char **arglist, *program;
 
     if (verbose)
        printf ("  %sFcc %s: ", msgstate == RESENT ? "Resent-" : "", folder);
@@ -1850,8 +1804,14 @@ fcc (char *file, char *folder)
                    *folder == '+' || *folder == '@' ? "" : "+", folder);
 
            /* now exec the fileproc */
-           execlp (fileproc, r1bindex (fileproc, '/'),
-                   "-link", "-file", file, fold, NULL);
+
+           arglist = argsplit(fileproc, &program, &argp);
+           arglist[argp++] = "-link";
+           arglist[argp++] = "-file";
+           arglist[argp++] = file;
+           arglist[argp++] = fold;
+           arglist[argp] = NULL;
+           execvp (program, arglist);
            _exit (-1);
 
        default: