]> diplodocus.org Git - nmh/blobdiff - uip/post.c
mhparse.h: Add externs for preferred_types[], etc.
[nmh] / uip / post.c
index 3c9a61e80c5577ef4cc6288a65677f013bb77650..6dc18d101783a98d2e7259a7e56881b0b6e712d3 100644 (file)
@@ -15,6 +15,8 @@
 #include <h/utils.h>
 #include <h/tws.h>
 #include <h/mts.h>
 #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>
 
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
@@ -288,8 +290,9 @@ static char *partno = NULL;
 static void putfmt (char *, char *, int *, FILE *);
 static void start_headers (void);
 static void finish_headers (FILE *);
 static void putfmt (char *, char *, int *, FILE *);
 static void start_headers (void);
 static void finish_headers (FILE *);
-static int get_header (char *, struct headers *);
-static int putadr (char *, char *, struct mailname *, FILE *, unsigned int);
+static int get_header (char *, struct headers *) PURE;
+static int putadr (char *, char *, struct mailname *, FILE *, unsigned int,
+                  char *, unsigned int);
 static void putgrp (char *, char *, FILE *, unsigned int);
 static int insert (struct mailname *);
 static void pl (void);
 static void putgrp (char *, char *, FILE *, unsigned int);
 static int insert (struct mailname *);
 static void pl (void);
@@ -298,12 +301,12 @@ static int annoaux (struct mailname *);
 static void insert_fcc (struct headers *, char *);
 static void make_bcc_file (int);
 static void verify_all_addresses (int, int, char *, int, char *);
 static void insert_fcc (struct headers *, char *);
 static void make_bcc_file (int);
 static void verify_all_addresses (int, int, char *, int, char *);
-static void chkadr (void);
+static void chkadr (void) PURE;
 static void sigon (void);
 static void sigoff (void);
 static void p_refile (char *);
 static void fcc (char *, char *);
 static void sigon (void);
 static void sigoff (void);
 static void p_refile (char *);
 static void fcc (char *, char *);
-static void die (char *, char *, ...);
+static void fatal (char *, char *, ...) CHECK_PRINTF(2, 3);
 static void post (char *, int, int, int, char *, int, char *);
 static void do_text (char *file, int fd);
 static void do_an_address (struct mailname *, int);
 static void post (char *, int, int, int, char *, int, char *);
 static void do_text (char *file, int fd);
 static void do_an_address (struct mailname *, int);
@@ -320,7 +323,7 @@ main (int argc, char **argv)
     char *cp, *msg = NULL, **argp, **arguments, *envelope;
     char buf[NMH_BUFSIZ], name[NAMESZ], *auth_svc = NULL;
     FILE *in, *out;
     char *cp, *msg = NULL, **argp, **arguments, *envelope;
     char buf[NMH_BUFSIZ], name[NAMESZ], *auth_svc = NULL;
     FILE *in, *out;
-    m_getfld_state_t gstate = 0;
+    m_getfld_state_t gstate;
 
     if (nmh_init(argv[0], 0 /* use context_foil() */)) { return 1; }
 
 
     if (nmh_init(argv[0], 0 /* use context_foil() */)) { return 1; }
 
@@ -581,8 +584,7 @@ main (int argc, char **argv)
        }
        if (msg)
            adios (NULL, "only one message at a time!");
        }
        if (msg)
            adios (NULL, "only one message at a time!");
-       else
-           msg = cp;
+        msg = cp;
     }
 
     alias (AliasFile);
     }
 
     alias (AliasFile);
@@ -616,16 +618,17 @@ main (int argc, char **argv)
 
     hdrtab = msgstate == NORMAL ? NHeaders : RHeaders;
 
 
     hdrtab = msgstate == NORMAL ? NHeaders : RHeaders;
 
+    gstate = m_getfld_state_init(in);
     for (compnum = 1;;) {
        int bufsz = sizeof buf;
     for (compnum = 1;;) {
        int bufsz = sizeof buf;
-       switch (state = m_getfld (&gstate, name, buf, &bufsz, in)) {
+       switch (state = m_getfld2(&gstate, name, buf, &bufsz)) {
            case FLD: 
            case FLDPLUS: 
                 compnum++;
                cp = mh_xstrdup(buf);
                while (state == FLDPLUS) {
                    bufsz = sizeof buf;
            case FLD: 
            case FLDPLUS: 
                 compnum++;
                cp = mh_xstrdup(buf);
                while (state == FLDPLUS) {
                    bufsz = sizeof buf;
-                   state = m_getfld (&gstate, name, buf, &bufsz, in);
+                   state = m_getfld2(&gstate, name, buf, &bufsz);
                    cp = add (buf, cp);
                }
                putfmt (name, cp, &eai, out);
                    cp = add (buf, cp);
                }
                putfmt (name, cp, &eai, out);
@@ -639,7 +642,7 @@ main (int argc, char **argv)
                fprintf (out, "\n%s", buf);
                while (state == BODY) {
                    bufsz = sizeof buf;
                fprintf (out, "\n%s", buf);
                while (state == BODY) {
                    bufsz = sizeof buf;
-                   state = m_getfld (&gstate, name, buf, &bufsz, in);
+                   state = m_getfld2(&gstate, name, buf, &bufsz);
                    fputs (buf, out);
                }
                break;
                    fputs (buf, out);
                }
                break;
@@ -666,9 +669,8 @@ main (int argc, char **argv)
     if (debug) {
        pl ();
        done (0);
     if (debug) {
        pl ();
        done (0);
-    } else {
-       fclose (out);
     }
     }
+    fclose (out);
 
     /*
      * Here's how we decide which address to use as the envelope-from
 
     /*
      * Here's how we decide which address to use as the envelope-from
@@ -788,6 +790,8 @@ putfmt (char *name, char *str, int *eai, FILE *out)
     int count, grp, i, keep;
     char *cp, *pp, *qp;
     char namep[BUFSIZ], error[BUFSIZ];
     int count, grp, i, keep;
     char *cp, *pp, *qp;
     char namep[BUFSIZ], error[BUFSIZ];
+    char *savehdr = NULL;
+    unsigned int savehdrlen = 0;
     struct mailname *mp = NULL, *np = NULL;
     struct headers *hdr;
 
     struct mailname *mp = NULL, *np = NULL;
     struct headers *hdr;
 
@@ -871,6 +875,19 @@ putfmt (char *name, char *str, int *eai, FILE *out)
        return;
     }
 
        return;
     }
 
+    /*
+     * If this is a From:/Resent-From: header, save the full thing for
+     * later in case we need it for use when constructing a Bcc draft message.
+     * Because we want to capture the results of alias expansion, save
+     * the output from putadr().
+     */
+
+    if ((msgstate == RESENT) ? (hdr->set & MRFM) : (hdr->set & MFRM)) {
+       savehdr = fullfrom;
+       savehdr[0] = '\0';
+       savehdrlen = sizeof(fullfrom);
+    }
+
     tmpaddrs.m_next = NULL;
 
     for (count = 0; (cp = getname (str)); count++) {
     tmpaddrs.m_next = NULL;
 
     for (count = 0; (cp = getname (str)); count++) {
@@ -971,9 +988,8 @@ putfmt (char *name, char *str, int *eai, FILE *out)
                    mp->m_bcc++;
                if (np->m_ingrp)
                    mp->m_ingrp = np->m_ingrp;
                    mp->m_bcc++;
                if (np->m_ingrp)
                    mp->m_ingrp = np->m_ingrp;
-               else
-                   if (mp->m_gname)
-                       putgrp (namep, mp->m_gname, out, hdr->flags);
+               else if (mp->m_gname)
+                    putgrp (namep, mp->m_gname, out, hdr->flags);
                if (mp->m_ingrp) {
                    if (sm_mts == MTS_SENDMAIL_PIPE) {
                        /* Catch this before sendmail chokes with:
                if (mp->m_ingrp) {
                    if (sm_mts == MTS_SENDMAIL_PIPE) {
                        /* Catch this before sendmail chokes with:
@@ -990,7 +1006,8 @@ putfmt (char *name, char *str, int *eai, FILE *out)
 
                    grp++;
                }
 
                    grp++;
                }
-               if (putadr (namep, qp, mp, out, hdr->flags))
+               if (putadr (namep, qp, mp, out, hdr->flags, savehdr,
+                           savehdrlen))
                    msgflags |= (hdr->set & (MVIS | MINV));
                else
                    mnfree (mp);
                    msgflags |= (hdr->set & (MVIS | MINV));
                else
                    mnfree (mp);
@@ -1039,7 +1056,7 @@ putfmt (char *name, char *str, int *eai, FILE *out)
                putgrp (namep, mp->m_gname, out, hdr->flags);
            if (mp->m_ingrp)
                grp++;
                putgrp (namep, mp->m_gname, out, hdr->flags);
            if (mp->m_ingrp)
                grp++;
-           keep = putadr (namep, "", mp, out, hdr->flags);
+           keep = putadr (namep, "", mp, out, hdr->flags, savehdr, savehdrlen);
            np = mp->m_next;
            if (keep) {
                mp->m_next = NULL;
            np = mp->m_next;
            if (keep) {
                mp->m_next = NULL;
@@ -1050,17 +1067,11 @@ putfmt (char *name, char *str, int *eai, FILE *out)
        }
 
     /*
        }
 
     /*
-     * If this is a From:/Resent-From: header, save the full thing for
-     * later in case we need it for use when constructing a Bcc draft message
+     * If it was a From header, strip off any trailing newlines from
+     * the alias-expanded From line.
      */
 
     if ((msgstate == RESENT) ? (hdr->set & MRFM) : (hdr->set & MFRM)) {
      */
 
     if ((msgstate == RESENT) ? (hdr->set & MRFM) : (hdr->set & MFRM)) {
-       strncpy(fullfrom, str, sizeof(fullfrom));
-       fullfrom[sizeof(fullfrom) - 1] = 0;
-       /*
-        * Strip off any trailing newlines
-        */
-
        while (*fullfrom && fullfrom[strlen(fullfrom) - 1] == '\n') {
            fullfrom[strlen(fullfrom) - 1] = '\0';
        }
        while (*fullfrom && fullfrom[strlen(fullfrom) - 1] == '\n') {
            fullfrom[strlen(fullfrom) - 1] = '\0';
        }
@@ -1219,9 +1230,11 @@ get_header (char *header, struct headers *table)
 
 
 static int
 
 
 static int
-putadr (char *name, char *aka, struct mailname *mp, FILE *out, unsigned int flags)
+putadr (char *name, char *aka, struct mailname *mp, FILE *out,
+       unsigned int flags, char *savehdr, unsigned int savehdrsize)
 {
 {
-    int len;
+    int len, saveappend = 0;
+    unsigned int shlen;
     char *cp;
     char buffer[BUFSIZ];
 
     char *cp;
     char buffer[BUFSIZ];
 
@@ -1236,6 +1249,11 @@ putadr (char *name, char *aka, struct mailname *mp, FILE *out, unsigned int flag
        linepos += (nameoutput = strlen (name) + 2);
     }
 
        linepos += (nameoutput = strlen (name) + 2);
     }
 
+    if (savehdr) {
+       shlen = strlen(savehdr);
+       saveappend = 1;
+    }
+
     if (*aka && mp->m_type != UUCPHOST && !mp->m_pers)
        mp->m_pers = mh_xstrdup(aka);
     if (format) {
     if (*aka && mp->m_type != UUCPHOST && !mp->m_pers)
        mp->m_pers = mh_xstrdup(aka);
     if (format) {
@@ -1251,15 +1269,34 @@ putadr (char *name, char *aka, struct mailname *mp, FILE *out, unsigned int flag
     len = strlen (cp);
 
     if (linepos != nameoutput) {
     len = strlen (cp);
 
     if (linepos != nameoutput) {
-       if (len + linepos + 2 > outputlinelen)
+       if (len + linepos + 2 > outputlinelen) {
            fprintf (out, ",\n%*s", linepos = nameoutput, "");
            fprintf (out, ",\n%*s", linepos = nameoutput, "");
-       else {
+           if (saveappend) {
+               if (shlen + 2 + nameoutput + len >= savehdrsize) {
+                   saveappend = 0;
+               } else {
+                   snprintf(savehdr + shlen, savehdrsize - shlen, ",\n%*s",
+                            linepos, "");
+               }
+           }
+       } else {
            fputs (", ", out);
            linepos += 2;
            fputs (", ", out);
            linepos += 2;
+           if (saveappend) {
+               if (shlen + 2 + len >= savehdrsize) {
+                   saveappend = 0;
+               } else {
+                   strncat(savehdr, ", ", savehdrsize - shlen);
+               }
+           }
        }
     }
 
     fputs (cp, out);
        }
     }
 
     fputs (cp, out);
+
+    if (saveappend && shlen + len < savehdrsize)
+       strncat(savehdr, cp, savehdrsize - shlen + len);
+
     linepos += len;
 
     return (flags & HTRY);
     linepos += len;
 
     return (flags & HTRY);
@@ -1455,11 +1492,10 @@ make_bcc_file (int dashstuff)
        while (find_prefix () == NOTOK) {
            if (*cp < 'z')
                (*cp)++;
        while (find_prefix () == NOTOK) {
            if (*cp < 'z')
                (*cp)++;
-           else
-               if (*++cp == 0)
-                   adios (NULL, "can't find a unique delimiter string");
-               else
-                   (*cp)++;
+           else if (*++cp == 0)
+                adios (NULL, "can't find a unique delimiter string");
+            else
+                (*cp)++;
        }
 
        fprintf (out, "%s: %s\n%s: multipart/digest; boundary=\"",
        }
 
        fprintf (out, "%s: %s\n%s: multipart/digest; boundary=\"",
@@ -1566,18 +1602,16 @@ find_prefix (void)
 }
 
 
 }
 
 
-#define        plural(x) (x == 1 ? "" : "s")
-
 static void
 chkadr (void)
 {
     if (badadr && unkadr)
 static void
 chkadr (void)
 {
     if (badadr && unkadr)
-       die (NULL, "%d address%s unparsable, %d addressee%s undeliverable",
-               badadr, plural (badadr), unkadr, plural (badadr));
+       fatal (NULL, "%d address%s unparsable, %d addressee%s undeliverable",
+               badadr, PLURALS(badadr), unkadr, PLURALS(badadr));
     if (badadr)
     if (badadr)
-       die (NULL, "%d address%s unparsable", badadr, plural (badadr));
+       fatal (NULL, "%d address%s unparsable", badadr, PLURALS(badadr));
     if (unkadr)
     if (unkadr)
-       die (NULL, "%d addressee%s undeliverable", unkadr, plural (unkadr));
+       fatal (NULL, "%d addressee%s undeliverable", unkadr, PLURALS(unkadr));
 }
 
 
 }
 
 
@@ -1618,7 +1652,7 @@ do_addresses (int bccque, int talk)
     chkadr ();
 
     if (rp_isbad (retval = sm_waend ()))
     chkadr ();
 
     if (rp_isbad (retval = sm_waend ()))
-       die (NULL, "problem ending addresses; %s", rp_string (retval));
+       fatal (NULL, "problem ending addresses; %s", rp_string (retval));
 }
 
 
 }
 
 
@@ -1684,7 +1718,7 @@ post (char *file, int bccque, int talk, int eai, char *envelope,
         int eightbit = 0;
 
         if (fd == NOTOK) {
         int eightbit = 0;
 
         if (fd == NOTOK) {
-          die (file, "unable to re-open");
+          fatal (file, "unable to re-open");
         }
 
         if (msgflags & MMIM  &&  cte != UNKNOWN) {
         }
 
         if (msgflags & MMIM  &&  cte != UNKNOWN) {
@@ -1694,7 +1728,7 @@ post (char *file, int bccque, int talk, int eai, char *envelope,
         } else {
             if (scan_input (fd, &eightbit) == NOTOK) {
                 close (fd);
         } else {
             if (scan_input (fd, &eightbit) == NOTOK) {
                 close (fd);
-                die (file, "problem reading from");
+                fatal (file, "problem reading from");
             }
         }
 
             }
         }
 
@@ -1703,7 +1737,7 @@ post (char *file, int bccque, int talk, int eai, char *envelope,
                                        oauth_flag ? auth_svc : NULL, tlsflag))
                || rp_isbad (retval = sm_winit (envelope, eai, eightbit))) {
            close (fd);
                                        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));
+           fatal (NULL, "problem initializing server; %s", rp_string (retval));
        }
 
         do_addresses (bccque, talk && verbose);
        }
 
         do_addresses (bccque, talk && verbose);
@@ -1746,7 +1780,7 @@ verify_all_addresses (int talk, int eai, char *envelope, int oauth_flag,
                                        verbose, snoop, sasl, saslmech, user,
                                        oauth_flag ? auth_svc : NULL, tlsflag))
                || rp_isbad (retval = sm_winit (envelope, eai, eightbit))) {
                                        verbose, snoop, sasl, saslmech, user,
                                        oauth_flag ? auth_svc : NULL, tlsflag))
                || rp_isbad (retval = sm_winit (envelope, eai, eightbit))) {
-           die (NULL, "problem initializing server; %s", rp_string (retval));
+           fatal (NULL, "problem initializing server; %s", rp_string (retval));
        }
     }
 
        }
     }
 
@@ -1836,7 +1870,7 @@ do_an_address (struct mailname *lp, int talk)
        default: 
            if (!talk)
                fprintf (stderr, "  %s: ", addr);
        default: 
            if (!talk)
                fprintf (stderr, "  %s: ", addr);
-           die (NULL, "unexpected response; %s", rp_string (retval));
+           fatal (NULL, "unexpected response; %s", rp_string (retval));
     }
 
     fflush (stdout);
     }
 
     fflush (stdout);
@@ -1849,15 +1883,15 @@ do_text (char *file, int fd)
     int retval, state;
     char buf[BUFSIZ];
 
     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)))
 
     while ((state = read (fd, buf, sizeof(buf))) > 0) {
        if (rp_isbad (retval = sm_wtxt (buf, state)))
-           die (NULL, "problem writing text; %s\n", rp_string (retval));
+           fatal (NULL, "problem writing text; %s\n", rp_string (retval));
     }
 
     if (state == NOTOK)
     }
 
     if (state == NOTOK)
-       die (file, "problem reading from");
+       fatal (file, "problem reading from");
 
     switch (retval = sm_wtend ()) {
        case RP_OK: 
 
     switch (retval = sm_wtend ()) {
        case RP_OK: 
@@ -1865,11 +1899,11 @@ do_text (char *file, int fd)
 
        case RP_NO: 
        case RP_NDEL: 
 
        case RP_NO: 
        case RP_NDEL: 
-           die (NULL, "posting failed; %s", rp_string (retval));
-           /* FALLTHRU */
+           fatal (NULL, "posting failed; %s", rp_string (retval));
+           break;
 
        default: 
 
        default: 
-           die (NULL, "unexpected response; %s", rp_string (retval));
+           fatal (NULL, "unexpected response; %s", rp_string (retval));
     }
 }
 
     }
 }
 
@@ -1988,7 +2022,7 @@ fcc (char *file, char *folder)
                if (!verbose)
                    fprintf (stderr, "  %sFcc %s: ",
                            msgstate == RESENT ? "Resent-" : "", 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");
            } else {
                if (verbose)
                    puts("folder ok");
@@ -2003,7 +2037,7 @@ fcc (char *file, char *folder)
  */
 
 static void
  */
 
 static void
-die (char *what, char *fmt, ...)
+fatal (char *what, char *fmt, ...)
 {
     int err;
     va_list ap;
 {
     int err;
     va_list ap;